Search in sources :

Example 1 with BlueOceanDomainRequirement

use of io.jenkins.blueocean.rest.impl.pipeline.credential.BlueOceanDomainRequirement in project blueocean-plugin by jenkinsci.

the class GithubScm method validateAndCreate.

@Override
public HttpResponse validateAndCreate(@JsonBody JSONObject request) {
    String accessToken = (String) request.get("accessToken");
    if (accessToken == null) {
        throw new ServiceException.BadRequestExpception("accessToken is required");
    }
    try {
        User authenticatedUser = getAuthenticatedUser();
        HttpURLConnection connection = connect(String.format("%s/%s", getUri(), "user"), accessToken);
        validateAccessTokenScopes(connection);
        String data = IOUtils.toString(connection.getInputStream());
        GHUser user = GithubScm.om.readValue(data, GHUser.class);
        if (user.getEmail() != null) {
            Mailer.UserProperty p = authenticatedUser.getProperty(Mailer.UserProperty.class);
            // the one from Github?
            if (p == null) {
                authenticatedUser.addProperty(new Mailer.UserProperty(user.getEmail()));
            }
        }
        //Now we know the token is valid. Lets find credential
        StandardUsernamePasswordCredentials githubCredential = CredentialsUtils.findCredential(getId(), StandardUsernamePasswordCredentials.class, new BlueOceanDomainRequirement());
        final StandardUsernamePasswordCredentials credential = new UsernamePasswordCredentialsImpl(CredentialsScope.USER, "github", "Github Access Token", authenticatedUser.getId(), accessToken);
        if (githubCredential == null) {
            CredentialsUtils.createCredentialsInUserStore(credential, authenticatedUser, getCredentialsDomainName(getUri()), ImmutableList.<DomainSpecification>of(new BlueOceanDomainSpecification()));
        } else {
            CredentialsUtils.updateCredentialsInUserStore(githubCredential, credential, authenticatedUser, getCredentialsDomainName(getUri()), ImmutableList.<DomainSpecification>of(new BlueOceanDomainSpecification()));
        }
        return createResponse(credential.getId());
    } catch (IOException e) {
        throw new ServiceException.UnexpectedErrorException(e.getMessage());
    }
}
Also used : GHUser(org.kohsuke.github.GHUser) User(hudson.model.User) BlueOceanDomainSpecification(io.jenkins.blueocean.rest.impl.pipeline.credential.BlueOceanDomainSpecification) Mailer(hudson.tasks.Mailer) GHUser(org.kohsuke.github.GHUser) IOException(java.io.IOException) UsernamePasswordCredentialsImpl(com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl) StandardUsernamePasswordCredentials(com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials) HttpURLConnection(java.net.HttpURLConnection) ServiceException(io.jenkins.blueocean.commons.ServiceException) BlueOceanDomainRequirement(io.jenkins.blueocean.rest.impl.pipeline.credential.BlueOceanDomainRequirement)

Example 2 with BlueOceanDomainRequirement

use of io.jenkins.blueocean.rest.impl.pipeline.credential.BlueOceanDomainRequirement in project blueocean-plugin by jenkinsci.

the class GithubPipelineCreateRequest method validateCredentialId.

static void validateCredentialId(String credentialId, String apiUrl) throws IOException {
    if (credentialId != null && !credentialId.trim().isEmpty()) {
        StandardUsernamePasswordCredentials credentials = CredentialsUtils.findCredential(credentialId, StandardUsernamePasswordCredentials.class, new BlueOceanDomainRequirement());
        if (credentials == null) {
            throw new ServiceException.BadRequestExpception(new ErrorMessage(400, "Failed to create Github pipeline").add(new ErrorMessage.Error("scmConfig.credentialId", ErrorMessage.Error.ErrorCodes.NOT_FOUND.toString(), "No Credentials instance found for credentialId: " + credentialId)));
        } else {
            String accessToken = credentials.getPassword().getPlainText();
            validateGithubAccessToken(accessToken, apiUrl);
        }
    }
}
Also used : StandardUsernamePasswordCredentials(com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials) BlueOceanDomainRequirement(io.jenkins.blueocean.rest.impl.pipeline.credential.BlueOceanDomainRequirement) ErrorMessage(io.jenkins.blueocean.commons.ErrorMessage)

Example 3 with BlueOceanDomainRequirement

use of io.jenkins.blueocean.rest.impl.pipeline.credential.BlueOceanDomainRequirement in project blueocean-plugin by jenkinsci.

the class GithubPipelineCreateRequest method create.

@SuppressWarnings("unchecked")
@Override
public BluePipeline create(Reachable parent) throws IOException {
    String apiUrl = null;
    //default
    String orgName = getName();
    String credentialId = null;
    StringBuilder sb = new StringBuilder();
    List<String> repos = new ArrayList<>();
    if (scmConfig != null) {
        apiUrl = StringUtils.defaultIfBlank(scmConfig.getUri(), GithubScm.DEFAULT_API_URI);
        if (scmConfig.getConfig().get("orgName") instanceof String) {
            orgName = (String) scmConfig.getConfig().get("orgName");
        }
        credentialId = scmConfig.getCredentialId();
        if (scmConfig != null && scmConfig.getConfig().get("repos") instanceof List) {
            for (String r : (List<String>) scmConfig.getConfig().get("repos")) {
                sb.append(String.format("(%s\\b)?", r));
                repos.add(r);
            }
        }
    }
    User authenticatedUser = User.current();
    if (authenticatedUser == null) {
        throw new ServiceException.UnauthorizedException("Must login to create a pipeline");
    }
    TopLevelItem item = null;
    try {
        if (credentialId != null) {
            validateCredentialId(credentialId, apiUrl);
        }
        item = create(Jenkins.getInstance(), getName(), DESCRIPTOR, CustomOrganizationFolderDescriptor.class);
        if (item instanceof OrganizationFolder) {
            if (credentialId != null) {
                //Find domain attached to this credentialId, if present check if it's BlueOcean specific domain then
                //add the properties otherwise simply use it
                Domain domain = CredentialsUtils.findDomain(credentialId, authenticatedUser);
                if (domain == null) {
                    //this should not happen since validateCredentialId found the credential
                    throw new ServiceException.BadRequestExpception(new ErrorMessage(400, "Failed to create pipeline").add(new ErrorMessage.Error("scm.credentialId", ErrorMessage.Error.ErrorCodes.INVALID.toString(), "No domain in user credentials found for credentialId: " + scmConfig.getCredentialId())));
                }
                if (domain.test(new BlueOceanDomainRequirement())) {
                    ((OrganizationFolder) item).addProperty(new BlueOceanCredentialsProvider.FolderPropertyImpl(authenticatedUser.getId(), credentialId, BlueOceanCredentialsProvider.createDomain(apiUrl)));
                }
            }
            GitHubSCMNavigator gitHubSCMNavigator = new GitHubSCMNavigator(apiUrl, orgName, credentialId, credentialId);
            if (sb.length() > 0) {
                gitHubSCMNavigator.setPattern(sb.toString());
            }
            // cick of github scan build
            OrganizationFolder organizationFolder = (OrganizationFolder) item;
            organizationFolder.getNavigators().replace(gitHubSCMNavigator);
            if (repos.size() == 1) {
                SCMSourceEvent.fireNow(new SCMSourceEventImpl(repos.get(0), item, apiUrl, gitHubSCMNavigator));
            } else {
                organizationFolder.scheduleBuild(new Cause.UserIdCause());
            }
            return new GithubOrganizationFolder(organizationFolder, parent.getLink());
        }
    } catch (Exception e) {
        String msg = String.format("Error creating pipeline %s: %s", getName(), e.getMessage());
        logger.error(msg, e);
        if (item != null) {
            try {
                item.delete();
            } catch (InterruptedException e1) {
                logger.error(String.format("Error creating pipeline %s: %s", getName(), e1.getMessage()), e1);
                throw new ServiceException.UnexpectedErrorException("Error cleaning up pipeline " + getName() + " due to error: " + e.getMessage(), e);
            }
        }
        if (e instanceof ServiceException) {
            throw e;
        }
        throw new ServiceException.UnexpectedErrorException(msg, e);
    }
    return null;
}
Also used : User(hudson.model.User) ArrayList(java.util.ArrayList) TopLevelItem(hudson.model.TopLevelItem) Cause(hudson.model.Cause) ArrayList(java.util.ArrayList) List(java.util.List) CustomOrganizationFolderDescriptor(jenkins.branch.CustomOrganizationFolderDescriptor) OrganizationFolder(jenkins.branch.OrganizationFolder) BlueOceanCredentialsProvider(io.jenkins.blueocean.rest.impl.pipeline.credential.BlueOceanCredentialsProvider) GitHubSCMNavigator(org.jenkinsci.plugins.github_branch_source.GitHubSCMNavigator) IOException(java.io.IOException) ServiceException(io.jenkins.blueocean.commons.ServiceException) ServiceException(io.jenkins.blueocean.commons.ServiceException) BlueOceanDomainRequirement(io.jenkins.blueocean.rest.impl.pipeline.credential.BlueOceanDomainRequirement) Domain(com.cloudbees.plugins.credentials.domains.Domain) ErrorMessage(io.jenkins.blueocean.commons.ErrorMessage)

Example 4 with BlueOceanDomainRequirement

use of io.jenkins.blueocean.rest.impl.pipeline.credential.BlueOceanDomainRequirement in project blueocean-plugin by jenkinsci.

the class GithubOrgFolderTest method shouldFindUserStoreCredential.

@Test
public void shouldFindUserStoreCredential() throws IOException {
    //add username password credential to user's credential store in user domain and in USER scope
    User user = login();
    CredentialsStore store = null;
    for (CredentialsStore s : CredentialsProvider.lookupStores(user)) {
        if (s.hasPermission(CredentialsProvider.CREATE) && s.hasPermission(CredentialsProvider.UPDATE)) {
            store = s;
            break;
        }
    }
    assertNotNull(store);
    store.addDomain(new Domain("github-domain", "Github Domain to store personal access token", Collections.<DomainSpecification>singletonList(new BlueOceanDomainSpecification())));
    Domain domain = store.getDomainByName("github-domain");
    StandardUsernamePasswordCredentials credential = new UsernamePasswordCredentialsImpl(CredentialsScope.USER, "github", "Github Access Token", user.getId(), "12345");
    store.addCredentials(domain, credential);
    //create another credentials with same id in system store with different description
    for (CredentialsStore s : CredentialsProvider.lookupStores(Jenkins.getInstance())) {
        s.addCredentials(Domain.global(), new UsernamePasswordCredentialsImpl(CredentialsScope.USER, "github", "System Github Access Token", user.getId(), "12345"));
    }
    //create org folder and attach user and credential id to it
    OrganizationFolder organizationFolder = j.createProject(OrganizationFolder.class, "demo");
    AbstractFolderProperty prop = new BlueOceanCredentialsProvider.FolderPropertyImpl(user.getId(), credential.getId(), BlueOceanCredentialsProvider.createDomain("https://api.github.com"));
    organizationFolder.addProperty(prop);
    // lookup for created credential id in system store, it should resolve to previously created user store credential
    StandardCredentials c = Connector.lookupScanCredentials(organizationFolder, "https://api.github.com", credential.getId());
    assertEquals("Github Access Token", c.getDescription());
    assertNotNull(c);
    assertTrue(c instanceof StandardUsernamePasswordCredentials);
    StandardUsernamePasswordCredentials usernamePasswordCredentials = (StandardUsernamePasswordCredentials) c;
    assertEquals(credential.getId(), usernamePasswordCredentials.getId());
    assertEquals(credential.getPassword().getPlainText(), usernamePasswordCredentials.getPassword().getPlainText());
    assertEquals(credential.getUsername(), usernamePasswordCredentials.getUsername());
    //check the domain
    Domain d = CredentialsUtils.findDomain(credential.getId(), user);
    assertNotNull(d);
    assertTrue(d.test(new BlueOceanDomainRequirement()));
    //now remove this property
    organizationFolder.getProperties().remove(prop);
    //it must resolve to system credential
    c = Connector.lookupScanCredentials(organizationFolder, null, credential.getId());
    assertEquals("System Github Access Token", c.getDescription());
}
Also used : StandardUsernamePasswordCredentials(com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials) User(hudson.model.User) OrganizationFolder(jenkins.branch.OrganizationFolder) BlueOceanDomainRequirement(io.jenkins.blueocean.rest.impl.pipeline.credential.BlueOceanDomainRequirement) CredentialsStore(com.cloudbees.plugins.credentials.CredentialsStore) BlueOceanDomainSpecification(io.jenkins.blueocean.rest.impl.pipeline.credential.BlueOceanDomainSpecification) Domain(com.cloudbees.plugins.credentials.domains.Domain) UsernamePasswordCredentialsImpl(com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl) StandardCredentials(com.cloudbees.plugins.credentials.common.StandardCredentials) BlueOceanDomainSpecification(io.jenkins.blueocean.rest.impl.pipeline.credential.BlueOceanDomainSpecification) DomainSpecification(com.cloudbees.plugins.credentials.domains.DomainSpecification) AbstractFolderProperty(com.cloudbees.hudson.plugins.folder.AbstractFolderProperty) PipelineBaseTest(io.jenkins.blueocean.rest.impl.pipeline.PipelineBaseTest) Test(org.junit.Test)

Example 5 with BlueOceanDomainRequirement

use of io.jenkins.blueocean.rest.impl.pipeline.credential.BlueOceanDomainRequirement in project blueocean-plugin by jenkinsci.

the class GithubScm method getOrganizations.

@Override
public Container<ScmOrganization> getOrganizations() {
    StaplerRequest request = Stapler.getCurrentRequest();
    String credentialId = getCredentialIdFromRequest(request);
    User authenticatedUser = getAuthenticatedUser();
    final StandardUsernamePasswordCredentials credential = CredentialsUtils.findCredential(credentialId, StandardUsernamePasswordCredentials.class, new BlueOceanDomainRequirement());
    if (credential == null) {
        throw new ServiceException.BadRequestExpception(String.format("Credential id: %s not found for user %s", credentialId, authenticatedUser.getId()));
    }
    String accessToken = credential.getPassword().getPlainText();
    try {
        GitHub github = new GitHubBuilder().withOAuthToken(accessToken).withRateLimitHandler(new RateLimitHandlerImpl()).withEndpoint(getUri()).build();
        final Link link = getLink().rel("organizations");
        // preserve the same order that github org api returns
        Map<String, ScmOrganization> orgMap = new LinkedHashMap<>();
        for (Map.Entry<String, GHOrganization> entry : github.getMyOrganizations().entrySet()) {
            orgMap.put(entry.getKey(), new GithubOrganization(GithubScm.this, entry.getValue(), credential, link));
        }
        GHMyself user = github.getMyself();
        if (orgMap.get(user.getLogin()) == null) {
            //this is to take care of case if/when github starts reporting user login as org later on
            orgMap = new HashMap<>(orgMap);
            orgMap.put(user.getLogin(), new GithubUserOrganization(user, credential, this));
        }
        final Map<String, ScmOrganization> orgs = orgMap;
        return new Container<ScmOrganization>() {

            @Override
            public ScmOrganization get(String name) {
                ScmOrganization org = orgs.get(name);
                if (org == null) {
                    throw new ServiceException.NotFoundException(String.format("GitHub organization %s not found", name));
                }
                return org;
            }

            @Override
            public Link getLink() {
                return link;
            }

            @Override
            public Iterator<ScmOrganization> iterator() {
                return orgs.values().iterator();
            }
        };
    } catch (IOException e) {
        if (e instanceof HttpException) {
            HttpException ex = (HttpException) e;
            if (ex.getResponseCode() == 401) {
                throw new ServiceException.PreconditionRequired("Invalid Github accessToken", ex);
            } else if (ex.getResponseCode() == 403) {
                throw new ServiceException.PreconditionRequired("Github accessToken does not have required scopes. Expected scopes 'user:email, repo'", ex);
            }
        }
        throw new ServiceException.UnexpectedErrorException(e.getMessage(), e);
    }
}
Also used : GHMyself(org.kohsuke.github.GHMyself) GHUser(org.kohsuke.github.GHUser) User(hudson.model.User) GitHub(org.kohsuke.github.GitHub) StaplerRequest(org.kohsuke.stapler.StaplerRequest) GitHubBuilder(org.kohsuke.github.GitHubBuilder) LinkedHashMap(java.util.LinkedHashMap) StandardUsernamePasswordCredentials(com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials) ScmOrganization(io.jenkins.blueocean.rest.impl.pipeline.scm.ScmOrganization) Container(io.jenkins.blueocean.rest.model.Container) GHOrganization(org.kohsuke.github.GHOrganization) HttpException(org.kohsuke.github.HttpException) IOException(java.io.IOException) ServiceException(io.jenkins.blueocean.commons.ServiceException) BlueOceanDomainRequirement(io.jenkins.blueocean.rest.impl.pipeline.credential.BlueOceanDomainRequirement) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Link(io.jenkins.blueocean.rest.hal.Link)

Aggregations

BlueOceanDomainRequirement (io.jenkins.blueocean.rest.impl.pipeline.credential.BlueOceanDomainRequirement)6 User (hudson.model.User)5 StandardUsernamePasswordCredentials (com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials)4 ServiceException (io.jenkins.blueocean.commons.ServiceException)4 Domain (com.cloudbees.plugins.credentials.domains.Domain)3 ErrorMessage (io.jenkins.blueocean.commons.ErrorMessage)3 IOException (java.io.IOException)3 UsernamePasswordCredentialsImpl (com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl)2 Cause (hudson.model.Cause)2 TopLevelItem (hudson.model.TopLevelItem)2 BlueOceanCredentialsProvider (io.jenkins.blueocean.rest.impl.pipeline.credential.BlueOceanCredentialsProvider)2 BlueOceanDomainSpecification (io.jenkins.blueocean.rest.impl.pipeline.credential.BlueOceanDomainSpecification)2 OrganizationFolder (jenkins.branch.OrganizationFolder)2 GHUser (org.kohsuke.github.GHUser)2 AbstractFolderProperty (com.cloudbees.hudson.plugins.folder.AbstractFolderProperty)1 CredentialsStore (com.cloudbees.plugins.credentials.CredentialsStore)1 StandardCredentials (com.cloudbees.plugins.credentials.common.StandardCredentials)1 DomainSpecification (com.cloudbees.plugins.credentials.domains.DomainSpecification)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 Mailer (hudson.tasks.Mailer)1