123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- /*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
- package org.sonar.server.project.ws;
-
- import javax.annotation.CheckForNull;
- import javax.annotation.Nullable;
- import org.sonar.api.server.ws.Change;
- import org.sonar.api.server.ws.Request;
- import org.sonar.api.server.ws.Response;
- import org.sonar.api.server.ws.WebService;
- import org.sonar.db.DbClient;
- import org.sonar.db.DbSession;
- import org.sonar.db.component.ComponentDto;
- import org.sonar.db.organization.OrganizationDto;
- import org.sonar.server.component.ComponentUpdater;
- import org.sonar.server.project.Visibility;
- import org.sonar.server.user.UserSession;
- import org.sonarqube.ws.Projects.CreateWsResponse;
-
- import static org.apache.commons.lang.StringUtils.abbreviate;
- import static org.sonar.api.resources.Qualifiers.PROJECT;
- import static org.sonar.core.component.ComponentKeys.MAX_COMPONENT_KEY_LENGTH;
- import static org.sonar.db.component.ComponentValidator.MAX_COMPONENT_NAME_LENGTH;
- import static org.sonar.db.permission.OrganizationPermission.PROVISION_PROJECTS;
- import static org.sonar.server.component.NewComponent.newComponentBuilder;
- import static org.sonar.server.project.ws.ProjectsWsSupport.PARAM_ORGANIZATION;
- import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
- import static org.sonar.server.ws.WsUtils.writeProtobuf;
- import static org.sonarqube.ws.client.project.ProjectsWsParameters.ACTION_CREATE;
- import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_NAME;
- import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_PROJECT;
- import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_VISIBILITY;
-
- public class CreateAction implements ProjectsWsAction {
-
- private final ProjectsWsSupport support;
- private final DbClient dbClient;
- private final UserSession userSession;
- private final ComponentUpdater componentUpdater;
-
- public CreateAction(ProjectsWsSupport support, DbClient dbClient, UserSession userSession, ComponentUpdater componentUpdater) {
- this.support = support;
- this.dbClient = dbClient;
- this.userSession = userSession;
- this.componentUpdater = componentUpdater;
- }
-
- @Override
- public void define(WebService.NewController context) {
- WebService.NewAction action = context.createAction(ACTION_CREATE)
- .setDescription("Create a project.<br/>" +
- "Requires 'Create Projects' permission")
- .setSince("4.0")
- .setPost(true)
- .setResponseExample(getClass().getResource("create-example.json"))
- .setHandler(this);
-
- action.setChangelog(
- new Change("7.1", "The 'visibility' parameter is public"));
-
- action.createParam(PARAM_PROJECT)
- .setDescription("Key of the project")
- .setRequired(true)
- .setMaximumLength(MAX_COMPONENT_KEY_LENGTH)
- .setExampleValue(KEY_PROJECT_EXAMPLE_001);
-
- action.createParam(PARAM_NAME)
- .setDescription("Name of the project. If name is longer than %d, it is abbreviated.", MAX_COMPONENT_NAME_LENGTH)
- .setRequired(true)
- .setExampleValue("SonarQube");
-
- action.createParam(PARAM_VISIBILITY)
- .setDescription("Whether the created project should be visible to everyone, or only specific user/groups.<br/>" +
- "If no visibility is specified, the default project visibility of the organization will be used.")
- .setRequired(false)
- .setSince("6.4")
- .setPossibleValues(Visibility.getLabels());
-
- support.addOrganizationParam(action);
- }
-
- @Override
- public void handle(Request request, Response response) throws Exception {
- CreateRequest createRequest = toCreateRequest(request);
- writeProtobuf(doHandle(createRequest), request, response);
- }
-
- private CreateWsResponse doHandle(CreateRequest request) {
- try (DbSession dbSession = dbClient.openSession(false)) {
- OrganizationDto organization = support.getOrganization(dbSession, request.getOrganization());
- userSession.checkPermission(PROVISION_PROJECTS, organization);
- String visibility = request.getVisibility();
- boolean changeToPrivate = visibility == null ? dbClient.organizationDao().getNewProjectPrivate(dbSession, organization) : "private".equals(visibility);
- support.checkCanUpdateProjectsVisibility(organization, changeToPrivate);
-
- ComponentDto componentDto = componentUpdater.create(dbSession, newComponentBuilder()
- .setOrganizationUuid(organization.getUuid())
- .setKey(request.getProjectKey())
- .setName(request.getName())
- .setPrivate(changeToPrivate)
- .setQualifier(PROJECT)
- .build(),
- userSession.isLoggedIn() ? userSession.getUserId() : null);
- return toCreateResponse(componentDto);
- }
- }
-
- private static CreateRequest toCreateRequest(Request request) {
- return CreateRequest.builder()
- .setOrganization(request.param(PARAM_ORGANIZATION))
- .setProjectKey(request.mandatoryParam(PARAM_PROJECT))
- .setName(abbreviate(request.mandatoryParam(PARAM_NAME), MAX_COMPONENT_NAME_LENGTH))
- .setVisibility(request.param(PARAM_VISIBILITY))
- .build();
- }
-
- private static CreateWsResponse toCreateResponse(ComponentDto componentDto) {
- return CreateWsResponse.newBuilder()
- .setProject(CreateWsResponse.Project.newBuilder()
- .setKey(componentDto.getDbKey())
- .setName(componentDto.name())
- .setQualifier(componentDto.qualifier())
- .setVisibility(Visibility.getLabel(componentDto.isPrivate())))
- .build();
- }
-
- static class CreateRequest {
-
- private final String organization;
- private final String projectKey;
- private final String name;
- @CheckForNull
- private final String visibility;
-
- private CreateRequest(Builder builder) {
- this.organization = builder.organization;
- this.projectKey = builder.projectKey;
- this.name = builder.name;
- this.visibility = builder.visibility;
- }
-
- @CheckForNull
- public String getOrganization() {
- return organization;
- }
-
- @CheckForNull
- public String getProjectKey() {
- return projectKey;
- }
-
- @CheckForNull
- public String getName() {
- return name;
- }
-
- @CheckForNull
- public String getVisibility() {
- return visibility;
- }
-
- public static Builder builder() {
- return new Builder();
- }
- }
-
- static class Builder {
- private String organization;
- private String projectKey;
- private String name;
- @CheckForNull
- private String visibility;
-
- private Builder() {
- }
-
- public Builder setOrganization(@Nullable String organization) {
- this.organization = organization;
- return this;
- }
-
- public Builder setProjectKey(@Nullable String projectKey) {
- this.projectKey = projectKey;
- return this;
- }
-
- public Builder setName(@Nullable String name) {
- this.name = name;
- return this;
- }
-
- public Builder setVisibility(@Nullable String visibility) {
- this.visibility = visibility;
- return this;
- }
-
- public CreateRequest build() {
- return new CreateRequest(this);
- }
- }
- }
|