<insert id="insert" parameterType="Group" useGeneratedKeys="false"> | <insert id="insert" parameterType="Group" useGeneratedKeys="false"> | ||||
insert into groups ( | insert into groups ( | ||||
uuid, | uuid, | ||||
organization_uuid, | |||||
name, | name, | ||||
description, | description, | ||||
created_at, | created_at, | ||||
updated_at | updated_at | ||||
) values ( | ) values ( | ||||
#{uuid,jdbcType=VARCHAR}, | #{uuid,jdbcType=VARCHAR}, | ||||
'asd', | |||||
#{name,jdbcType=VARCHAR}, | #{name,jdbcType=VARCHAR}, | ||||
#{description,jdbcType=VARCHAR}, | #{description,jdbcType=VARCHAR}, | ||||
#{createdAt,jdbcType=TIMESTAMP}, | #{createdAt,jdbcType=TIMESTAMP}, |
CREATE UNIQUE INDEX "UNIQ_GROUP_ROLES" ON "GROUP_ROLES"("GROUP_UUID", "COMPONENT_UUID", "ROLE"); | CREATE UNIQUE INDEX "UNIQ_GROUP_ROLES" ON "GROUP_ROLES"("GROUP_UUID", "COMPONENT_UUID", "ROLE"); | ||||
CREATE TABLE "GROUPS"( | CREATE TABLE "GROUPS"( | ||||
"ORGANIZATION_UUID" VARCHAR(40) NOT NULL, | |||||
"NAME" VARCHAR(500), | |||||
"NAME" VARCHAR(500) NOT NULL, | |||||
"DESCRIPTION" VARCHAR(200), | "DESCRIPTION" VARCHAR(200), | ||||
"CREATED_AT" TIMESTAMP, | "CREATED_AT" TIMESTAMP, | ||||
"UPDATED_AT" TIMESTAMP, | "UPDATED_AT" TIMESTAMP, | ||||
"UUID" VARCHAR(40) NOT NULL | "UUID" VARCHAR(40) NOT NULL | ||||
); | ); | ||||
ALTER TABLE "GROUPS" ADD CONSTRAINT "PK_GROUPS" PRIMARY KEY("UUID"); | ALTER TABLE "GROUPS" ADD CONSTRAINT "PK_GROUPS" PRIMARY KEY("UUID"); | ||||
CREATE UNIQUE INDEX "UNIQ_GROUPS_NAME" ON "GROUPS"("NAME"); | |||||
CREATE TABLE "GROUPS_USERS"( | CREATE TABLE "GROUPS_USERS"( | ||||
"GROUP_UUID" VARCHAR(40) NOT NULL, | "GROUP_UUID" VARCHAR(40) NOT NULL, |
db.users().insertMember(group2, user3); | db.users().insertMember(group2, user3); | ||||
// group3 has the permission "perm1" but has no users | // group3 has the permission "perm1" but has no users | ||||
GroupDto group3 = db.users().insertGroup("g2"); | |||||
GroupDto group3 = db.users().insertGroup("g3"); | |||||
db.users().insertPermissionOnGroup(group3, "perm1"); | db.users().insertPermissionOnGroup(group3, "perm1"); | ||||
db.users().insertPermissionOnUser(user4, "perm1"); | db.users().insertPermissionOnUser(user4, "perm1"); |
import java.util.function.Consumer; | import java.util.function.Consumer; | ||||
import javax.annotation.CheckForNull; | import javax.annotation.CheckForNull; | ||||
import javax.annotation.Nullable; | import javax.annotation.Nullable; | ||||
import org.sonar.api.security.DefaultGroups; | |||||
import org.sonar.api.web.UserRole; | import org.sonar.api.web.UserRole; | ||||
import org.sonar.core.util.Uuids; | import org.sonar.core.util.Uuids; | ||||
import org.sonar.core.util.stream.MoreCollectors; | import org.sonar.core.util.stream.MoreCollectors; | ||||
import org.sonar.db.project.ProjectDto; | import org.sonar.db.project.ProjectDto; | ||||
import static com.google.common.base.Preconditions.checkArgument; | import static com.google.common.base.Preconditions.checkArgument; | ||||
import static java.lang.String.format; | |||||
import static java.util.Arrays.stream; | import static java.util.Arrays.stream; | ||||
import static org.apache.commons.lang.math.RandomUtils.nextLong; | import static org.apache.commons.lang.math.RandomUtils.nextLong; | ||||
import static org.sonar.db.permission.OrganizationPermission.ADMINISTER; | import static org.sonar.db.permission.OrganizationPermission.ADMINISTER; | ||||
import static org.sonar.db.user.GroupTesting.newGroupDto; | |||||
public class UserDbTester { | public class UserDbTester { | ||||
private static final Set<String> PUBLIC_PERMISSIONS = ImmutableSet.of(UserRole.USER, UserRole.CODEVIEWER); // FIXME to check with Simon | private static final Set<String> PUBLIC_PERMISSIONS = ImmutableSet.of(UserRole.USER, UserRole.CODEVIEWER); // FIXME to check with Simon | ||||
// GROUPS | // GROUPS | ||||
public GroupDto insertGroup(String name) { | public GroupDto insertGroup(String name) { | ||||
GroupDto group = GroupTesting.newGroupDto().setName(name); | |||||
GroupDto group = newGroupDto().setName(name); | |||||
return insertGroup(group); | return insertGroup(group); | ||||
} | } | ||||
public GroupDto insertGroup() { | public GroupDto insertGroup() { | ||||
GroupDto group = GroupTesting.newGroupDto(); | |||||
GroupDto group = newGroupDto(); | |||||
return insertGroup(group); | return insertGroup(group); | ||||
} | } | ||||
return dto; | return dto; | ||||
} | } | ||||
public GroupDto insertDefaultGroup(GroupDto dto) { | |||||
db.getDbClient().organizationDao().getDefaultGroupUuid(db.getSession(), db.getDefaultOrganization().getUuid()) | |||||
.ifPresent(groupUuid -> { | |||||
throw new IllegalArgumentException(format("Organization '%s' has already a default group", db.getDefaultOrganization().getUuid())); | |||||
}); | |||||
db.getDbClient().groupDao().insert(db.getSession(), dto); | |||||
db.getDbClient().organizationDao().setDefaultGroupUuid(db.getSession(), db.getDefaultOrganization().getUuid(), dto); | |||||
public GroupDto insertDefaultGroup() { | |||||
GroupDto dto = db.getDbClient().groupDao().insert(db.getSession(), newGroupDto().setName(DefaultGroups.USERS).setDescription("Users")); | |||||
db.commit(); | db.commit(); | ||||
return dto; | return dto; | ||||
} | } | ||||
public GroupDto insertDefaultGroup(String name) { | |||||
return insertDefaultGroup(GroupTesting.newGroupDto().setName(name)); | |||||
} | |||||
public GroupDto insertDefaultGroup() { | |||||
return insertDefaultGroup(GroupTesting.newGroupDto()); | |||||
} | |||||
@CheckForNull | @CheckForNull | ||||
public GroupDto selectGroupByUuid(String groupUuid) { | public GroupDto selectGroupByUuid(String groupUuid) { | ||||
return db.getDbClient().groupDao().selectByUuid(db.getSession(), groupUuid); | return db.getDbClient().groupDao().selectByUuid(db.getSession(), groupUuid); |
/* | |||||
* SonarQube | |||||
* Copyright (C) 2009-2020 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.platform.db.migration.version.v86; | |||||
import java.sql.SQLException; | |||||
import org.sonar.db.Database; | |||||
import org.sonar.server.platform.db.migration.def.VarcharColumnDef; | |||||
import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder; | |||||
import org.sonar.server.platform.db.migration.step.DdlChange; | |||||
public class AddUniqueIndexOnNameColumnOfGroupsTable extends DdlChange { | |||||
private static final String TABLE_NAME = "groups"; | |||||
private static final String INDEX_NAME = "uniq_groups_name"; | |||||
public AddUniqueIndexOnNameColumnOfGroupsTable(Database db) { | |||||
super(db); | |||||
} | |||||
@Override | |||||
public void execute(Context context) throws SQLException { | |||||
context.execute(new CreateIndexBuilder() | |||||
.setUnique(true) | |||||
.setTable(TABLE_NAME) | |||||
.setName(INDEX_NAME) | |||||
.addColumn(new VarcharColumnDef.Builder() | |||||
.setColumnName("name") | |||||
.setIgnoreOracleUnit(true) | |||||
.setLimit(500) | |||||
.setIsNullable(false) | |||||
.build()) | |||||
.build()); | |||||
} | |||||
} |
.add(4108, "Drop 'organization_uuid' in 'user_roles'", DropOrganizationInUserRoles.class) | .add(4108, "Drop 'organization_uuid' in 'user_roles'", DropOrganizationInUserRoles.class) | ||||
.add(4109, "Drop 'organization_uuid' in 'group_roles'", DropOrganizationInGroupRoles.class) | .add(4109, "Drop 'organization_uuid' in 'group_roles'", DropOrganizationInGroupRoles.class) | ||||
.add(4110, "Drop 'organization_uuid' in 'permission_templates'", DropOrganizationInPermissionTemplates.class) | .add(4110, "Drop 'organization_uuid' in 'permission_templates'", DropOrganizationInPermissionTemplates.class) | ||||
.add(4111, "Drop 'organization_uuid' in 'groups'", DropOrganizationInGroups.class) | |||||
.add(4112, "Make 'name' column in 'groups' table not nullable", MakeNameColumnInGroupsTableNotNullable.class) | |||||
.add(4113, "Make 'name' column in 'groups' table unique", AddUniqueIndexOnNameColumnOfGroupsTable.class) | |||||
; | ; | ||||
} | } | ||||
} | } |
/* | |||||
* SonarQube | |||||
* Copyright (C) 2009-2020 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.platform.db.migration.version.v86; | |||||
import java.sql.SQLException; | |||||
import org.sonar.db.Database; | |||||
import org.sonar.server.platform.db.migration.sql.DropColumnsBuilder; | |||||
import org.sonar.server.platform.db.migration.step.DdlChange; | |||||
public class DropOrganizationInGroups extends DdlChange { | |||||
private static final String TABLE_NAME = "groups"; | |||||
public DropOrganizationInGroups(Database db) { | |||||
super(db); | |||||
} | |||||
@Override | |||||
public void execute(Context context) throws SQLException { | |||||
context.execute(new DropColumnsBuilder(getDialect(), TABLE_NAME, "organization_uuid").build()); | |||||
} | |||||
} |
/* | |||||
* SonarQube | |||||
* Copyright (C) 2009-2020 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.platform.db.migration.version.v86; | |||||
import java.sql.SQLException; | |||||
import org.sonar.db.Database; | |||||
import org.sonar.server.platform.db.migration.def.VarcharColumnDef; | |||||
import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder; | |||||
import org.sonar.server.platform.db.migration.step.DdlChange; | |||||
import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; | |||||
public class MakeNameColumnInGroupsTableNotNullable extends DdlChange { | |||||
private static final String TABLE = "groups"; | |||||
private static final VarcharColumnDef columnDefinition = newVarcharColumnDefBuilder() | |||||
.setColumnName("name") | |||||
.setIsNullable(false) | |||||
.setIgnoreOracleUnit(true) | |||||
.setLimit(500) | |||||
.build(); | |||||
public MakeNameColumnInGroupsTableNotNullable(Database db) { | |||||
super(db); | |||||
} | |||||
@Override | |||||
public void execute(Context context) throws SQLException { | |||||
context.execute(new AlterColumnsBuilder(getDialect(), TABLE) | |||||
.updateColumn(columnDefinition) | |||||
.build()); | |||||
} | |||||
} |
/* | |||||
* SonarQube | |||||
* Copyright (C) 2009-2020 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.platform.db.migration.version.v86; | |||||
import java.sql.SQLException; | |||||
import org.junit.Rule; | |||||
import org.junit.Test; | |||||
import org.sonar.db.CoreDbTester; | |||||
import org.sonar.server.platform.db.migration.step.MigrationStep; | |||||
public class AddUniqueIndexOnNameColumnOfGroupsTableTest { | |||||
@Rule | |||||
public CoreDbTester db = CoreDbTester.createForSchema(AddUniqueIndexOnNameColumnOfGroupsTableTest.class, "schema.sql"); | |||||
private final MigrationStep underTest = new AddUniqueIndexOnNameColumnOfGroupsTable(db.database()); | |||||
@Test | |||||
public void execute() throws SQLException { | |||||
underTest.execute(); | |||||
db.assertUniqueIndex("groups", "uniq_groups_name", "name"); | |||||
} | |||||
} |
/* | |||||
* SonarQube | |||||
* Copyright (C) 2009-2020 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.platform.db.migration.version.v86; | |||||
import java.sql.SQLException; | |||||
import org.junit.Rule; | |||||
import org.junit.Test; | |||||
import org.sonar.db.CoreDbTester; | |||||
import org.sonar.server.platform.db.migration.step.MigrationStep; | |||||
public class DropOrganizationInGroupsTest { | |||||
@Rule | |||||
public CoreDbTester dbTester = CoreDbTester.createForSchema(DropOrganizationInGroupsTest.class, "schema.sql"); | |||||
private final MigrationStep underTest = new DropOrganizationInGroups(dbTester.database()); | |||||
@Test | |||||
public void column_has_been_dropped() throws SQLException { | |||||
underTest.execute(); | |||||
dbTester.assertColumnDoesNotExist("groups", "organization_uuid"); | |||||
} | |||||
} |
/* | |||||
* SonarQube | |||||
* Copyright (C) 2009-2020 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.platform.db.migration.version.v86; | |||||
import java.sql.SQLException; | |||||
import org.junit.Rule; | |||||
import org.junit.Test; | |||||
import org.sonar.db.CoreDbTester; | |||||
import org.sonar.server.platform.db.migration.step.MigrationStep; | |||||
import static java.sql.Types.VARCHAR; | |||||
public class MakeNameColumnInGroupsTableNotNullableTest { | |||||
@Rule | |||||
public CoreDbTester db = CoreDbTester.createForSchema(MakeNameColumnInGroupsTableNotNullableTest.class, "schema.sql"); | |||||
private final MigrationStep underTest = new MakeNameColumnInGroupsTableNotNullable(db.database()); | |||||
@Test | |||||
public void uuid_column_is_not_null() throws SQLException { | |||||
underTest.execute(); | |||||
db.assertColumnDefinition("groups", "name", VARCHAR, 500, false); | |||||
} | |||||
} |
CREATE TABLE "GROUPS"( | |||||
"NAME" VARCHAR(500) NOT NULL, | |||||
"DESCRIPTION" VARCHAR(200), | |||||
"CREATED_AT" TIMESTAMP, | |||||
"UPDATED_AT" TIMESTAMP, | |||||
"UUID" VARCHAR(40) NOT NULL | |||||
); | |||||
ALTER TABLE "GROUPS" ADD CONSTRAINT "PK_GROUPS" PRIMARY KEY("UUID"); |
CREATE TABLE "GROUPS"( | |||||
"ORGANIZATION_UUID" VARCHAR(40) NOT NULL, | |||||
"NAME" VARCHAR(500), | |||||
"DESCRIPTION" VARCHAR(200), | |||||
"CREATED_AT" TIMESTAMP, | |||||
"UPDATED_AT" TIMESTAMP, | |||||
"UUID" VARCHAR(40) NOT NULL | |||||
); | |||||
ALTER TABLE "GROUPS" ADD CONSTRAINT "PK_GROUPS" PRIMARY KEY("UUID"); |
CREATE TABLE "GROUPS"( | |||||
"NAME" VARCHAR(500), | |||||
"DESCRIPTION" VARCHAR(200), | |||||
"CREATED_AT" TIMESTAMP, | |||||
"UPDATED_AT" TIMESTAMP, | |||||
"UUID" VARCHAR(40) NOT NULL | |||||
); | |||||
ALTER TABLE "GROUPS" ADD CONSTRAINT "PK_GROUPS" PRIMARY KEY("UUID"); |
import org.sonar.db.DbTester; | import org.sonar.db.DbTester; | ||||
import org.sonar.db.organization.OrganizationDto; | import org.sonar.db.organization.OrganizationDto; | ||||
//TODO fix this | |||||
public class TestDefaultOrganizationProvider implements DefaultOrganizationProvider { | public class TestDefaultOrganizationProvider implements DefaultOrganizationProvider { | ||||
private final DefaultOrganizationProvider delegate; | private final DefaultOrganizationProvider delegate; |
*/ | */ | ||||
package org.sonar.server.usergroups; | package org.sonar.server.usergroups; | ||||
import org.sonar.api.security.DefaultGroups; | |||||
import org.sonar.db.DbClient; | import org.sonar.db.DbClient; | ||||
import org.sonar.db.DbSession; | import org.sonar.db.DbSession; | ||||
import org.sonar.db.user.GroupDto; | import org.sonar.db.user.GroupDto; | ||||
import org.sonar.server.organization.DefaultOrganizationProvider; | |||||
import static java.lang.String.format; | |||||
import static java.util.Objects.requireNonNull; | |||||
public class DefaultGroupFinder { | public class DefaultGroupFinder { | ||||
private final DbClient dbClient; | private final DbClient dbClient; | ||||
private final DefaultOrganizationProvider defaultOrganizationProvider; | |||||
public DefaultGroupFinder(DbClient dbClient, DefaultOrganizationProvider defaultOrganizationProvider) { | |||||
public DefaultGroupFinder(DbClient dbClient) { | |||||
this.dbClient = dbClient; | this.dbClient = dbClient; | ||||
this.defaultOrganizationProvider = defaultOrganizationProvider; | |||||
} | } | ||||
public GroupDto findDefaultGroup(DbSession dbSession) { | public GroupDto findDefaultGroup(DbSession dbSession) { | ||||
String defaultGroupUuid = dbClient.organizationDao().getDefaultGroupUuid(dbSession, defaultOrganizationProvider.get().getUuid()) | |||||
.orElseThrow(() -> new IllegalStateException("Default group cannot be found ")); | |||||
return requireNonNull(dbClient.groupDao().selectByUuid(dbSession, defaultGroupUuid), format("Group '%s' cannot be found", defaultGroupUuid)); | |||||
return dbClient.groupDao().selectByName(dbSession, DefaultGroups.USERS) | |||||
.orElseThrow(() -> new IllegalStateException("Default group cannot be found")); | |||||
} | } | ||||
} | } |
private CredentialsLocalAuthentication localAuthentication = new CredentialsLocalAuthentication(db.getDbClient()); | private CredentialsLocalAuthentication localAuthentication = new CredentialsLocalAuthentication(db.getDbClient()); | ||||
private UserIndexer userIndexer = new UserIndexer(db.getDbClient(), es.client()); | private UserIndexer userIndexer = new UserIndexer(db.getDbClient(), es.client()); | ||||
private UserRegistrarImpl userIdentityAuthenticator = new UserRegistrarImpl( | |||||
private final DefaultGroupFinder defaultGroupFinder = new DefaultGroupFinder(db.getDbClient()); | |||||
private final UserRegistrarImpl userIdentityAuthenticator = new UserRegistrarImpl( | |||||
db.getDbClient(), | db.getDbClient(), | ||||
new UserUpdater(mock(NewUserNotifier.class), db.getDbClient(), userIndexer, defaultOrganizationProvider, new DefaultGroupFinder(db.getDbClient(), defaultOrganizationProvider), | |||||
settings.asConfig(), | |||||
new UserUpdater(mock(NewUserNotifier.class), db.getDbClient(), userIndexer, defaultOrganizationProvider, defaultGroupFinder, settings.asConfig(), | |||||
localAuthentication), | localAuthentication), | ||||
new DefaultGroupFinder(db.getDbClient(), defaultOrganizationProvider)); | |||||
defaultGroupFinder); | |||||
private HttpServletResponse response = mock(HttpServletResponse.class); | private HttpServletResponse response = mock(HttpServletResponse.class); | ||||
private JwtHttpHandler jwtHttpHandler = mock(JwtHttpHandler.class); | private JwtHttpHandler jwtHttpHandler = mock(JwtHttpHandler.class); | ||||
when(system2.now()).thenReturn(NOW); | when(system2.now()).thenReturn(NOW); | ||||
group1 = db.users().insertGroup(GROUP1); | group1 = db.users().insertGroup(GROUP1); | ||||
group2 = db.users().insertGroup(GROUP2); | group2 = db.users().insertGroup(GROUP2); | ||||
sonarUsers = db.users().insertDefaultGroup("sonar-users"); | |||||
sonarUsers = db.users().insertDefaultGroup(); | |||||
} | } | ||||
@Test | @Test |
private UserIndexer userIndexer = new UserIndexer(db.getDbClient(), es.client()); | private UserIndexer userIndexer = new UserIndexer(db.getDbClient(), es.client()); | ||||
private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db); | private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db); | ||||
private CredentialsLocalAuthentication localAuthentication = new CredentialsLocalAuthentication(db.getDbClient()); | private CredentialsLocalAuthentication localAuthentication = new CredentialsLocalAuthentication(db.getDbClient()); | ||||
private DefaultGroupFinder groupFinder = new DefaultGroupFinder(db.getDbClient(), defaultOrganizationProvider); | |||||
private final DefaultGroupFinder groupFinder = new DefaultGroupFinder(db.getDbClient()); | |||||
private UserUpdater userUpdater = new UserUpdater( | private UserUpdater userUpdater = new UserUpdater( | ||||
mock(NewUserNotifier.class), | mock(NewUserNotifier.class), | ||||
db.getDbClient(), | db.getDbClient(), | ||||
} | } | ||||
private GroupDto insertDefaultGroup() { | private GroupDto insertDefaultGroup() { | ||||
return db.users().insertDefaultGroup("sonar-users"); | |||||
return db.users().insertDefaultGroup(); | |||||
} | } | ||||
} | } |
private CredentialsLocalAuthentication localAuthentication = new CredentialsLocalAuthentication(db.getDbClient()); | private CredentialsLocalAuthentication localAuthentication = new CredentialsLocalAuthentication(db.getDbClient()); | ||||
private UserUpdater underTest = new UserUpdater(newUserNotifier, dbClient, userIndexer, defaultOrganizationProvider, | private UserUpdater underTest = new UserUpdater(newUserNotifier, dbClient, userIndexer, defaultOrganizationProvider, | ||||
new DefaultGroupFinder(dbClient, defaultOrganizationProvider), settings.asConfig(), localAuthentication); | |||||
new DefaultGroupFinder(dbClient), settings.asConfig(), localAuthentication); | |||||
@Test | @Test | ||||
public void create_user() { | public void create_user() { | ||||
.setName("Marius") | .setName("Marius") | ||||
.setEmail("marius@mail.com") | .setEmail("marius@mail.com") | ||||
.setPassword("password") | .setPassword("password") | ||||
.setScmAccounts(asList("jo")) | |||||
.setScmAccounts(singletonList("jo")) | |||||
.build(), u -> { | .build(), u -> { | ||||
}); | }); | ||||
} | } | ||||
.setName("Marius2") | .setName("Marius2") | ||||
.setEmail("marius2@mail.com") | .setEmail("marius2@mail.com") | ||||
.setPassword("password2") | .setPassword("password2") | ||||
.setScmAccounts(asList(DEFAULT_LOGIN)) | |||||
.setScmAccounts(singletonList(DEFAULT_LOGIN)) | |||||
.build(), u -> { | .build(), u -> { | ||||
}); | }); | ||||
} | } | ||||
.setName("Marius2") | .setName("Marius2") | ||||
.setEmail("marius2@mail.com") | .setEmail("marius2@mail.com") | ||||
.setPassword("password2") | .setPassword("password2") | ||||
.setScmAccounts(asList("marius2@mail.com")) | |||||
.setScmAccounts(singletonList("marius2@mail.com")) | |||||
.build(), u -> { | .build(), u -> { | ||||
}); | }); | ||||
} | } | ||||
} | } | ||||
@Test | @Test | ||||
public void associate_default_group_when_creating_user_and_organizations_are_disabled() { | |||||
public void associate_default_group_when_creating_user() { | |||||
GroupDto defaultGroup = createDefaultGroup(); | GroupDto defaultGroup = createDefaultGroup(); | ||||
underTest.createAndCommit(db.getSession(), NewUser.builder() | underTest.createAndCommit(db.getSession(), NewUser.builder() | ||||
.build(), u -> { | .build(), u -> { | ||||
}); | }); | ||||
Multimap<String, String> groups = dbClient.groupMembershipDao().selectGroupsByLogins(session, asList("user")); | |||||
Multimap<String, String> groups = dbClient.groupMembershipDao().selectGroupsByLogins(session, singletonList("user")); | |||||
assertThat(groups.get("user")).containsOnly(defaultGroup.getName()); | assertThat(groups.get("user")).containsOnly(defaultGroup.getName()); | ||||
} | } | ||||
public class UserUpdaterReactivateTest { | public class UserUpdaterReactivateTest { | ||||
private System2 system2 = new AlwaysIncreasingSystem2(); | |||||
private final System2 system2 = new AlwaysIncreasingSystem2(); | |||||
@Rule | @Rule | ||||
public ExpectedException expectedException = ExpectedException.none(); | public ExpectedException expectedException = ExpectedException.none(); | ||||
@Rule | @Rule | ||||
public DbTester db = DbTester.create(system2); | public DbTester db = DbTester.create(system2); | ||||
private DbClient dbClient = db.getDbClient(); | |||||
private NewUserNotifier newUserNotifier = mock(NewUserNotifier.class); | |||||
private DbSession session = db.getSession(); | |||||
private UserIndexer userIndexer = new UserIndexer(dbClient, es.client()); | |||||
private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db); | |||||
private MapSettings settings = new MapSettings(); | |||||
private CredentialsLocalAuthentication localAuthentication = new CredentialsLocalAuthentication(db.getDbClient()); | |||||
private UserUpdater underTest = new UserUpdater(newUserNotifier, dbClient, userIndexer, defaultOrganizationProvider, | |||||
new DefaultGroupFinder(dbClient, defaultOrganizationProvider), | |||||
private final DbClient dbClient = db.getDbClient(); | |||||
private final NewUserNotifier newUserNotifier = mock(NewUserNotifier.class); | |||||
private final DbSession session = db.getSession(); | |||||
private final UserIndexer userIndexer = new UserIndexer(dbClient, es.client()); | |||||
private final DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db); | |||||
private final MapSettings settings = new MapSettings(); | |||||
private final CredentialsLocalAuthentication localAuthentication = new CredentialsLocalAuthentication(db.getDbClient()); | |||||
private final UserUpdater underTest = new UserUpdater(newUserNotifier, dbClient, userIndexer, defaultOrganizationProvider, | |||||
new DefaultGroupFinder(dbClient), | |||||
settings.asConfig(), localAuthentication); | settings.asConfig(), localAuthentication); | ||||
@Test | @Test |
private MapSettings settings = new MapSettings(); | private MapSettings settings = new MapSettings(); | ||||
private CredentialsLocalAuthentication localAuthentication = new CredentialsLocalAuthentication(db.getDbClient()); | private CredentialsLocalAuthentication localAuthentication = new CredentialsLocalAuthentication(db.getDbClient()); | ||||
private UserUpdater underTest = new UserUpdater(newUserNotifier, dbClient, userIndexer, defaultOrganizationProvider, | private UserUpdater underTest = new UserUpdater(newUserNotifier, dbClient, userIndexer, defaultOrganizationProvider, | ||||
new DefaultGroupFinder(dbClient, defaultOrganizationProvider), settings.asConfig(), localAuthentication); | |||||
new DefaultGroupFinder(dbClient), settings.asConfig(), localAuthentication); | |||||
@Test | @Test | ||||
public void update_user() { | public void update_user() { |
import org.junit.Rule; | import org.junit.Rule; | ||||
import org.junit.Test; | import org.junit.Test; | ||||
import org.junit.rules.ExpectedException; | |||||
import org.sonar.db.DbSession; | |||||
import org.sonar.db.DbTester; | import org.sonar.db.DbTester; | ||||
import org.sonar.db.user.GroupDto; | import org.sonar.db.user.GroupDto; | ||||
import org.sonar.server.organization.TestDefaultOrganizationProvider; | |||||
import static java.lang.String.format; | |||||
import static org.assertj.core.api.Assertions.assertThat; | import static org.assertj.core.api.Assertions.assertThat; | ||||
import static org.assertj.core.api.Assertions.assertThatThrownBy; | |||||
public class DefaultGroupFinderTest { | public class DefaultGroupFinderTest { | ||||
@Rule | |||||
public ExpectedException expectedException = ExpectedException.none(); | |||||
@Rule | @Rule | ||||
public DbTester db = DbTester.create(); | public DbTester db = DbTester.create(); | ||||
private DefaultGroupFinder underTest = new DefaultGroupFinder(db.getDbClient(), TestDefaultOrganizationProvider.from(db)); | |||||
private final DefaultGroupFinder underTest = new DefaultGroupFinder(db.getDbClient()); | |||||
@Test | @Test | ||||
public void find_default_group() { | public void find_default_group() { | ||||
GroupDto defaultGroup = db.users().insertDefaultGroup("default"); | |||||
GroupDto defaultGroup = db.users().insertDefaultGroup(); | |||||
GroupDto result = underTest.findDefaultGroup(db.getSession()); | GroupDto result = underTest.findDefaultGroup(db.getSession()); | ||||
assertThat(result.getUuid()).isEqualTo(defaultGroup.getUuid()); | assertThat(result.getUuid()).isEqualTo(defaultGroup.getUuid()); | ||||
assertThat(result.getName()).isEqualTo("default"); | |||||
assertThat(result.getName()).isEqualTo("sonar-users"); | |||||
} | } | ||||
@Test | @Test | ||||
public void fail_with_ISE_when_no_default_group() { | public void fail_with_ISE_when_no_default_group() { | ||||
db.users().insertGroup(); | db.users().insertGroup(); | ||||
DbSession session = db.getSession(); | |||||
expectedException.expect(IllegalStateException.class); | |||||
expectedException.expectMessage(format("Default group cannot be found")); | |||||
underTest.findDefaultGroup(db.getSession()); | |||||
assertThatThrownBy(() -> underTest.findDefaultGroup(session)) | |||||
.isInstanceOf(IllegalStateException.class) | |||||
.hasMessage("Default group cannot be found"); | |||||
} | } | ||||
@Test | @Test | ||||
public void fail_with_NPE_when_default_group_does_not_exist() { | |||||
GroupDto defaultGroup = db.users().insertDefaultGroup("default"); | |||||
public void fail_with_ISE_when_default_group_does_not_exist() { | |||||
GroupDto defaultGroup = db.users().insertDefaultGroup(); | |||||
db.getDbClient().groupDao().deleteByUuid(db.getSession(), defaultGroup.getUuid()); | db.getDbClient().groupDao().deleteByUuid(db.getSession(), defaultGroup.getUuid()); | ||||
DbSession session = db.getSession(); | |||||
expectedException.expect(NullPointerException.class); | |||||
expectedException.expectMessage(format("Group '%s' cannot be found", defaultGroup.getUuid())); | |||||
underTest.findDefaultGroup(db.getSession()); | |||||
assertThatThrownBy(() -> underTest.findDefaultGroup(session)) | |||||
.isInstanceOf(IllegalStateException.class) | |||||
.hasMessage("Default group cannot be found"); | |||||
} | } | ||||
} | } |
public GroupUuidOrAnyone findGroup(DbSession dbSession, Request request) { | public GroupUuidOrAnyone findGroup(DbSession dbSession, Request request) { | ||||
String groupUuid = request.param(PARAM_GROUP_ID); | String groupUuid = request.param(PARAM_GROUP_ID); | ||||
String groupName = request.param(PARAM_GROUP_NAME); | String groupName = request.param(PARAM_GROUP_NAME); | ||||
GroupWsRef groupRef = GroupWsRef.create(groupUuid, null, groupName); | |||||
GroupWsRef groupRef = GroupWsRef.create(groupUuid, groupName); | |||||
return groupWsSupport.findGroupOrAnyone(dbSession, groupRef); | return groupWsSupport.findGroupOrAnyone(dbSession, groupRef); | ||||
} | } | ||||
import static org.sonar.server.usergroups.ws.GroupWsSupport.DESCRIPTION_MAX_LENGTH; | import static org.sonar.server.usergroups.ws.GroupWsSupport.DESCRIPTION_MAX_LENGTH; | ||||
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_GROUP_DESCRIPTION; | import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_GROUP_DESCRIPTION; | ||||
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_GROUP_NAME; | import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_GROUP_NAME; | ||||
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_ORGANIZATION_KEY; | |||||
import static org.sonar.server.usergroups.ws.GroupWsSupport.toProtobuf; | import static org.sonar.server.usergroups.ws.GroupWsSupport.toProtobuf; | ||||
import static org.sonar.server.ws.WsUtils.writeProtobuf; | import static org.sonar.server.ws.WsUtils.writeProtobuf; | ||||
.setChangelog( | .setChangelog( | ||||
new Change("8.4", "Field 'id' format in the response changes from integer to string.")); | new Change("8.4", "Field 'id' format in the response changes from integer to string.")); | ||||
action.createParam(PARAM_ORGANIZATION_KEY) | |||||
.setDescription("Key of organization. If unset then default organization is used.") | |||||
.setExampleValue("my-org") | |||||
.setSince("6.2") | |||||
.setInternal(true); | |||||
action.createParam(PARAM_GROUP_NAME) | action.createParam(PARAM_GROUP_NAME) | ||||
.setRequired(true) | .setRequired(true) | ||||
.setMaximumLength(GROUP_NAME_MAX_LENGTH) | .setMaximumLength(GROUP_NAME_MAX_LENGTH) | ||||
private void writeResponse(Request request, Response response, GroupDto group) { | private void writeResponse(Request request, Response response, GroupDto group) { | ||||
UserGroups.CreateWsResponse.Builder respBuilder = UserGroups.CreateWsResponse.newBuilder(); | UserGroups.CreateWsResponse.Builder respBuilder = UserGroups.CreateWsResponse.newBuilder(); | ||||
// 'default' is always false as it's not possible to create a default group | // 'default' is always false as it's not possible to create a default group | ||||
// TODO | |||||
respBuilder.setGroup(toProtobuf("org", group, 0, false)); | |||||
respBuilder.setGroup(toProtobuf(group, 0, false)); | |||||
writeProtobuf(respBuilder.build(), request, response); | writeProtobuf(respBuilder.build(), request, response); | ||||
} | } | ||||
} | } |
package org.sonar.server.usergroups.ws; | package org.sonar.server.usergroups.ws; | ||||
import java.util.Objects; | import java.util.Objects; | ||||
import javax.annotation.CheckForNull; | |||||
import javax.annotation.Nullable; | import javax.annotation.Nullable; | ||||
import javax.annotation.concurrent.Immutable; | import javax.annotation.concurrent.Immutable; | ||||
import org.sonar.api.security.DefaultGroups; | import org.sonar.api.security.DefaultGroups; | ||||
* of these two options: | * of these two options: | ||||
* <ul> | * <ul> | ||||
* <li>group uuid, for instance 1234</li> | * <li>group uuid, for instance 1234</li> | ||||
* <li>group name and optional organization key</li> | |||||
* <li>group name</li> | |||||
* </ul> | * </ul> | ||||
* | * | ||||
* The reference is then converted to a {@link GroupUuid} or {@link GroupUuidOrAnyone}. | * The reference is then converted to a {@link GroupUuid} or {@link GroupUuidOrAnyone}. | ||||
public class GroupWsRef { | public class GroupWsRef { | ||||
private final String uuid; | private final String uuid; | ||||
private final String organizationKey; | |||||
private final String name; | private final String name; | ||||
private GroupWsRef(String uuid, @Nullable String organizationKey, @Nullable String name) { | |||||
private GroupWsRef(@Nullable String uuid, @Nullable String name) { | |||||
this.uuid = uuid; | this.uuid = uuid; | ||||
this.organizationKey = organizationKey; | |||||
this.name = name; | this.name = name; | ||||
} | } | ||||
/** | /** | ||||
* @return {@code true} if uuid is defined and {@link #getUuid()} can be called. If {@code false}, then | * @return {@code true} if uuid is defined and {@link #getUuid()} can be called. If {@code false}, then | ||||
* the couple {organizationKey, name} is defined and the methods {@link #getOrganizationKey()}/{@link #getName()} | |||||
* can be called. | |||||
* the name is defined and the method {@link #getName()} can be called. | |||||
*/ | */ | ||||
public boolean hasUuid() { | public boolean hasUuid() { | ||||
return uuid != null; | return uuid != null; | ||||
/** | /** | ||||
* @return the group uuid | * @return the group uuid | ||||
* @throws IllegalStateException if {@link #getUuid()} is {@code false} | |||||
* @throws IllegalStateException if {@link #hasUuid()} is {@code false} | |||||
*/ | */ | ||||
public String getUuid() { | public String getUuid() { | ||||
checkState(hasUuid(), "Id is not present. Please see hasUuid()."); | checkState(hasUuid(), "Id is not present. Please see hasUuid()."); | ||||
return uuid; | return uuid; | ||||
} | } | ||||
/** | |||||
* @return the organization key | |||||
* @throws IllegalStateException if {@link #getUuid()} is {@code true} | |||||
*/ | |||||
@CheckForNull | |||||
public String getOrganizationKey() { | |||||
checkState(!hasUuid(), "Organization is not present. Please see hasId()."); | |||||
return organizationKey; | |||||
} | |||||
/** | /** | ||||
* @return the non-null group name. Can be anyone. | * @return the non-null group name. Can be anyone. | ||||
* @throws IllegalStateException if {@link #getUuid()} is {@code true} | * @throws IllegalStateException if {@link #getUuid()} is {@code true} | ||||
* as they can't be referenced by an uuid. | * as they can't be referenced by an uuid. | ||||
*/ | */ | ||||
static GroupWsRef fromUuid(String uuid) { | static GroupWsRef fromUuid(String uuid) { | ||||
return new GroupWsRef(uuid, null, null); | |||||
return new GroupWsRef(uuid, null); | |||||
} | } | ||||
/** | /** | ||||
* Creates a reference to a group by its organization and name. Virtual groups "Anyone" are | |||||
* Creates a reference to a group by its name. Virtual groups "Anyone" are | |||||
* supported. | * supported. | ||||
* | * | ||||
* @param organizationKey key of organization. If {@code null}, then default organization will be used. | |||||
* @param name non-null name. Can refer to anyone group (case-insensitive {@code "anyone"}). | * @param name non-null name. Can refer to anyone group (case-insensitive {@code "anyone"}). | ||||
*/ | */ | ||||
static GroupWsRef fromName(@Nullable String organizationKey, String name) { | |||||
return new GroupWsRef(null, organizationKey, requireNonNull(name)); | |||||
static GroupWsRef fromName(String name) { | |||||
return new GroupWsRef(null, requireNonNull(name)); | |||||
} | } | ||||
public static GroupWsRef create(@Nullable String uuid, @Nullable String organizationKey, @Nullable String name) { | |||||
public static GroupWsRef create(@Nullable String uuid, @Nullable String name) { | |||||
if (uuid != null) { | if (uuid != null) { | ||||
checkRequest(organizationKey == null && name == null, "Either group id or couple organization/group name must be set"); | |||||
checkRequest(name == null, "Either group id or group name must be set"); | |||||
return fromUuid(uuid); | return fromUuid(uuid); | ||||
} | } | ||||
checkRequest(name != null, "Group name or group id must be provided"); | checkRequest(name != null, "Group name or group id must be provided"); | ||||
return fromName(organizationKey, name); | |||||
return fromName(name); | |||||
} | } | ||||
public boolean isAnyone() { | public boolean isAnyone() { | ||||
return false; | return false; | ||||
} | } | ||||
GroupWsRef that = (GroupWsRef) o; | GroupWsRef that = (GroupWsRef) o; | ||||
return Objects.equals(uuid, that.uuid) && Objects.equals(organizationKey, that.organizationKey) && Objects.equals(name, that.name); | |||||
return Objects.equals(uuid, that.uuid) && Objects.equals(name, that.name); | |||||
} | } | ||||
@Override | @Override | ||||
public int hashCode() { | public int hashCode() { | ||||
return Objects.hash(uuid, organizationKey, name); | |||||
return Objects.hash(uuid, name); | |||||
} | } | ||||
@Override | @Override | ||||
public String toString() { | public String toString() { | ||||
StringBuilder sb = new StringBuilder("GroupWsRef{"); | |||||
sb.append("uuid=").append(uuid); | |||||
sb.append(", organizationKey='").append(organizationKey).append('\''); | |||||
sb.append(", name='").append(name).append('\''); | |||||
sb.append('}'); | |||||
return sb.toString(); | |||||
return "GroupWsRef{uuid=" + uuid + ", name='" + name + "'}"; | |||||
} | } | ||||
} | } |
public class GroupWsSupport { | public class GroupWsSupport { | ||||
static final String PARAM_GROUP_ID = "id"; | static final String PARAM_GROUP_ID = "id"; | ||||
static final String PARAM_ORGANIZATION_KEY = "organization"; | |||||
static final String PARAM_GROUP_NAME = "name"; | static final String PARAM_GROUP_NAME = "name"; | ||||
static final String PARAM_GROUP_DESCRIPTION = "description"; | static final String PARAM_GROUP_DESCRIPTION = "description"; | ||||
static final String PARAM_LOGIN = "login"; | static final String PARAM_LOGIN = "login"; | ||||
} | } | ||||
/** | /** | ||||
* Find a group by its id (parameter {@link #PARAM_GROUP_ID}) or couple organization key/group name | |||||
* (parameters {@link #PARAM_ORGANIZATION_KEY} and {@link #PARAM_GROUP_NAME}). The virtual | |||||
* Find a group by its id (parameter {@link #PARAM_GROUP_ID}) or group name (parameter {@link #PARAM_GROUP_NAME}). The virtual | |||||
* group "Anyone" is not supported. | * group "Anyone" is not supported. | ||||
* | * | ||||
* @throws NotFoundException if parameters are missing/incorrect, if the requested group does not exist | * @throws NotFoundException if parameters are missing/incorrect, if the requested group does not exist | ||||
public GroupDto findGroupDto(DbSession dbSession, Request request) { | public GroupDto findGroupDto(DbSession dbSession, Request request) { | ||||
String uuid = request.param(PARAM_GROUP_ID); | String uuid = request.param(PARAM_GROUP_ID); | ||||
String organizationKey = request.param(PARAM_ORGANIZATION_KEY); | |||||
String name = request.param(PARAM_GROUP_NAME); | String name = request.param(PARAM_GROUP_NAME); | ||||
return findGroupDto(dbSession, GroupWsRef.create(uuid, organizationKey, name)); | |||||
return findGroupDto(dbSession, GroupWsRef.create(uuid, name)); | |||||
} | } | ||||
public GroupDto findGroupDto(DbSession dbSession, GroupWsRef ref) { | public GroupDto findGroupDto(DbSession dbSession, GroupWsRef ref) { | ||||
checkArgument(!defaultGroup.getUuid().equals(groupDto.getUuid()), "Default group '%s' cannot be used to perform this action", groupDto.getName()); | checkArgument(!defaultGroup.getUuid().equals(groupDto.getUuid()), "Default group '%s' cannot be used to perform this action", groupDto.getName()); | ||||
} | } | ||||
static UserGroups.Group.Builder toProtobuf(String org, GroupDto group, int membersCount, boolean isDefault) { | |||||
static UserGroups.Group.Builder toProtobuf(GroupDto group, int membersCount, boolean isDefault) { | |||||
UserGroups.Group.Builder wsGroup = UserGroups.Group.newBuilder() | UserGroups.Group.Builder wsGroup = UserGroups.Group.newBuilder() | ||||
.setId(group.getUuid()) | .setId(group.getUuid()) | ||||
.setOrganization(org) | |||||
.setName(group.getName()) | .setName(group.getName()) | ||||
.setMembersCount(membersCount) | .setMembersCount(membersCount) | ||||
.setDefault(isDefault); | .setDefault(isDefault); | ||||
} | } | ||||
private static void defineGroupNameWsParameter(WebService.NewAction action) { | private static void defineGroupNameWsParameter(WebService.NewAction action) { | ||||
action.createParam(PARAM_ORGANIZATION_KEY) | |||||
.setDescription("Key of organization") | |||||
.setExampleValue("my-org") | |||||
.setInternal(true) | |||||
.setSince("6.2"); | |||||
action.createParam(PARAM_GROUP_NAME) | action.createParam(PARAM_GROUP_NAME) | ||||
.setDescription("Group name") | .setDescription("Group name") | ||||
.setExampleValue("sonar-administrators"); | .setExampleValue("sonar-administrators"); |
import org.sonar.api.server.ws.Change; | import org.sonar.api.server.ws.Change; | ||||
import org.sonar.api.server.ws.Request; | import org.sonar.api.server.ws.Request; | ||||
import org.sonar.api.server.ws.Response; | import org.sonar.api.server.ws.Response; | ||||
import org.sonar.api.server.ws.WebService; | |||||
import org.sonar.api.server.ws.WebService.NewController; | import org.sonar.api.server.ws.WebService.NewController; | ||||
import org.sonar.api.server.ws.WebService.Param; | import org.sonar.api.server.ws.WebService.Param; | ||||
import org.sonar.api.utils.Paging; | import org.sonar.api.utils.Paging; | ||||
import static org.sonar.api.utils.Paging.forPageIndex; | import static org.sonar.api.utils.Paging.forPageIndex; | ||||
import static org.sonar.db.permission.OrganizationPermission.ADMINISTER; | import static org.sonar.db.permission.OrganizationPermission.ADMINISTER; | ||||
import static org.sonar.server.es.SearchOptions.MAX_PAGE_SIZE; | import static org.sonar.server.es.SearchOptions.MAX_PAGE_SIZE; | ||||
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_ORGANIZATION_KEY; | |||||
import static org.sonar.server.ws.WsUtils.writeProtobuf; | import static org.sonar.server.ws.WsUtils.writeProtobuf; | ||||
import static org.sonarqube.ws.UserGroups.Group; | import static org.sonarqube.ws.UserGroups.Group; | ||||
import static org.sonarqube.ws.UserGroups.SearchWsResponse; | import static org.sonarqube.ws.UserGroups.SearchWsResponse; | ||||
@Override | @Override | ||||
public void define(NewController context) { | public void define(NewController context) { | ||||
WebService.NewAction action = context.createAction("search") | |||||
context.createAction("search") | |||||
.setDescription("Search for user groups.<br>" + | .setDescription("Search for user groups.<br>" + | ||||
"Requires the following permission: 'Administer System'.") | "Requires the following permission: 'Administer System'.") | ||||
.setHandler(this) | .setHandler(this) | ||||
new Change("8.4", "Field 'id' in the response is deprecated. Format changes from integer to string."), | new Change("8.4", "Field 'id' in the response is deprecated. Format changes from integer to string."), | ||||
new Change("6.4", "Paging response fields moved to a Paging object"), | new Change("6.4", "Paging response fields moved to a Paging object"), | ||||
new Change("6.4", "'default' response field has been added")); | new Change("6.4", "'default' response field has been added")); | ||||
action.createParam(PARAM_ORGANIZATION_KEY) | |||||
.setDescription("Key of organization. If not set then groups are searched in default organization.") | |||||
.setExampleValue("my-org") | |||||
.setSince("6.2") | |||||
.setInternal(true); | |||||
} | } | ||||
@Override | @Override |
import org.sonar.db.DbSession; | import org.sonar.db.DbSession; | ||||
import org.sonar.db.user.GroupDto; | import org.sonar.db.user.GroupDto; | ||||
import org.sonar.db.user.UserMembershipQuery; | import org.sonar.db.user.UserMembershipQuery; | ||||
import org.sonar.server.organization.DefaultOrganizationProvider; | |||||
import org.sonar.server.user.UserSession; | import org.sonar.server.user.UserSession; | ||||
import org.sonarqube.ws.UserGroups; | import org.sonarqube.ws.UserGroups; | ||||
private final DbClient dbClient; | private final DbClient dbClient; | ||||
private final UserSession userSession; | private final UserSession userSession; | ||||
private final GroupWsSupport support; | private final GroupWsSupport support; | ||||
private final DefaultOrganizationProvider defaultOrganizationProvider; | |||||
public UpdateAction(DbClient dbClient, UserSession userSession, GroupWsSupport support, DefaultOrganizationProvider defaultOrganizationProvider) { | |||||
public UpdateAction(DbClient dbClient, UserSession userSession, GroupWsSupport support) { | |||||
this.dbClient = dbClient; | this.dbClient = dbClient; | ||||
this.userSession = userSession; | this.userSession = userSession; | ||||
this.support = support; | this.support = support; | ||||
this.defaultOrganizationProvider = defaultOrganizationProvider; | |||||
} | } | ||||
@Override | @Override | ||||
UserGroups.UpdateWsResponse.Builder respBuilder = UserGroups.UpdateWsResponse.newBuilder(); | UserGroups.UpdateWsResponse.Builder respBuilder = UserGroups.UpdateWsResponse.newBuilder(); | ||||
// 'default' is always false as it's not possible to update a default group | // 'default' is always false as it's not possible to update a default group | ||||
respBuilder.setGroup(toProtobuf(defaultOrganizationProvider.get().getKey(), group, membersCount, false)); | |||||
respBuilder.setGroup(toProtobuf(group, membersCount, false)); | |||||
writeProtobuf(respBuilder.build(), request, response); | writeProtobuf(respBuilder.build(), request, response); | ||||
} | } | ||||
{ | { | ||||
"id": 2, | "id": 2, | ||||
"name": "sonar-users", | "name": "sonar-users", | ||||
"description": "Sonar Users", | |||||
"description": "Users", | |||||
"selected": true, | "selected": true, | ||||
"default": true | "default": true | ||||
} | } |
"groups": [ | "groups": [ | ||||
{ | { | ||||
"id": "AU-Tpxb--iU5OvuD2FLy", | "id": "AU-Tpxb--iU5OvuD2FLy", | ||||
"name": "users", | |||||
"name": "sonar-users", | |||||
"description": "Users", | "description": "Users", | ||||
"membersCount": 17, | "membersCount": 17, | ||||
"default": true | "default": true |
protected abstract A buildWsAction(); | protected abstract A buildWsAction(); | ||||
protected GroupWsSupport newGroupWsSupport() { | protected GroupWsSupport newGroupWsSupport() { | ||||
return new GroupWsSupport(db.getDbClient(), new DefaultGroupFinder(db.getDbClient(), defaultOrganizationProvider)); | |||||
return new GroupWsSupport(db.getDbClient(), new DefaultGroupFinder(db.getDbClient())); | |||||
} | } | ||||
protected PermissionWsSupport newPermissionWsSupport() { | protected PermissionWsSupport newPermissionWsSupport() { |
@Before | @Before | ||||
public void setUp() { | public void setUp() { | ||||
DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db); | DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db); | ||||
GroupWsSupport groupWsSupport = new GroupWsSupport(dbClient, new DefaultGroupFinder(db.getDbClient(), defaultOrganizationProvider)); | |||||
GroupWsSupport groupWsSupport = new GroupWsSupport(dbClient, new DefaultGroupFinder(db.getDbClient())); | |||||
this.underTestWithoutViews = new WsActionTester(new DeleteTemplateAction(dbClient, userSession, | this.underTestWithoutViews = new WsActionTester(new DeleteTemplateAction(dbClient, userSession, | ||||
new PermissionWsSupport(dbClient, new ComponentFinder(dbClient, resourceTypes), groupWsSupport), defaultTemplatesResolver, defaultOrganizationProvider)); | new PermissionWsSupport(dbClient, new ComponentFinder(dbClient, resourceTypes), groupWsSupport), defaultTemplatesResolver, defaultOrganizationProvider)); | ||||
this.underTestWithViews = new WsActionTester(new DeleteTemplateAction(dbClient, userSession, | this.underTestWithViews = new WsActionTester(new DeleteTemplateAction(dbClient, userSession, |
public class ChangePasswordActionTest { | public class ChangePasswordActionTest { | ||||
private System2 system2 = new AlwaysIncreasingSystem2(); | |||||
@Rule | @Rule | ||||
public ExpectedException expectedException = ExpectedException.none(); | public ExpectedException expectedException = ExpectedException.none(); | ||||
@Rule | @Rule | ||||
private UserUpdater userUpdater = new UserUpdater( | private UserUpdater userUpdater = new UserUpdater( | ||||
mock(NewUserNotifier.class), db.getDbClient(), new UserIndexer(db.getDbClient(), es.client()), testDefaultOrganizationProvider, | mock(NewUserNotifier.class), db.getDbClient(), new UserIndexer(db.getDbClient(), es.client()), testDefaultOrganizationProvider, | ||||
new DefaultGroupFinder(db.getDbClient(), testDefaultOrganizationProvider), | |||||
new DefaultGroupFinder(db.getDbClient()), | |||||
new MapSettings().asConfig(), | new MapSettings().asConfig(), | ||||
localAuthentication); | localAuthentication); | ||||
@Before | @Before | ||||
public void setUp() { | public void setUp() { | ||||
db.users().insertDefaultGroup("sonar-users"); | |||||
db.users().insertDefaultGroup(); | |||||
} | } | ||||
@Test | @Test |
public class CreateActionTest { | public class CreateActionTest { | ||||
private static final String DEFAULT_GROUP_NAME = "sonar-users"; | |||||
private MapSettings settings = new MapSettings(); | private MapSettings settings = new MapSettings(); | ||||
private System2 system2 = new AlwaysIncreasingSystem2(); | private System2 system2 = new AlwaysIncreasingSystem2(); | ||||
private WsActionTester tester = new WsActionTester(new CreateAction( | private WsActionTester tester = new WsActionTester(new CreateAction( | ||||
db.getDbClient(), | db.getDbClient(), | ||||
new UserUpdater(mock(NewUserNotifier.class), db.getDbClient(), userIndexer, defaultOrganizationProvider, | new UserUpdater(mock(NewUserNotifier.class), db.getDbClient(), userIndexer, defaultOrganizationProvider, | ||||
new DefaultGroupFinder(db.getDbClient(), defaultOrganizationProvider), settings.asConfig(), localAuthentication), | |||||
new DefaultGroupFinder(db.getDbClient()), settings.asConfig(), localAuthentication), | |||||
userSessionRule)); | userSessionRule)); | ||||
@Before | @Before | ||||
public void setUp() { | public void setUp() { | ||||
defaultGroup = db.users().insertDefaultGroup(DEFAULT_GROUP_NAME); | |||||
defaultGroup = db.users().insertDefaultGroup(); | |||||
} | } | ||||
@Test | @Test |
import org.sonar.db.user.UserDto; | import org.sonar.db.user.UserDto; | ||||
import org.sonar.server.exceptions.ForbiddenException; | import org.sonar.server.exceptions.ForbiddenException; | ||||
import org.sonar.server.exceptions.NotFoundException; | import org.sonar.server.exceptions.NotFoundException; | ||||
import org.sonar.server.organization.TestDefaultOrganizationProvider; | |||||
import org.sonar.server.tester.UserSessionRule; | import org.sonar.server.tester.UserSessionRule; | ||||
import org.sonar.server.usergroups.DefaultGroupFinder; | import org.sonar.server.usergroups.DefaultGroupFinder; | ||||
import org.sonar.server.ws.TestRequest; | import org.sonar.server.ws.TestRequest; | ||||
public UserSessionRule userSession = UserSessionRule.standalone().logIn().setRoot(); | public UserSessionRule userSession = UserSessionRule.standalone().logIn().setRoot(); | ||||
private WsActionTester ws = new WsActionTester(new GroupsAction(db.getDbClient(), userSession, | private WsActionTester ws = new WsActionTester(new GroupsAction(db.getDbClient(), userSession, | ||||
new DefaultGroupFinder(db.getDbClient(), TestDefaultOrganizationProvider.from(db)))); | |||||
new DefaultGroupFinder(db.getDbClient()))); | |||||
@Test | @Test | ||||
public void empty_groups() { | public void empty_groups() { | ||||
insertUser(); | insertUser(); | ||||
insertDefaultGroup("sonar-users", "Sonar Users"); | |||||
insertDefaultGroup(); | |||||
GroupsWsResponse response = call(ws.newRequest().setParam("login", USER_LOGIN)); | GroupsWsResponse response = call(ws.newRequest().setParam("login", USER_LOGIN)); | ||||
@Test | @Test | ||||
public void return_selected_groups_selected_param_is_set_to_all() { | public void return_selected_groups_selected_param_is_set_to_all() { | ||||
UserDto user = insertUser(); | UserDto user = insertUser(); | ||||
GroupDto usersGroup = insertDefaultGroup("sonar-users", "Sonar Users"); | |||||
GroupDto usersGroup = insertDefaultGroup(); | |||||
GroupDto adminGroup = insertGroup("sonar-admins", "Sonar Admins"); | GroupDto adminGroup = insertGroup("sonar-admins", "Sonar Admins"); | ||||
addUserToGroup(user, usersGroup); | addUserToGroup(user, usersGroup); | ||||
@Test | @Test | ||||
public void return_selected_groups_selected_param_is_set_to_selected() { | public void return_selected_groups_selected_param_is_set_to_selected() { | ||||
UserDto user = insertUser(); | UserDto user = insertUser(); | ||||
GroupDto usersGroup = insertDefaultGroup("sonar-users", "Sonar Users"); | |||||
GroupDto usersGroup = insertDefaultGroup(); | |||||
insertGroup("sonar-admins", "Sonar Admins"); | insertGroup("sonar-admins", "Sonar Admins"); | ||||
addUserToGroup(user, usersGroup); | addUserToGroup(user, usersGroup); | ||||
@Test | @Test | ||||
public void return_selected_groups_selected_param_is_not_set() { | public void return_selected_groups_selected_param_is_not_set() { | ||||
UserDto user = insertUser(); | UserDto user = insertUser(); | ||||
GroupDto usersGroup = insertDefaultGroup("sonar-users", "Sonar Users"); | |||||
GroupDto usersGroup = insertDefaultGroup(); | |||||
insertGroup("sonar-admins", "Sonar Admins"); | insertGroup("sonar-admins", "Sonar Admins"); | ||||
addUserToGroup(user, usersGroup); | addUserToGroup(user, usersGroup); | ||||
@Test | @Test | ||||
public void return_not_selected_groups_selected_param_is_set_to_deselected() { | public void return_not_selected_groups_selected_param_is_set_to_deselected() { | ||||
UserDto user = insertUser(); | UserDto user = insertUser(); | ||||
GroupDto usersGroup = insertDefaultGroup("sonar-users", "Sonar Users"); | |||||
GroupDto usersGroup = insertDefaultGroup(); | |||||
GroupDto adminGroup = insertGroup("sonar-admins", "Sonar Admins"); | GroupDto adminGroup = insertGroup("sonar-admins", "Sonar Admins"); | ||||
addUserToGroup(user, usersGroup); | addUserToGroup(user, usersGroup); | ||||
.containsOnly(tuple(adminGroup.getUuid(), adminGroup.getName(), adminGroup.getDescription(), false)); | .containsOnly(tuple(adminGroup.getUuid(), adminGroup.getName(), adminGroup.getDescription(), false)); | ||||
} | } | ||||
@Test | |||||
public void return_group_not_having_description() { | |||||
UserDto user = insertUser(); | |||||
GroupDto group = insertDefaultGroup("sonar-users", null); | |||||
addUserToGroup(user, group); | |||||
GroupsWsResponse response = call(ws.newRequest().setParam("login", "john").setParam(Param.SELECTED, ALL.value())); | |||||
assertThat(response.getGroupsList()).extracting(GroupsWsResponse.Group::hasDescription).containsOnly(false); | |||||
} | |||||
@Test | @Test | ||||
public void search_with_pagination() { | public void search_with_pagination() { | ||||
UserDto user = insertUser(); | UserDto user = insertUser(); | ||||
insertDefaultGroup("sonar-users", "Sonar Users"); | |||||
insertDefaultGroup(); | |||||
for (int i = 1; i <= 9; i++) { | for (int i = 1; i <= 9; i++) { | ||||
GroupDto groupDto = insertGroup("group-" + i, "group-" + i); | GroupDto groupDto = insertGroup("group-" + i, "group-" + i); | ||||
addUserToGroup(user, groupDto); | addUserToGroup(user, groupDto); | ||||
@Test | @Test | ||||
public void search_by_text_query() { | public void search_by_text_query() { | ||||
UserDto user = insertUser(); | UserDto user = insertUser(); | ||||
GroupDto usersGroup = insertDefaultGroup("sonar-users", "Sonar Users"); | |||||
GroupDto usersGroup = insertDefaultGroup(); | |||||
GroupDto adminGroup = insertGroup("sonar-admins", "Sonar Admins"); | GroupDto adminGroup = insertGroup("sonar-admins", "Sonar Admins"); | ||||
addUserToGroup(user, usersGroup); | addUserToGroup(user, usersGroup); | ||||
@Test | @Test | ||||
public void return_default_group_information() { | public void return_default_group_information() { | ||||
UserDto user = insertUser(); | UserDto user = insertUser(); | ||||
GroupDto usersGroup = insertDefaultGroup("sonar-users", "Sonar Users"); | |||||
GroupDto usersGroup = insertDefaultGroup(); | |||||
GroupDto adminGroup = insertGroup("sonar-admins", "Sonar Admins"); | GroupDto adminGroup = insertGroup("sonar-admins", "Sonar Admins"); | ||||
addUserToGroup(user, usersGroup); | addUserToGroup(user, usersGroup); | ||||
@Test | @Test | ||||
public void return_groups() { | public void return_groups() { | ||||
UserDto user = insertUser(); | UserDto user = insertUser(); | ||||
GroupDto group = db.users().insertDefaultGroup(newGroupDto().setName("group1")); | |||||
GroupDto group = db.users().insertDefaultGroup(); | |||||
addUserToGroup(user, group); | addUserToGroup(user, group); | ||||
GroupsWsResponse response = call(ws.newRequest() | GroupsWsResponse response = call(ws.newRequest() | ||||
@Test | @Test | ||||
public void fail_on_unknown_user() { | public void fail_on_unknown_user() { | ||||
insertDefaultGroup("sonar-users", "Sonar Users"); | |||||
insertDefaultGroup(); | |||||
expectedException.expect(NotFoundException.class); | expectedException.expect(NotFoundException.class); | ||||
expectedException.expectMessage("Unknown user: john"); | expectedException.expectMessage("Unknown user: john"); | ||||
@Test | @Test | ||||
public void fail_on_disabled_user() { | public void fail_on_disabled_user() { | ||||
UserDto userDto = db.users().insertUser(user -> user.setLogin("disabled").setActive(false)); | UserDto userDto = db.users().insertUser(user -> user.setLogin("disabled").setActive(false)); | ||||
insertDefaultGroup("sonar-users", "Sonar Users"); | |||||
insertDefaultGroup(); | |||||
expectedException.expect(NotFoundException.class); | expectedException.expect(NotFoundException.class); | ||||
expectedException.expectMessage("Unknown user: disabled"); | expectedException.expectMessage("Unknown user: disabled"); | ||||
@Test | @Test | ||||
public void fail_when_page_size_is_greater_than_500() { | public void fail_when_page_size_is_greater_than_500() { | ||||
UserDto user = insertUser(); | UserDto user = insertUser(); | ||||
insertDefaultGroup("sonar-users", "Sonar Users"); | |||||
insertDefaultGroup(); | |||||
expectedException.expect(IllegalArgumentException.class); | expectedException.expect(IllegalArgumentException.class); | ||||
expectedException.expectMessage("The 'ps' parameter must be less than 500"); | expectedException.expectMessage("The 'ps' parameter must be less than 500"); | ||||
@Test | @Test | ||||
public void test_json_example() { | public void test_json_example() { | ||||
UserDto user = insertUser(); | UserDto user = insertUser(); | ||||
GroupDto usersGroup = insertDefaultGroup("sonar-users", "Sonar Users"); | |||||
GroupDto usersGroup = insertDefaultGroup(); | |||||
insertGroup("sonar-admins", "Sonar Admins"); | insertGroup("sonar-admins", "Sonar Admins"); | ||||
addUserToGroup(user, usersGroup); | addUserToGroup(user, usersGroup); | ||||
return db.users().insertGroup(newGroupDto().setName(name).setDescription(description)); | return db.users().insertGroup(newGroupDto().setName(name).setDescription(description)); | ||||
} | } | ||||
private GroupDto insertDefaultGroup(String name, String description) { | |||||
return db.users().insertDefaultGroup(newGroupDto().setName(name).setDescription(description)); | |||||
private GroupDto insertDefaultGroup() { | |||||
return db.users().insertDefaultGroup(); | |||||
} | } | ||||
private void addUserToGroup(UserDto user, GroupDto usersGroup) { | private void addUserToGroup(UserDto user, GroupDto usersGroup) { |
private WsActionTester ws = new WsActionTester(new UpdateAction( | private WsActionTester ws = new WsActionTester(new UpdateAction( | ||||
new UserUpdater(mock(NewUserNotifier.class), dbClient, userIndexer, defaultOrganizationProvider, | new UserUpdater(mock(NewUserNotifier.class), dbClient, userIndexer, defaultOrganizationProvider, | ||||
new DefaultGroupFinder(db.getDbClient(), defaultOrganizationProvider), settings.asConfig(), localAuthentication), | |||||
new DefaultGroupFinder(db.getDbClient()), settings.asConfig(), localAuthentication), | |||||
userSession, new UserJsonWriter(userSession), dbClient)); | userSession, new UserJsonWriter(userSession), dbClient)); | ||||
@Before | @Before | ||||
public void setUp() { | public void setUp() { | ||||
db.users().insertDefaultGroup("sonar-users"); | |||||
db.users().insertDefaultGroup(); | |||||
} | } | ||||
@Test | @Test |
import org.sonar.db.user.UserDto; | import org.sonar.db.user.UserDto; | ||||
import org.sonar.server.exceptions.NotFoundException; | import org.sonar.server.exceptions.NotFoundException; | ||||
import org.sonar.server.exceptions.UnauthorizedException; | import org.sonar.server.exceptions.UnauthorizedException; | ||||
import org.sonar.server.organization.TestDefaultOrganizationProvider; | |||||
import org.sonar.server.tester.UserSessionRule; | import org.sonar.server.tester.UserSessionRule; | ||||
import org.sonar.server.usergroups.DefaultGroupFinder; | import org.sonar.server.usergroups.DefaultGroupFinder; | ||||
import org.sonar.server.ws.TestRequest; | import org.sonar.server.ws.TestRequest; | ||||
@Rule | @Rule | ||||
public ExpectedException expectedException = ExpectedException.none(); | public ExpectedException expectedException = ExpectedException.none(); | ||||
private TestDefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db); | |||||
private WsActionTester ws = new WsActionTester(new AddUserAction(db.getDbClient(), userSession, newGroupWsSupport())); | |||||
private final WsActionTester ws = new WsActionTester(new AddUserAction(db.getDbClient(), userSession, newGroupWsSupport())); | |||||
@Test | @Test | ||||
public void verify_definition() { | public void verify_definition() { | ||||
Action wsDef = ws.getDef(); | Action wsDef = ws.getDef(); | ||||
assertThat(wsDef.isInternal()).isEqualTo(false); | |||||
assertThat(wsDef.isInternal()).isFalse(); | |||||
assertThat(wsDef.since()).isEqualTo("5.2"); | assertThat(wsDef.since()).isEqualTo("5.2"); | ||||
assertThat(wsDef.isPost()).isEqualTo(true); | |||||
assertThat(wsDef.isPost()).isTrue(); | |||||
assertThat(wsDef.changelog()).extracting(Change::getVersion, Change::getDescription).containsOnly( | assertThat(wsDef.changelog()).extracting(Change::getVersion, Change::getDescription).containsOnly( | ||||
tuple("8.4", "Parameter 'id' is deprecated. Format changes from integer to string. Use 'name' instead.")); | tuple("8.4", "Parameter 'id' is deprecated. Format changes from integer to string. Use 'name' instead.")); | ||||
} | } | ||||
@Test | @Test | ||||
public void fail_to_add_user_to_default_group() { | public void fail_to_add_user_to_default_group() { | ||||
UserDto user = db.users().insertUser(); | UserDto user = db.users().insertUser(); | ||||
GroupDto defaultGroup = db.users().insertDefaultGroup("default"); | |||||
GroupDto defaultGroup = db.users().insertDefaultGroup(); | |||||
loginAsAdmin(); | loginAsAdmin(); | ||||
expectedException.expect(IllegalArgumentException.class); | expectedException.expect(IllegalArgumentException.class); | ||||
expectedException.expectMessage("Default group 'default' cannot be used to perform this action"); | |||||
expectedException.expectMessage("Default group 'sonar-users' cannot be used to perform this action"); | |||||
newRequest() | newRequest() | ||||
.setParam("id", defaultGroup.getUuid()) | .setParam("id", defaultGroup.getUuid()) | ||||
} | } | ||||
private GroupWsSupport newGroupWsSupport() { | private GroupWsSupport newGroupWsSupport() { | ||||
return new GroupWsSupport(db.getDbClient(), new DefaultGroupFinder(db.getDbClient(), defaultOrganizationProvider)); | |||||
return new GroupWsSupport(db.getDbClient(), new DefaultGroupFinder(db.getDbClient())); | |||||
} | } | ||||
} | } |
import org.sonar.db.user.GroupDto; | import org.sonar.db.user.GroupDto; | ||||
import org.sonar.server.exceptions.ForbiddenException; | import org.sonar.server.exceptions.ForbiddenException; | ||||
import org.sonar.server.exceptions.ServerException; | import org.sonar.server.exceptions.ServerException; | ||||
import org.sonar.server.organization.DefaultOrganization; | |||||
import org.sonar.server.organization.TestDefaultOrganizationProvider; | |||||
import org.sonar.server.tester.UserSessionRule; | import org.sonar.server.tester.UserSessionRule; | ||||
import org.sonar.server.usergroups.DefaultGroupFinder; | import org.sonar.server.usergroups.DefaultGroupFinder; | ||||
import org.sonar.server.ws.WsActionTester; | import org.sonar.server.ws.WsActionTester; | ||||
@Rule | @Rule | ||||
public ExpectedException expectedException = ExpectedException.none(); | public ExpectedException expectedException = ExpectedException.none(); | ||||
private TestDefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db); | |||||
private CreateAction underTest = new CreateAction(db.getDbClient(), userSession, newGroupWsSupport(), new SequenceUuidFactory()); | |||||
private WsActionTester tester = new WsActionTester(underTest); | |||||
private final CreateAction underTest = new CreateAction(db.getDbClient(), userSession, newGroupWsSupport(), new SequenceUuidFactory()); | |||||
private final WsActionTester tester = new WsActionTester(underTest); | |||||
@Test | @Test | ||||
public void define_create_action() { | public void define_create_action() { | ||||
assertThat(action.key()).isEqualTo("create"); | assertThat(action.key()).isEqualTo("create"); | ||||
assertThat(action.isPost()).isTrue(); | assertThat(action.isPost()).isTrue(); | ||||
assertThat(action.responseExampleAsString()).isNotEmpty(); | assertThat(action.responseExampleAsString()).isNotEmpty(); | ||||
assertThat(action.params()).hasSize(3); | |||||
assertThat(action.params()).hasSize(2); | |||||
assertThat(action.changelog()).extracting(Change::getVersion, Change::getDescription).containsOnly( | assertThat(action.changelog()).extracting(Change::getVersion, Change::getDescription).containsOnly( | ||||
tuple("8.4", "Field 'id' format in the response changes from integer to string.")); | tuple("8.4", "Field 'id' format in the response changes from integer to string.")); | ||||
} | } | ||||
} | } | ||||
private GroupWsSupport newGroupWsSupport() { | private GroupWsSupport newGroupWsSupport() { | ||||
return new GroupWsSupport(db.getDbClient(), new DefaultGroupFinder(db.getDbClient(), defaultOrganizationProvider)); | |||||
} | |||||
private DefaultOrganization getDefaultOrganization() { | |||||
return defaultOrganizationProvider.get(); | |||||
return new GroupWsSupport(db.getDbClient(), new DefaultGroupFinder(db.getDbClient())); | |||||
} | } | ||||
} | } |
import org.sonar.db.user.GroupDto; | import org.sonar.db.user.GroupDto; | ||||
import org.sonar.db.user.UserDto; | import org.sonar.db.user.UserDto; | ||||
import org.sonar.server.exceptions.NotFoundException; | import org.sonar.server.exceptions.NotFoundException; | ||||
import org.sonar.server.organization.TestDefaultOrganizationProvider; | |||||
import org.sonar.server.tester.UserSessionRule; | import org.sonar.server.tester.UserSessionRule; | ||||
import org.sonar.server.usergroups.DefaultGroupFinder; | import org.sonar.server.usergroups.DefaultGroupFinder; | ||||
import org.sonar.server.ws.TestRequest; | import org.sonar.server.ws.TestRequest; | ||||
@Rule | @Rule | ||||
public DbTester db = DbTester.create(new AlwaysIncreasingSystem2()); | public DbTester db = DbTester.create(new AlwaysIncreasingSystem2()); | ||||
private ComponentDbTester componentTester = new ComponentDbTester(db); | |||||
private TestDefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db); | |||||
private WsActionTester ws = new WsActionTester(new DeleteAction(db.getDbClient(), userSession, newGroupWsSupport())); | |||||
private final ComponentDbTester componentTester = new ComponentDbTester(db); | |||||
private final WsActionTester ws = new WsActionTester(new DeleteAction(db.getDbClient(), userSession, newGroupWsSupport())); | |||||
@Test | @Test | ||||
public void verify_definition() { | public void verify_definition() { | ||||
Action wsDef = ws.getDef(); | Action wsDef = ws.getDef(); | ||||
assertThat(wsDef.isInternal()).isEqualTo(false); | |||||
assertThat(wsDef.isInternal()).isFalse(); | |||||
assertThat(wsDef.since()).isEqualTo("5.2"); | assertThat(wsDef.since()).isEqualTo("5.2"); | ||||
assertThat(wsDef.isPost()).isEqualTo(true); | |||||
assertThat(wsDef.isPost()).isTrue(); | |||||
assertThat(wsDef.changelog()).extracting(Change::getVersion, Change::getDescription).containsOnly( | assertThat(wsDef.changelog()).extracting(Change::getVersion, Change::getDescription).containsOnly( | ||||
tuple("8.4", "Parameter 'id' is deprecated. Format changes from integer to string. Use 'name' instead.")); | tuple("8.4", "Parameter 'id' is deprecated. Format changes from integer to string. Use 'name' instead.")); | ||||
} | } | ||||
.setParam("id", group.getUuid()) | .setParam("id", group.getUuid()) | ||||
.execute(); | .execute(); | ||||
assertThat(db.countRowsOfTable("groups_users")).isEqualTo(0); | |||||
assertThat(db.countRowsOfTable("groups_users")).isZero(); | |||||
} | } | ||||
@Test | @Test | ||||
.setParam("id", group.getUuid()) | .setParam("id", group.getUuid()) | ||||
.execute(); | .execute(); | ||||
assertThat(db.countRowsOfTable("group_roles")).isEqualTo(0); | |||||
assertThat(db.countRowsOfTable("group_roles")).isZero(); | |||||
} | } | ||||
@Test | @Test | ||||
.setParam("id", group.getUuid()) | .setParam("id", group.getUuid()) | ||||
.execute(); | .execute(); | ||||
assertThat(db.countRowsOfTable("perm_templates_groups")).isEqualTo(0); | |||||
assertThat(db.countRowsOfTable("perm_templates_groups")).isZero(); | |||||
} | } | ||||
@Test | @Test | ||||
@Test | @Test | ||||
public void fail_to_delete_default_group() { | public void fail_to_delete_default_group() { | ||||
loginAsAdmin(); | loginAsAdmin(); | ||||
GroupDto defaultGroup = db.users().insertDefaultGroup("default"); | |||||
GroupDto defaultGroup = db.users().insertDefaultGroup(); | |||||
expectedException.expect(IllegalArgumentException.class); | expectedException.expect(IllegalArgumentException.class); | ||||
expectedException.expectMessage("Default group 'default' cannot be used to perform this action"); | |||||
expectedException.expectMessage("Default group 'sonar-users' cannot be used to perform this action"); | |||||
newRequest() | newRequest() | ||||
.setParam("id", defaultGroup.getUuid()) | .setParam("id", defaultGroup.getUuid()) | ||||
db.users().insertDefaultGroup(); | db.users().insertDefaultGroup(); | ||||
GroupDto adminGroup1 = db.users().insertGroup("admins"); | GroupDto adminGroup1 = db.users().insertGroup("admins"); | ||||
db.users().insertPermissionOnGroup(adminGroup1, SYSTEM_ADMIN); | db.users().insertPermissionOnGroup(adminGroup1, SYSTEM_ADMIN); | ||||
GroupDto adminGroup2 = db.users().insertGroup("admins"); | |||||
GroupDto adminGroup2 = db.users().insertGroup("admins2"); | |||||
db.users().insertPermissionOnGroup(adminGroup2, SYSTEM_ADMIN); | db.users().insertPermissionOnGroup(adminGroup2, SYSTEM_ADMIN); | ||||
UserDto bigBoss = db.users().insertUser(); | UserDto bigBoss = db.users().insertUser(); | ||||
db.users().insertMember(adminGroup2, bigBoss); | db.users().insertMember(adminGroup2, bigBoss); | ||||
.setParam(PARAM_GROUP_ID, adminGroup1.getUuid()) | .setParam(PARAM_GROUP_ID, adminGroup1.getUuid()) | ||||
.execute(); | .execute(); | ||||
} | } | ||||
private void addAdmin() { | private void addAdmin() { | ||||
UserDto admin = db.users().insertUser(); | UserDto admin = db.users().insertUser(); | ||||
db.users().insertPermissionOnUser(admin, SYSTEM_ADMIN); | db.users().insertPermissionOnUser(admin, SYSTEM_ADMIN); | ||||
} | } | ||||
private void loginAsAdmin() { | private void loginAsAdmin() { | ||||
userSession.logIn().addPermission(ADMINISTER); | userSession.logIn().addPermission(ADMINISTER); | ||||
} | } | ||||
} | } | ||||
private GroupWsSupport newGroupWsSupport() { | private GroupWsSupport newGroupWsSupport() { | ||||
return new GroupWsSupport(db.getDbClient(), new DefaultGroupFinder(db.getDbClient(), defaultOrganizationProvider)); | |||||
return new GroupWsSupport(db.getDbClient(), new DefaultGroupFinder(db.getDbClient())); | |||||
} | } | ||||
} | } |
@Test | @Test | ||||
public void test_ref_by_name() { | public void test_ref_by_name() { | ||||
GroupWsRef ref = fromName("ORG1", "the-group"); | |||||
GroupWsRef ref = fromName("the-group"); | |||||
assertThat(ref.hasUuid()).isFalse(); | assertThat(ref.hasUuid()).isFalse(); | ||||
assertThat(ref.getOrganizationKey()).isEqualTo("ORG1"); | |||||
assertThat(ref.getName()).isEqualTo("the-group"); | assertThat(ref.getName()).isEqualTo("the-group"); | ||||
assertThat(ref.isAnyone()).isFalse(); | assertThat(ref.isAnyone()).isFalse(); | ||||
} | } | ||||
public void test_equals_and_hashCode() { | public void test_equals_and_hashCode() { | ||||
GroupWsRef refId1 = GroupWsRef.fromUuid("10"); | GroupWsRef refId1 = GroupWsRef.fromUuid("10"); | ||||
GroupWsRef refId2 = GroupWsRef.fromUuid("11"); | GroupWsRef refId2 = GroupWsRef.fromUuid("11"); | ||||
assertThat(refId1.equals(refId1)).isTrue(); | |||||
assertThat(refId1.equals(GroupWsRef.fromUuid("10"))).isTrue(); | |||||
assertThat(refId1.hashCode()).isEqualTo(GroupWsRef.fromUuid("10").hashCode()); | |||||
assertThat(refId1.equals(refId2)).isFalse(); | |||||
assertThat(refId1) | |||||
.isEqualTo(refId1) | |||||
.isEqualTo(GroupWsRef.fromUuid("10")) | |||||
.hasSameHashCodeAs(GroupWsRef.fromUuid("10")) | |||||
.isNotEqualTo(refId2); | |||||
GroupWsRef refName1 = fromName("ORG1", "the-group"); | |||||
GroupWsRef refName2 = fromName("ORG1", "the-group2"); | |||||
GroupWsRef refName3 = fromName("ORG2", "the-group2"); | |||||
assertThat(refName1.equals(refName1)).isTrue(); | |||||
assertThat(refName1.equals(fromName("ORG1", "the-group"))).isTrue(); | |||||
assertThat(refName1.hashCode()).isEqualTo(fromName("ORG1", "the-group").hashCode()); | |||||
assertThat(refName1.equals(refName2)).isFalse(); | |||||
assertThat(refName2.equals(refName3)).isFalse(); | |||||
GroupWsRef refName1 = fromName("the-group"); | |||||
GroupWsRef refName2 = fromName("the-group2"); | |||||
GroupWsRef refName3 = fromName("the-group2"); | |||||
assertThat(refName1) | |||||
.isEqualTo(refName1) | |||||
.isEqualTo(fromName("the-group")) | |||||
.hasSameHashCodeAs(fromName("the-group")) | |||||
.isNotEqualTo(refName2); | |||||
assertThat(refName2).isEqualTo(refName3); | |||||
} | } | ||||
@Test | @Test | ||||
public void test_toString() { | public void test_toString() { | ||||
GroupWsRef refId = GroupWsRef.fromUuid("10"); | GroupWsRef refId = GroupWsRef.fromUuid("10"); | ||||
assertThat(refId.toString()).isEqualTo("GroupWsRef{uuid=10, organizationKey='null', name='null'}"); | |||||
assertThat(refId).hasToString("GroupWsRef{uuid=10, name='null'}"); | |||||
} | } | ||||
@Test | @Test | ||||
public void reference_anyone_by_its_name() { | public void reference_anyone_by_its_name() { | ||||
GroupWsRef ref = GroupWsRef.fromName("my-org", "Anyone"); | |||||
assertThat(ref.getOrganizationKey()).isEqualTo("my-org"); | |||||
GroupWsRef ref = GroupWsRef.fromName("Anyone"); | |||||
assertThat(ref.getName()).isEqualTo("Anyone"); | assertThat(ref.getName()).isEqualTo("Anyone"); | ||||
assertThat(ref.isAnyone()).isTrue(); | assertThat(ref.isAnyone()).isTrue(); | ||||
// case-insensitive | // case-insensitive | ||||
ref = GroupWsRef.fromName("my-org", "anyone"); | |||||
assertThat(ref.getOrganizationKey()).isEqualTo("my-org"); | |||||
ref = GroupWsRef.fromName("anyone"); | |||||
assertThat(ref.getName()).isEqualTo("anyone"); | assertThat(ref.getName()).isEqualTo("anyone"); | ||||
assertThat(ref.isAnyone()).isTrue(); | assertThat(ref.isAnyone()).isTrue(); | ||||
} | } |
import org.sonar.server.exceptions.BadRequestException; | import org.sonar.server.exceptions.BadRequestException; | ||||
import org.sonar.server.exceptions.ForbiddenException; | import org.sonar.server.exceptions.ForbiddenException; | ||||
import org.sonar.server.exceptions.NotFoundException; | import org.sonar.server.exceptions.NotFoundException; | ||||
import org.sonar.server.organization.TestDefaultOrganizationProvider; | |||||
import org.sonar.server.tester.UserSessionRule; | import org.sonar.server.tester.UserSessionRule; | ||||
import org.sonar.server.usergroups.DefaultGroupFinder; | import org.sonar.server.usergroups.DefaultGroupFinder; | ||||
import org.sonar.server.ws.TestRequest; | import org.sonar.server.ws.TestRequest; | ||||
@Rule | @Rule | ||||
public ExpectedException expectedException = ExpectedException.none(); | public ExpectedException expectedException = ExpectedException.none(); | ||||
private WsActionTester ws = new WsActionTester( | |||||
new RemoveUserAction(db.getDbClient(), userSession, new GroupWsSupport(db.getDbClient(), new DefaultGroupFinder(db.getDbClient(), TestDefaultOrganizationProvider.from(db))))); | |||||
private final WsActionTester ws = new WsActionTester( | |||||
new RemoveUserAction(db.getDbClient(), userSession, new GroupWsSupport(db.getDbClient(), new DefaultGroupFinder(db.getDbClient())))); | |||||
@Test | @Test | ||||
public void verify_definition() { | public void verify_definition() { | ||||
Action wsDef = ws.getDef(); | Action wsDef = ws.getDef(); | ||||
assertThat(wsDef.isInternal()).isEqualTo(false); | |||||
assertThat(wsDef.isInternal()).isFalse(); | |||||
assertThat(wsDef.since()).isEqualTo("5.2"); | assertThat(wsDef.since()).isEqualTo("5.2"); | ||||
assertThat(wsDef.isPost()).isEqualTo(true); | |||||
assertThat(wsDef.isPost()).isTrue(); | |||||
assertThat(wsDef.changelog()).extracting(Change::getVersion, Change::getDescription).containsOnly( | assertThat(wsDef.changelog()).extracting(Change::getVersion, Change::getDescription).containsOnly( | ||||
tuple("8.4", "Parameter 'id' is deprecated. Format changes from integer to string. Use 'name' instead.")); | tuple("8.4", "Parameter 'id' is deprecated. Format changes from integer to string. Use 'name' instead.")); | ||||
} | } | ||||
@Test | @Test | ||||
public void fail_to_remove_user_from_default_group() { | public void fail_to_remove_user_from_default_group() { | ||||
UserDto user = db.users().insertUser(); | UserDto user = db.users().insertUser(); | ||||
GroupDto defaultGroup = db.users().insertDefaultGroup("default"); | |||||
GroupDto defaultGroup = db.users().insertDefaultGroup(); | |||||
db.users().insertMember(defaultGroup, user); | db.users().insertMember(defaultGroup, user); | ||||
loginAsAdmin(); | loginAsAdmin(); | ||||
expectedException.expect(IllegalArgumentException.class); | expectedException.expect(IllegalArgumentException.class); | ||||
expectedException.expectMessage("Default group 'default' cannot be used to perform this action"); | |||||
expectedException.expectMessage("Default group 'sonar-users' cannot be used to perform this action"); | |||||
newRequest() | newRequest() | ||||
.setParam("id", defaultGroup.getUuid()) | .setParam("id", defaultGroup.getUuid()) |
@Rule | @Rule | ||||
public ExpectedException expectedException = ExpectedException.none(); | public ExpectedException expectedException = ExpectedException.none(); | ||||
private WsActionTester ws = new WsActionTester(new SearchAction(db.getDbClient(), userSession, | |||||
new DefaultGroupFinder(db.getDbClient(), TestDefaultOrganizationProvider.from(db)))); | |||||
private final WsActionTester ws = new WsActionTester(new SearchAction(db.getDbClient(), userSession, | |||||
new DefaultGroupFinder(db.getDbClient()))); | |||||
@Test | @Test | ||||
public void define_search_action() { | public void define_search_action() { | ||||
assertThat(action).isNotNull(); | assertThat(action).isNotNull(); | ||||
assertThat(action.key()).isEqualTo("search"); | assertThat(action.key()).isEqualTo("search"); | ||||
assertThat(action.responseExampleAsString()).isNotEmpty(); | assertThat(action.responseExampleAsString()).isNotEmpty(); | ||||
assertThat(action.params()).hasSize(5); | |||||
assertThat(action.params()).hasSize(4); | |||||
assertThat(action.changelog()).extracting(Change::getVersion, Change::getDescription).containsOnly( | assertThat(action.changelog()).extracting(Change::getVersion, Change::getDescription).containsOnly( | ||||
tuple("8.4", "Field 'id' in the response is deprecated. Format changes from integer to string."), | tuple("8.4", "Field 'id' in the response is deprecated. Format changes from integer to string."), | ||||
tuple("6.4", "Paging response fields moved to a Paging object"), | tuple("6.4", "Paging response fields moved to a Paging object"), | ||||
@Test | @Test | ||||
public void search_without_parameters() { | public void search_without_parameters() { | ||||
insertDefaultGroup(db.getDefaultOrganization(), "users", 0); | |||||
insertGroup(db.getDefaultOrganization(), "admins", 0); | |||||
insertGroup(db.getDefaultOrganization(), "customer1", 0); | |||||
insertGroup(db.getDefaultOrganization(), "customer2", 0); | |||||
insertGroup(db.getDefaultOrganization(), "customer3", 0); | |||||
insertDefaultGroup(0); | |||||
insertGroup("admins", 0); | |||||
insertGroup("customer1", 0); | |||||
insertGroup("customer2", 0); | |||||
insertGroup("customer3", 0); | |||||
loginAsAdmin(); | loginAsAdmin(); | ||||
SearchWsResponse response = call(ws.newRequest()); | SearchWsResponse response = call(ws.newRequest()); | ||||
tuple("customer1", "Customer1", 0), | tuple("customer1", "Customer1", 0), | ||||
tuple("customer2", "Customer2", 0), | tuple("customer2", "Customer2", 0), | ||||
tuple("customer3", "Customer3", 0), | tuple("customer3", "Customer3", 0), | ||||
tuple("users", "Users", 0)); | |||||
tuple("sonar-users", "Users", 0)); | |||||
} | } | ||||
@Test | @Test | ||||
public void search_with_members() { | public void search_with_members() { | ||||
insertDefaultGroup(db.getDefaultOrganization(), "users", 5); | |||||
insertGroup(db.getDefaultOrganization(), "admins", 1); | |||||
insertGroup(db.getDefaultOrganization(), "customer1", 0); | |||||
insertGroup(db.getDefaultOrganization(), "customer2", 4); | |||||
insertGroup(db.getDefaultOrganization(), "customer3", 0); | |||||
insertDefaultGroup(5); | |||||
insertGroup("admins", 1); | |||||
insertGroup("customer1", 0); | |||||
insertGroup("customer2", 4); | |||||
insertGroup("customer3", 0); | |||||
loginAsAdmin(); | loginAsAdmin(); | ||||
SearchWsResponse response = call(ws.newRequest()); | SearchWsResponse response = call(ws.newRequest()); | ||||
tuple("customer1", "Customer1", 0), | tuple("customer1", "Customer1", 0), | ||||
tuple("customer2", "Customer2", 4), | tuple("customer2", "Customer2", 4), | ||||
tuple("customer3", "Customer3", 0), | tuple("customer3", "Customer3", 0), | ||||
tuple("users", "Users", 5)); | |||||
tuple("sonar-users", "Users", 5)); | |||||
} | } | ||||
@Test | @Test | ||||
public void search_with_query() { | public void search_with_query() { | ||||
insertDefaultGroup(db.getDefaultOrganization(), "users", 0); | |||||
insertGroup(db.getDefaultOrganization(), "admins", 0); | |||||
insertGroup(db.getDefaultOrganization(), "customer%_%/1", 0); | |||||
insertGroup(db.getDefaultOrganization(), "customer%_%/2", 0); | |||||
insertGroup(db.getDefaultOrganization(), "customer%_%/3", 0); | |||||
insertDefaultGroup(0); | |||||
insertGroup("admins", 0); | |||||
insertGroup("customer%_%/1", 0); | |||||
insertGroup("customer%_%/2", 0); | |||||
insertGroup("customer%_%/3", 0); | |||||
loginAsAdmin(); | loginAsAdmin(); | ||||
SearchWsResponse response = call(ws.newRequest().setParam(TEXT_QUERY, "tomer%_%/")); | SearchWsResponse response = call(ws.newRequest().setParam(TEXT_QUERY, "tomer%_%/")); | ||||
@Test | @Test | ||||
public void search_with_paging() { | public void search_with_paging() { | ||||
insertDefaultGroup(db.getDefaultOrganization(), "users", 0); | |||||
insertGroup(db.getDefaultOrganization(), "admins", 0); | |||||
insertGroup(db.getDefaultOrganization(), "customer1", 0); | |||||
insertGroup(db.getDefaultOrganization(), "customer2", 0); | |||||
insertGroup(db.getDefaultOrganization(), "customer3", 0); | |||||
insertDefaultGroup(0); | |||||
insertGroup("admins", 0); | |||||
insertGroup("customer1", 0); | |||||
insertGroup("customer2", 0); | |||||
insertGroup("customer3", 0); | |||||
loginAsAdmin(); | loginAsAdmin(); | ||||
SearchWsResponse response = call(ws.newRequest().setParam(PAGE_SIZE, "3")); | SearchWsResponse response = call(ws.newRequest().setParam(PAGE_SIZE, "3")); | ||||
assertThat(response.getPaging()).extracting(Paging::getPageIndex, Paging::getPageSize, Paging::getTotal).containsOnly(2, 3, 5); | assertThat(response.getPaging()).extracting(Paging::getPageIndex, Paging::getPageSize, Paging::getTotal).containsOnly(2, 3, 5); | ||||
assertThat(response.getGroupsList()).extracting(Group::getName, Group::getDescription, Group::getMembersCount).containsOnly( | assertThat(response.getGroupsList()).extracting(Group::getName, Group::getDescription, Group::getMembersCount).containsOnly( | ||||
tuple("customer3", "Customer3", 0), | tuple("customer3", "Customer3", 0), | ||||
tuple("users", "Users", 0)); | |||||
tuple("sonar-users", "Users", 0)); | |||||
response = call(ws.newRequest().setParam(PAGE_SIZE, "3").setParam(PAGE, "3")); | response = call(ws.newRequest().setParam(PAGE_SIZE, "3").setParam(PAGE, "3")); | ||||
assertThat(response.getPaging()).extracting(Paging::getPageIndex, Paging::getPageSize, Paging::getTotal).containsOnly(3, 3, 5); | assertThat(response.getPaging()).extracting(Paging::getPageIndex, Paging::getPageSize, Paging::getTotal).containsOnly(3, 3, 5); | ||||
@Test | @Test | ||||
public void search_with_fields() { | public void search_with_fields() { | ||||
insertDefaultGroup(db.getDefaultOrganization(), "sonar-users", 0); | |||||
insertDefaultGroup(0); | |||||
loginAsAdmin(); | loginAsAdmin(); | ||||
assertThat(call(ws.newRequest()).getGroupsList()).extracting(Group::hasId, Group::hasName, Group::hasDescription, Group::hasMembersCount) | assertThat(call(ws.newRequest()).getGroupsList()).extracting(Group::hasId, Group::hasName, Group::hasDescription, Group::hasMembersCount) | ||||
@Test | @Test | ||||
public void return_default_group() { | public void return_default_group() { | ||||
db.users().insertDefaultGroup("default"); | |||||
db.users().insertDefaultGroup(); | |||||
loginAsAdmin(); | loginAsAdmin(); | ||||
SearchWsResponse response = call(ws.newRequest()); | SearchWsResponse response = call(ws.newRequest()); | ||||
assertThat(response.getGroupsList()).extracting(Group::getName, Group::getDefault).containsOnly(tuple("default", true)); | |||||
} | |||||
@Test | |||||
public void fail_when_no_default_group() { | |||||
db.users().insertGroup("users"); | |||||
loginAsAdmin(); | |||||
expectedException.expect(IllegalStateException.class); | |||||
expectedException.expectMessage("Default group cannot be found"); | |||||
call(ws.newRequest()); | |||||
assertThat(response.getGroupsList()).extracting(Group::getName, Group::getDefault).containsOnly(tuple("sonar-users", true)); | |||||
} | } | ||||
@Test | @Test | ||||
@Test | @Test | ||||
public void test_json_example() { | public void test_json_example() { | ||||
insertDefaultGroup(db.getDefaultOrganization(), "users", 17); | |||||
insertGroup(db.getDefaultOrganization(), "administrators", 2); | |||||
insertDefaultGroup(17); | |||||
insertGroup("administrators", 2); | |||||
loginAsAdmin(); | loginAsAdmin(); | ||||
String response = ws.newRequest().setMediaType(MediaTypes.JSON).execute().getInput(); | String response = ws.newRequest().setMediaType(MediaTypes.JSON).execute().getInput(); | ||||
assertThat(action.isInternal()).isFalse(); | assertThat(action.isInternal()).isFalse(); | ||||
assertThat(action.responseExampleAsString()).isNotEmpty(); | assertThat(action.responseExampleAsString()).isNotEmpty(); | ||||
assertThat(action.params()).extracting(WebService.Param::key).containsOnly("p", "q", "ps", "f", "organization"); | |||||
assertThat(action.params()).extracting(WebService.Param::key).containsOnly("p", "q", "ps", "f"); | |||||
assertThat(action.param("f").possibleValues()).containsOnly("name", "description", "membersCount"); | assertThat(action.param("f").possibleValues()).containsOnly("name", "description", "membersCount"); | ||||
} | } | ||||
return request.executeProtobuf(SearchWsResponse.class); | return request.executeProtobuf(SearchWsResponse.class); | ||||
} | } | ||||
private void insertDefaultGroup(OrganizationDto org, String name, int numberOfMembers) { | |||||
GroupDto group = newGroupDto().setName(name).setDescription(capitalize(name)); | |||||
db.users().insertDefaultGroup(group); | |||||
private void insertDefaultGroup(int numberOfMembers) { | |||||
GroupDto group = db.users().insertDefaultGroup(); | |||||
addMembers(group, numberOfMembers); | addMembers(group, numberOfMembers); | ||||
} | } | ||||
private void insertGroup(OrganizationDto org, String name, int numberOfMembers) { | |||||
private void insertGroup(String name, int numberOfMembers) { | |||||
GroupDto group = newGroupDto().setName(name).setDescription(capitalize(name)); | GroupDto group = newGroupDto().setName(name).setDescription(capitalize(name)); | ||||
db.users().insertGroup(group); | db.users().insertGroup(group); | ||||
addMembers(group, numberOfMembers); | addMembers(group, numberOfMembers); |
import org.sonar.server.exceptions.ForbiddenException; | import org.sonar.server.exceptions.ForbiddenException; | ||||
import org.sonar.server.exceptions.NotFoundException; | import org.sonar.server.exceptions.NotFoundException; | ||||
import org.sonar.server.exceptions.ServerException; | import org.sonar.server.exceptions.ServerException; | ||||
import org.sonar.server.organization.TestDefaultOrganizationProvider; | |||||
import org.sonar.server.tester.UserSessionRule; | import org.sonar.server.tester.UserSessionRule; | ||||
import org.sonar.server.usergroups.DefaultGroupFinder; | import org.sonar.server.usergroups.DefaultGroupFinder; | ||||
import org.sonar.server.ws.TestRequest; | import org.sonar.server.ws.TestRequest; | ||||
@Rule | @Rule | ||||
public ExpectedException expectedException = ExpectedException.none(); | public ExpectedException expectedException = ExpectedException.none(); | ||||
private TestDefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db); | |||||
private WsActionTester ws = new WsActionTester( | |||||
new UpdateAction(db.getDbClient(), userSession, new GroupWsSupport(db.getDbClient(), new DefaultGroupFinder(db.getDbClient(), defaultOrganizationProvider)), | |||||
defaultOrganizationProvider)); | |||||
private final WsActionTester ws = new WsActionTester( | |||||
new UpdateAction(db.getDbClient(), userSession, new GroupWsSupport(db.getDbClient(), new DefaultGroupFinder(db.getDbClient())))); | |||||
@Test | @Test | ||||
public void verify_definition() { | public void verify_definition() { | ||||
@Test | @Test | ||||
public void fail_to_update_default_group_name() { | public void fail_to_update_default_group_name() { | ||||
GroupDto group = db.users().insertDefaultGroup("default"); | |||||
GroupDto group = db.users().insertDefaultGroup(); | |||||
loginAsAdmin(); | loginAsAdmin(); | ||||
expectedException.expect(IllegalArgumentException.class); | expectedException.expect(IllegalArgumentException.class); | ||||
expectedException.expectMessage("Default group 'default' cannot be used to perform this action"); | |||||
expectedException.expectMessage("Default group 'sonar-users' cannot be used to perform this action"); | |||||
newRequest() | newRequest() | ||||
.setParam("id", group.getUuid()) | .setParam("id", group.getUuid()) | ||||
@Test | @Test | ||||
public void fail_to_update_default_group_description() { | public void fail_to_update_default_group_description() { | ||||
GroupDto group = db.users().insertDefaultGroup("default"); | |||||
GroupDto group = db.users().insertDefaultGroup(); | |||||
loginAsAdmin(); | loginAsAdmin(); | ||||
expectedException.expect(IllegalArgumentException.class); | expectedException.expect(IllegalArgumentException.class); | ||||
expectedException.expectMessage("Default group 'default' cannot be used to perform this action"); | |||||
expectedException.expectMessage("Default group 'sonar-users' cannot be used to perform this action"); | |||||
newRequest() | newRequest() | ||||
.setParam("id", group.getUuid()) | .setParam("id", group.getUuid()) |
public DbTester db = DbTester.create(System2.INSTANCE); | public DbTester db = DbTester.create(System2.INSTANCE); | ||||
@Rule | @Rule | ||||
public UserSessionRule userSession = UserSessionRule.standalone(); | public UserSessionRule userSession = UserSessionRule.standalone(); | ||||
private TestDefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db); | |||||
private WsActionTester ws = new WsActionTester( | |||||
new UsersAction(db.getDbClient(), userSession, new GroupWsSupport(db.getDbClient(), new DefaultGroupFinder(db.getDbClient(), defaultOrganizationProvider)))); | |||||
private final WsActionTester ws = new WsActionTester( | |||||
new UsersAction(db.getDbClient(), userSession, new GroupWsSupport(db.getDbClient(), new DefaultGroupFinder(db.getDbClient())))); | |||||
@Test | @Test | ||||
public void verify_definition() { | public void verify_definition() { | ||||
Action wsDef = ws.getDef(); | Action wsDef = ws.getDef(); | ||||
assertThat(wsDef.isInternal()).isEqualTo(false); | |||||
assertThat(wsDef.isInternal()).isFalse(); | |||||
assertThat(wsDef.since()).isEqualTo("5.2"); | assertThat(wsDef.since()).isEqualTo("5.2"); | ||||
assertThat(wsDef.isPost()).isEqualTo(false); | |||||
assertThat(wsDef.isPost()).isFalse(); | |||||
assertThat(wsDef.changelog()).extracting(Change::getVersion, Change::getDescription).containsOnly( | assertThat(wsDef.changelog()).extracting(Change::getVersion, Change::getDescription).containsOnly( | ||||
tuple("8.4", "Parameter 'id' is deprecated. Format changes from integer to string. Use 'name' instead.")); | tuple("8.4", "Parameter 'id' is deprecated. Format changes from integer to string. Use 'name' instead.")); | ||||
} | } | ||||
.setParam("id", group.getUuid()) | .setParam("id", group.getUuid()) | ||||
.execute() | .execute() | ||||
.getInput()).isSimilarTo("{\n" + | .getInput()).isSimilarTo("{\n" + | ||||
" \"users\": [\n" + | |||||
" {\"login\": \"ada\", \"name\": \"Ada Lovelace\", \"selected\": true}\n" + | |||||
" ]\n" + | |||||
"}"); | |||||
" \"users\": [\n" + | |||||
" {\"login\": \"ada\", \"name\": \"Ada Lovelace\", \"selected\": true}\n" + | |||||
" ]\n" + | |||||
"}"); | |||||
assertJson(newUsersRequest() | assertJson(newUsersRequest() | ||||
.setParam("id", group.getUuid()) | .setParam("id", group.getUuid()) | ||||
.setParam(Param.SELECTED, SelectionMode.SELECTED.value()) | .setParam(Param.SELECTED, SelectionMode.SELECTED.value()) | ||||
.execute() | .execute() | ||||
.getInput()).isSimilarTo("{\n" + | .getInput()).isSimilarTo("{\n" + | ||||
" \"users\": [\n" + | |||||
" {\"login\": \"ada\", \"name\": \"Ada Lovelace\", \"selected\": true}\n" + | |||||
" ]\n" + | |||||
"}"); | |||||
" \"users\": [\n" + | |||||
" {\"login\": \"ada\", \"name\": \"Ada Lovelace\", \"selected\": true}\n" + | |||||
" ]\n" + | |||||
"}"); | |||||
} | } | ||||
@Test | @Test | ||||
.setParam(Param.SELECTED, SelectionMode.ALL.value()) | .setParam(Param.SELECTED, SelectionMode.ALL.value()) | ||||
.execute() | .execute() | ||||
.getInput()).isSimilarTo("{\n" + | .getInput()).isSimilarTo("{\n" + | ||||
" \"p\": 1,\n" + | |||||
" \"ps\": 1,\n" + | |||||
" \"total\": 2,\n" + | |||||
" \"users\": [\n" + | |||||
" {\"login\": \"ada\", \"name\": \"Ada Lovelace\", \"selected\": true}\n" + | |||||
" ]\n" + | |||||
"}"); | |||||
" \"p\": 1,\n" + | |||||
" \"ps\": 1,\n" + | |||||
" \"total\": 2,\n" + | |||||
" \"users\": [\n" + | |||||
" {\"login\": \"ada\", \"name\": \"Ada Lovelace\", \"selected\": true}\n" + | |||||
" ]\n" + | |||||
"}"); | |||||
assertJson(newUsersRequest() | assertJson(newUsersRequest() | ||||
.setParam("id", group.getUuid()) | .setParam("id", group.getUuid()) | ||||
.setParam(Param.SELECTED, SelectionMode.ALL.value()) | .setParam(Param.SELECTED, SelectionMode.ALL.value()) | ||||
.execute() | .execute() | ||||
.getInput()).isSimilarTo("{\n" + | .getInput()).isSimilarTo("{\n" + | ||||
" \"p\": 2,\n" + | |||||
" \"ps\": 1,\n" + | |||||
" \"total\": 2,\n" + | |||||
" \"users\": [\n" + | |||||
" {\"login\": \"grace\", \"name\": \"Grace Hopper\", \"selected\": false}\n" + | |||||
" ]\n" + | |||||
"}"); | |||||
" \"p\": 2,\n" + | |||||
" \"ps\": 1,\n" + | |||||
" \"total\": 2,\n" + | |||||
" \"users\": [\n" + | |||||
" {\"login\": \"grace\", \"name\": \"Grace Hopper\", \"selected\": false}\n" + | |||||
" ]\n" + | |||||
"}"); | |||||
} | } | ||||
@Test | @Test | ||||
.setParam(Param.SELECTED, SelectionMode.ALL.value()) | .setParam(Param.SELECTED, SelectionMode.ALL.value()) | ||||
.execute() | .execute() | ||||
.getInput()).isSimilarTo("{\n" + | .getInput()).isSimilarTo("{\n" + | ||||
" \"users\": [\n" + | |||||
" {\"login\": \"ada.login\", \"name\": \"Ada Lovelace\", \"selected\": true},\n" + | |||||
" {\"login\": \"grace\", \"name\": \"Grace Hopper\", \"selected\": false}\n" + | |||||
" ]\n" + | |||||
"}\n"); | |||||
" \"users\": [\n" + | |||||
" {\"login\": \"ada.login\", \"name\": \"Ada Lovelace\", \"selected\": true},\n" + | |||||
" {\"login\": \"grace\", \"name\": \"Grace Hopper\", \"selected\": false}\n" + | |||||
" ]\n" + | |||||
"}\n"); | |||||
assertJson(newUsersRequest().setParam("id", group.getUuid()) | assertJson(newUsersRequest().setParam("id", group.getUuid()) | ||||
.setParam("q", ".logi") | .setParam("q", ".logi") | ||||
.execute() | .execute() | ||||
.getInput()).isSimilarTo("{\n" + | .getInput()).isSimilarTo("{\n" + | ||||
" \"users\": [\n" + | |||||
" {\n" + | |||||
" \"login\": \"ada.login\",\n" + | |||||
" \"name\": \"Ada Lovelace\",\n" + | |||||
" \"selected\": true\n" + | |||||
" }\n" + | |||||
" ]\n" + | |||||
"}\n"); | |||||
" \"users\": [\n" + | |||||
" {\n" + | |||||
" \"login\": \"ada.login\",\n" + | |||||
" \"name\": \"Ada Lovelace\",\n" + | |||||
" \"selected\": true\n" + | |||||
" }\n" + | |||||
" ]\n" + | |||||
"}\n"); | |||||
assertJson(newUsersRequest().setParam("id", group.getUuid()) | assertJson(newUsersRequest().setParam("id", group.getUuid()) | ||||
.setParam("q", "OvE") | .setParam("q", "OvE") | ||||
.execute() | .execute() | ||||
.getInput()).isSimilarTo("{\n" + | .getInput()).isSimilarTo("{\n" + | ||||
" \"users\": [\n" + | |||||
" {\n" + | |||||
" \"login\": \"ada.login\",\n" + | |||||
" \"name\": \"Ada Lovelace\",\n" + | |||||
" \"selected\": true\n" + | |||||
" }\n" + | |||||
" ]\n" + | |||||
"}\n"); | |||||
" \"users\": [\n" + | |||||
" {\n" + | |||||
" \"login\": \"ada.login\",\n" + | |||||
" \"name\": \"Ada Lovelace\",\n" + | |||||
" \"selected\": true\n" + | |||||
" }\n" + | |||||
" ]\n" + | |||||
"}\n"); | |||||
assertJson(newUsersRequest().setParam("id", group.getUuid()) | assertJson(newUsersRequest().setParam("id", group.getUuid()) | ||||
.setParam("q", "mail") | .setParam("q", "mail") | ||||
.execute() | .execute() | ||||
.getInput()).isSimilarTo("{\n" + | .getInput()).isSimilarTo("{\n" + | ||||
" \"users\": [\n" + | |||||
" {\n" + | |||||
" \"login\": \"ada.login\",\n" + | |||||
" \"name\": \"Ada Lovelace\",\n" + | |||||
" \"selected\": true\n" + | |||||
" }\n" + | |||||
" ]\n" + | |||||
"}\n"); | |||||
" \"users\": [\n" + | |||||
" {\n" + | |||||
" \"login\": \"ada.login\",\n" + | |||||
" \"name\": \"Ada Lovelace\",\n" + | |||||
" \"selected\": true\n" + | |||||
" }\n" + | |||||
" ]\n" + | |||||
"}\n"); | |||||
} | } | ||||
@Test | @Test |
} | } | ||||
message Group { | message Group { | ||||
reserved 2; | |||||
optional string id = 1; | optional string id = 1; | ||||
optional string organization = 2; | |||||
optional string name = 3; | optional string name = 3; | ||||
optional string description = 4; | optional string description = 4; | ||||
optional int32 membersCount = 5; | optional int32 membersCount = 5; |