package org.sonar.server.user.ws;
import java.util.Collection;
-import java.util.Optional;
+import java.util.List;
+import java.util.stream.Collectors;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService.NewController;
-import org.sonar.api.utils.text.JsonWriter;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.permission.OrganizationPermission;
import org.sonar.db.user.UserDto;
import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.server.user.UserSession;
+import org.sonarqube.ws.WsUsers.CurrentWsResponse;
-import static com.google.common.base.Strings.isNullOrEmpty;
-import static java.util.Collections.emptyList;
+import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.base.Strings.emptyToNull;
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;
+import static org.sonar.core.util.Protobuf.setNullable;
+import static org.sonar.server.ws.WsUtils.writeProtobuf;
+import static org.sonarqube.ws.WsUsers.CurrentWsResponse.Permissions;
+import static org.sonarqube.ws.WsUsers.CurrentWsResponse.newBuilder;
public class CurrentAction implements UsersWsAction {
private final UserSession userSession;
@Override
public void handle(Request request, Response response) throws Exception {
- try (DbSession dbSession = dbClient.openSession(false)) {
- Optional<UserDto> user = Optional.empty();
- Collection<String> groups = emptyList();
- if (userSession.isLoggedIn()) {
- user = selectCurrentUser(dbSession);
- groups = selectGroups(dbSession);
+ if (userSession.isLoggedIn()) {
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ writeProtobuf(toWsResponse(dbSession, userSession.getLogin()), request, response);
}
- writeResponse(response, user, groups);
+ } else {
+ writeProtobuf(newBuilder()
+ .setIsLoggedIn(false)
+ .setPermissions(Permissions.newBuilder().addAllGlobal(getGlobalPermissions()).build())
+ .build(),
+ request, response);
}
}
- private Optional<UserDto> selectCurrentUser(DbSession dbSession) {
- return Optional.ofNullable(dbClient.userDao().selectActiveUserByLogin(dbSession, userSession.getLogin()));
+ private CurrentWsResponse toWsResponse(DbSession dbSession, String userLogin) {
+ UserDto user = dbClient.userDao().selectActiveUserByLogin(dbSession, userLogin);
+ checkState(user != null, "User login '%s' cannot be found", userLogin);
+ Collection<String> groups = dbClient.groupMembershipDao().selectGroupsByLogins(dbSession, singletonList(userLogin)).get(userLogin);
+
+ CurrentWsResponse.Builder builder = newBuilder()
+ .setIsLoggedIn(true)
+ .setLogin(user.getLogin())
+ .setName(user.getName())
+ .setLocal(user.isLocal())
+ .addAllGroups(groups)
+ .addAllScmAccounts(user.getScmAccountsAsList())
+ .setPermissions(Permissions.newBuilder().addAllGlobal(getGlobalPermissions()).build());
+ setNullable(emptyToNull(user.getEmail()), builder::setEmail);
+ setNullable(user.getExternalIdentity(), builder::setExternalIdentity);
+ setNullable(user.getExternalIdentityProvider(), builder::setExternalProvider);
+ return builder.build();
}
- private Collection<String> selectGroups(DbSession dbSession) {
- return dbClient.groupMembershipDao().selectGroupsByLogins(dbSession, singletonList(userSession.getLogin()))
- .get(userSession.getLogin());
- }
-
- private void writeResponse(Response response, Optional<UserDto> user, Collection<String> groups) {
- JsonWriter json = response.newJsonWriter().beginObject();
- writeUserDetails(json, user, groups);
- json.endObject().close();
- }
-
- private void writeUserDetails(JsonWriter json, Optional<UserDto> optionalUser, Collection<String> groups) {
- json
- .prop("isLoggedIn", userSession.isLoggedIn())
- .prop("login", userSession.getLogin())
- .prop("name", userSession.getName());
- if (optionalUser.isPresent()) {
- UserDto user = optionalUser.get();
- if (!isNullOrEmpty(user.getEmail())) {
- 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);
- writeGroups(json, groups);
- writePermissions(json);
- }
-
- private static void writeScmAccounts(JsonWriter json, Optional<UserDto> optionalUser) {
- json.name("scmAccounts");
- json.beginArray();
- if (optionalUser.isPresent()) {
- for (String scmAccount : optionalUser.get().getScmAccountsAsList()) {
- json.value(scmAccount);
- }
- }
- json.endArray();
- }
-
- private static void writeGroups(JsonWriter json, Collection<String> groups) {
- json.name("groups");
- json.beginArray();
- for (String group : groups) {
- json.value(group);
- }
- json.endArray();
- }
-
- private void writePermissions(JsonWriter json) {
- json.name("permissions").beginObject();
- writeGlobalPermissions(json);
- json.endObject();
- }
-
- private void writeGlobalPermissions(JsonWriter json) {
- json.name("global").beginArray();
-
+ private List<String> getGlobalPermissions() {
String defaultOrganizationUuid = defaultOrganizationProvider.get().getUuid();
- OrganizationPermission.all()
+ return OrganizationPermission.all()
.filter(permission -> userSession.hasPermission(permission, defaultOrganizationUuid))
- .forEach(permission -> json.value(permission.getKey()));
-
- json.endArray();
+ .map(OrganizationPermission::getKey)
+ .collect(Collectors.toList());
}
-
}
*/
package org.sonar.server.user.ws;
-import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.System2;
import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
-import org.sonar.db.user.GroupDto;
import org.sonar.db.user.UserDto;
-import org.sonar.db.user.UserGroupDto;
import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.server.organization.TestDefaultOrganizationProvider;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.WsActionTester;
+import org.sonarqube.ws.WsUsers.CurrentWsResponse;
import static com.google.common.collect.Lists.newArrayList;
-import static org.sonar.db.user.GroupTesting.newGroupDto;
-import static org.sonar.db.user.UserTesting.newUserDto;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.db.permission.OrganizationPermission.ADMINISTER;
import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_PROFILES;
+import static org.sonar.db.permission.OrganizationPermission.PROVISION_PROJECTS;
import static org.sonar.db.permission.OrganizationPermission.SCAN;
+import static org.sonar.db.user.GroupTesting.newGroupDto;
import static org.sonar.test.JsonAssert.assertJson;
public class CurrentActionTest {
public UserSessionRule userSessionRule = UserSessionRule.standalone();
@Rule
public DbTester db = DbTester.create(System2.INSTANCE);
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
private DbClient dbClient = db.getDbClient();
private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
- private WsActionTester ws;
+ private WsActionTester ws = new WsActionTester(new CurrentAction(userSessionRule, dbClient, defaultOrganizationProvider));
+
+ @Test
+ public void return_user_info() {
+ db.users().insertUser(user -> user
+ .setLogin("obiwan.kenobi")
+ .setName("Obiwan Kenobi")
+ .setEmail("obiwan.kenobi@starwars.com")
+ .setLocal(true)
+ .setExternalIdentity("obiwan")
+ .setExternalIdentityProvider("sonarqube")
+ .setScmAccounts(newArrayList("obiwan:github", "obiwan:bitbucket")));
+ userSessionRule.logIn("obiwan.kenobi");
+
+ CurrentWsResponse response = call();
- @Before
- public void before() {
- ws = new WsActionTester(new CurrentAction(userSessionRule, dbClient, defaultOrganizationProvider));
+ assertThat(response)
+ .extracting(CurrentWsResponse::getIsLoggedIn, CurrentWsResponse::getLogin, CurrentWsResponse::getName, CurrentWsResponse::getEmail, CurrentWsResponse::getLocal,
+ CurrentWsResponse::getExternalIdentity, CurrentWsResponse::getExternalProvider, CurrentWsResponse::getScmAccountsList)
+ .containsExactly(true, "obiwan.kenobi", "Obiwan Kenobi", "obiwan.kenobi@starwars.com", true, "obiwan", "sonarqube",
+ newArrayList("obiwan:github", "obiwan:bitbucket"));
}
@Test
- public void json_example() {
- userSessionRule.logIn("obiwan.kenobi").setName("Obiwan Kenobi");
+ public void return_minimal_user_info() {
+ db.users().insertUser(user -> user
+ .setLogin("obiwan.kenobi")
+ .setName("Obiwan Kenobi")
+ .setEmail(null)
+ .setLocal(true)
+ .setExternalIdentity("obiwan")
+ .setExternalIdentityProvider("sonarqube")
+ .setScmAccounts((String) null));
+ userSessionRule.logIn("obiwan.kenobi");
+
+ CurrentWsResponse response = call();
+
+ assertThat(response)
+ .extracting(CurrentWsResponse::getIsLoggedIn, CurrentWsResponse::getLogin, CurrentWsResponse::getName, CurrentWsResponse::getLocal,
+ CurrentWsResponse::getExternalIdentity, CurrentWsResponse::getExternalProvider)
+ .containsExactly(true, "obiwan.kenobi", "Obiwan Kenobi", true, "obiwan", "sonarqube");
+ assertThat(response.hasEmail()).isFalse();
+ assertThat(response.getScmAccountsList()).isEmpty();
+ assertThat(response.getGroupsList()).isEmpty();
+ assertThat(response.getPermissions().getGlobalList()).isEmpty();
+ }
+
+ @Test
+ public void convert_empty_email_to_null() {
+ db.users().insertUser(user -> user
+ .setLogin("obiwan.kenobi")
+ .setEmail(""));
+ userSessionRule.logIn("obiwan.kenobi");
- // permissions on default organization
+ CurrentWsResponse response = call();
+
+ assertThat(response.hasEmail()).isFalse();
+ }
+
+ @Test
+ public void return_group_membership() {
+ UserDto user = db.users().insertUser();
+ userSessionRule.logIn(user.getLogin());
+ db.users().insertMember(db.users().insertGroup(newGroupDto().setName("Jedi")), user);
+ db.users().insertMember(db.users().insertGroup(newGroupDto().setName("Rebel")), user);
+
+ CurrentWsResponse response = call();
+
+ assertThat(response.getGroupsList()).containsOnly("Jedi", "Rebel");
+ }
+
+ @Test
+ public void return_permissions() {
+ UserDto user = db.users().insertUser();
userSessionRule
+ .logIn(user.getLogin())
+ // permissions on default organization
.addPermission(SCAN, db.getDefaultOrganization())
- .addPermission(ADMINISTER_QUALITY_PROFILES, db.getDefaultOrganization());
+ .addPermission(ADMINISTER_QUALITY_PROFILES, db.getDefaultOrganization())
+ // permissions on other organizations are ignored
+ .addPermission(ADMINISTER, db.organizations().insert());
- // permissions on other organizations are ignored
- userSessionRule.addPermission(ADMINISTER, db.organizations().insert());
-
- UserDto obiwan = db.users().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 = db.users().insertGroup(newGroupDto().setName("Jedi"));
- GroupDto rebel = db.users().insertGroup(newGroupDto().setName("Rebel"));
- db.users().insertGroup(newGroupDto().setName("Sith"));
- dbClient.userGroupDao().insert(db.getSession(), new UserGroupDto()
- .setUserId(obiwan.getId())
- .setGroupId(jedi.getId()));
- dbClient.userGroupDao().insert(db.getSession(), new UserGroupDto()
- .setUserId(obiwan.getId())
- .setGroupId(rebel.getId()));
- db.commit();
+ CurrentWsResponse response = call();
- String response = ws.newRequest().execute().getInput();
+ assertThat(response.getPermissions().getGlobalList()).containsOnly("profileadmin", "scan");
+ }
- assertJson(response).isSimilarTo(getClass().getResource("current-example.json"));
+ @Test
+ public void fail_with_ISE_when_user_login_in_db_does_not_exist() {
+ db.users().insertUser(usert -> usert.setLogin("another"));
+ userSessionRule.logIn("obiwan.kenobi");
+
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("User login 'obiwan.kenobi' cannot be found");
+
+ call();
}
@Test
public void anonymous() {
- userSessionRule.anonymous();
+ userSessionRule
+ .anonymous()
+ .addPermission(SCAN, db.getDefaultOrganization())
+ .addPermission(PROVISION_PROJECTS, db.getDefaultOrganization());
+
+ CurrentWsResponse response = call();
+
+ assertThat(response.getIsLoggedIn()).isFalse();
+ assertThat(response.getPermissions().getGlobalList()).containsOnly("scan", "provisioning");
+ assertThat(response)
+ .extracting(CurrentWsResponse::hasLogin, CurrentWsResponse::hasName, CurrentWsResponse::hasEmail, CurrentWsResponse::hasLocal,
+ CurrentWsResponse::hasExternalIdentity, CurrentWsResponse::hasExternalProvider)
+ .containsOnly(false);
+ assertThat(response.getScmAccountsList()).isEmpty();
+ assertThat(response.getGroupsList()).isEmpty();
+ }
+
+ @Test
+ public void json_example() {
+ userSessionRule
+ .logIn("obiwan.kenobi")
+ .addPermission(SCAN, db.getDefaultOrganization())
+ .addPermission(ADMINISTER_QUALITY_PROFILES, db.getDefaultOrganization());
+ UserDto obiwan = db.users().insertUser(user -> user
+ .setLogin("obiwan.kenobi")
+ .setName("Obiwan Kenobi")
+ .setEmail("obiwan.kenobi@starwars.com")
+ .setLocal(true)
+ .setExternalIdentity("obiwan.kenobi")
+ .setExternalIdentityProvider("sonarqube")
+ .setScmAccounts(newArrayList("obiwan:github", "obiwan:bitbucket")));
+ db.users().insertMember(db.users().insertGroup(newGroupDto().setName("Jedi")), obiwan);
+ db.users().insertMember(db.users().insertGroup(newGroupDto().setName("Rebel")), obiwan);
String response = ws.newRequest().execute().getInput();
- assertJson(response).isSimilarTo(getClass().getResource("CurrentActionTest/anonymous.json"));
+ assertJson(response).isSimilarTo(getClass().getResource("current-example.json"));
}
+
+ @Test
+ public void test_definition() {
+ WebService.Action definition = ws.getDef();
+ assertThat(definition.key()).isEqualTo("current");
+ assertThat(definition.description()).isEqualTo("Get the details of the current authenticated user.");
+ assertThat(definition.since()).isEqualTo("5.2");
+ assertThat(definition.isPost()).isFalse();
+ assertThat(definition.isInternal()).isTrue();
+ assertThat(definition.responseExampleAsString()).isNotEmpty();
+ assertThat(definition.params()).isEmpty();
+ assertThat(definition.changelog()).isEmpty();
+ }
+
+ private CurrentWsResponse call() {
+ return ws.newRequest().executeProtobuf(CurrentWsResponse.class);
+ }
+
}