From 6bc9a1d45c04a067371834980203ef753d32086d Mon Sep 17 00:00:00 2001 From: Teryk Bellahsene Date: Mon, 21 Mar 2016 17:20:40 +0100 Subject: [PATCH] SONAR-7478 External identity information in users WS --- .../sonar/server/user/ws/CurrentAction.java | 4 ++ .../sonar/server/user/ws/UserJsonWriter.java | 23 ++++--- .../sonar/server/user/ws/current-example.json | 2 + .../sonar/server/user/ws/search-example.json | 8 ++- .../server/user/ws/CurrentActionTest.java | 3 + .../server/user/ws/SearchActionTest.java | 68 +++++++++++++++---- 6 files changed, 84 insertions(+), 24 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/ws/CurrentAction.java b/server/sonar-server/src/main/java/org/sonar/server/user/ws/CurrentAction.java index d05399763e0..dee0ad0fdc9 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/user/ws/CurrentAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/user/ws/CurrentAction.java @@ -33,6 +33,8 @@ import org.sonar.server.user.UserSession; import static com.google.common.base.Strings.isNullOrEmpty; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; +import static org.sonar.server.user.ws.UserJsonWriter.FIELD_EXTERNAL_IDENTITY; +import static org.sonar.server.user.ws.UserJsonWriter.FIELD_EXTERNAL_PROVIDER; public class CurrentAction implements UsersWsAction { private final UserSession userSession; @@ -95,6 +97,8 @@ public class CurrentAction implements UsersWsAction { json.prop("email", user.getEmail()); } json.prop("local", user.isLocal()); + json.prop(FIELD_EXTERNAL_IDENTITY, user.getExternalIdentity()); + json.prop(FIELD_EXTERNAL_PROVIDER, user.getExternalIdentityProvider()); } writeScmAccounts(json, optionalUser); diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/ws/UserJsonWriter.java b/server/sonar-server/src/main/java/org/sonar/server/user/ws/UserJsonWriter.java index 88abcd1c8c3..f77a2fb985f 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/user/ws/UserJsonWriter.java +++ b/server/sonar-server/src/main/java/org/sonar/server/user/ws/UserJsonWriter.java @@ -34,16 +34,19 @@ import static org.sonar.server.ws.JsonWriterUtils.writeIfNeeded; public class UserJsonWriter { - private static final String FIELD_LOGIN = "login"; - private static final String FIELD_NAME = "name"; - private static final String FIELD_EMAIL = "email"; - private static final String FIELD_SCM_ACCOUNTS = "scmAccounts"; - private static final String FIELD_GROUPS = "groups"; - private static final String FIELD_ACTIVE = "active"; - private static final String FIELD_TOKENS_COUNT = "tokensCount"; - private static final String FIELD_LOCAL = "local"; + static final String FIELD_LOGIN = "login"; + static final String FIELD_NAME = "name"; + static final String FIELD_EMAIL = "email"; + static final String FIELD_SCM_ACCOUNTS = "scmAccounts"; + static final String FIELD_GROUPS = "groups"; + static final String FIELD_ACTIVE = "active"; + static final String FIELD_TOKENS_COUNT = "tokensCount"; + static final String FIELD_LOCAL = "local"; + static final String FIELD_EXTERNAL_IDENTITY = "externalIdentity"; + static final String FIELD_EXTERNAL_PROVIDER = "externalProvider"; - public static final Set FIELDS = ImmutableSet.of(FIELD_NAME, FIELD_EMAIL, FIELD_SCM_ACCOUNTS, FIELD_GROUPS, FIELD_ACTIVE, FIELD_LOCAL); + public static final Set FIELDS = ImmutableSet.of(FIELD_NAME, FIELD_EMAIL, FIELD_SCM_ACCOUNTS, FIELD_GROUPS, FIELD_ACTIVE, FIELD_LOCAL, FIELD_EXTERNAL_IDENTITY, + FIELD_EXTERNAL_PROVIDER); private static final Set CONCISE_FIELDS = ImmutableSet.of(FIELD_NAME, FIELD_EMAIL, FIELD_ACTIVE); private final UserSession userSession; @@ -69,6 +72,8 @@ public class UserJsonWriter { writeIfNeeded(json, user.getEmail(), FIELD_EMAIL, fields); writeIfNeeded(json, user.isActive(), FIELD_ACTIVE, fields); writeIfNeeded(json, user.isLocal(), FIELD_LOCAL, fields); + writeIfNeeded(json, user.getExternalIdentity(), FIELD_EXTERNAL_IDENTITY, fields); + writeIfNeeded(json, user.getExternalIdentityProvider(), FIELD_EXTERNAL_PROVIDER, fields); writeGroupsIfNeeded(json, groups, fields); writeScmAccountsIfNeeded(json, fields, user); writeTokensCount(json, tokensCount); diff --git a/server/sonar-server/src/main/resources/org/sonar/server/user/ws/current-example.json b/server/sonar-server/src/main/resources/org/sonar/server/user/ws/current-example.json index 4a6ce26ec20..57d6511b5f8 100644 --- a/server/sonar-server/src/main/resources/org/sonar/server/user/ws/current-example.json +++ b/server/sonar-server/src/main/resources/org/sonar/server/user/ws/current-example.json @@ -4,6 +4,8 @@ "name": "Obiwan Kenobi", "email": "obiwan.kenobi@starwars.com", "local": true, + "externalIdentity": "obiwan.kenobi", + "externalProvider": "sonarqube", "scmAccounts": [ "obiwan:github", "obiwan:bitbucket" diff --git a/server/sonar-server/src/main/resources/org/sonar/server/user/ws/search-example.json b/server/sonar-server/src/main/resources/org/sonar/server/user/ws/search-example.json index 21b96a064ca..1746fe7b4c6 100644 --- a/server/sonar-server/src/main/resources/org/sonar/server/user/ws/search-example.json +++ b/server/sonar-server/src/main/resources/org/sonar/server/user/ws/search-example.json @@ -11,7 +11,9 @@ "sonar-administrators" ], "tokensCount": 1, - "local": true + "local": true, + "externalIdentity": "fmallet", + "externalProvider": "sonarqube" }, { "login": "sbrandhof", @@ -26,7 +28,9 @@ "sonar-users" ], "tokensCount": 3, - "local": false + "local": false, + "externalIdentity": "sbrandhof@ldap.com", + "externalProvider": "LDAP" } ] } diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/ws/CurrentActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/user/ws/CurrentActionTest.java index 50d73e96b03..0bf0cb397da 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/user/ws/CurrentActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/user/ws/CurrentActionTest.java @@ -61,6 +61,9 @@ public class CurrentActionTest { .setGlobalPermissions(GlobalPermissions.ALL.toArray(new String[0])); UserDto obiwan = userDb.insertUser( newUserDto("obiwan.kenobi", "Obiwan Kenobi", "obiwan.kenobi@starwars.com") + .setLocal(true) + .setExternalIdentity("obiwan.kenobi") + .setExternalIdentityProvider("sonarqube") .setScmAccounts(newArrayList("obiwan:github", "obiwan:bitbucket"))); GroupDto jedi = groupDb.insertGroup(newGroupDto().setName("Jedi")); GroupDto rebel = groupDb.insertGroup(newGroupDto().setName("Rebel")); diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/ws/SearchActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/user/ws/SearchActionTest.java index 86c377eb49f..ee48a84a72e 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/user/ws/SearchActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/user/ws/SearchActionTest.java @@ -32,6 +32,7 @@ import org.sonar.core.permission.GlobalPermissions; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.DbTester; +import org.sonar.db.user.GroupDbTester; import org.sonar.db.user.GroupDto; import org.sonar.db.user.UserDbTester; import org.sonar.db.user.UserDto; @@ -43,11 +44,14 @@ import org.sonar.server.user.index.UserIndex; import org.sonar.server.user.index.UserIndexDefinition; import org.sonar.server.ws.WsTester; +import static com.google.common.collect.Lists.newArrayList; +import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.db.user.GroupTesting.newGroupDto; import static org.sonar.db.user.UserTesting.newUserDto; import static org.sonar.db.user.UserTokenTesting.newUserToken; - +import static org.sonar.test.JsonAssert.assertJson; public class SearchActionTest { @@ -58,6 +62,7 @@ public class SearchActionTest { @Rule public DbTester db = DbTester.create(System2.INSTANCE); UserDbTester userDb = new UserDbTester(db); + GroupDbTester groupDb = new GroupDbTester(db); DbClient dbClient = db.getDbClient(); final DbSession dbSession = db.getSession(); @@ -71,6 +76,37 @@ public class SearchActionTest { ws = new WsTester(new UsersWs(new SearchAction(index, dbClient, new UserJsonWriter(userSession)))); } + @Test + public void search_json_example() throws Exception { + UserDto fmallet = userDb.insertUser(newUserDto("fmallet", "Freddy Mallet", "f@m.com") + .setActive(true) + .setLocal(true) + .setScmAccounts(emptyList())); + UserDto simon = userDb.insertUser(newUserDto("sbrandhof", "Simon", "s.brandhof@company.tld") + .setActive(true) + .setLocal(false) + .setExternalIdentity("sbrandhof@ldap.com") + .setExternalIdentityProvider("LDAP") + .setScmAccounts(newArrayList("simon.brandhof", "s.brandhof@company.tld"))); + GroupDto sonarUsers = groupDb.insertGroup(newGroupDto().setName("sonar-users")); + GroupDto sonarAdministrators = groupDb.insertGroup(newGroupDto().setName("sonar-administrators")); + dbClient.userGroupDao().insert(dbSession, new UserGroupDto().setUserId(simon.getId()).setGroupId(sonarUsers.getId())); + dbClient.userGroupDao().insert(dbSession, new UserGroupDto().setUserId(fmallet.getId()).setGroupId(sonarUsers.getId())); + dbClient.userGroupDao().insert(dbSession, new UserGroupDto().setUserId(fmallet.getId()).setGroupId(sonarAdministrators.getId())); + + for (int i = 0; i < 3; i++) { + dbClient.userTokenDao().insert(dbSession, newUserToken().setLogin(simon.getLogin())); + } + dbClient.userTokenDao().insert(dbSession, newUserToken().setLogin(fmallet.getLogin())); + db.commit(); + esTester.putDocuments(UserIndexDefinition.INDEX, UserIndexDefinition.TYPE_USER, toUserDoc(fmallet), toUserDoc(simon)); + loginAsAdmin(); + + String response = ws.newGetRequest("api/users", "search").execute().outputAsString(); + + assertJson(response).isSimilarTo(getClass().getResource("search-example.json")); + } + @Test public void search_empty() throws Exception { ws.newGetRequest("api/users", "search").execute().assertJson(getClass(), "empty.json"); @@ -88,8 +124,7 @@ public class SearchActionTest { injectUsers(5); UserDto user = userDb.insertUser( newUserDto("user-%_%-login", "user-name", "user@mail.com") - .setScmAccounts("user1") - ); + .setScmAccounts("user1")); esTester.putDocuments(UserIndexDefinition.INDEX, UserIndexDefinition.TYPE_USER, new UserDoc() .setActive(true) @@ -184,7 +219,7 @@ public class SearchActionTest { String name = String.format("User %d", index); List scmAccounts = singletonList(String.format("user-%d", index)); - userDtos.add(dbClient.userDao().insert(dbSession, new UserDto() + UserDto userDto = dbClient.userDao().insert(dbSession, new UserDto() .setActive(true) .setCreatedAt(createdAt) .setEmail(email) @@ -192,16 +227,12 @@ public class SearchActionTest { .setName(name) .setScmAccounts(scmAccounts) .setLocal(true) - .setUpdatedAt(createdAt))); + .setExternalIdentity(login) + .setExternalIdentityProvider("sonarqube") + .setUpdatedAt(createdAt)); + userDtos.add(userDto); - users[index] = new UserDoc() - .setActive(true) - .setCreatedAt(createdAt) - .setEmail(email) - .setLogin(login) - .setName(name) - .setScmAccounts(scmAccounts) - .setUpdatedAt(createdAt); + users[index] = toUserDoc(userDto); for (int tokenIndex = 0; tokenIndex < index; tokenIndex++) { dbClient.userTokenDao().insert(dbSession, newUserToken() @@ -214,6 +245,17 @@ public class SearchActionTest { return userDtos; } + private static UserDoc toUserDoc(UserDto dto) { + return new UserDoc() + .setActive(dto.isActive()) + .setCreatedAt(dto.getCreatedAt()) + .setEmail(dto.getEmail()) + .setLogin(dto.getLogin()) + .setName(dto.getName()) + .setScmAccounts(dto.getScmAccountsAsList()) + .setUpdatedAt(dto.getUpdatedAt()); + } + private void loginAsAdmin() { userSession.login("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); } -- 2.39.5