import java.util.Random;
import javax.annotation.Nullable;
import org.apache.commons.codec.digest.DigestUtils;
+import org.sonar.api.config.Settings;
import org.sonar.api.platform.NewUserHandler;
import org.sonar.api.server.ServerSide;
import org.sonar.api.utils.System2;
import static com.google.common.base.Strings.isNullOrEmpty;
import static com.google.common.collect.Lists.newArrayList;
import static java.lang.String.format;
+import static org.sonar.core.config.CorePropertyDefinitions.ONBOARDING_TUTORIAL_SHOW_TO_NEW_USERS;
import static org.sonar.db.user.UserDto.encryptPassword;
import static org.sonar.server.ws.WsUtils.checkFound;
import static org.sonar.server.ws.WsUtils.checkRequest;
private final DefaultOrganizationProvider defaultOrganizationProvider;
private final OrganizationCreation organizationCreation;
private final DefaultGroupFinder defaultGroupFinder;
+ private final Settings settings;
public UserUpdater(NewUserNotifier newUserNotifier, DbClient dbClient, UserIndexer userIndexer, System2 system2, OrganizationFlags organizationFlags,
- DefaultOrganizationProvider defaultOrganizationProvider, OrganizationCreation organizationCreation, DefaultGroupFinder defaultGroupFinder) {
+ DefaultOrganizationProvider defaultOrganizationProvider, OrganizationCreation organizationCreation, DefaultGroupFinder defaultGroupFinder, Settings settings) {
this.newUserNotifier = newUserNotifier;
this.dbClient = dbClient;
this.userIndexer = userIndexer;
this.defaultOrganizationProvider = defaultOrganizationProvider;
this.organizationCreation = organizationCreation;
this.defaultGroupFinder = defaultGroupFinder;
+ this.settings = settings;
}
public UserDto create(DbSession dbSession, NewUser newUser) {
}
// Hack to allow to change the password of the user
existingUser.setLocal(true);
+ setOnboarded(existingUser);
updateUserDto(dbSession, updateUser, existingUser);
updateUser(dbSession, existingUser);
addUserToDefaultOrganizationAndDefaultGroup(dbSession, existingUser);
}
setExternalIdentity(userDto, newUser.externalIdentity());
+ setOnboarded(userDto);
checkRequest(messages.isEmpty(), messages);
return userDto;
}
}
+ private void setOnboarded(UserDto userDto) {
+ boolean showOnboarding = settings.getBoolean(ONBOARDING_TUTORIAL_SHOW_TO_NEW_USERS);
+ userDto.setOnboarded(!showOnboarding);
+ }
+
private static boolean checkNotEmptyParam(@Nullable String value, String param, List<String> messages) {
if (isNullOrEmpty(value)) {
messages.add(format(Validation.CANT_BE_EMPTY_MESSAGE, param));
private UserIdentityAuthenticator userIdentityAuthenticator = new UserIdentityAuthenticator(
db.getDbClient(),
new UserUpdater(mock(NewUserNotifier.class), db.getDbClient(), mock(UserIndexer.class), System2.INSTANCE, organizationFlags, defaultOrganizationProvider, organizationCreation,
- new DefaultGroupFinder(db.getDbClient())),
+ new DefaultGroupFinder(db.getDbClient()), settings),
defaultOrganizationProvider, organizationFlags, new DefaultGroupFinder(db.getDbClient()));
private HttpServletResponse response = mock(HttpServletResponse.class);
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
+import org.sonar.api.config.MapSettings;
import org.sonar.api.server.authentication.UserIdentity;
import org.sonar.api.utils.System2;
import org.sonar.api.utils.internal.AlwaysIncreasingSystem2;
import static java.util.Arrays.stream;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
+import static org.sonar.core.config.CorePropertyDefinitions.ONBOARDING_TUTORIAL_SHOW_TO_NEW_USERS;
import static org.sonar.db.user.UserTesting.newUserDto;
import static org.sonar.server.authentication.event.AuthenticationEvent.Method;
import static org.sonar.server.authentication.event.AuthenticationEvent.Source;
private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
private OrganizationCreation organizationCreation = mock(OrganizationCreation.class);
private TestOrganizationFlags organizationFlags = TestOrganizationFlags.standalone();
+ private MapSettings settings = new MapSettings();
private UserUpdater userUpdater = new UserUpdater(
mock(NewUserNotifier.class),
organizationFlags,
defaultOrganizationProvider,
organizationCreation,
- new DefaultGroupFinder(db.getDbClient()));
+ new DefaultGroupFinder(db.getDbClient()),
+ settings);
private UserIdentityAuthenticator underTest = new UserIdentityAuthenticator(db.getDbClient(), userUpdater, defaultOrganizationProvider, organizationFlags,
new DefaultGroupFinder(db.getDbClient()));
checkGroupMembership(user, group1);
}
+ @Test
+ public void authenticate_new_user_sets_onboarded_flag_to_false_when_onboarding_setting_is_set_to_true() {
+ organizationFlags.setEnabled(true);
+ settings.setProperty(ONBOARDING_TUTORIAL_SHOW_TO_NEW_USERS, true);
+
+ underTest.authenticate(USER_IDENTITY, IDENTITY_PROVIDER, Source.realm(Method.BASIC, IDENTITY_PROVIDER.getName()));
+
+ assertThat(db.users().selectUserByLogin(USER_LOGIN).get().isOnboarded()).isFalse();
+ }
+
+ @Test
+ public void authenticate_new_user_sets_onboarded_flag_to_true_when_onboarding_setting_is_set_to_false() {
+ organizationFlags.setEnabled(true);
+ settings.setProperty(ONBOARDING_TUTORIAL_SHOW_TO_NEW_USERS, false);
+
+ underTest.authenticate(USER_IDENTITY, IDENTITY_PROVIDER, Source.realm(Method.BASIC, IDENTITY_PROVIDER.getName()));
+
+ assertThat(db.users().selectUserByLogin(USER_LOGIN).get().isOnboarded()).isTrue();
+ }
+
@Test
public void authenticate_existing_user() throws Exception {
db.users().insertUser(newUserDto()
import com.google.common.collect.Multimap;
import java.util.List;
import org.elasticsearch.search.SearchHit;
-import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.config.MapSettings;
import org.sonar.api.platform.NewUserHandler;
import org.sonar.api.utils.System2;
+import org.sonar.api.utils.internal.TestSystem2;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
+import static org.sonar.core.config.CorePropertyDefinitions.ONBOARDING_TUTORIAL_SHOW_TO_NEW_USERS;
import static org.sonar.db.user.UserTesting.newDisabledUser;
import static org.sonar.db.user.UserTesting.newLocalUser;
import static org.sonar.db.user.UserTesting.newUserDto;
private static final long PAST = 1000000000000L;
private static final String DEFAULT_LOGIN = "marius";
- private System2 system2 = mock(System2.class);
+ private System2 system2 = new TestSystem2().setNow(NOW);
@Rule
public ExpectedException expectedException = ExpectedException.none();
private OrganizationCreation organizationCreation = mock(OrganizationCreation.class);
private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
private TestOrganizationFlags organizationFlags = TestOrganizationFlags.standalone();
+ private MapSettings settings = new MapSettings();
private UserUpdater underTest = new UserUpdater(newUserNotifier, dbClient, userIndexer, system2, organizationFlags, defaultOrganizationProvider, organizationCreation,
- new DefaultGroupFinder(dbClient));
-
- @Before
- public void setUp() {
- when(system2.now()).thenReturn(NOW);
- }
+ new DefaultGroupFinder(dbClient), settings);
@Test
public void create_user() {
entry("email", "user@mail.com"));
}
+ @Test
+ public void create_user_with_minimum_fields() {
+ createDefaultGroup();
+
+ underTest.create(db.getSession(), NewUser.builder()
+ .setLogin("us")
+ .setName("User")
+ .build());
+
+ UserDto dto = dbClient.userDao().selectByLogin(session, "us");
+ assertThat(dto.getId()).isNotNull();
+ assertThat(dto.getLogin()).isEqualTo("us");
+ assertThat(dto.getName()).isEqualTo("User");
+ assertThat(dto.getEmail()).isNull();
+ assertThat(dto.getScmAccounts()).isNull();
+ assertThat(dto.isActive()).isTrue();
+ }
+
@Test
public void create_user_with_sq_authority_when_no_authority_set() throws Exception {
createDefaultGroup();
assertThat(dto.getSalt()).isNull();
}
- @Test
- public void create_user_with_minimum_fields() {
- createDefaultGroup();
-
- underTest.create(db.getSession(), NewUser.builder()
- .setLogin("us")
- .setName("User")
- .build());
-
- UserDto dto = dbClient.userDao().selectByLogin(session, "us");
- assertThat(dto.getId()).isNotNull();
- assertThat(dto.getLogin()).isEqualTo("us");
- assertThat(dto.getName()).isEqualTo("User");
- assertThat(dto.getEmail()).isNull();
- assertThat(dto.getScmAccounts()).isNull();
- assertThat(dto.isActive()).isTrue();
- }
-
@Test
public void create_user_with_scm_accounts_containing_blank_or_null_entries() {
createDefaultGroup();
assertThat(dbClient.userDao().selectByLogin(session, "user").getScmAccountsAsList()).containsOnly("u1");
}
+ @Test
+ public void create_not_onboarded_user_if_onboarding_setting_is_set_to_false() {
+ createDefaultGroup();
+ settings.setProperty(ONBOARDING_TUTORIAL_SHOW_TO_NEW_USERS, false);
+
+ underTest.create(db.getSession(), NewUser.builder()
+ .setLogin("user")
+ .setName("User")
+ .build());
+
+ assertThat(dbClient.userDao().selectByLogin(session, "user").isOnboarded()).isTrue();
+ }
+
+ @Test
+ public void create_onboarded_user_if_onboarding_setting_is_set_to_true() {
+ createDefaultGroup();
+ settings.setProperty(ONBOARDING_TUTORIAL_SHOW_TO_NEW_USERS, true);
+
+ UserDto user = underTest.create(db.getSession(), NewUser.builder()
+ .setLogin("user")
+ .setName("User")
+ .build());
+
+ assertThat(dbClient.userDao().selectByLogin(session, "user").isOnboarded()).isFalse();
+ }
+
@Test
public void fail_to_create_user_with_missing_login() {
expectedException.expect(BadRequestException.class);
assertThat(dbClient.organizationMemberDao().select(db.getSession(), defaultOrganizationProvider.get().getUuid(), dto.getId())).isNotPresent();
}
+ @Test
+ public void reactivate_not_onboarded_user_if_onboarding_setting_is_set_to_false() {
+ settings.setProperty(ONBOARDING_TUTORIAL_SHOW_TO_NEW_USERS, false);
+ UserDto user = db.users().insertUser(u -> u
+ .setActive(false)
+ .setOnboarded(false));
+ createDefaultGroup();
+
+ underTest.create(db.getSession(), NewUser.builder()
+ .setLogin(user.getLogin())
+ .setName("name")
+ .build());
+
+ assertThat(dbClient.userDao().selectByLogin(session, user.getLogin()).isOnboarded()).isTrue();
+ }
+
+ @Test
+ public void reactivate_onboarded_user_if_onboarding_setting_is_set_to_true() {
+ settings.setProperty(ONBOARDING_TUTORIAL_SHOW_TO_NEW_USERS, true);
+ UserDto user = db.users().insertUser(u -> u
+ .setActive(false)
+ .setOnboarded(true));
+ createDefaultGroup();
+
+ underTest.create(db.getSession(), NewUser.builder()
+ .setLogin(user.getLogin())
+ .setName("name")
+ .build());
+
+ assertThat(dbClient.userDao().selectByLogin(session, user.getLogin()).isOnboarded()).isFalse();
+ }
+
@Test
public void update_user() {
UserDto user = db.users().insertUser(newLocalUser(DEFAULT_LOGIN, "Marius", "marius@email.com")
organizationFlags,
TestDefaultOrganizationProvider.from(db),
mock(OrganizationCreation.class),
- new DefaultGroupFinder(db.getDbClient()));
+ new DefaultGroupFinder(db.getDbClient()),
+ new MapSettings());
private WsTester tester = new WsTester(new UsersWs(new ChangePasswordAction(db.getDbClient(), userUpdater, userSessionRule)));
private WsActionTester tester = new WsActionTester(new CreateAction(
db.getDbClient(),
new UserUpdater(mock(NewUserNotifier.class), db.getDbClient(), userIndexer, system2, organizationFlags, defaultOrganizationProvider,
- organizationCreation, new DefaultGroupFinder(db.getDbClient())),
+ organizationCreation, new DefaultGroupFinder(db.getDbClient()), settings),
userSessionRule));
@Before
userIndexer = new UserIndexer(dbClient, esTester.client());
tester = new WsTester(new UsersWs(new UpdateAction(
new UserUpdater(mock(NewUserNotifier.class), dbClient, userIndexer, system2, organizationFlags, defaultOrganizationProvider, ORGANIZATION_CREATION_NOT_USED_FOR_UPDATE,
- new DefaultGroupFinder(dbTester.getDbClient())),
+ new DefaultGroupFinder(dbTester.getDbClient()), settings),
userSessionRule,
new UserJsonWriter(userSessionRule), dbClient)));
}