@CheckForNull
private UserDto getUser(DbSession dbSession, UserIdentity userIdentity, IdentityProvider provider) {
- String externalId = userIdentity.getProviderId();
- UserDto user = dbClient.userDao().selectByExternalIdAndIdentityProvider(dbSession, externalId == null ? userIdentity.getProviderLogin() : externalId, provider.getKey());
+ UserDto user = dbClient.userDao().selectByExternalIdAndIdentityProvider(dbSession, getProviderIdOrProviderLogin(userIdentity), provider.getKey());
+ if (user != null) {
+ return user;
+ }
// We need to search by login because :
- // 1. external id may have not been set before,
- // 2. user may have been provisioned,
- // 3. user may have been disabled.
- return user != null ? user : dbClient.userDao().selectByLogin(dbSession, userIdentity.getLogin());
+ // 1. user may have been provisioned,
+ // 2. user may have been disabled.
+ String login = userIdentity.getLogin();
+ if (login == null) {
+ return null;
+ }
+ return dbClient.userDao().selectByLogin(dbSession, login);
+ }
+
+ private UserDto registerNewUser(DbSession dbSession, @Nullable UserDto disabledUser, UserIdentityAuthenticatorParameters authenticatorParameters) {
+ Optional<UserDto> otherUserToIndex = detectEmailUpdate(dbSession, authenticatorParameters);
+ NewUser newUser = createNewUser(authenticatorParameters);
+ if (disabledUser == null) {
+ return userUpdater.createAndCommit(dbSession, newUser, u -> syncGroups(dbSession, authenticatorParameters.getUserIdentity(), u), toArray(otherUserToIndex));
+ }
+ return userUpdater.reactivateAndCommit(dbSession, disabledUser, newUser, u -> syncGroups(dbSession, authenticatorParameters.getUserIdentity(), u), toArray(otherUserToIndex));
}
private UserDto registerExistingUser(DbSession dbSession, UserDto userDto, UserIdentityAuthenticatorParameters authenticatorParameters) {
UpdateUser update = new UpdateUser()
- .setLogin(authenticatorParameters.getUserIdentity().getLogin())
.setEmail(authenticatorParameters.getUserIdentity().getEmail())
.setName(authenticatorParameters.getUserIdentity().getName())
.setExternalIdentity(new ExternalIdentity(
authenticatorParameters.getProvider().getKey(),
authenticatorParameters.getUserIdentity().getProviderLogin(),
authenticatorParameters.getUserIdentity().getProviderId()));
+ String login = authenticatorParameters.getUserIdentity().getLogin();
+ if (login != null) {
+ update.setLogin(login);
+ }
detectLoginUpdate(dbSession, userDto, update, authenticatorParameters);
Optional<UserDto> otherUserToIndex = detectEmailUpdate(dbSession, authenticatorParameters);
userUpdater.updateAndCommit(dbSession, userDto, update, u -> syncGroups(dbSession, authenticatorParameters.getUserIdentity(), u), toArray(otherUserToIndex));
return userDto;
}
- private UserDto registerNewUser(DbSession dbSession, @Nullable UserDto disabledUser, UserIdentityAuthenticatorParameters authenticatorParameters) {
- Optional<UserDto> otherUserToIndex = detectEmailUpdate(dbSession, authenticatorParameters);
- NewUser newUser = createNewUser(authenticatorParameters);
- if (disabledUser == null) {
- return userUpdater.createAndCommit(dbSession, newUser, u -> syncGroups(dbSession, authenticatorParameters.getUserIdentity(), u), toArray(otherUserToIndex));
- }
- return userUpdater.reactivateAndCommit(dbSession, disabledUser, newUser, u -> syncGroups(dbSession, authenticatorParameters.getUserIdentity(), u), toArray(otherUserToIndex));
- }
-
private Optional<UserDto> detectEmailUpdate(DbSession dbSession, UserIdentityAuthenticatorParameters authenticatorParameters) {
String email = authenticatorParameters.getUserIdentity().getEmail();
if (email == null) {
UserDto existingUser = existingUsers.get(0);
if (existingUser == null
|| Objects.equals(existingUser.getLogin(), authenticatorParameters.getUserIdentity().getLogin())
- || (Objects.equals(existingUser.getExternalId(), authenticatorParameters.getUserIdentity().getProviderId())
+ || (Objects.equals(existingUser.getExternalId(), getProviderIdOrProviderLogin(authenticatorParameters.getUserIdentity()))
&& Objects.equals(existingUser.getExternalIdentityProvider(), authenticatorParameters.getProvider().getKey()))) {
return Optional.empty();
}
if (!userIdentity.shouldSyncGroups()) {
return;
}
- String userLogin = userIdentity.getLogin();
+ String userLogin = userDto.getLogin();
Set<String> userGroups = new HashSet<>(dbClient.groupMembershipDao().selectGroupsByLogins(dbSession, singletonList(userLogin)).get(userLogin));
Set<String> identityGroups = userIdentity.getGroups();
LOGGER.debug("List of groups returned by the identity provider '{}'", identityGroups);
if (!authenticatorParameters.getProvider().allowsUsersToSignUp()) {
throw AuthenticationException.newBuilder()
.setSource(authenticatorParameters.getSource())
- .setLogin(authenticatorParameters.getUserIdentity().getLogin())
+ .setLogin(authenticatorParameters.getUserIdentity().getProviderLogin())
.setMessage(format("User signup disabled for provider '%s'", identityProviderKey))
.setPublicMessage(format("'%s' users are not allowed to sign up", identityProviderKey))
.build();
private static AuthenticationException generateExistingEmailError(UserIdentityAuthenticatorParameters authenticatorParameters, String email) {
return AuthenticationException.newBuilder()
.setSource(authenticatorParameters.getSource())
- .setLogin(authenticatorParameters.getUserIdentity().getLogin())
+ .setLogin(authenticatorParameters.getUserIdentity().getProviderLogin())
.setMessage(format("Email '%s' is already used", email))
.setPublicMessage(format(
"You can't sign up because email '%s' is already used by an existing user. This means that you probably already registered with another account.",
.build();
}
+ private static String getProviderIdOrProviderLogin(UserIdentity userIdentity) {
+ String providerId = userIdentity.getProviderId();
+ return providerId == null ? userIdentity.getProviderLogin() : providerId;
+ }
+
}
this.externalIdentity = builder.externalIdentity;
}
+ @CheckForNull
public String login() {
return login;
}
private String password;
private ExternalIdentity externalIdentity;
- public Builder setLogin(String login) {
+ public Builder setLogin(@Nullable String login) {
this.login = login;
return this;
}
import java.util.function.Consumer;
import java.util.stream.Stream;
import javax.annotation.Nullable;
+import org.apache.commons.lang.math.RandomUtils;
import org.sonar.api.config.Configuration;
import org.sonar.api.platform.NewUserHandler;
import org.sonar.api.server.ServerSide;
import static java.util.stream.Stream.concat;
import static org.sonar.api.CoreProperties.DEFAULT_ISSUE_ASSIGNEE;
import static org.sonar.core.config.CorePropertyDefinitions.ONBOARDING_TUTORIAL_SHOW_TO_NEW_USERS;
+import static org.sonar.core.util.Slug.slugify;
import static org.sonar.core.util.stream.MoreCollectors.toList;
import static org.sonar.server.ws.WsUtils.checkRequest;
private static final String NAME_PARAM = "Name";
private static final String EMAIL_PARAM = "Email";
- private static final int LOGIN_MIN_LENGTH = 2;
+ public static final int LOGIN_MIN_LENGTH = 2;
public static final int LOGIN_MAX_LENGTH = 255;
public static final int EMAIL_MAX_LENGTH = 100;
public static final int NAME_MAX_LENGTH = 200;
private final LocalAuthentication localAuthentication;
public UserUpdater(NewUserNotifier newUserNotifier, DbClient dbClient, UserIndexer userIndexer, OrganizationFlags organizationFlags,
- DefaultOrganizationProvider defaultOrganizationProvider, OrganizationUpdater organizationUpdater, DefaultGroupFinder defaultGroupFinder, Configuration config,
- LocalAuthentication localAuthentication) {
+ DefaultOrganizationProvider defaultOrganizationProvider, OrganizationUpdater organizationUpdater, DefaultGroupFinder defaultGroupFinder, Configuration config,
+ LocalAuthentication localAuthentication) {
this.newUserNotifier = newUserNotifier;
this.dbClient = dbClient;
this.userIndexer = userIndexer;
private void reactivateUser(DbSession dbSession, UserDto disabledUser, NewUser newUser) {
UpdateUser updateUser = new UpdateUser()
- .setLogin(newUser.login())
.setName(newUser.name())
.setEmail(newUser.email())
.setScmAccounts(newUser.scmAccounts())
.setExternalIdentity(newUser.externalIdentity());
- if (newUser.password() != null) {
- updateUser.setPassword(newUser.password());
+ String login = newUser.login();
+ if (login != null) {
+ updateUser.setLogin(login);
+ }
+ String password = newUser.password();
+ if (password != null) {
+ updateUser.setPassword(password);
}
setOnboarded(disabledUser);
updateDto(dbSession, updateUser, disabledUser);
List<String> messages = new ArrayList<>();
String login = newUser.login();
- if (validateLoginFormat(login, messages)) {
+ if (isNullOrEmpty(login)) {
+ userDto.setLogin(generateUniqueLogin(dbSession, newUser.name()));
+ } else if (validateLoginFormat(login, messages)) {
checkLoginUniqueness(dbSession, login);
userDto.setLogin(login);
}
return userDto;
}
+ private String generateUniqueLogin(DbSession dbSession, String userName) {
+ String slugName = slugify(userName);
+ for (int i = 0; i < 10; i++) {
+ String login = slugName + RandomUtils.nextInt(100_000);
+ UserDto existingUser = dbClient.userDao().selectByLogin(dbSession, login);
+ if (existingUser == null) {
+ return login;
+ }
+ }
+ throw new IllegalStateException("Cannot create unique login for user name " + userName);
+ }
+
private boolean updateDto(DbSession dbSession, UpdateUser update, UserDto dto) {
List<String> messages = newArrayList();
boolean changed = updateLogin(dbSession, update, dto, messages);
import static org.sonar.server.user.ExternalIdentity.SQ_AUTHORITY;
import static org.sonar.server.user.UserUpdater.EMAIL_MAX_LENGTH;
import static org.sonar.server.user.UserUpdater.LOGIN_MAX_LENGTH;
+import static org.sonar.server.user.UserUpdater.LOGIN_MIN_LENGTH;
import static org.sonar.server.user.UserUpdater.NAME_MAX_LENGTH;
import static org.sonar.server.user.ws.EmailValidator.isValidIfPresent;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
action.createParam(PARAM_LOGIN)
.setRequired(true)
+ .setMinimumLength(LOGIN_MIN_LENGTH)
.setMaximumLength(LOGIN_MAX_LENGTH)
.setDescription("User login")
.setExampleValue("myuser");
checkGroupMembership(user);
}
+ @Test
+ public void authenticate_new_user_generate_login_when_no_login_provided() {
+ organizationFlags.setEnabled(true);
+
+ underTest.authenticate(UserIdentityAuthenticatorParameters.builder()
+ .setUserIdentity(UserIdentity.builder()
+ .setProviderId("ABCD")
+ .setProviderLogin("johndoo")
+ .setName("John Doe")
+ .setEmail("john@email.com")
+ .build())
+ .setProvider(IDENTITY_PROVIDER)
+ .setSource(Source.realm(BASIC, IDENTITY_PROVIDER.getName()))
+ .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
+ .setUpdateLoginStrategy(UpdateLoginStrategy.ALLOW)
+ .build());
+
+ UserDto user = db.getDbClient().userDao().selectByEmail(db.getSession(), "john@email.com").get(0);
+ assertThat(user).isNotNull();
+ assertThat(user.isActive()).isTrue();
+ assertThat(user.getLogin()).isNotEqualTo("John Doe").startsWith("john-doe");
+ assertThat(user.getEmail()).isEqualTo("john@email.com");
+ assertThat(user.getExternalLogin()).isEqualTo("johndoo");
+ assertThat(user.getExternalIdentityProvider()).isEqualTo("github");
+ assertThat(user.getExternalId()).isEqualTo("ABCD");
+ }
+
@Test
public void authenticate_new_user_with_groups() {
organizationFlags.setEnabled(true);
Source source = Source.realm(AuthenticationEvent.Method.FORM, IDENTITY_PROVIDER.getName());
expectedException.expect(authenticationException().from(source)
- .withLogin(USER_IDENTITY.getLogin())
+ .withLogin(USER_IDENTITY.getProviderLogin())
.andPublicMessage("You can't sign up because email 'john@email.com' is already used by an existing user. " +
"This means that you probably already registered with another account."));
expectedException.expectMessage("Email 'john@email.com' is already used");
Source source = Source.realm(AuthenticationEvent.Method.FORM, IDENTITY_PROVIDER.getName());
expectedException.expect(authenticationException().from(source)
- .withLogin(USER_IDENTITY.getLogin())
+ .withLogin(USER_IDENTITY.getProviderLogin())
.andPublicMessage("You can't sign up because email 'john@email.com' is already used by an existing user. " +
"This means that you probably already registered with another account."));
expectedException.expectMessage("Email 'john@email.com' is already used");
.setAllowsUsersToSignUp(false);
Source source = Source.realm(AuthenticationEvent.Method.FORM, identityProvider.getName());
- expectedException.expect(authenticationException().from(source).withLogin(USER_IDENTITY.getLogin()).andPublicMessage("'github' users are not allowed to sign up"));
+ expectedException.expect(authenticationException().from(source).withLogin(USER_IDENTITY.getProviderLogin()).andPublicMessage("'github' users are not allowed to sign up"));
expectedException.expectMessage("User signup disabled for provider 'github'");
underTest.authenticate(UserIdentityAuthenticatorParameters.builder()
}
@Test
- public void authenticate_existing_user_matching_login() {
+ public void authenticate_and_update_existing_user_matching_login() {
db.users().insertUser(u -> u
.setLogin(USER_LOGIN)
.setName("Old name")
}
@Test
- public void authenticate_existing_user_matching_external_id() {
+ public void authenticate_and_update_existing_user_matching_external_id() {
UserDto user = db.users().insertUser(u -> u
.setLogin("Old login")
.setName("Old name")
true);
}
+ @Test
+ public void authenticate_existing_user_and_update_only_identity_provider_key() {
+ UserDto user = db.users().insertUser(u -> u
+ .setLogin(USER_LOGIN)
+ .setName(USER_IDENTITY.getName())
+ .setEmail(USER_IDENTITY.getEmail())
+ .setExternalId(USER_IDENTITY.getProviderId())
+ .setExternalLogin(USER_IDENTITY.getProviderLogin())
+ .setExternalIdentityProvider("old identity provider"));
+
+ underTest.authenticate(UserIdentityAuthenticatorParameters.builder()
+ .setUserIdentity(USER_IDENTITY)
+ .setProvider(IDENTITY_PROVIDER)
+ .setSource(Source.local(BASIC))
+ .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
+ .setUpdateLoginStrategy(UpdateLoginStrategy.ALLOW)
+ .build());
+
+ assertThat(db.getDbClient().userDao().selectByUuid(db.getSession(), user.getUuid()))
+ .extracting(UserDto::getLogin, UserDto::getName, UserDto::getEmail, UserDto::getExternalId, UserDto::getExternalLogin, UserDto::getExternalIdentityProvider,
+ UserDto::isActive)
+ .containsExactlyInAnyOrder(USER_LOGIN, USER_IDENTITY.getName(), USER_IDENTITY.getEmail(), USER_IDENTITY.getProviderId(), USER_IDENTITY.getProviderLogin(),
+ IDENTITY_PROVIDER.getKey(),
+ true);
+ }
+
@Test
public void authenticate_existing_user_matching_login_when_external_id_is_null() {
UserDto user = db.users().insertUser(u -> u
.contains(user.getLogin(), "John", "john@email.com", "johndoo", "johndoo", "github", true);
}
+ @Test
+ public void authenticate_existing_user_when_login_is_not_provided() {
+ UserDto user = db.users().insertUser(u -> u.setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
+
+ underTest.authenticate(UserIdentityAuthenticatorParameters.builder()
+ .setUserIdentity(UserIdentity.builder()
+ .setProviderId(user.getExternalId())
+ .setProviderLogin(user.getExternalLogin())
+ // No login provided
+ .setName(user.getName())
+ .setEmail(user.getEmail())
+ .build())
+ .setProvider(IDENTITY_PROVIDER)
+ .setSource(Source.local(BASIC))
+ .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
+ .setUpdateLoginStrategy(UpdateLoginStrategy.ALLOW)
+ .build());
+
+ // No new user is created
+ assertThat(db.countRowsOfTable(db.getSession(), "users")).isEqualTo(1);
+ assertThat(db.getDbClient().userDao().selectByUuid(db.getSession(), user.getUuid()))
+ .extracting(UserDto::getLogin, UserDto::getName, UserDto::getEmail, UserDto::getExternalId, UserDto::getExternalLogin, UserDto::getExternalIdentityProvider,
+ UserDto::isActive)
+ .contains(user.getLogin(), user.getName(), user.getEmail(), user.getExternalId(), user.getExternalLogin(), user.getExternalIdentityProvider(), true);
+ }
+
@Test
public void authenticate_existing_user_with_login_update_and_strategy_is_ALLOW() {
UserDto user = db.users().insertUser(u -> u
.build();
expectedException.expect(authenticationException().from(Source.realm(AuthenticationEvent.Method.FORM, IDENTITY_PROVIDER.getName()))
- .withLogin(userIdentity.getLogin())
+ .withLogin(userIdentity.getProviderLogin())
.andPublicMessage("You can't sign up because email 'john@email.com' is already used by an existing user. " +
"This means that you probably already registered with another account."));
expectedException.expectMessage("Email 'john@email.com' is already used");
@Test
public void does_not_fail_to_authenticate_user_when_email_has_not_changed_and_strategy_is_FORBID() {
organizationFlags.setEnabled(true);
- UserDto currentUser = db.users().insertUser(u -> u.setEmail("john@email.com"));
+ UserDto currentUser = db.users().insertUser(u -> u.setEmail("john@email.com")
+ .setExternalIdentityProvider(IDENTITY_PROVIDER.getKey()));
UserIdentity userIdentity = UserIdentity.builder()
.setLogin(currentUser.getLogin())
- .setProviderLogin("johndoo")
+ .setProviderId(currentUser.getExternalId())
+ .setProviderLogin(currentUser.getExternalLogin())
.setName("John")
.setEmail("john@email.com")
.build();
assertThat(dto.isActive()).isTrue();
}
+ @Test
+ public void create_user_generates_unique_login_no_login_provided() {
+ createDefaultGroup();
+
+ UserDto user = underTest.createAndCommit(db.getSession(), NewUser.builder()
+ .setName("John Doe")
+ .build(), u -> {
+ });
+
+ UserDto dto = dbClient.userDao().selectByLogin(session, user.getLogin());
+ assertThat(dto.getLogin()).startsWith("john-doe");
+ assertThat(dto.getName()).isEqualTo("John Doe");
+ }
+
+ @Test
+ public void create_user_generates_unique_login_when_login_is_emnpty() {
+ createDefaultGroup();
+
+ UserDto user = underTest.createAndCommit(db.getSession(), NewUser.builder()
+ .setLogin("")
+ .setName("John Doe")
+ .build(), u -> {
+ });
+
+ UserDto dto = dbClient.userDao().selectByLogin(session, user.getLogin());
+ assertThat(dto.getLogin()).startsWith("john-doe");
+ assertThat(dto.getName()).isEqualTo("John Doe");
+ }
+
@Test
public void create_user_with_sq_authority_when_no_authority_set() {
createDefaultGroup();
underTest.createAndCommit(db.getSession(), NewUser.builder()
.setLogin("user")
.setName("User")
- .setExternalIdentity(new ExternalIdentity(SQ_AUTHORITY, "user", null))
+ .setExternalIdentity(new ExternalIdentity(SQ_AUTHORITY, "user", "user"))
.build(), u -> {
});
assertThat(es.getIds(UserIndexDefinition.INDEX_TYPE_USER)).containsExactlyInAnyOrder(created.getUuid(), otherUser.getUuid());
}
- @Test
- public void fail_to_create_user_with_missing_login() {
- expectedException.expect(BadRequestException.class);
- expectedException.expectMessage("Login can't be empty");
-
- underTest.createAndCommit(db.getSession(), NewUser.builder()
- .setLogin(null)
- .setName("Marius")
- .setEmail("marius@mail.com")
- .setPassword("password")
- .build(), u -> {
- });
- }
-
@Test
public void fail_to_create_user_with_invalid_login() {
expectedException.expect(BadRequestException.class);
});
fail();
} catch (BadRequestException e) {
- assertThat(e.errors()).hasSize(3);
+ assertThat(e.errors()).containsExactlyInAnyOrder("Name can't be empty", "Password can't be empty");
}
}
.setName("User")
.setExternalIdentity(new ExternalIdentity(existingUser.getExternalIdentityProvider(), existingUser.getExternalLogin(), existingUser.getExternalId()))
.build(), u -> {
- });
+ });
}
@Test
assertThat(reloaded.getUpdatedAt()).isGreaterThan(user.getCreatedAt());
}
+ @Test
+ public void reactivate_user_without_providing_login() {
+ UserDto user = db.users().insertUser(u -> u.setActive(false));
+ createDefaultGroup();
+
+ underTest.reactivateAndCommit(db.getSession(), user, NewUser.builder()
+ .setName("Marius2")
+ .setEmail("marius2@mail.com")
+ .setPassword("password2")
+ .build(),
+ u -> {
+ });
+
+ UserDto reloaded = dbClient.userDao().selectByUuid(session, user.getUuid());
+ assertThat(reloaded.isActive()).isTrue();
+ assertThat(reloaded.getLogin()).isEqualTo(user.getLogin());
+ }
+
@Test
public void reactivate_user_not_having_password() {
UserDto user = db.users().insertDisabledUser(u -> u.setSalt(null).setCryptedPassword(null));
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.user.NewUserNotifier;
import org.sonar.server.user.UserUpdater;
-import org.sonar.server.user.index.UserIndex;
import org.sonar.server.user.index.UserIndexDefinition;
import org.sonar.server.user.index.UserIndexer;
import org.sonar.server.user.ws.CreateAction.CreateRequest;
@Rule
public ExpectedException expectedException = ExpectedException.none();
- private UserIndex index = new UserIndex(es.client(), System2.INSTANCE);
private UserIndexer userIndexer = new UserIndexer(db.getDbClient(), es.client());
private GroupDto defaultGroupInDefaultOrg;
private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
.build());
}
+ @Test
+ public void fail_when_login_is_too_short() {
+ logInAsSystemAdministrator();
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("'login' length (1) is shorter than the minimum authorized (2)");
+ call(CreateRequest.builder()
+ .setLogin("a")
+ .setName("John")
+ .setPassword("1234")
+ .build());
+ }
+
@Test
public void fail_when_missing_name() {
logInAsSystemAdministrator();
}
@Test
- public void throw_ForbiddenException_if_not_system_administrator() throws Exception {
+ public void throw_ForbiddenException_if_not_system_administrator() {
userSessionRule.logIn().setNonSystemAdministrator();
expectedException.expect(ForbiddenException.class);
*/
package org.sonar.server.user.ws;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.function.Consumer;
import java.util.stream.IntStream;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.server.ws.WebService.Param;
import org.sonar.api.utils.System2;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
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.es.EsTester;
import org.sonar.server.issue.ws.AvatarResolverImpl;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.user.index.UserIndex;
import org.sonar.server.user.index.UserIndexer;
-import org.sonar.server.ws.WsTester;
+import org.sonar.server.ws.WsActionTester;
+import org.sonarqube.ws.Common.Paging;
+import org.sonarqube.ws.Users.SearchWsResponse;
+import org.sonarqube.ws.Users.SearchWsResponse.User;
-import static com.google.common.collect.Lists.newArrayList;
+import static java.util.Arrays.asList;
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.assertj.core.api.Assertions.tuple;
import static org.sonar.test.JsonAssert.assertJson;
public class SearchActionTest {
- private System2 system2 = System2.INSTANCE;
-
@Rule
public EsTester es = EsTester.create();
public UserSessionRule userSession = UserSessionRule.standalone();
@Rule
- public DbTester db = DbTester.create(system2);
+ public DbTester db = DbTester.create();
- private DbClient dbClient = db.getDbClient();
- private DbSession dbSession = db.getSession();
- private UserIndex index = new UserIndex(es.client(), system2);
- private UserIndexer userIndexer = new UserIndexer(dbClient, es.client());
- private WsTester ws = new WsTester(new UsersWs(new SearchAction(userSession, index, dbClient, new AvatarResolverImpl())));
+ private UserIndex index = new UserIndex(es.client(), System2.INSTANCE);
+ private UserIndexer userIndexer = new UserIndexer(db.getDbClient(), es.client());
+ private WsActionTester ws = new WsActionTester(new SearchAction(userSession, index, db.getDbClient(), new AvatarResolverImpl()));
@Test
- public void test_json_example() throws Exception {
- UserDto fmallet = db.users().insertUser(u -> u.setLogin("fmallet").setName("Freddy Mallet").setEmail("f@m.com")
- .setActive(true)
- .setLocal(true)
- .setScmAccounts(emptyList())
- .setExternalLogin("fmallet")
- .setExternalIdentityProvider("sonarqube"));
- UserDto simon = db.users().insertUser(u -> u.setLogin("sbrandhof").setName("Simon").setEmail("s.brandhof@company.tld")
- .setActive(true)
- .setLocal(false)
- .setExternalLogin("sbrandhof@ldap.com")
- .setExternalIdentityProvider("LDAP")
- .setScmAccounts(newArrayList("simon.brandhof", "s.brandhof@company.tld")));
- GroupDto sonarUsers = db.users().insertGroup(newGroupDto().setName("sonar-users"));
- GroupDto sonarAdministrators = db.users().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()));
- db.commit();
- for (int i = 0; i < 3; i++) {
- db.users().insertToken(simon);
- }
- db.users().insertToken(fmallet);
+ public void search_for_all_users() {
+ UserDto user1 = db.users().insertUser();
+ UserDto user2 = db.users().insertUser();
userIndexer.indexOnStartup(null);
- loginAsSystemAdministrator();
-
- String response = ws.newGetRequest("api/users", "search").execute().outputAsString();
-
- assertJson(response).isSimilarTo(getClass().getResource("search-example.json"));
- }
-
- @Test
- public void search_empty() throws Exception {
- loginAsSimpleUser();
- ws.newGetRequest("api/users", "search").execute().assertJson("{\n" +
- " \"paging\": {\n" +
- " \"pageIndex\": 1,\n" +
- " \"pageSize\": 50,\n" +
- " \"total\": 0\n" +
- " },\n" +
- " \"users\": []\n" +
- "}");
- }
+ userSession.logIn();
- @Test
- public void search_without_parameters() throws Exception {
- loginAsSimpleUser();
- injectUsers(5);
+ SearchWsResponse response = ws.newRequest()
+ .executeProtobuf(SearchWsResponse.class);
- ws.newGetRequest("api/users", "search").execute().assertJson(getClass(), "five_users.json");
+ assertThat(response.getUsersList())
+ .extracting(User::getLogin, User::getName)
+ .containsExactlyInAnyOrder(
+ tuple(user1.getLogin(), user1.getName()),
+ tuple(user2.getLogin(), user2.getName()));
}
@Test
- public void search_with_query() throws Exception {
- loginAsSimpleUser();
- injectUsers(5);
+ public void search_with_query() {
+ userSession.logIn();
UserDto user = db.users().insertUser(u -> u
.setLogin("user-%_%-login")
.setName("user-name")
.setScmAccounts(singletonList("user1")));
userIndexer.indexOnStartup(null);
- ws.newGetRequest("api/users", "search").setParam("q", "user-%_%-").execute().assertJson(getClass(), "user_one.json");
- ws.newGetRequest("api/users", "search").setParam("q", "user@MAIL.com").execute().assertJson(getClass(), "user_one.json");
- ws.newGetRequest("api/users", "search").setParam("q", "user-name").execute().assertJson(getClass(), "user_one.json");
+ assertThat(ws.newRequest()
+ .setParam("q", "user-%_%-")
+ .executeProtobuf(SearchWsResponse.class).getUsersList())
+ .extracting(User::getLogin)
+ .containsExactlyInAnyOrder(user.getLogin());
+ assertThat(ws.newRequest()
+ .setParam("q", "user@MAIL.com")
+ .executeProtobuf(SearchWsResponse.class).getUsersList())
+ .extracting(User::getLogin)
+ .containsExactlyInAnyOrder(user.getLogin());
+ assertThat(ws.newRequest()
+ .setParam("q", "user-name")
+ .executeProtobuf(SearchWsResponse.class).getUsersList())
+ .extracting(User::getLogin)
+ .containsExactlyInAnyOrder(user.getLogin());
}
@Test
- public void search_with_paging() throws Exception {
- loginAsSimpleUser();
- injectUsers(10);
+ public void return_avatar() {
+ UserDto user = db.users().insertUser(u -> u.setEmail("john@doe.com"));
+ userIndexer.indexOnStartup(null);
+ userSession.logIn();
+
+ SearchWsResponse response = ws.newRequest()
+ .executeProtobuf(SearchWsResponse.class);
- ws.newGetRequest("api/users", "search").setParam(Param.PAGE_SIZE, "5").execute().assertJson(getClass(), "page_one.json");
- ws.newGetRequest("api/users", "search").setParam(Param.PAGE_SIZE, "5").setParam(Param.PAGE, "2").execute().assertJson(getClass(), "page_two.json");
+ assertThat(response.getUsersList())
+ .extracting(User::getLogin, User::getAvatar)
+ .containsExactlyInAnyOrder(tuple(user.getLogin(), "6a6c19fea4a3676970167ce51f39e6ee"));
}
@Test
- public void search_with_fields() throws Exception {
- loginAsSimpleUser();
- injectUsers(1);
-
- assertThat(ws.newGetRequest("api/users", "search").execute().outputAsString())
- .contains("login")
- .contains("name")
- .contains("avatar")
- .contains("scmAccounts")
- .doesNotContain("groups");
-
- assertThat(ws.newGetRequest("api/users", "search").setParam(Param.FIELDS, "").execute().outputAsString())
- .contains("login")
- .contains("name")
- .contains("avatar")
- .contains("scmAccounts")
- .doesNotContain("groups");
-
- assertThat(ws.newGetRequest("api/users", "search").setParam(Param.FIELDS, "scmAccounts").execute().outputAsString())
- .contains("login")
- .doesNotContain("name")
- .doesNotContain("avatar")
- .contains("scmAccounts")
- .doesNotContain("groups");
-
- assertThat(ws.newGetRequest("api/users", "search").setParam(Param.FIELDS, "groups").execute().outputAsString())
- .contains("login")
- .doesNotContain("name")
- .doesNotContain("avatar")
- .doesNotContain("scmAccounts")
- .doesNotContain("groups");
-
- loginAsSystemAdministrator();
-
- assertThat(ws.newGetRequest("api/users", "search").execute().outputAsString())
- .contains("login")
- .contains("name")
- .contains("email")
- .contains("avatar")
- .contains("scmAccounts")
- .contains("groups");
-
- assertThat(ws.newGetRequest("api/users", "search").setParam(Param.FIELDS, "groups").execute().outputAsString())
- .contains("login")
- .doesNotContain("name")
- .doesNotContain("email")
- .doesNotContain("avatar")
- .doesNotContain("scmAccounts")
- .contains("groups");
+ public void return_scm_accounts() {
+ UserDto user = db.users().insertUser(u -> u.setScmAccounts(asList("john1", "john2")));
+ userIndexer.indexOnStartup(null);
+ userSession.logIn();
+
+ SearchWsResponse response = ws.newRequest()
+ .executeProtobuf(SearchWsResponse.class);
+
+ assertThat(response.getUsersList())
+ .extracting(User::getLogin, u -> u.getScmAccounts().getScmAccountsList())
+ .containsExactlyInAnyOrder(tuple(user.getLogin(), asList("john1", "john2")));
}
@Test
- public void search_with_groups() throws Exception {
- loginAsSystemAdministrator();
- injectUsers(1);
+ public void return_tokens_count() {
+ UserDto user = db.users().insertUser();
+ db.users().insertToken(user);
+ db.users().insertToken(user);
+ userIndexer.indexOnStartup(null);
+ userSession.logIn();
+
+ SearchWsResponse response = ws.newRequest()
+ .executeProtobuf(SearchWsResponse.class);
- ws.newGetRequest("api/users", "search").execute().assertJson(getClass(), "user_with_groups.json");
+ assertThat(response.getUsersList())
+ .extracting(User::getLogin, User::getTokensCount)
+ .containsExactlyInAnyOrder(tuple(user.getLogin(), 2));
}
@Test
- public void does_not_return_email_when_not_when_system_administer() throws Exception {
- loginAsSimpleUser();
- insertUser(user -> user.setLogin("john").setName("John").setEmail("john@email.com"));
-
- ws.newGetRequest("api/users", "search").execute().assertJson(
- "{" +
- " \"users\": [" +
- " {" +
- " \"login\": \"john\"," +
- " \"name\": \"John\"," +
- " \"avatar\": \"41193cdbffbf06be0cdf231b28c54b18\"" +
- " }" +
- " ]" +
- "}");
+ public void return_email_only_when_system_administer() {
+ UserDto user = db.users().insertUser();
+ userIndexer.indexOnStartup(null);
+
+ userSession.logIn().setSystemAdministrator();
+ assertThat(ws.newRequest()
+ .executeProtobuf(SearchWsResponse.class).getUsersList())
+ .extracting(User::getLogin, User::getEmail)
+ .containsExactlyInAnyOrder(tuple(user.getLogin(), user.getEmail()));
+
+ userSession.logIn();
+ assertThat(ws.newRequest()
+ .executeProtobuf(SearchWsResponse.class).getUsersList())
+ .extracting(User::getLogin, User::hasEmail)
+ .containsExactlyInAnyOrder(tuple(user.getLogin(), false));
}
@Test
- public void return_email_and_avatar_when_system_administer() throws Exception {
- loginAsSystemAdministrator();
- insertUser(user -> user.setLogin("john").setName("John").setEmail("john@email.com"));
-
- ws.newGetRequest("api/users", "search").execute().assertJson(
- "{" +
- " \"users\": [" +
- " {" +
- " \"login\": \"john\"," +
- " \"name\": \"John\"," +
- " \"email\": \"john@email.com\"," +
- " \"avatar\": \"41193cdbffbf06be0cdf231b28c54b18\"" +
- " }" +
- " ]" +
- "}");
+ public void return_user_not_having_email() {
+ UserDto user = db.users().insertUser(u -> u.setEmail(null));
+ userIndexer.indexOnStartup(null);
+ userSession.logIn().setSystemAdministrator();
+
+ SearchWsResponse response = ws.newRequest()
+ .executeProtobuf(SearchWsResponse.class);
+
+ assertThat(response.getUsersList())
+ .extracting(User::getLogin, User::hasEmail)
+ .containsExactlyInAnyOrder(tuple(user.getLogin(), false));
}
@Test
- public void does_not_fail_when_user_has_no_email() throws Exception {
- loginAsSystemAdministrator();
- insertUser(user -> user.setLogin("john").setName("John").setEmail(null));
-
- ws.newGetRequest("api/users", "search").execute().assertJson(
- "{" +
- " \"users\": [" +
- " {" +
- " \"login\": \"john\"," +
- " \"name\": \"John\"" +
- " }" +
- " ]" +
- "}");
+ public void return_groups_only_when_system_administer() {
+ UserDto user = db.users().insertUser();
+ GroupDto group1 = db.users().insertGroup(db.getDefaultOrganization(), "group1");
+ GroupDto group2 = db.users().insertGroup(db.getDefaultOrganization(), "group2");
+ GroupDto group3 = db.users().insertGroup(db.getDefaultOrganization(), "group3");
+ db.users().insertMember(group1, user);
+ db.users().insertMember(group2, user);
+ userIndexer.indexOnStartup(null);
+
+ userSession.logIn().setSystemAdministrator();
+ assertThat(ws.newRequest()
+ .executeProtobuf(SearchWsResponse.class).getUsersList())
+ .extracting(User::getLogin, u -> u.getGroups().getGroupsList())
+ .containsExactlyInAnyOrder(tuple(user.getLogin(), asList(group1.getName(), group2.getName())));
+
+ userSession.logIn();
+ assertThat(ws.newRequest()
+ .executeProtobuf(SearchWsResponse.class).getUsersList())
+ .extracting(User::getLogin, User::hasGroups)
+ .containsExactlyInAnyOrder(tuple(user.getLogin(), false));
}
@Test
- public void only_return_login_and_name_when_not_logged() throws Exception {
+ public void only_return_login_and_name_when_not_logged() {
+ UserDto user = db.users().insertUser();
+ db.users().insertToken(user);
+ GroupDto group = db.users().insertGroup(db.getDefaultOrganization());
+ db.users().insertMember(group, user);
+ userIndexer.indexOnStartup(null);
userSession.anonymous();
- db.users().insertUser(u -> u.setLogin("john").setName("John").setEmail("john@email.com"));
- dbSession.commit();
- userIndexer.indexOnStartup(null);
+ SearchWsResponse response = ws.newRequest()
+ .executeProtobuf(SearchWsResponse.class);
- ws.newGetRequest("api/users", "search").execute().assertJson(
- "{" +
- " \"users\": [" +
- " {" +
- " \"login\": \"john\"," +
- " \"name\": \"John\"" +
- " }" +
- " ]" +
- "}");
+ assertThat(response.getUsersList())
+ .extracting(User::getLogin, User::getName, User::hasTokensCount, User::hasScmAccounts, User::hasAvatar, User::hasGroups)
+ .containsExactlyInAnyOrder(tuple(user.getLogin(), user.getName(), false, false, false, false));
}
- private List<UserDto> injectUsers(int numberOfUsers) {
- List<UserDto> userDtos = new ArrayList<>();
- GroupDto group1 = db.users().insertGroup(newGroupDto().setName("sonar-users"));
- GroupDto group2 = db.users().insertGroup(newGroupDto().setName("sonar-admins"));
- for (int index = 0; index < numberOfUsers; index++) {
- String email = String.format("user-%d@mail.com", index);
- String login = String.format("user-%d", index);
- String name = String.format("User %d", index);
- List<String> scmAccounts = singletonList(String.format("user-%d", index));
-
- UserDto userDto = db.users().insertUser(u -> u.setActive(true)
- .setEmail(email)
- .setLogin(login)
- .setName(name)
- .setScmAccounts(scmAccounts)
- .setLocal(true)
- .setExternalLogin(login)
- .setExternalIdentityProvider("sonarqube"));
- userDtos.add(userDto);
-
- IntStream.range(0, index).forEach(i -> db.users().insertToken(userDto, t -> t.setName(String.format("%s-%d", login, i))));
- db.users().insertMember(group1, userDto);
- db.users().insertMember(group2, userDto);
- }
+ @Test
+ public void search_with_fields() {
+ UserDto user = db.users().insertUser();
+ GroupDto group = db.users().insertGroup(db.getDefaultOrganization());
+ db.users().insertMember(group, user);
userIndexer.indexOnStartup(null);
- return userDtos;
+ userSession.logIn().setSystemAdministrator();
+
+ assertThat(ws.newRequest()
+ .setParam(Param.FIELDS, "scmAccounts")
+ .executeProtobuf(SearchWsResponse.class)
+ .getUsersList())
+ .extracting(User::getLogin, User::hasName, User::hasScmAccounts, User::hasAvatar, User::hasGroups)
+ .containsExactlyInAnyOrder(tuple(user.getLogin(), false, true, false, false));
+ assertThat(ws.newRequest()
+ .setParam(Param.FIELDS, "groups")
+ .executeProtobuf(SearchWsResponse.class)
+ .getUsersList())
+ .extracting(User::getLogin, User::hasName, User::hasScmAccounts, User::hasAvatar, User::hasGroups)
+ .containsExactlyInAnyOrder(tuple(user.getLogin(), false, false, false, true));
+ assertThat(ws.newRequest()
+ .setParam(Param.FIELDS, "")
+ .executeProtobuf(SearchWsResponse.class)
+ .getUsersList())
+ .extracting(User::getLogin, User::hasName, User::hasScmAccounts, User::hasAvatar, User::hasGroups)
+ .containsExactlyInAnyOrder(tuple(user.getLogin(), true, true, true, true));
+ assertThat(ws.newRequest()
+ .executeProtobuf(SearchWsResponse.class)
+ .getUsersList())
+ .extracting(User::getLogin, User::hasName, User::hasScmAccounts, User::hasAvatar, User::hasGroups)
+ .containsExactlyInAnyOrder(tuple(user.getLogin(), true, true, true, true));
}
- private UserDto insertUser(Consumer<UserDto> populateUserDto) {
- UserDto user = db.users().insertUser(populateUserDto);
+ @Test
+ public void search_with_paging() {
+ userSession.logIn();
+ IntStream.rangeClosed(0, 9).forEach(i -> db.users().insertUser(u -> u.setLogin("user-" + i).setName("User " + i)));
userIndexer.indexOnStartup(null);
- return user;
- }
- private void loginAsSystemAdministrator() {
- userSession.logIn().setSystemAdministrator();
+ SearchWsResponse response = ws.newRequest()
+ .setParam(Param.PAGE_SIZE, "5")
+ .executeProtobuf(SearchWsResponse.class);
+ assertThat(response.getUsersList())
+ .extracting(User::getLogin)
+ .containsExactly("user-0", "user-1", "user-2", "user-3", "user-4");
+ assertThat(response.getPaging())
+ .extracting(Paging::getPageIndex, Paging::getPageSize, Paging::getTotal)
+ .containsExactly(1, 5, 10);
+
+ response = ws.newRequest()
+ .setParam(Param.PAGE_SIZE, "5")
+ .setParam(Param.PAGE, "2")
+ .executeProtobuf(SearchWsResponse.class);
+ assertThat(response.getUsersList())
+ .extracting(User::getLogin)
+ .containsExactly("user-5", "user-6", "user-7", "user-8", "user-9");
+ assertThat(response.getPaging())
+ .extracting(Paging::getPageIndex, Paging::getPageSize, Paging::getTotal)
+ .containsExactly(2, 5, 10);
}
- private void loginAsSimpleUser() {
+ @Test
+ public void return_empty_result_when_no_user() {
userSession.logIn();
+
+ SearchWsResponse response = ws.newRequest()
+ .executeProtobuf(SearchWsResponse.class);
+
+ assertThat(response.getUsersList()).isEmpty();
+ assertThat(response.getPaging().getTotal()).isZero();
+ }
+
+ @Test
+ public void test_json_example() {
+ UserDto fmallet = db.users().insertUser(u -> u.setLogin("fmallet").setName("Freddy Mallet").setEmail("f@m.com")
+ .setLocal(true)
+ .setScmAccounts(emptyList())
+ .setExternalLogin("fmallet")
+ .setExternalIdentityProvider("sonarqube"));
+ UserDto simon = db.users().insertUser(u -> u.setLogin("sbrandhof").setName("Simon").setEmail("s.brandhof@company.tld")
+ .setLocal(false)
+ .setExternalLogin("sbrandhof@ldap.com")
+ .setExternalIdentityProvider("LDAP")
+ .setScmAccounts(asList("simon.brandhof", "s.brandhof@company.tld")));
+ GroupDto sonarUsers = db.users().insertGroup(db.getDefaultOrganization(), "sonar-users");
+ GroupDto sonarAdministrators = db.users().insertGroup(db.getDefaultOrganization(), "sonar-administrators");
+ db.users().insertMember(sonarUsers, simon);
+ db.users().insertMember(sonarUsers, fmallet);
+ db.users().insertMember(sonarAdministrators, fmallet);
+ db.users().insertToken(simon);
+ db.users().insertToken(simon);
+ db.users().insertToken(simon);
+ db.users().insertToken(fmallet);
+ userIndexer.indexOnStartup(null);
+ userSession.logIn().setSystemAdministrator();
+
+ String response = ws.newRequest().execute().getInput();
+
+ assertJson(response).isSimilarTo(getClass().getResource("search-example.json"));
}
}
+++ /dev/null
-{
- "paging": {
- "pageIndex": 1,
- "pageSize": 50,
- "total": 5
- },
- "users": [
- {
- "login": "user-0",
- "name": "User 0",
- "avatar": "7df9eb5cfa0b534812fd8e77c06bdccf",
- "scmAccounts": [
- "user-0"
- ],
- "tokensCount": 0,
- "local": true
- },
- {
- "login": "user-1",
- "name": "User 1",
- "avatar": "071241157c57e21956c73081138ecb6e",
- "scmAccounts": [
- "user-1"
- ],
- "tokensCount": 1,
- "local": true
- },
- {
- "login": "user-2",
- "name": "User 2",
- "avatar": "25c3b9b5609693983e1f9ed80820d7aa",
- "scmAccounts": [
- "user-2"
- ],
- "tokensCount": 2,
- "local": true
- },
- {
- "login": "user-3",
- "name": "User 3",
- "avatar": "61061cc5edb4b771d22509bc47eeaccf",
- "scmAccounts": [
- "user-3"
- ],
- "tokensCount": 3,
- "local": true
- },
- {
- "login": "user-4",
- "name": "User 4",
- "avatar": "07a317a07eb517ddf02bc592491ddf1b",
- "scmAccounts": [
- "user-4"
- ],
- "tokensCount": 4,
- "local": true
- }
- ]
-}
+++ /dev/null
-{
- "paging": {
- "pageIndex": 1,
- "pageSize": 5,
- "total": 10
- },
- "users": [
- {
- "login": "user-0"
- },
- {
- "login": "user-1"
- },
- {
- "login": "user-2"
- },
- {
- "login": "user-3"
- },
- {
- "login": "user-4"
- }
- ]
-}
+++ /dev/null
-{
- "paging": {
- "pageIndex": 2,
- "pageSize": 5,
- "total": 10
- },
- "users": [
- {
- "login": "user-5"
- },
- {
- "login": "user-6"
- },
- {
- "login": "user-7"
- },
- {
- "login": "user-8"
- },
- {
- "login": "user-9"
- }
- ]
-}
+++ /dev/null
-{
- "paging": {
- "pageIndex": 1,
- "pageSize": 50,
- "total": 1
- },
- "users": [
- {
- "login": "user-%_%-login",
- "name": "user-name",
- "avatar": "6ad193f57f79ac444c3621370da955e9",
- "active": true,
- "scmAccounts": [
- "user1"
- ],
- "tokensCount": 0,
- "local": true
- }
- ]
-}
+++ /dev/null
-{
- "paging": {
- "pageIndex": 1,
- "pageSize": 50,
- "total": 1
- },
- "users": [
- {
- "login": "user-0",
- "name": "User 0",
- "email": "user-0@mail.com",
- "scmAccounts": [
- "user-0"
- ],
- "groups": ["sonar-admins", "sonar-users"],
- "local": true
- }
- ]
-}
import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Objects.requireNonNull;
+import static org.apache.commons.lang.StringUtils.isBlank;
import static org.apache.commons.lang.StringUtils.isNotBlank;
/**
@Immutable
public final class UserIdentity {
+ @Nullable
private final String id;
private final String providerLogin;
+ @Nullable
private final String login;
private final String name;
+ @Nullable
private final String email;
private final boolean groupsProvided;
private final Set<String> groups;
}
/**
- * Non-blank user login, unique for the SonarQube platform.
+ * User login, unique for the SonarQube platform.
* If two {@link IdentityProvider} define two users with the same login, then users are considered as identical.
+ *
+ * Since 7.4, a unique login will be generated if result is null and the user referenced by {@link #getProviderId()}
+ * or {@link #getProviderLogin()} does not already exist.
*/
+ @CheckForNull
public String getLogin() {
return login;
}
}
/**
- * @see UserIdentity#getLogin() ()
+ * @see UserIdentity#getLogin()
*/
- public Builder setLogin(String login) {
+ public Builder setLogin(@Nullable String login) {
this.login = login;
return this;
}
checkArgument(providerLogin.length() <= 255, "Provider login size is incorrect (maximum 255 characters)");
}
- private static void validateLogin(String login) {
- checkArgument(isNotBlank(login), "User login must not be blank");
- checkArgument(login.length() <= 255 && login.length() >= 2, "User login size is incorrect (Between 2 and 255 characters)");
+ private static void validateLogin(@Nullable String login) {
+ checkArgument(isBlank(login) || (login.length() <= 255 && login.length() >= 2), "User login size is incorrect (Between 2 and 255 characters)");
}
private static void validateName(String name) {
public void create_user_with_minimum_fields() {
UserIdentity underTest = UserIdentity.builder()
.setProviderLogin("john")
- .setLogin("1234")
.setName("John")
.build();
- assertThat(underTest.getProviderId()).isNull();
assertThat(underTest.getProviderLogin()).isEqualTo("john");
- assertThat(underTest.getLogin()).isEqualTo("1234");
assertThat(underTest.getName()).isEqualTo("John");
+ assertThat(underTest.getProviderId()).isNull();
+ assertThat(underTest.getLogin()).isNull();
assertThat(underTest.getEmail()).isNull();
assertThat(underTest.shouldSyncGroups()).isFalse();
assertThat(underTest.getGroups()).isEmpty();
.build();
}
- @Test
- public void fail_when_login_is_empty() {
- thrown.expect(IllegalArgumentException.class);
- thrown.expectMessage("User login must not be blank");
- UserIdentity.builder()
- .setProviderLogin("john")
- .setLogin("")
- .setName("John")
- .setEmail("john@email.com")
- .build();
- }
-
@Test
public void fail_when_login_is_too_long() {
thrown.expect(IllegalArgumentException.class);