Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #99 from mryan43/master
[JENKINS-41657] Allow filling of credential ids from admin panel
  • Loading branch information
jglick committed Jun 16, 2017
2 parents 2903930 + 707fe65 commit 0997b9d
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 8 deletions.
8 changes: 7 additions & 1 deletion src/main/java/hudson/plugins/mercurial/MercurialSCM.java
Expand Up @@ -1062,14 +1062,20 @@ public boolean configure(StaplerRequest req, JSONObject json) throws FormExcepti
}

public ListBoxModel doFillCredentialsIdItems(@AncestorInPath Job<?,?> owner, @QueryParameter String source) {
if (owner == null || !owner.hasPermission(Item.EXTENDED_READ)) {
if (!hasAccessToCredentialsMetadata(owner)) {
return new ListBoxModel();
}
return new StandardUsernameListBoxModel()
.withEmptySelection()
.withAll(availableCredentials(owner, new EnvVars( ).expand( source )));
}

private boolean hasAccessToCredentialsMetadata(Job<?,?> owner) {
if (owner == null){
return Jenkins.getActiveInstance().hasPermission(Jenkins.ADMINISTER);
}
return owner.hasPermission(Item.EXTENDED_READ);
}
}

private static final long serialVersionUID = 1L;
Expand Down
52 changes: 45 additions & 7 deletions src/main/java/hudson/plugins/mercurial/MercurialSCMSource.java
Expand Up @@ -6,11 +6,7 @@
import com.cloudbees.plugins.credentials.domains.URIRequirementBuilder;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.SuppressWarnings;
import hudson.EnvVars;
import hudson.Extension;
import hudson.FilePath;
import hudson.Launcher;
import hudson.Util;
import hudson.*;
import hudson.model.Action;
import hudson.model.Descriptor;
import hudson.model.Item;
Expand Down Expand Up @@ -71,7 +67,7 @@ public MercurialSCMSource(String id, String installation, String source, String
this.browser = browser;
this.clean = clean;
}

public String getInstallation() {
return installation;
}
Expand Down Expand Up @@ -190,6 +186,41 @@ public long lastModified() {
}
}

@Override
@CheckForNull
protected SCMRevision retrieve(@NonNull String thingName, @NonNull TaskListener listener) throws IOException, InterruptedException {
MercurialInstallation inst = MercurialSCM.findInstallation(installation);
if (inst == null) {
listener.error("No configured Mercurial installation");
return null;
}
if (!inst.isUseCaches()) {
listener.error("Mercurial installation " + installation + " does not support caches");
return null;
}
final Node node = Jenkins.getActiveInstance();
Launcher launcher = node.createLauncher(listener);
StandardUsernameCredentials credentials = getCredentials();
final FilePath cache = Cache.fromURL(source, credentials, inst.getMasterCacheRoot()).repositoryCache(inst, node, launcher, listener, true);
if (cache == null) {
listener.error("Could not use caches, not fetching branch heads");
return null;
}
final HgExe hg = new HgExe(inst, credentials, launcher, node, listener, new EnvVars());
try {
String revision = hg.popen(cache, listener, true, new ArgumentListBuilder("log", "-r", "present("+thingName+")", "--template", "{node} {branch}"));
if (revision.isEmpty()){
return null;
}
String hash = revision.substring(0, revision.indexOf(' '));
String branch = revision.substring(revision.indexOf(' ')+1, revision.length());
return new MercurialRevision(new SCMHead(branch), hash);
} finally {
hg.close();
}

}

@SuppressWarnings("DB_DUPLICATE_BRANCHES")
@Override public SCM build(SCMHead head, SCMRevision revision) {
String rev = revision == null ? head.getName() : ((MercurialRevision) revision).hash;
Expand Down Expand Up @@ -230,14 +261,21 @@ private static List<? extends StandardUsernameCredentials> availableCredentials(
}

public ListBoxModel doFillCredentialsIdItems(@AncestorInPath SCMSourceOwner owner, @QueryParameter String source) {
if (owner == null || !owner.hasPermission(Item.EXTENDED_READ)) {
if (!hasAccessToCredentialsMetadata(owner)) {
return new ListBoxModel();
}
return new StandardUsernameListBoxModel()
.withEmptySelection()
.withAll(availableCredentials(owner, source));
}

private boolean hasAccessToCredentialsMetadata(SCMSourceOwner owner){
if (owner == null){
return Jenkins.getActiveInstance().hasPermission(Jenkins.ADMINISTER);
}
return owner.hasPermission(Item.EXTENDED_READ);
}

public FormValidation doCheckBranchPattern(@QueryParameter String value) {
try {
Pattern.compile(value);
Expand Down
16 changes: 16 additions & 0 deletions src/test/java/hudson/plugins/mercurial/ConfigurationTest.java
Expand Up @@ -49,6 +49,7 @@
import org.junit.Rule;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.MockAuthorizationStrategy;

public class ConfigurationTest {

Expand Down Expand Up @@ -91,6 +92,21 @@ public class ConfigurationTest {
assertFalse(scm.isDisableChangeLog());
}

@Test public void doFillCredentialsIdItemsWithoutJobWhenAdmin() throws Exception {
r.jenkins.setSecurityRealm(r.createDummySecurityRealm());
ProjectMatrixAuthorizationStrategy as = new ProjectMatrixAuthorizationStrategy();
as.add(Jenkins.ADMINISTER, "alice");
r.jenkins.setAuthorizationStrategy(as);
final UsernamePasswordCredentialsImpl c = new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, null, "test", "bob", "s3cr3t");
CredentialsProvider.lookupStores(r.jenkins).iterator().next().addCredentials(Domain.global(), c);
ACL.impersonate(User.get("alice").impersonate(), new Runnable() {
@Override public void run() {
ListBoxModel options = r.jenkins.getDescriptorByType(MercurialSCM.DescriptorImpl.class).doFillCredentialsIdItems(null, "http://nowhere.net/");
assertEquals(CredentialsNameProvider.name(c), options.get(1).name);
}
});
}

@Issue("SECURITY-158")
@Test public void doFillCredentialsIdItems() throws Exception {
r.jenkins.setSecurityRealm(r.createDummySecurityRealm());
Expand Down
73 changes: 73 additions & 0 deletions src/test/java/hudson/plugins/mercurial/MercurialSCMSourceTest.java
@@ -0,0 +1,73 @@
package hudson.plugins.mercurial;

import hudson.FilePath;
import hudson.tools.ToolProperty;
import hudson.util.LogTaskListener;
import hudson.util.StreamTaskListener;
import jenkins.scm.api.SCMRevision;
import org.junit.*;
import org.junit.rules.TemporaryFolder;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.JenkinsRule;

import java.util.Collections;
import java.util.logging.Level;
import java.util.logging.Logger;

import static org.junit.Assert.assertTrue;

@Issue("JENKINS-41657")
public class MercurialSCMSourceTest {

@ClassRule public static JenkinsRule j = new JenkinsRule();
@ClassRule public static MercurialRule m = new MercurialRule(j);
@ClassRule public static TemporaryFolder tmp = new TemporaryFolder();

private static LogTaskListener listener;
private static MercurialSCMSource mercurialSCMSource;

@BeforeClass
public static void prepareEnvironment() throws Exception {
String instName = "caching";
MercurialInstallation installation = new MercurialInstallation(instName, "", "hg", false, true, null, false, null,
Collections.<ToolProperty<?>>emptyList());
listener = new LogTaskListener(Logger.getLogger(MercurialSCMSourceTest.class.getName()), Level.INFO);
j.jenkins.getDescriptorByType(MercurialInstallation.DescriptorImpl.class).setInstallations(installation);
FilePath repo = new FilePath(tmp.getRoot());
installation.forNode(j.jenkins, StreamTaskListener.fromStdout());
m.hg(repo, "init");
repo.child("file").write("initial content", "UTF-8");
m.hg(repo, "commit", "--addremove", "--message=initial");
m.hg(repo, "tag", "version-1.0");
m.hg(repo, "branch", "my-branch");
repo.child("file2").write("content in branch", "UTF-8");
m.hg(repo, "commit", "--addremove", "--message=branch");
m.hg(repo, "tag", "version-1.1");


installation.forNode(j.jenkins, StreamTaskListener.fromStdout());
mercurialSCMSource = new MercurialSCMSource(null, instName, tmp.getRoot().toURI().toURL().toString(), null, null, null, null, null, true);
}

@Test public void testRetrieveUnknownRevision() throws Exception {
Assert.assertNull(mercurialSCMSource.retrieve("does_not_exist", listener));
}

@Test public void testRetrieveTag() throws Exception {
SCMRevision revision = mercurialSCMSource.retrieve("version-1.1", listener);
assertTrue(revision.toString().startsWith("my-branch:"));
revision = mercurialSCMSource.retrieve("version-1.0", listener);
assertTrue(revision.toString().startsWith("default:"));
}

@Test public void testRetrieveBranchTip() throws Exception {
SCMRevision revision = mercurialSCMSource.retrieve("my-branch", listener);
assertTrue(revision.toString().startsWith("my-branch:"));
}

@Test public void testRetrieveRepoTip() throws Exception {
SCMRevision revision = mercurialSCMSource.retrieve("tip", listener);
assertTrue(revision.toString().startsWith("my-branch:"));
}

}

0 comments on commit 0997b9d

Please sign in to comment.