import com.google.common.base.Optional;
import javax.annotation.Nullable;
+import org.sonar.api.resources.Qualifiers;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
+import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.NotFoundException;
import static com.google.common.base.Preconditions.checkArgument;
return getIfPresentOrFail(dbClient.componentDao().selectByUuid(dbSession, uuid), String.format("Component id '%s' not found", uuid));
}
+ public ComponentDto getProjectByUuidOrKey(DbSession dbSession, @Nullable String projectUuid, @Nullable String projectKey) {
+ ComponentDto project = getByUuidOrKey(dbSession, projectUuid, projectKey);
+ checkIsProjectOrModule(project);
+
+ return project;
+ }
+
private static ComponentDto getIfPresentOrFail(Optional<ComponentDto> component, String errorMsg) {
if (!component.isPresent()) {
throw new NotFoundException(errorMsg);
}
return component.get();
}
+
+ private static void checkIsProjectOrModule(ComponentDto component) {
+ if (!Qualifiers.PROJECT.equals(component.qualifier()) && !Qualifiers.MODULE.equals(component.qualifier())) {
+ throw new BadRequestException(String.format("Component '%s' (id: %s) must be a project or a module.", component.key(), component.uuid()));
+ }
+ }
}
package org.sonar.server.permission;
import com.google.common.base.Strings;
+import java.util.Map;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.sonar.core.permission.ComponentPermissions;
import org.sonar.core.permission.GlobalPermissions;
import org.sonar.server.exceptions.BadRequestException;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-
-import java.util.Map;
-
public class PermissionChange {
static final String USER_KEY = "user";
package org.sonar.server.permission.ws;
+import javax.annotation.Nullable;
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.db.component.ComponentDto;
+import org.sonar.server.component.ComponentFinder;
import org.sonar.server.permission.PermissionChange;
import org.sonar.server.permission.PermissionUpdater;
-import static org.sonar.server.permission.ws.PermissionWsCommons.searchName;
-
public class AddGroupAction implements PermissionsWsAction {
public static final String ACTION = "add_group";
public static final String PARAM_PERMISSION = "permission";
public static final String PARAM_GROUP_NAME = "groupName";
public static final String PARAM_GROUP_ID = "groupId";
+ public static final String PARAM_PROJECT_ID = "projectId";
+ public static final String PARAM_PROJECT_KEY = "projectKey";
- private final PermissionUpdater permissionUpdater;
private final DbClient dbClient;
+ private final PermissionWsCommons permissionWsCommons;
+ private final PermissionUpdater permissionUpdater;
+ private final ComponentFinder componentFinder;
- public AddGroupAction(PermissionUpdater permissionUpdater, DbClient dbClient) {
+ public AddGroupAction(DbClient dbClient, PermissionWsCommons permissionWsCommons, PermissionUpdater permissionUpdater, ComponentFinder componentFinder) {
+ this.permissionWsCommons = permissionWsCommons;
this.permissionUpdater = permissionUpdater;
this.dbClient = dbClient;
+ this.componentFinder = componentFinder;
}
@Override
public void define(WebService.NewController context) {
WebService.NewAction action = context.createAction(ACTION)
.setDescription("Add permission to a group.<br /> " +
+ "If the project id is provided, a project permission is created.<br />" +
"The group name or group id must be provided. <br />" +
"Requires 'Administer System' permission.")
.setSince("5.2")
.setExampleValue("sonar-administrators");
action.createParam(PARAM_GROUP_ID)
- .setDescription("Group ID")
+ .setDescription("Group id")
.setExampleValue("42");
+
+ action.createParam(PARAM_PROJECT_ID)
+ .setDescription("Project id")
+ .setExampleValue("ce4c03d6-430f-40a9-b777-ad877c00aa4d");
+
+ action.createParam(PARAM_PROJECT_KEY)
+ .setDescription("Project key")
+ .setExampleValue("org.apache.hbas:hbase");
}
@Override
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_ID);
+ String projectKey = request.param(PARAM_PROJECT_KEY);
- String groupName = searchName(dbClient, groupNameParam, groupId);
+ DbSession dbSession = dbClient.openSession(false);
+ try {
+ String groupName = permissionWsCommons.searchGroupName(dbSession, groupNameParam, groupId);
+ PermissionChange permissionChange = permissionChange(dbSession, permission, groupName, projectUuid, projectKey);
- permissionUpdater.addPermission(
- new PermissionChange()
- .setPermission(permission)
- .setGroup(groupName)
- );
+ permissionUpdater.addPermission(permissionChange);
+ } finally {
+ dbClient.closeSession(dbSession);
+ }
response.noContent();
}
+
+ private PermissionChange permissionChange(DbSession dbSession, String permission, String groupName, @Nullable String projectUuid, @Nullable String projectKey) {
+ PermissionChange permissionChange = new PermissionChange()
+ .setPermission(permission)
+ .setGroup(groupName);
+ if (isProjectUuidOrProjectKeyProvided(projectUuid, projectKey)) {
+ ComponentDto project = componentFinder.getProjectByUuidOrKey(dbSession, projectUuid, projectKey);
+ permissionChange.setComponentKey(project.key());
+ }
+ return permissionChange;
+ }
+
+ private static boolean isProjectUuidOrProjectKeyProvided(@Nullable String projectUuid, @Nullable String projectKey) {
+ return projectUuid != null || projectKey != null;
+ }
}
public class PermissionWsCommons {
- private PermissionWsCommons() {
- // static stuff only
+ private final DbClient dbClient;
+
+ public PermissionWsCommons(DbClient dbClient) {
+ this.dbClient = dbClient;
}
- public static String searchName(DbClient dbClient, @Nullable String groupNameParam, @Nullable Long groupId) {
+ public String searchGroupName(DbSession dbSession, @Nullable String groupNameParam, @Nullable Long groupId) {
checkParameters(groupNameParam, groupId);
if (groupNameParam != null) {
return groupNameParam;
}
- DbSession dbSession = dbClient.openSession(false);
- try {
- GroupDto group = dbClient.groupDao().selectById(dbSession, groupId);
- if (group == null) {
- throw new NotFoundException(String.format("Group with id '%d' is not found", groupId));
- }
-
- return group.getName();
- } finally {
- dbClient.closeSession(dbSession);
+ GroupDto group = dbClient.groupDao().selectById(dbSession, groupId);
+ if (group == null) {
+ throw new NotFoundException(String.format("Group with id '%d' is not found", groupId));
}
+
+ return group.getName();
}
private static void checkParameters(@Nullable String groupName, @Nullable Long groupId) {
RemoveUserAction.class,
UsersAction.class,
GroupsAction.class,
- SearchGlobalPermissionsAction.class);
+ SearchGlobalPermissionsAction.class,
+ PermissionWsCommons.class);
}
}
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 static org.sonar.server.permission.ws.PermissionWsCommons.searchName;
-
public class RemoveGroupAction implements PermissionsWsAction {
public static final String ACTION = "remove_group";
public static final String PARAM_GROUP_NAME = "groupName";
public static final String PARAM_GROUP_ID = "groupId";
- private final PermissionUpdater permissionUpdater;
private final DbClient dbClient;
+ private final PermissionWsCommons permissionWsCommons;
+ private final PermissionUpdater permissionUpdater;
- public RemoveGroupAction(PermissionUpdater permissionUpdater, DbClient dbClient) {
- this.permissionUpdater = permissionUpdater;
+ public RemoveGroupAction(DbClient dbClient, PermissionWsCommons permissionWsCommons, PermissionUpdater permissionUpdater) {
this.dbClient = dbClient;
+ this.permissionWsCommons = permissionWsCommons;
+ this.permissionUpdater = permissionUpdater;
}
@Override
String groupNameParam = request.param(PARAM_GROUP_NAME);
Long groupId = request.paramAsLong(PARAM_GROUP_ID);
- String groupName = searchName(dbClient, groupNameParam, groupId);
+ DbSession dbSession = dbClient.openSession(false);
+ try {
+ String groupName = permissionWsCommons.searchGroupName(dbSession, groupNameParam, groupId);
- permissionUpdater.removePermission(
- new PermissionChange()
- .setPermission(permission)
- .setGroup(groupName)
- );
+ permissionUpdater.removePermission(
+ new PermissionChange()
+ .setPermission(permission)
+ .setGroup(groupName)
+ );
+ } finally {
+ dbClient.closeSession(dbSession);
+ }
response.noContent();
}
import org.junit.rules.ExpectedException;
import org.mockito.ArgumentCaptor;
import org.sonar.api.utils.System2;
+import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
+import org.sonar.db.component.ComponentDto;
import org.sonar.db.user.GroupDto;
+import org.sonar.server.component.ComponentFinder;
+import org.sonar.server.component.ComponentTesting;
import org.sonar.server.exceptions.BadRequestException;
+import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.exceptions.ServerException;
import org.sonar.server.permission.PermissionChange;
import org.sonar.server.permission.PermissionUpdater;
import static org.mockito.Mockito.verify;
import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
import static org.sonar.server.permission.ws.AddGroupAction.ACTION;
+import static org.sonar.server.permission.ws.AddGroupAction.PARAM_GROUP_ID;
+import static org.sonar.server.permission.ws.AddGroupAction.PARAM_GROUP_NAME;
+import static org.sonar.server.permission.ws.AddGroupAction.PARAM_PERMISSION;
+import static org.sonar.server.permission.ws.AddGroupAction.PARAM_PROJECT_ID;
+import static org.sonar.server.permission.ws.AddGroupAction.PARAM_PROJECT_KEY;
+import static org.sonar.server.permission.ws.PermissionsWs.ENDPOINT;
@Category(DbTests.class)
public class AddGroupActionTest {
@Rule
public ExpectedException expectedException = ExpectedException.none();
private PermissionUpdater permissionUpdater;
+ private DbClient dbClient;
+ private ArgumentCaptor<PermissionChange> permissionChangeCaptor;
@Before
public void setUp() {
permissionUpdater = mock(PermissionUpdater.class);
+ permissionChangeCaptor = ArgumentCaptor.forClass(PermissionChange.class);
+ dbClient = db.getDbClient();
ws = new WsTester(new PermissionsWs(
- new AddGroupAction(permissionUpdater, db.getDbClient())));
+ new AddGroupAction(dbClient, new PermissionWsCommons(dbClient), permissionUpdater, new ComponentFinder(dbClient))));
userSession.login("admin").setGlobalPermissions(SYSTEM_ADMIN);
-
}
@Test
public void call_permission_service_with_right_data() throws Exception {
- ws.newPostRequest(PermissionsWs.ENDPOINT, ACTION)
- .setParam(AddGroupAction.PARAM_GROUP_NAME, "sonar-administrators")
- .setParam(AddGroupAction.PARAM_PERMISSION, SYSTEM_ADMIN)
+ newRequest()
+ .setParam(PARAM_GROUP_NAME, "sonar-administrators")
+ .setParam(PARAM_PERMISSION, SYSTEM_ADMIN)
.execute();
- ArgumentCaptor<PermissionChange> permissionChangeCaptor = ArgumentCaptor.forClass(PermissionChange.class);
verify(permissionUpdater).addPermission(permissionChangeCaptor.capture());
PermissionChange permissionChange = permissionChangeCaptor.getValue();
assertThat(permissionChange.group()).isEqualTo("sonar-administrators");
}
@Test
- public void search_with_group_id() throws Exception {
- GroupDto group = db.getDbClient().groupDao().insert(db.getSession(), new GroupDto()
- .setName("sonar-administrators"));
- db.getSession().commit();
+ public void add_with_group_id() throws Exception {
+ GroupDto group = insertGroup("sonar-administrators");
+ commit();
+
+ newRequest()
+ .setParam(PARAM_GROUP_ID, group.getId().toString())
+ .setParam(PARAM_PERMISSION, SYSTEM_ADMIN)
+ .execute();
+
+ verify(permissionUpdater).addPermission(permissionChangeCaptor.capture());
+ PermissionChange permissionChange = permissionChangeCaptor.getValue();
+ assertThat(permissionChange.group()).isEqualTo("sonar-administrators");
+ }
+
+ @Test
+ public void add_with_project_uuid() throws Exception {
+ insertGroup("sonar-administrators");
+ insertComponent(ComponentTesting.newProjectDto("project-uuid").setKey("project-key"));
+ commit();
+
+ newRequest()
+ .setParam(PARAM_GROUP_NAME, "sonar-administrators")
+ .setParam(PARAM_PROJECT_ID, "project-uuid")
+ .setParam(PARAM_PERMISSION, SYSTEM_ADMIN)
+ .execute();
+
+ verify(permissionUpdater).addPermission(permissionChangeCaptor.capture());
+ PermissionChange permissionChange = permissionChangeCaptor.getValue();
+ assertThat(permissionChange.component()).isEqualTo("project-key");
+ assertThat(permissionChange.group()).isEqualTo("sonar-administrators");
+ }
- ws.newPostRequest(PermissionsWs.ENDPOINT, ACTION)
- .setParam(AddGroupAction.PARAM_GROUP_ID, group.getId().toString())
- .setParam(AddGroupAction.PARAM_PERMISSION, SYSTEM_ADMIN)
+ @Test
+ public void add_with_project_key() throws Exception {
+ insertGroup("sonar-administrators");
+ insertComponent(ComponentTesting.newProjectDto("project-uuid").setKey("project-key"));
+ commit();
+
+ newRequest()
+ .setParam(PARAM_GROUP_NAME, "sonar-administrators")
+ .setParam(PARAM_PROJECT_KEY, "project-key")
+ .setParam(PARAM_PERMISSION, SYSTEM_ADMIN)
.execute();
- ArgumentCaptor<PermissionChange> permissionChangeCaptor = ArgumentCaptor.forClass(PermissionChange.class);
verify(permissionUpdater).addPermission(permissionChangeCaptor.capture());
PermissionChange permissionChange = permissionChangeCaptor.getValue();
+ assertThat(permissionChange.component()).isEqualTo("project-key");
assertThat(permissionChange.group()).isEqualTo("sonar-administrators");
}
+ @Test
+ public void fail_if_project_uuid_not_found() throws Exception {
+ expectedException.expect(NotFoundException.class);
+
+ insertGroup("sonar-administrators");
+ insertComponent(ComponentTesting.newProjectDto("project-uuid").setKey("project-key"));
+ commit();
+
+ newRequest()
+ .setParam(PARAM_GROUP_NAME, "sonar-administrators")
+ .setParam(PARAM_PROJECT_ID, "unknown-project-uuid")
+ .setParam(PARAM_PERMISSION, SYSTEM_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");
+ insertComponent(project);
+ insertComponent(ComponentTesting.newFileDto(project, "file-uuid"));
+ commit();
+
+ newRequest()
+ .setParam(PARAM_GROUP_NAME, "sonar-administrators")
+ .setParam(PARAM_PROJECT_ID, "file-uuid")
+ .setParam(PARAM_PERMISSION, SYSTEM_ADMIN)
+ .execute();
+ }
+
@Test
public void fail_when_get_request() throws Exception {
expectedException.expect(ServerException.class);
- ws.newGetRequest(PermissionsWs.ENDPOINT, ACTION)
- .setParam(AddGroupAction.PARAM_GROUP_NAME, "sonar-administrators")
- .setParam(AddGroupAction.PARAM_PERMISSION, SYSTEM_ADMIN)
+ ws.newGetRequest(ENDPOINT, ACTION)
+ .setParam(PARAM_GROUP_NAME, "sonar-administrators")
+ .setParam(PARAM_PERMISSION, SYSTEM_ADMIN)
.execute();
}
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Group name or group id must be provided, not both");
- ws.newPostRequest(PermissionsWs.ENDPOINT, ACTION)
- .setParam(AddGroupAction.PARAM_PERMISSION, SYSTEM_ADMIN)
+ newRequest()
+ .setParam(PARAM_PERMISSION, SYSTEM_ADMIN)
.execute();
}
public void fail_when_permission_is_missing() throws Exception {
expectedException.expect(IllegalArgumentException.class);
- ws.newPostRequest(PermissionsWs.ENDPOINT, ACTION)
- .setParam(AddGroupAction.PARAM_GROUP_NAME, "sonar-administrators")
+ newRequest()
+ .setParam(PARAM_GROUP_NAME, "sonar-administrators")
.execute();
}
+
+ private WsTester.TestRequest newRequest() {
+ return ws.newPostRequest(ENDPOINT, ACTION);
+ }
+
+ private void commit() {
+ db.getSession().commit();
+ }
+
+ private void insertComponent(ComponentDto component) {
+ dbClient.componentDao().insert(db.getSession(), component);
+ }
+
+ private GroupDto insertGroup(String name) {
+ return dbClient.groupDao().insert(db.getSession(), new GroupDto().setName(name));
+ }
}
public void verify_count_of_added_components() {
ComponentContainer container = new ComponentContainer();
new PermissionsWsModule().configure(container);
- assertThat(container.size()).isEqualTo(10);
+ assertThat(container.size()).isEqualTo(11);
}
}
public void setUp() {
permissionUpdater = mock(PermissionUpdater.class);
ws = new WsTester(new PermissionsWs(
- new RemoveGroupAction(permissionUpdater, db.getDbClient())));
+ new RemoveGroupAction(db.getDbClient(), new PermissionWsCommons(db.getDbClient()), permissionUpdater)));
userSession.login("admin").setGlobalPermissions(SYSTEM_ADMIN);
}