]> source.dussan.org Git - sonarqube.git/commitdiff
Improvements on all permissions/* WS
authorTeryk Bellahsene <teryk.bellahsene@sonarsource.com>
Tue, 11 Aug 2015 13:50:28 +0000 (15:50 +0200)
committerTeryk Bellahsene <teryk.bellahsene@sonarsource.com>
Thu, 13 Aug 2015 06:30:40 +0000 (08:30 +0200)
- use PermissionRequest
- add checks
- improve WS descriptions

15 files changed:
server/sonar-server/src/main/java/org/sonar/server/permission/ws/AddGroupAction.java
server/sonar-server/src/main/java/org/sonar/server/permission/ws/AddUserAction.java
server/sonar-server/src/main/java/org/sonar/server/permission/ws/GroupsAction.java
server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionRequest.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionWsCommons.java
server/sonar-server/src/main/java/org/sonar/server/permission/ws/RemoveGroupAction.java
server/sonar-server/src/main/java/org/sonar/server/permission/ws/RemoveUserAction.java
server/sonar-server/src/main/java/org/sonar/server/permission/ws/UsersAction.java
server/sonar-server/src/main/java/org/sonar/server/ws/WsUtils.java
server/sonar-server/src/test/java/org/sonar/server/permission/ws/AddGroupActionTest.java
server/sonar-server/src/test/java/org/sonar/server/permission/ws/AddUserActionTest.java
server/sonar-server/src/test/java/org/sonar/server/permission/ws/GroupsActionTest.java
server/sonar-server/src/test/java/org/sonar/server/permission/ws/RemoveGroupActionTest.java
server/sonar-server/src/test/java/org/sonar/server/permission/ws/RemoveUserActionTest.java
server/sonar-server/src/test/java/org/sonar/server/permission/ws/UsersActionTest.java

index a0f59e0d136bf2d0124ca20558ad88161a8c47ac..6e7ec7c6afcf51ae00fe28c522fbc65349a7e5b7 100644 (file)
@@ -23,17 +23,17 @@ package org.sonar.server.permission.ws;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
-import org.sonar.core.permission.GlobalPermissions;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.server.permission.PermissionChange;
 import org.sonar.server.permission.PermissionUpdater;
+import org.sonar.server.permission.ws.PermissionRequest.Builder;
 
-import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_GROUP_ID;
-import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_GROUP_NAME;
-import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PERMISSION;
-import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PROJECT_UUID;
-import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PROJECT_KEY;
+import static org.sonar.server.permission.ws.PermissionWsCommons.createGroupIdParameter;
+import static org.sonar.server.permission.ws.PermissionWsCommons.createGroupNameParameter;
+import static org.sonar.server.permission.ws.PermissionWsCommons.createPermissionParameter;
+import static org.sonar.server.permission.ws.PermissionWsCommons.createProjectKeyParameter;
+import static org.sonar.server.permission.ws.PermissionWsCommons.createProjectUuidParameter;
 
 public class AddGroupAction implements PermissionsWsAction {
 
@@ -60,33 +60,19 @@ public class AddGroupAction implements PermissionsWsAction {
       .setPost(true)
       .setHandler(this);
 
-    action.createParam(PARAM_PERMISSION)
-      .setDescription("Permission")
-      .setRequired(true)
-      .setPossibleValues(GlobalPermissions.ALL);
-
-    action.createParam(PARAM_GROUP_NAME)
-      .setDescription("Group name or 'anyone' (whatever the case)")
-      .setExampleValue("sonar-administrators");
-
-    action.createParam(PARAM_GROUP_ID)
-      .setDescription("Group id")
-      .setExampleValue("42");
-
-    action.createParam(PARAM_PROJECT_UUID)
-      .setDescription("Project id")
-      .setExampleValue("ce4c03d6-430f-40a9-b777-ad877c00aa4d");
-
-    action.createParam(PARAM_PROJECT_KEY)
-      .setDescription("Project key")
-      .setExampleValue("org.apache.hbas:hbase");
+    createPermissionParameter(action);
+    createGroupNameParameter(action);
+    createGroupIdParameter(action);
+    createProjectUuidParameter(action);
+    createProjectKeyParameter(action);
   }
 
   @Override
   public void handle(Request request, Response response) throws Exception {
     DbSession dbSession = dbClient.openSession(false);
     try {
-      PermissionChange permissionChange = permissionWsCommons.buildGroupPermissionChange(dbSession, request);
+      PermissionRequest permissionRequest = new Builder(request).withGroup().build();
+      PermissionChange permissionChange = permissionWsCommons.buildGroupPermissionChange(dbSession, permissionRequest);
       permissionUpdater.addPermission(permissionChange);
     } finally {
       dbClient.closeSession(dbSession);
index 8aff38fc470c884b79c1fe3baeb8dfb95136eecd..525bb3a98c5c15d14385ce62e4051ad99d4ed291 100644 (file)
@@ -23,23 +23,27 @@ package org.sonar.server.permission.ws;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
-import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
 import org.sonar.server.permission.PermissionChange;
 import org.sonar.server.permission.PermissionUpdater;
+import org.sonar.server.permission.ws.PermissionRequest.Builder;
 
-import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PERMISSION;
-import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PROJECT_UUID;
-import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PROJECT_KEY;
-import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_USER_LOGIN;
+import static org.sonar.server.permission.ws.PermissionWsCommons.createPermissionParameter;
+import static org.sonar.server.permission.ws.PermissionWsCommons.createProjectKeyParameter;
+import static org.sonar.server.permission.ws.PermissionWsCommons.createProjectUuidParameter;
+import static org.sonar.server.permission.ws.PermissionWsCommons.createUserLoginParameter;
 
 public class AddUserAction implements PermissionsWsAction {
 
   public static final String ACTION = "add_user";
 
+  private final DbClient dbClient;
   private final PermissionUpdater permissionUpdater;
   private final PermissionWsCommons permissionWsCommons;
 
-  public AddUserAction(PermissionUpdater permissionUpdater, PermissionWsCommons permissionWsCommons) {
+  public AddUserAction(DbClient dbClient, PermissionUpdater permissionUpdater, PermissionWsCommons permissionWsCommons) {
+    this.dbClient = dbClient;
     this.permissionUpdater = permissionUpdater;
     this.permissionWsCommons = permissionWsCommons;
   }
@@ -54,30 +58,23 @@ public class AddUserAction implements PermissionsWsAction {
       .setPost(true)
       .setHandler(this);
 
-    action.createParam(PARAM_PERMISSION)
-      .setDescription("Permission")
-      .setRequired(true)
-      .setPossibleValues(GlobalPermissions.ALL);
-
-    action.createParam(PARAM_USER_LOGIN)
-      .setRequired(true)
-      .setDescription("User login")
-      .setExampleValue("g.hopper");
-
-    action.createParam(PARAM_PROJECT_UUID)
-      .setDescription("Project id")
-      .setExampleValue("ce4c03d6-430f-40a9-b777-ad877c00aa4d");
-
-    action.createParam(PARAM_PROJECT_KEY)
-      .setDescription("Project key")
-      .setExampleValue("org.apache.hbas:hbase");
+    createPermissionParameter(action);
+    createUserLoginParameter(action);
+    createProjectUuidParameter(action);
+    createProjectKeyParameter(action);
   }
 
   @Override
   public void handle(Request request, Response response) throws Exception {
-    PermissionChange permissionChange = permissionWsCommons.buildUserPermissionChange(request);
-    permissionUpdater.addPermission(permissionChange);
+    DbSession dbSession = dbClient.openSession(false);
+    try {
+      PermissionRequest permissionRequest = new Builder(request).withUser().build();
+      PermissionChange permissionChange = permissionWsCommons.buildUserPermissionChange(dbSession, permissionRequest);
+      permissionUpdater.addPermission(permissionChange);
 
-    response.noContent();
+      response.noContent();
+    } finally {
+      dbClient.closeSession(dbSession);
+    }
   }
 }
index 3343ade3b265b9707d04c32d781344b5658c2d78..926f18c4b8a69a4ca668b83c027506039ed6c363 100644 (file)
@@ -21,7 +21,6 @@
 package org.sonar.server.permission.ws;
 
 import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableSortedSet;
 import com.google.common.io.Resources;
 import java.util.List;
 import org.sonar.api.server.ws.Request;
@@ -29,22 +28,20 @@ import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.server.ws.WebService.Param;
 import org.sonar.api.server.ws.WebService.SelectionMode;
-import org.sonar.core.permission.ComponentPermissions;
-import org.sonar.core.permission.GlobalPermissions;
 import org.sonar.core.permission.GroupWithPermission;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.permission.PermissionQuery;
 import org.sonar.server.permission.GroupWithPermissionQueryResult;
 import org.sonar.server.permission.PermissionFinder;
+import org.sonar.server.permission.ws.PermissionRequest.Builder;
 import org.sonarqube.ws.Common;
 import org.sonarqube.ws.Permissions;
 
 import static com.google.common.base.Objects.firstNonNull;
-import static org.sonar.core.permission.GlobalPermissions.DASHBOARD_SHARING;
 import static org.sonar.server.permission.PermissionQueryParser.toMembership;
-import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PERMISSION;
-import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PROJECT_KEY;
-import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PROJECT_UUID;
+import static org.sonar.server.permission.ws.PermissionWsCommons.createPermissionParameter;
+import static org.sonar.server.permission.ws.PermissionWsCommons.createProjectKeyParameter;
+import static org.sonar.server.permission.ws.PermissionWsCommons.createProjectUuidParameter;
 import static org.sonar.server.ws.WsUtils.writeProtobuf;
 
 public class GroupsAction implements PermissionsWsAction {
@@ -71,38 +68,24 @@ public class GroupsAction implements PermissionsWsAction {
       .setResponseExample(Resources.getResource(getClass(), "groups-example.json"))
       .setHandler(this);
 
-    action.createParam(PARAM_PERMISSION)
-      .setExampleValue(DASHBOARD_SHARING)
-      .setRequired(true)
-      .setPossibleValues(ImmutableSortedSet.naturalOrder()
-        .addAll(GlobalPermissions.ALL)
-        .addAll(ComponentPermissions.ALL)
-        .build());
-
-    action.createParam(PARAM_PROJECT_UUID)
-      .setExampleValue("ce4c03d6-430f-40a9-b777-ad877c00aa4d")
-      .setDescription("Project id");
-
-    action.createParam(PARAM_PROJECT_KEY)
-      .setExampleValue("org.apache.hbas:hbase")
-      .setDescription("Project key");
+    createPermissionParameter(action);
+    createProjectUuidParameter(action);
+    createProjectKeyParameter(action);
   }
 
   @Override
   public void handle(Request wsRequest, Response wsResponse) throws Exception {
-    int page = wsRequest.mandatoryParamAsInt(Param.PAGE);
-    int pageSize = wsRequest.mandatoryParamAsInt(Param.PAGE_SIZE);
-
-    Optional<ComponentDto> project = permissionWsCommons.searchProject(wsRequest);
+    PermissionRequest request = new Builder(wsRequest).withPagination().build();
+    Optional<ComponentDto> project = permissionWsCommons.searchProject(request);
     permissionWsCommons.checkPermissions(project);
 
-    PermissionQuery permissionQuery = buildPermissionQuery(wsRequest, project);
-    Permissions.GroupsResponse groupsResponse = groupsResponse(permissionQuery, page, pageSize);
+    PermissionQuery permissionQuery = buildPermissionQuery(request, project);
+    Permissions.GroupsResponse groupsResponse = groupsResponse(permissionQuery, request);
 
     writeProtobuf(groupsResponse, wsRequest, wsResponse);
   }
 
-  private Permissions.GroupsResponse groupsResponse(PermissionQuery permissionQuery, int page, int pageSize) {
+  private Permissions.GroupsResponse groupsResponse(PermissionQuery permissionQuery, PermissionRequest permissionRequest) {
     GroupWithPermissionQueryResult groupsResult = permissionFinder.findGroupsWithPermission(permissionQuery);
     List<GroupWithPermission> groupsWithPermission = groupsResult.groups();
 
@@ -128,32 +111,21 @@ public class GroupsAction implements PermissionsWsAction {
 
     groupsResponse.setPaging(
       paging
-        .setPageIndex(page)
-        .setPageSize(pageSize)
+        .setPageIndex(permissionRequest.page())
+        .setPageSize(permissionRequest.pageSize())
         .setTotal(groupsResult.total())
       );
 
     return groupsResponse.build();
   }
 
-  private static PermissionQuery buildPermissionQuery(Request wsRequest, Optional<ComponentDto> project) {
-    String permission = wsRequest.mandatoryParam("permission");
-    String selected = wsRequest.param(Param.SELECTED);
-    int page = wsRequest.mandatoryParamAsInt(Param.PAGE);
-    int pageSize = wsRequest.mandatoryParamAsInt(Param.PAGE_SIZE);
-    String query = wsRequest.param(Param.TEXT_QUERY);
-    if (query != null) {
-      selected = SelectionMode.ALL.value();
-    }
-
+  private static PermissionQuery buildPermissionQuery(PermissionRequest request, Optional<ComponentDto> project) {
     PermissionQuery.Builder permissionQuery = PermissionQuery.builder()
-      .permission(permission)
-      .pageIndex(page)
-      .pageSize(pageSize)
-      .membership(toMembership(firstNonNull(selected, SelectionMode.SELECTED.value())));
-    if (query != null) {
-      permissionQuery.search(query);
-    }
+      .permission(request.permission())
+      .pageIndex(request.page())
+      .pageSize(request.pageSize())
+      .membership(toMembership(firstNonNull(request.selected(), SelectionMode.SELECTED.value())))
+      .search(request.query());
     if (project.isPresent()) {
       permissionQuery.component(project.get().getKey());
     }
diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionRequest.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionRequest.java
new file mode 100644 (file)
index 0000000..f2f366d
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.permission.ws;
+
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.WebService.SelectionMode;
+import org.sonar.core.permission.ComponentPermissions;
+import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.server.exceptions.BadRequestException;
+
+import static org.sonar.api.server.ws.WebService.Param.PAGE;
+import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE;
+import static org.sonar.api.server.ws.WebService.Param.SELECTED;
+import static org.sonar.api.server.ws.WebService.Param.TEXT_QUERY;
+import static org.sonar.server.permission.ws.PermissionWsCommons.GLOBAL_PERMISSIONS_ONE_LINE;
+import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_GROUP_ID;
+import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_GROUP_NAME;
+import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PROJECT_KEY;
+import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PROJECT_UUID;
+import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_USER_LOGIN;
+import static org.sonar.server.permission.ws.PermissionWsCommons.PROJECT_PERMISSIONS_ONE_LINE;
+import static org.sonar.server.ws.WsUtils.checkRequest;
+
+public class PermissionRequest {
+  private final String permission;
+  private final String userLogin;
+  private final Long groupId;
+  private final String groupName;
+  private final String projectUuid;
+  private final String projectKey;
+  private final boolean hasProject;
+  private final Integer page;
+  private final Integer pageSize;
+  private final String selected;
+  private final String query;
+
+  private PermissionRequest(Builder builder) {
+    permission = builder._permission;
+    userLogin = builder._userLogin;
+    groupId = builder._groupId;
+    groupName = builder._groupName;
+    projectUuid = builder._projectUuid;
+    projectKey = builder._projectKey;
+    hasProject = builder._hasProject;
+    page = builder._page;
+    pageSize = builder._pageSize;
+    selected = builder._selected;
+    query = builder._query;
+  }
+
+  public static class Builder {
+
+    private final Request request;
+
+    private boolean withUser;
+    private boolean withGroup;
+    private boolean withPagination;
+
+    private String _permission;
+    private String _userLogin;
+
+    private Long _groupId;
+    private String _groupName;
+    private String _projectUuid;
+    private String _projectKey;
+    private boolean _hasProject;
+    private Integer _page;
+    private Integer _pageSize;
+    private String _selected;
+    private String _query;
+
+    public Builder(Request request) {
+      this.request = request;
+    }
+
+    public PermissionRequest build() {
+      _permission = request.mandatoryParam(PermissionWsCommons.PARAM_PERMISSION);
+      setUserLogin(request);
+      setGroup(request);
+      setProject(request);
+      setPaging(request);
+      setSelected(request);
+      setQuery(request);
+      checkPermissionParameter();
+
+      return new PermissionRequest(this);
+    }
+
+    public Builder withUser() {
+      this.withUser = true;
+      return this;
+    }
+
+    public Builder withGroup() {
+      this.withGroup = true;
+      return this;
+    }
+
+    public Builder withPagination() {
+      this.withPagination = true;
+      return this;
+    }
+
+    private void setQuery(Request request) {
+      if (request.hasParam(TEXT_QUERY)) {
+        _query = request.param(TEXT_QUERY);
+        if (_query != null) {
+          _selected = SelectionMode.ALL.value();
+        }
+      }
+    }
+
+    private void setSelected(Request request) {
+      if (request.hasParam(SELECTED)) {
+        _selected = request.mandatoryParam(SELECTED);
+      }
+    }
+
+    private void setPaging(Request request) {
+      if (withPagination) {
+        _page = request.mandatoryParamAsInt(PAGE);
+        _pageSize = request.mandatoryParamAsInt(PAGE_SIZE);
+      }
+    }
+
+    private void setUserLogin(Request request) {
+      if (withUser) {
+        _userLogin = request.mandatoryParam(PARAM_USER_LOGIN);
+      }
+    }
+
+    private void setGroup(Request request) {
+      if (withGroup) {
+        Long groupId = request.paramAsLong(PARAM_GROUP_ID);
+        String groupName = request.param(PARAM_GROUP_NAME);
+        checkRequest(groupId != null ^ groupName != null, "Group name or group id must be provided, not both.");
+        _groupId = groupId;
+        _groupName = groupName;
+      }
+    }
+
+    private void setProject(Request request) {
+      if (request.hasParam(PARAM_PROJECT_UUID) || request.hasParam(PARAM_PROJECT_KEY)) {
+        String projectUuid = request.param(PARAM_PROJECT_UUID);
+        String projectKey = request.param(PARAM_PROJECT_KEY);
+
+        if (projectUuid != null || projectKey != null) {
+          checkRequest(projectUuid != null ^ projectKey != null, "Project id or project key can be provided, not both.");
+          _projectUuid = projectUuid;
+          _projectKey = projectKey;
+          _hasProject = true;
+        }
+      }
+    }
+
+    private void checkPermissionParameter() {
+      if (_hasProject) {
+        if (!ComponentPermissions.ALL.contains(_permission)) {
+          throw new BadRequestException(String.format("Incorrect value '%s' for project permissions. Values allowed: %s.", _permission, PROJECT_PERMISSIONS_ONE_LINE));
+        }
+      } else {
+        if (!GlobalPermissions.ALL.contains(_permission)) {
+          throw new BadRequestException(String.format("Incorrect value '%s' for global permissions. Values allowed: %s.", _permission, GLOBAL_PERMISSIONS_ONE_LINE));
+        }
+      }
+    }
+
+  }
+
+  public String permission() {
+    return permission;
+  }
+
+  public String userLogin() {
+    return userLogin;
+  }
+
+  public Long groupId() {
+    return groupId;
+  }
+
+  public String groupName() {
+    return groupName;
+  }
+
+  public String projectUuid() {
+    return projectUuid;
+  }
+
+  public String projectKey() {
+    return projectKey;
+  }
+
+  public Integer page() {
+    return page;
+  }
+
+  public Integer pageSize() {
+    return pageSize;
+  }
+
+  public String selected() {
+    return selected;
+  }
+
+  public String query() {
+    return query;
+  }
+
+  public boolean hasProject() {
+    return hasProject;
+  }
+}
index 1c76b21d7692cef26b95b985da1ae54211c59edb..a825a075c716240aeb3570be788754575c5f3525 100644 (file)
@@ -22,8 +22,9 @@ package org.sonar.server.permission.ws;
 
 import com.google.common.base.Joiner;
 import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableSortedSet;
 import javax.annotation.Nullable;
-import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.WebService.NewAction;
 import org.sonar.api.web.UserRole;
 import org.sonar.core.permission.ComponentPermissions;
 import org.sonar.core.permission.GlobalPermissions;
@@ -32,7 +33,6 @@ import org.sonar.db.DbSession;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.user.GroupDto;
 import org.sonar.server.component.ComponentFinder;
-import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.exceptions.NotFoundException;
 import org.sonar.server.permission.PermissionChange;
 import org.sonar.server.user.UserSession;
@@ -47,8 +47,19 @@ public class PermissionWsCommons {
   public static final String PARAM_PROJECT_UUID = "projectId";
   public static final String PARAM_PROJECT_KEY = "projectKey";
   public static final String PARAM_USER_LOGIN = "login";
-  private static final String PROJECT_PERMISSIONS_ONE_LINE = Joiner.on(",").join(ComponentPermissions.ALL);
-  private static final String GLOBAL_PERMISSIONS_ONE_LINE = Joiner.on(",").join(GlobalPermissions.ALL);
+  static final String PROJECT_PERMISSIONS_ONE_LINE = Joiner.on(", ").join(ComponentPermissions.ALL);
+  static final String GLOBAL_PERMISSIONS_ONE_LINE = Joiner.on(", ").join(GlobalPermissions.ALL);
+  private static final String PERMISSION_PARAM_DESCRIPTION = String.format("Permission" +
+    "<ul>" +
+    "<li>Possible values for global permissions: %s</li>" +
+    "<li>Possible values for project permissions %s</li>" +
+    "</ul>",
+    GLOBAL_PERMISSIONS_ONE_LINE,
+    PROJECT_PERMISSIONS_ONE_LINE);
+  private static final ImmutableSortedSet<Comparable<?>> POSSIBLE_PERMISSIONS = ImmutableSortedSet.naturalOrder()
+    .addAll(GlobalPermissions.ALL)
+    .addAll(ComponentPermissions.ALL)
+    .build();
 
   private final DbClient dbClient;
   private final ComponentFinder componentFinder;
@@ -61,7 +72,6 @@ public class PermissionWsCommons {
   }
 
   public String searchGroupName(DbSession dbSession, @Nullable String groupNameParam, @Nullable Long groupId) {
-    checkParameters(groupNameParam, groupId);
     if (groupNameParam != null) {
       return groupNameParam;
     }
@@ -74,70 +84,41 @@ public class PermissionWsCommons {
     return group.getName();
   }
 
-  public PermissionChange buildUserPermissionChange(Request request) {
-    String permission = request.mandatoryParam(PARAM_PERMISSION);
-    String userLogin = request.mandatoryParam(PARAM_USER_LOGIN);
-
-    DbSession dbSession = dbClient.openSession(false);
-    try {
-      PermissionChange permissionChange = new PermissionChange()
-        .setPermission(permission)
-        .setUserLogin(userLogin);
-      addProjectToPermissionChange(dbSession, permissionChange, request.param(PARAM_PROJECT_UUID), request.param(PARAM_PROJECT_KEY));
-
-      return permissionChange;
-    } finally {
-      dbClient.closeSession(dbSession);
-    }
+  public PermissionChange buildUserPermissionChange(DbSession dbSession, PermissionRequest request) {
+    PermissionChange permissionChange = new PermissionChange()
+      .setPermission(request.permission())
+      .setUserLogin(request.userLogin());
+    addProjectToPermissionChange(dbSession, permissionChange, request);
 
+    return permissionChange;
   }
 
-  public PermissionChange buildGroupPermissionChange(DbSession dbSession, Request request) {
-    String permission = request.mandatoryParam(PARAM_PERMISSION);
-    String groupNameParam = request.param(PARAM_GROUP_NAME);
-    Long groupId = request.paramAsLong(PARAM_GROUP_ID);
-    String projectUuid = request.param(PARAM_PROJECT_UUID);
-    String projectKey = request.param(PARAM_PROJECT_KEY);
-
-    String groupName = searchGroupName(dbSession, groupNameParam, groupId);
+  public PermissionChange buildGroupPermissionChange(DbSession dbSession, PermissionRequest request) {
+    String groupName = searchGroupName(dbSession, request.groupName(), request.groupId());
 
     PermissionChange permissionChange = new PermissionChange()
-      .setPermission(permission)
+      .setPermission(request.permission())
       .setGroupName(groupName);
-    addProjectToPermissionChange(dbSession, permissionChange, projectUuid, projectKey);
+    addProjectToPermissionChange(dbSession, permissionChange, request);
 
     return permissionChange;
   }
 
-  private void addProjectToPermissionChange(DbSession dbSession, PermissionChange permissionChange, @Nullable String projectUuid, @Nullable String projectKey) {
-    if (isProjectUuidOrProjectKeyProvided(projectUuid, projectKey)) {
-      ComponentDto project = componentFinder.getProjectByUuidOrKey(dbSession, projectUuid, projectKey);
+  private void addProjectToPermissionChange(DbSession dbSession, PermissionChange permissionChange, PermissionRequest request) {
+    if (request.hasProject()) {
+      ComponentDto project = componentFinder.getProjectByUuidOrKey(dbSession, request.projectUuid(), request.projectKey());
       permissionChange.setComponentKey(project.key());
     }
   }
 
-  private static void checkParameters(@Nullable String groupName, @Nullable Long groupId) {
-    if (groupName != null ^ groupId != null) {
-      return;
+  Optional<ComponentDto> searchProject(PermissionRequest request) {
+    if (!request.hasProject()) {
+      return Optional.absent();
     }
 
-    throw new BadRequestException("Group name or group id must be provided, not both");
-  }
-
-  static boolean isProjectUuidOrProjectKeyProvided(@Nullable String projectUuid, @Nullable String projectKey) {
-    return projectUuid != null || projectKey != null;
-  }
-
-  Optional<ComponentDto> searchProject(Request request) {
-    String projectUuid = request.param(PARAM_PROJECT_UUID);
-    String projectKey = request.param(PARAM_PROJECT_KEY);
-
     DbSession dbSession = dbClient.openSession(false);
     try {
-      if (isProjectUuidOrProjectKeyProvided(projectUuid, projectKey)) {
-        return Optional.of(componentFinder.getProjectByUuidOrKey(dbSession, projectUuid, projectKey));
-      }
-      return Optional.absent();
+      return Optional.of(componentFinder.getProjectByUuidOrKey(dbSession, request.projectUuid(), request.projectKey()));
     } finally {
       dbClient.closeSession(dbSession);
     }
@@ -156,4 +137,42 @@ public class PermissionWsCommons {
   boolean projectPresentAndAdminPermissionsOnIt(Optional<ComponentDto> project) {
     return project.isPresent() && userSession.hasProjectPermissionByUuid(UserRole.ADMIN, project.get().projectUuid());
   }
+
+  static void createPermissionParameter(NewAction action) {
+    action.createParam(PARAM_PERMISSION)
+      .setDescription(PERMISSION_PARAM_DESCRIPTION)
+      .setRequired(true)
+      .setPossibleValues(POSSIBLE_PERMISSIONS);
+  }
+
+  static void createGroupNameParameter(NewAction action) {
+    action.createParam(PARAM_GROUP_NAME)
+      .setDescription("Group name or 'anyone' (case insensitive)")
+      .setExampleValue("sonar-administrators");
+  }
+
+  static void createGroupIdParameter(NewAction action) {
+    action.createParam(PARAM_GROUP_ID)
+      .setDescription("Group id")
+      .setExampleValue("42");
+  }
+
+  static void createProjectUuidParameter(NewAction action) {
+    action.createParam(PARAM_PROJECT_UUID)
+      .setDescription("Project id")
+      .setExampleValue("ce4c03d6-430f-40a9-b777-ad877c00aa4d");
+  }
+
+  static void createProjectKeyParameter(NewAction action) {
+    action.createParam(PARAM_PROJECT_KEY)
+      .setDescription("Project key")
+      .setExampleValue("org.apache.hbas:hbase");
+  }
+
+  static void createUserLoginParameter(NewAction action) {
+    action.createParam(PARAM_USER_LOGIN)
+      .setRequired(true)
+      .setDescription("User login")
+      .setExampleValue("g.hopper");
+  }
 }
index d375200ed1a1c08bb9206e3e7875e4c8c70e4795..0df209ca6ba92ae017261fa9dad1d08f3376f638 100644 (file)
@@ -23,17 +23,17 @@ package org.sonar.server.permission.ws;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
-import org.sonar.core.permission.GlobalPermissions;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.server.permission.PermissionChange;
 import org.sonar.server.permission.PermissionUpdater;
+import org.sonar.server.permission.ws.PermissionRequest.Builder;
 
-import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_GROUP_ID;
-import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_GROUP_NAME;
-import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PERMISSION;
-import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PROJECT_UUID;
-import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PROJECT_KEY;
+import static org.sonar.server.permission.ws.PermissionWsCommons.createGroupIdParameter;
+import static org.sonar.server.permission.ws.PermissionWsCommons.createGroupNameParameter;
+import static org.sonar.server.permission.ws.PermissionWsCommons.createPermissionParameter;
+import static org.sonar.server.permission.ws.PermissionWsCommons.createProjectKeyParameter;
+import static org.sonar.server.permission.ws.PermissionWsCommons.createProjectUuidParameter;
 
 public class RemoveGroupAction implements PermissionsWsAction {
 
@@ -54,38 +54,25 @@ public class RemoveGroupAction implements PermissionsWsAction {
     WebService.NewAction action = context.createAction(ACTION)
       .setDescription("Remove permission from a group.<br /> " +
         "The group id or group name must be provided, not both.<br />" +
+        "If the project id or project key is provided, a project permission is removed.<br />" +
         "Requires 'Administer System' permission.")
       .setSince("5.2")
       .setPost(true)
       .setHandler(this);
 
-    action.createParam(PARAM_PERMISSION)
-      .setDescription("Permission")
-      .setRequired(true)
-      .setPossibleValues(GlobalPermissions.ALL);
-
-    action.createParam(PARAM_GROUP_NAME)
-      .setDescription("Group name or 'anyone' (whatever the case)")
-      .setExampleValue("sonar-administrators");
-
-    action.createParam(PARAM_GROUP_ID)
-      .setDescription("Group id")
-      .setExampleValue("42");
-
-    action.createParam(PARAM_PROJECT_UUID)
-      .setDescription("Project id")
-      .setExampleValue("ce4c03d6-430f-40a9-b777-ad877c00aa4d");
-
-    action.createParam(PARAM_PROJECT_KEY)
-      .setDescription("Project key")
-      .setExampleValue("org.apache.hbas:hbase");
+    createPermissionParameter(action);
+    createGroupNameParameter(action);
+    createGroupIdParameter(action);
+    createProjectUuidParameter(action);
+    createProjectKeyParameter(action);
   }
 
   @Override
   public void handle(Request request, Response response) throws Exception {
     DbSession dbSession = dbClient.openSession(false);
     try {
-      PermissionChange permissionChange = permissionWsCommons.buildGroupPermissionChange(dbSession, request);
+      PermissionRequest permissionRequest = new Builder(request).withGroup().build();
+      PermissionChange permissionChange = permissionWsCommons.buildGroupPermissionChange(dbSession, permissionRequest);
       permissionUpdater.removePermission(permissionChange);
     } finally {
       dbClient.closeSession(dbSession);
index f3592876d3e9a008e3eaae8615fbf4150fa7b3eb..ae94c3b133b80cabc3a16faf994311326a5f3667 100644 (file)
@@ -23,23 +23,27 @@ package org.sonar.server.permission.ws;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
-import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
 import org.sonar.server.permission.PermissionChange;
 import org.sonar.server.permission.PermissionUpdater;
+import org.sonar.server.permission.ws.PermissionRequest.Builder;
 
-import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PERMISSION;
-import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PROJECT_UUID;
-import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PROJECT_KEY;
-import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_USER_LOGIN;
+import static org.sonar.server.permission.ws.PermissionWsCommons.createPermissionParameter;
+import static org.sonar.server.permission.ws.PermissionWsCommons.createProjectKeyParameter;
+import static org.sonar.server.permission.ws.PermissionWsCommons.createProjectUuidParameter;
+import static org.sonar.server.permission.ws.PermissionWsCommons.createUserLoginParameter;
 
 public class RemoveUserAction implements PermissionsWsAction {
 
   public static final String ACTION = "remove_user";
 
+  private final DbClient dbClient;
   private final PermissionUpdater permissionUpdater;
   private final PermissionWsCommons permissionWsCommons;
 
-  public RemoveUserAction(PermissionUpdater permissionUpdater, PermissionWsCommons permissionWsCommons) {
+  public RemoveUserAction(DbClient dbClient, PermissionUpdater permissionUpdater, PermissionWsCommons permissionWsCommons) {
+    this.dbClient = dbClient;
     this.permissionUpdater = permissionUpdater;
     this.permissionWsCommons = permissionWsCommons;
   }
@@ -48,36 +52,29 @@ public class RemoveUserAction implements PermissionsWsAction {
   public void define(WebService.NewController context) {
     WebService.NewAction action = context.createAction(ACTION)
       .setDescription("Remove permission from a user.<br /> " +
-        "If the project id is provided, a project permission is removed.<br />" +
+        "If the project id or project key is provided, a project permission is removed.<br />" +
         "Requires 'Administer System' permission.")
       .setSince("5.2")
       .setPost(true)
       .setHandler(this);
 
-    action.createParam(PARAM_PERMISSION)
-      .setDescription("Permission")
-      .setRequired(true)
-      .setPossibleValues(GlobalPermissions.ALL);
-
-    action.createParam(PARAM_USER_LOGIN)
-      .setRequired(true)
-      .setDescription("User login")
-      .setExampleValue("g.hopper");
-
-    action.createParam(PARAM_PROJECT_UUID)
-      .setDescription("Project id")
-      .setExampleValue("ce4c03d6-430f-40a9-b777-ad877c00aa4d");
-
-    action.createParam(PARAM_PROJECT_KEY)
-      .setDescription("Project key")
-      .setExampleValue("org.apache.hbas:hbase");
+    createPermissionParameter(action);
+    createUserLoginParameter(action);
+    createProjectUuidParameter(action);
+    createProjectKeyParameter(action);
   }
 
   @Override
   public void handle(Request request, Response response) throws Exception {
-    PermissionChange permissionChange = permissionWsCommons.buildUserPermissionChange(request);
-    permissionUpdater.removePermission(permissionChange);
+    DbSession dbSession = dbClient.openSession(false);
+    try {
+      PermissionRequest permissionRequest = new Builder(request).withUser().build();
+      PermissionChange permissionChange = permissionWsCommons.buildUserPermissionChange(dbSession, permissionRequest);
+      permissionUpdater.removePermission(permissionChange);
 
-    response.noContent();
+      response.noContent();
+    } finally {
+      dbClient.closeSession(dbSession);
+    }
   }
 }
index 05d0f9783aa2c766fea0a2d4fd10b602969857f9..329e12e6129fed53b9bc070bc3ea08f13ab7e9f0 100644 (file)
@@ -27,32 +27,29 @@ import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.server.ws.WebService.Param;
 import org.sonar.api.server.ws.WebService.SelectionMode;
-import org.sonar.core.permission.GlobalPermissions;
 import org.sonar.core.permission.UserWithPermission;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.permission.PermissionQuery;
 import org.sonar.server.permission.PermissionFinder;
 import org.sonar.server.permission.UserWithPermissionQueryResult;
-import org.sonar.server.user.UserSession;
+import org.sonar.server.permission.ws.PermissionRequest.Builder;
 import org.sonarqube.ws.Common;
 import org.sonarqube.ws.Permissions.UsersResponse;
 
 import static com.google.common.base.Objects.firstNonNull;
 import static org.sonar.server.permission.PermissionQueryParser.toMembership;
-import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PERMISSION;
-import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PROJECT_KEY;
-import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PROJECT_UUID;
+import static org.sonar.server.permission.ws.PermissionWsCommons.createPermissionParameter;
+import static org.sonar.server.permission.ws.PermissionWsCommons.createProjectKeyParameter;
+import static org.sonar.server.permission.ws.PermissionWsCommons.createProjectUuidParameter;
 import static org.sonar.server.ws.WsUtils.writeProtobuf;
 
 public class UsersAction implements PermissionsWsAction {
 
-  private final UserSession userSession;
   private final PermissionFinder permissionFinder;
   private final PermissionWsCommons permissionWsCommons;
 
-  public UsersAction(UserSession userSession, PermissionFinder permissionFinder, PermissionWsCommons permissionWsCommons) {
+  public UsersAction(PermissionFinder permissionFinder, PermissionWsCommons permissionWsCommons) {
     this.permissionWsCommons = permissionWsCommons;
-    this.userSession = userSession;
     this.permissionFinder = permissionFinder;
   }
 
@@ -71,29 +68,18 @@ public class UsersAction implements PermissionsWsAction {
       .setResponseExample(getClass().getResource("users-example.json"))
       .setHandler(this);
 
-    action.createParam(PARAM_PERMISSION)
-      .setExampleValue("scan")
-      .setRequired(true)
-      .setPossibleValues(GlobalPermissions.ALL);
-
-    action.createParam(PARAM_PROJECT_UUID)
-      .setExampleValue("ce4c03d6-430f-40a9-b777-ad877c00aa4d")
-      .setDescription("Project id");
-
-    action.createParam(PARAM_PROJECT_KEY)
-      .setExampleValue("org.apache.hbas:hbase")
-      .setDescription("Project key");
+    createPermissionParameter(action);
+    createProjectUuidParameter(action);
+    createProjectKeyParameter(action);
   }
 
   @Override
   public void handle(Request wsRequest, Response wsResponse) throws Exception {
-    int page = wsRequest.mandatoryParamAsInt(Param.PAGE);
-    int pageSize = wsRequest.mandatoryParamAsInt(Param.PAGE_SIZE);
-
-    Optional<ComponentDto> project = permissionWsCommons.searchProject(wsRequest);
+    PermissionRequest request = new Builder(wsRequest).withPagination().build();
+    Optional<ComponentDto> project = permissionWsCommons.searchProject(request);
     permissionWsCommons.checkPermissions(project);
-    PermissionQuery permissionQuery = buildPermissionQuery(wsRequest, project);
-    UsersResponse usersResponse = usersResponse(permissionQuery, page, pageSize);
+    PermissionQuery permissionQuery = buildPermissionQuery(request, project);
+    UsersResponse usersResponse = usersResponse(permissionQuery, request.page(), request.pageSize());
 
     writeProtobuf(usersResponse, wsRequest, wsResponse);
   }
@@ -124,24 +110,13 @@ public class UsersAction implements PermissionsWsAction {
     return userResponse.build();
   }
 
-  private static PermissionQuery buildPermissionQuery(Request request, Optional<ComponentDto> project) {
-    String permission = request.mandatoryParam(PARAM_PERMISSION);
-    String selected = request.param(Param.SELECTED);
-    int page = request.mandatoryParamAsInt(Param.PAGE);
-    int pageSize = request.mandatoryParamAsInt(Param.PAGE_SIZE);
-    String query = request.param(Param.TEXT_QUERY);
-    if (query != null) {
-      selected = SelectionMode.ALL.value();
-    }
-
+  private static PermissionQuery buildPermissionQuery(PermissionRequest request, Optional<ComponentDto> project) {
     PermissionQuery.Builder permissionQuery = PermissionQuery.builder()
-      .permission(permission)
-      .pageIndex(page)
-      .pageSize(pageSize)
-      .membership(toMembership(firstNonNull(selected, SelectionMode.SELECTED.value())));
-    if (query != null) {
-      permissionQuery.search(query);
-    }
+      .permission(request.permission())
+      .pageIndex(request.page())
+      .pageSize(request.pageSize())
+      .membership(toMembership(firstNonNull(request.selected(), SelectionMode.SELECTED.value())))
+      .search(request.query());
     if (project.isPresent()) {
       permissionQuery.component(project.get().getKey());
     }
index a075735b39137649ff99f09e9393bf1aea1d9ac1..707cbbde6c583445f2c41c4f92950477e39ba1af 100644 (file)
@@ -27,6 +27,7 @@ import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.utils.text.JsonWriter;
 import org.sonar.core.util.ProtobufJsonFormat;
+import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.plugins.MimeTypes;
 
 public class WsUtils {
@@ -51,4 +52,13 @@ public class WsUtils {
       IOUtils.closeQuietly(output);
     }
   }
+
+  /**
+   * @throws BadRequestException
+   */
+  public static void checkRequest(boolean expression, String errorMessage) {
+    if (!expression) {
+      throw new BadRequestException(errorMessage);
+    }
+  }
 }
index ddf3e2581d2331adfbba518ff26d6ca9524af8ba..c1197b227b88a317076f9283a5f46d31595c6999 100644 (file)
@@ -27,6 +27,7 @@ import org.junit.experimental.categories.Category;
 import org.junit.rules.ExpectedException;
 import org.mockito.ArgumentCaptor;
 import org.sonar.api.utils.System2;
+import org.sonar.api.web.UserRole;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbTester;
 import org.sonar.db.component.ComponentDto;
@@ -46,12 +47,13 @@ import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
+import static org.sonar.server.component.ComponentTesting.newProjectDto;
 import static org.sonar.server.permission.ws.AddGroupAction.ACTION;
 import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_GROUP_ID;
 import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_GROUP_NAME;
 import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PERMISSION;
-import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PROJECT_UUID;
 import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PROJECT_KEY;
+import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PROJECT_UUID;
 import static org.sonar.server.permission.ws.PermissionsWs.ENDPOINT;
 
 @Category(DbTests.class)
@@ -107,7 +109,7 @@ public class AddGroupActionTest {
   @Test
   public void add_with_project_uuid() throws Exception {
     insertGroup("sonar-administrators");
-    insertComponent(ComponentTesting.newProjectDto("project-uuid").setKey("project-key"));
+    insertComponent(newProjectDto("project-uuid").setKey("project-key"));
     commit();
 
     newRequest()
@@ -125,7 +127,7 @@ public class AddGroupActionTest {
   @Test
   public void add_with_project_key() throws Exception {
     insertGroup("sonar-administrators");
-    insertComponent(ComponentTesting.newProjectDto("project-uuid").setKey("project-key"));
+    insertComponent(newProjectDto("project-uuid").setKey("project-key"));
     commit();
 
     newRequest()
@@ -145,7 +147,7 @@ public class AddGroupActionTest {
     expectedException.expect(NotFoundException.class);
 
     insertGroup("sonar-administrators");
-    insertComponent(ComponentTesting.newProjectDto("project-uuid").setKey("project-key"));
+    insertComponent(newProjectDto("project-uuid").setKey("project-key"));
     commit();
 
     newRequest()
@@ -155,12 +157,25 @@ public class AddGroupActionTest {
       .execute();
   }
 
+  @Test
+  public void fail_if_project_permission_withou_project() throws Exception {
+    expectedException.expect(BadRequestException.class);
+
+    insertGroup("sonar-administrators");
+    commit();
+
+    newRequest()
+      .setParam(PARAM_GROUP_NAME, "sonar-administrators")
+      .setParam(PARAM_PERMISSION, UserRole.ISSUE_ADMIN)
+      .execute();
+  }
+
   @Test
   public void fail_if_component_uuid_is_not_a_project() throws Exception {
     expectedException.expect(BadRequestException.class);
 
     insertGroup("sonar-administrators");
-    ComponentDto project = ComponentTesting.newProjectDto("project-uuid").setKey("project-key");
+    ComponentDto project = newProjectDto("project-uuid").setKey("project-key");
     insertComponent(project);
     insertComponent(ComponentTesting.newFileDto(project, "file-uuid"));
     commit();
@@ -201,6 +216,21 @@ public class AddGroupActionTest {
       .execute();
   }
 
+  @Test
+  public void fail_when_project_uuid_and_project_key_are_provided() throws Exception {
+    expectedException.expect(BadRequestException.class);
+    expectedException.expectMessage("Project id or project key can be provided, not both.");
+    insertComponent(newProjectDto("project-uuid").setKey("project-key"));
+    commit();
+
+    newRequest()
+      .setParam(PARAM_GROUP_NAME, "sonar-administrators")
+      .setParam(PARAM_PERMISSION, SYSTEM_ADMIN)
+      .setParam(PARAM_PROJECT_UUID, "project-uuid")
+      .setParam(PARAM_PROJECT_KEY, "project-key")
+      .execute();
+  }
+
   private WsTester.TestRequest newRequest() {
     return ws.newPostRequest(ENDPOINT, ACTION);
   }
index feb0334deb0c25bea27be83e055003abe21a9aae..0c2ccf7d68daac8fba91a56548a91c65160575e1 100644 (file)
@@ -27,6 +27,7 @@ import org.junit.experimental.categories.Category;
 import org.junit.rules.ExpectedException;
 import org.mockito.ArgumentCaptor;
 import org.sonar.api.utils.System2;
+import org.sonar.api.web.UserRole;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.DbTester;
@@ -52,6 +53,7 @@ import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PERMISSIO
 import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PROJECT_UUID;
 import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PROJECT_KEY;
 import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_USER_LOGIN;
+import static org.sonar.server.permission.ws.PermissionsWs.ENDPOINT;
 
 @Category(DbTests.class)
 public class AddUserActionTest {
@@ -72,13 +74,13 @@ public class AddUserActionTest {
     dbClient = db.getDbClient();
     dbSession = db.getSession();
     ws = new WsTester(new PermissionsWs(
-      new AddUserAction(permissionUpdater, new PermissionWsCommons(dbClient, new ComponentFinder(dbClient), userSession))));
+      new AddUserAction(dbClient, permissionUpdater, new PermissionWsCommons(dbClient, new ComponentFinder(dbClient), userSession))));
     userSession.login("admin").setGlobalPermissions(SYSTEM_ADMIN);
   }
 
   @Test
   public void call_permission_service_with_right_data() throws Exception {
-    ws.newPostRequest(PermissionsWs.ENDPOINT, ACTION)
+    ws.newPostRequest(ENDPOINT, ACTION)
       .setParam(PARAM_USER_LOGIN, "ray.bradbury")
       .setParam(PARAM_PERMISSION, SYSTEM_ADMIN)
       .execute();
@@ -94,7 +96,7 @@ public class AddUserActionTest {
     dbClient.componentDao().insert(dbSession, newProjectDto("project-uuid").setKey("project-key"));
     commit();
 
-    ws.newPostRequest(PermissionsWs.ENDPOINT, ACTION)
+    ws.newPostRequest(ENDPOINT, ACTION)
       .setParam(PARAM_USER_LOGIN, "ray.bradbury")
       .setParam(PARAM_PROJECT_UUID, "project-uuid")
       .setParam(PermissionWsCommons.PARAM_PERMISSION, SYSTEM_ADMIN)
@@ -110,7 +112,7 @@ public class AddUserActionTest {
     dbClient.componentDao().insert(dbSession, newProjectDto("project-uuid").setKey("project-key"));
     commit();
 
-    ws.newPostRequest(PermissionsWs.ENDPOINT, ACTION)
+    ws.newPostRequest(ENDPOINT, ACTION)
       .setParam(PARAM_USER_LOGIN, "ray.bradbury")
       .setParam(PARAM_PROJECT_KEY, "project-key")
       .setParam(PermissionWsCommons.PARAM_PERMISSION, SYSTEM_ADMIN)
@@ -125,20 +127,30 @@ public class AddUserActionTest {
   public void fail_when_project_uuid_is_unknown() throws Exception {
     expectedException.expect(NotFoundException.class);
 
-    ws.newPostRequest(PermissionsWs.ENDPOINT, ACTION)
+    ws.newPostRequest(ENDPOINT, ACTION)
       .setParam(PARAM_USER_LOGIN, "ray.bradbury")
       .setParam(PARAM_PROJECT_UUID, "unknown-project-uuid")
       .setParam(PermissionWsCommons.PARAM_PERMISSION, SYSTEM_ADMIN)
       .execute();
   }
 
+  @Test
+  public void fail_when_project_permission_without_project() throws Exception {
+    expectedException.expect(BadRequestException.class);
+
+    ws.newPostRequest(ENDPOINT, ACTION)
+      .setParam(PARAM_USER_LOGIN, "ray.bradbury")
+      .setParam(PermissionWsCommons.PARAM_PERMISSION, UserRole.ISSUE_ADMIN)
+      .execute();
+  }
+
   @Test
   public void fail_when_component_is_not_a_project() throws Exception {
     expectedException.expect(BadRequestException.class);
     insertComponent(newFileDto(newProjectDto("project-uuid"), "file-uuid"));
     commit();
 
-    ws.newPostRequest(PermissionsWs.ENDPOINT, ACTION)
+    ws.newPostRequest(ENDPOINT, ACTION)
       .setParam(PARAM_USER_LOGIN, "ray.bradbury")
       .setParam(PARAM_PROJECT_UUID, "file-uuid")
       .setParam(PermissionWsCommons.PARAM_PERMISSION, SYSTEM_ADMIN)
@@ -149,7 +161,7 @@ public class AddUserActionTest {
   public void fail_when_get_request() throws Exception {
     expectedException.expect(ServerException.class);
 
-    ws.newGetRequest(PermissionsWs.ENDPOINT, ACTION)
+    ws.newGetRequest(ENDPOINT, ACTION)
       .setParam(PARAM_USER_LOGIN, "george.orwell")
       .setParam(PARAM_PERMISSION, SYSTEM_ADMIN)
       .execute();
@@ -159,7 +171,7 @@ public class AddUserActionTest {
   public void fail_when_user_login_is_missing() throws Exception {
     expectedException.expect(IllegalArgumentException.class);
 
-    ws.newPostRequest(PermissionsWs.ENDPOINT, ACTION)
+    ws.newPostRequest(ENDPOINT, ACTION)
       .setParam(PARAM_PERMISSION, SYSTEM_ADMIN)
       .execute();
   }
@@ -168,11 +180,26 @@ public class AddUserActionTest {
   public void fail_when_permission_is_missing() throws Exception {
     expectedException.expect(IllegalArgumentException.class);
 
-    ws.newPostRequest(PermissionsWs.ENDPOINT, ACTION)
+    ws.newPostRequest(ENDPOINT, ACTION)
       .setParam(PARAM_USER_LOGIN, "jrr.tolkien")
       .execute();
   }
 
+  @Test
+  public void fail_when_project_uuid_and_project_key_are_provided() throws Exception {
+    expectedException.expect(BadRequestException.class);
+    expectedException.expectMessage("Project id or project key can be provided, not both.");
+    insertComponent(newProjectDto("project-uuid").setKey("project-key"));
+    commit();
+
+    ws.newPostRequest(ENDPOINT, ACTION)
+      .setParam(PARAM_PERMISSION, SYSTEM_ADMIN)
+      .setParam(PARAM_USER_LOGIN, "ray.bradbury")
+      .setParam(PARAM_PROJECT_UUID, "project-uuid")
+      .setParam(PARAM_PROJECT_KEY, "project-key")
+      .execute();
+  }
+
   private void insertComponent(ComponentDto component) {
     dbClient.componentDao().insert(dbSession, component);
   }
index 90e08c50a1e564e4f52096c580c783b6127e4e96..b0be7661f9685d2be235c0866567a846c23889c1 100644 (file)
@@ -38,6 +38,7 @@ import org.sonar.db.component.ComponentDto;
 import org.sonar.db.user.GroupDto;
 import org.sonar.db.user.GroupRoleDto;
 import org.sonar.server.component.ComponentFinder;
+import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.exceptions.UnauthorizedException;
 import org.sonar.server.permission.PermissionFinder;
@@ -51,6 +52,7 @@ import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;
 import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
 import static org.sonar.server.component.ComponentTesting.newProjectDto;
 import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PERMISSION;
+import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PROJECT_KEY;
 import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PROJECT_UUID;
 import static org.sonar.test.JsonAssert.assertJson;
 
@@ -155,6 +157,15 @@ public class GroupsActionTest {
       .doesNotContain("group-3");
   }
 
+  @Test
+  public void fail_if_project_permission_without_project() {
+    expectedException.expect(BadRequestException.class);
+
+    ws.newRequest()
+      .setParam(PARAM_PERMISSION, UserRole.ISSUE_ADMIN)
+      .execute();
+  }
+
   @Test
   public void fail_if_not_logged_in() {
     expectedException.expect(UnauthorizedException.class);
@@ -183,6 +194,19 @@ public class GroupsActionTest {
       .execute();
   }
 
+  @Test
+  public void fail_if_project_uuid_and_project_key_are_provided() {
+    expectedException.expect(BadRequestException.class);
+    expectedException.expectMessage("Project id or project key can be provided, not both.");
+    dbClient.componentDao().insert(dbSession, newProjectDto("project-uuid").setKey("project-key"));
+
+    ws.newRequest()
+      .setParam(PARAM_PERMISSION, SCAN_EXECUTION)
+      .setParam(PARAM_PROJECT_UUID, "project-uuid")
+      .setParam(PARAM_PROJECT_KEY, "project-key")
+      .execute();
+  }
+
   private GroupDto insertGroup(GroupDto group) {
     GroupDto result = dbClient.groupDao().insert(dbSession, group);
     commit();
index 6d7b22b7aa1c84bdbc7826ef5dff56c4970133b4..ee80661ad6d0f4d5800ec776bb0a82df813f500c 100644 (file)
@@ -27,6 +27,7 @@ import org.junit.experimental.categories.Category;
 import org.junit.rules.ExpectedException;
 import org.mockito.ArgumentCaptor;
 import org.sonar.api.utils.System2;
+import org.sonar.api.web.UserRole;
 import org.sonar.db.DbSession;
 import org.sonar.db.DbTester;
 import org.sonar.db.component.ComponentDto;
@@ -50,8 +51,8 @@ import static org.sonar.server.component.ComponentTesting.newProjectDto;
 import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_GROUP_ID;
 import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_GROUP_NAME;
 import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PERMISSION;
-import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PROJECT_UUID;
 import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PROJECT_KEY;
+import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PROJECT_UUID;
 import static org.sonar.server.permission.ws.RemoveGroupAction.ACTION;
 
 @Category(DbTests.class)
@@ -145,6 +146,16 @@ public class RemoveGroupActionTest {
       .execute();
   }
 
+  @Test
+  public void fail_when_project_project_permission_without_project() throws Exception {
+    expectedException.expect(BadRequestException.class);
+
+    newRequest()
+      .setParam(PARAM_GROUP_NAME, "sonar-administrators")
+      .setParam(PARAM_PERMISSION, UserRole.ISSUE_ADMIN)
+      .execute();
+  }
+
   @Test
   public void fail_when_component_is_not_a_project() throws Exception {
     expectedException.expect(BadRequestException.class);
@@ -197,6 +208,21 @@ public class RemoveGroupActionTest {
       .execute();
   }
 
+  @Test
+  public void fail_when_project_uuid_and_project_key_are_provided() throws Exception {
+    expectedException.expect(BadRequestException.class);
+    expectedException.expectMessage("Project id or project key can be provided, not both.");
+    insertComponent(newProjectDto("project-uuid").setKey("project-key"));
+    commit();
+
+    newRequest()
+      .setParam(PARAM_GROUP_NAME, "sonar-administrators")
+      .setParam(PARAM_PERMISSION, SYSTEM_ADMIN)
+      .setParam(PARAM_PROJECT_UUID, "project-uuid")
+      .setParam(PARAM_PROJECT_KEY, "project-key")
+      .execute();
+  }
+
   private WsTester.TestRequest newRequest() {
     return ws.newPostRequest(PermissionsWs.ENDPOINT, ACTION);
   }
index 9fa33c0034b534355c4d921891956169aa88fce0..296a0f45d7e1f8392402d75c298f2daa94a21d25 100644 (file)
@@ -27,6 +27,7 @@ import org.junit.experimental.categories.Category;
 import org.junit.rules.ExpectedException;
 import org.mockito.ArgumentCaptor;
 import org.sonar.api.utils.System2;
+import org.sonar.api.web.UserRole;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.DbTester;
@@ -51,6 +52,7 @@ import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PERMISSIO
 import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PROJECT_KEY;
 import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PROJECT_UUID;
 import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_USER_LOGIN;
+import static org.sonar.server.permission.ws.PermissionsWs.ENDPOINT;
 import static org.sonar.server.permission.ws.RemoveUserAction.ACTION;
 
 @Category(DbTests.class)
@@ -72,7 +74,7 @@ public class RemoveUserActionTest {
     dbClient = db.getDbClient();
     dbSession = db.getSession();
     ws = new WsTester(new PermissionsWs(
-      new RemoveUserAction(permissionUpdater, new PermissionWsCommons(dbClient, new ComponentFinder(dbClient), userSession))));
+      new RemoveUserAction(dbClient, permissionUpdater, new PermissionWsCommons(dbClient, new ComponentFinder(dbClient), userSession))));
     userSession.login("admin").setGlobalPermissions(SYSTEM_ADMIN);
   }
 
@@ -126,7 +128,17 @@ public class RemoveUserActionTest {
     ws.newPostRequest(PermissionsWs.ENDPOINT, ACTION)
       .setParam(PARAM_USER_LOGIN, "ray.bradbury")
       .setParam(PARAM_PROJECT_UUID, "unknown-project-uuid")
-      .setParam(PARAM_PERMISSION, SYSTEM_ADMIN)
+      .setParam(PARAM_PERMISSION, UserRole.ISSUE_ADMIN)
+      .execute();
+  }
+
+  @Test
+  public void fail_when_project_permission_without_permission() throws Exception {
+    expectedException.expect(BadRequestException.class);
+
+    ws.newPostRequest(PermissionsWs.ENDPOINT, ACTION)
+      .setParam(PARAM_USER_LOGIN, "ray.bradbury")
+      .setParam(PARAM_PERMISSION, UserRole.ISSUE_ADMIN)
       .execute();
   }
 
@@ -170,6 +182,20 @@ public class RemoveUserActionTest {
       .execute();
   }
 
+  @Test
+  public void fail_when_project_uuid_and_project_key_are_provided() throws Exception {
+    expectedException.expect(BadRequestException.class);
+    expectedException.expectMessage("Project id or project key can be provided, not both.");
+    insertComponent(newProjectDto("project-uuid").setKey("project-key"));
+
+    ws.newPostRequest(ENDPOINT, ACTION)
+      .setParam(PARAM_PERMISSION, SYSTEM_ADMIN)
+      .setParam(PARAM_USER_LOGIN, "ray.bradbury")
+      .setParam(PARAM_PROJECT_UUID, "project-uuid")
+      .setParam(PARAM_PROJECT_KEY, "project-key")
+      .execute();
+  }
+
   private void insertComponent(ComponentDto component) {
     dbClient.componentDao().insert(dbSession, component);
     dbSession.commit();
index f3fc0c3ac0320241c73bffc24c04daba60da6d22..84da264f01de7274cf7a5473e5e0933ac57a09b6 100644 (file)
@@ -28,6 +28,7 @@ import org.junit.rules.ExpectedException;
 import org.sonar.api.server.ws.WebService.Param;
 import org.sonar.api.server.ws.WebService.SelectionMode;
 import org.sonar.api.utils.System2;
+import org.sonar.api.web.UserRole;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.DbTester;
@@ -35,6 +36,7 @@ import org.sonar.db.component.ComponentDto;
 import org.sonar.db.user.UserDto;
 import org.sonar.db.user.UserRoleDto;
 import org.sonar.server.component.ComponentFinder;
+import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.exceptions.UnauthorizedException;
 import org.sonar.server.permission.PermissionFinder;
@@ -43,10 +45,12 @@ import org.sonar.server.ws.WsActionTester;
 import org.sonar.test.DbTests;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.api.web.UserRole.ISSUE_ADMIN;
 import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;
 import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
 import static org.sonar.server.component.ComponentTesting.newProjectDto;
 import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PERMISSION;
+import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PROJECT_KEY;
 import static org.sonar.server.permission.ws.PermissionWsCommons.PARAM_PROJECT_UUID;
 import static org.sonar.test.JsonAssert.assertJson;
 
@@ -69,7 +73,7 @@ public class UsersActionTest {
   public void setUp() {
     PermissionFinder permissionFinder = new PermissionFinder(dbClient);
     PermissionWsCommons permissionWsCommons = new PermissionWsCommons(dbClient, new ComponentFinder(dbClient), userSession);
-    underTest = new UsersAction(userSession, permissionFinder, permissionWsCommons);
+    underTest = new UsersAction(permissionFinder, permissionWsCommons);
     ws = new WsActionTester(underTest);
 
     userSession.login("login").setGlobalPermissions(SYSTEM_ADMIN);
@@ -109,12 +113,12 @@ public class UsersActionTest {
     dbClient.componentDao().insert(dbSession, newProjectDto("project-uuid").setKey("project-key"));
     ComponentDto project = dbClient.componentDao().selectOrFailByUuid(dbSession, "project-uuid");
     UserDto user = insertUser(new UserDto().setLogin("project-user-login").setName("project-user-name"));
-    insertUserRole(new UserRoleDto().setRole(SCAN_EXECUTION).setUserId(user.getId()).setResourceId(project.getId()));
+    insertUserRole(new UserRoleDto().setRole(ISSUE_ADMIN).setUserId(user.getId()).setResourceId(project.getId()));
     commit();
     userSession.login().addProjectUuidPermissions(SYSTEM_ADMIN, "project-uuid");
 
     String result = ws.newRequest()
-      .setParam(PARAM_PERMISSION, SCAN_EXECUTION)
+      .setParam(PARAM_PERMISSION, ISSUE_ADMIN)
       .setParam(PARAM_PROJECT_UUID, "project-uuid")
       .execute().getInput();
 
@@ -132,7 +136,6 @@ public class UsersActionTest {
     assertThat(result).contains("login-1")
       .doesNotContain("login-2")
       .doesNotContain("login-3");
-
   }
 
   @Test
@@ -145,6 +148,16 @@ public class UsersActionTest {
     assertThat(result).contains("login-1", "login-2", "login-3");
   }
 
+  @Test
+  public void fail_if_project_permission_without_project() {
+    expectedException.expect(BadRequestException.class);
+
+    ws.newRequest()
+      .setParam(PARAM_PERMISSION, UserRole.ISSUE_ADMIN)
+      .setParam(Param.SELECTED, SelectionMode.ALL.value())
+      .execute();
+  }
+
   @Test
   public void fail_if_permission_parameter_is_not_filled() {
     expectedException.expect(IllegalArgumentException.class);
@@ -172,6 +185,20 @@ public class UsersActionTest {
       .execute();
   }
 
+  @Test
+  public void fail_if_project_uuid_and_project_key_are_provided() {
+    expectedException.expect(BadRequestException.class);
+    expectedException.expectMessage("Project id or project key can be provided, not both.");
+    dbClient.componentDao().insert(dbSession, newProjectDto("project-uuid").setKey("project-key"));
+    commit();
+
+    ws.newRequest()
+      .setParam(PARAM_PERMISSION, SYSTEM_ADMIN)
+      .setParam(PARAM_PROJECT_UUID, "project-uuid")
+      .setParam(PARAM_PROJECT_KEY, "project-key")
+      .execute();
+  }
+
   private UserDto insertUser(UserDto userDto) {
     UserDto user = dbClient.userDao().insert(dbSession, userDto.setActive(true));
     commit();