]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-8752 SONAR-8753 create org for new users
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Thu, 9 Feb 2017 14:17:54 +0000 (15:17 +0100)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Fri, 10 Feb 2017 17:29:37 +0000 (18:29 +0100)
both when user is created with api/users/create or at first authentication
this feature is controlled by property sonar.organizations.createPersonalOrg

server/sonar-server/src/main/java/org/sonar/server/organization/OrganizationCreation.java
server/sonar-server/src/main/java/org/sonar/server/organization/OrganizationCreationImpl.java
server/sonar-server/src/main/java/org/sonar/server/user/UserUpdater.java
server/sonar-server/src/test/java/org/sonar/server/authentication/SsoAuthenticatorTest.java
server/sonar-server/src/test/java/org/sonar/server/authentication/UserIdentityAuthenticatorTest.java
server/sonar-server/src/test/java/org/sonar/server/organization/OrganizationCreationImplTest.java
server/sonar-server/src/test/java/org/sonar/server/organization/ws/CreateActionTest.java
server/sonar-server/src/test/java/org/sonar/server/user/UserUpdaterTest.java
server/sonar-server/src/test/java/org/sonar/server/user/ws/ChangePasswordActionTest.java
server/sonar-server/src/test/java/org/sonar/server/user/ws/CreateActionTest.java
server/sonar-server/src/test/java/org/sonar/server/user/ws/UpdateActionTest.java

index 0fc54a78ab6d685474d2dc1cd17ab5cb78e63db3..c1caec8c5e1067df36a2dec5f9144504f1b57256 100644 (file)
  */
 package org.sonar.server.organization;
 
+import java.util.Optional;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 import org.sonar.api.web.UserRole;
 import org.sonar.db.DbSession;
 import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.user.UserDto;
 
 import static java.util.Objects.requireNonNull;
 
@@ -33,8 +35,8 @@ public interface OrganizationCreation {
   String PERM_TEMPLATE_DESCRIPTION_PATTERN = "Default permission template of organization %s";
 
   /**
-   * Create a new Organization with the specified properties and of which the specified user will assign Administer
-   * Organization permission.
+   * Create a new non guarded organization with the specified properties and of which the specified user will assign
+   * Administer Organization permission.
    * <p>
    * This method does several operations at once:
    * <ol>
@@ -61,8 +63,28 @@ public interface OrganizationCreation {
    */
   OrganizationDto create(DbSession dbSession, long createUserId, NewOrganization newOrganization) throws KeyConflictException;
 
+  /**
+   * Create a new guarded organization which details are based on the login of the specified User.
+   * <p>
+   * This method create the organization and its associated elements in exactly the same was as
+   * {@link #create(DbSession, long, NewOrganization)} with the organization's details computed from the
+   * user's login:
+   * <ul>
+   *   <li>key: generated from the user's login</li>
+   *   <li>name: the user's login</li>
+   *   <li>description, url and avatar: null</li>
+   * </ul>
+   * </p>
+   *
+   * @return the created organization or empty if feature is disabled
+   *
+   * @throws IllegalArgumentException if any field of {@code newOrganization} is invalid according to {@link OrganizationValidation}
+   * @throws IllegalStateException if an organization with the key generated from the login already exists
+   */
+  Optional<OrganizationDto> createForUser(DbSession dbSession, UserDto newUser);
+
   final class KeyConflictException extends Exception {
-    public KeyConflictException(String message) {
+    KeyConflictException(String message) {
       super(message);
     }
   }
index a802de4696081274a3352a72e82cbd9154d3ac22..fc842cf492b5ce252dc352f6d8dbde1ce051953b 100644 (file)
 package org.sonar.server.organization;
 
 import java.util.Date;
+import java.util.Optional;
 import javax.annotation.Nullable;
+import org.sonar.api.config.Settings;
 import org.sonar.api.utils.System2;
 import org.sonar.api.web.UserRole;
+import org.sonar.core.config.CorePropertyDefinitions;
 import org.sonar.core.permission.GlobalPermissions;
 import org.sonar.core.util.UuidFactory;
 import org.sonar.db.DbClient;
@@ -32,23 +35,28 @@ import org.sonar.db.organization.OrganizationDto;
 import org.sonar.db.permission.GroupPermissionDto;
 import org.sonar.db.permission.template.PermissionTemplateDto;
 import org.sonar.db.user.GroupDto;
+import org.sonar.db.user.UserDto;
 import org.sonar.db.user.UserGroupDto;
 
+import static com.google.common.base.Preconditions.checkState;
 import static java.lang.String.format;
 import static java.util.Objects.requireNonNull;
+import static org.sonar.server.organization.OrganizationCreation.NewOrganization.newOrganizationBuilder;
 
 public class OrganizationCreationImpl implements OrganizationCreation {
   private final DbClient dbClient;
   private final System2 system2;
   private final UuidFactory uuidFactory;
   private final OrganizationValidation organizationValidation;
+  private final Settings settings;
 
   public OrganizationCreationImpl(DbClient dbClient, System2 system2, UuidFactory uuidFactory,
-    OrganizationValidation organizationValidation) {
+    OrganizationValidation organizationValidation, Settings settings) {
     this.dbClient = dbClient;
     this.system2 = system2;
     this.uuidFactory = uuidFactory;
     this.organizationValidation = organizationValidation;
+    this.settings = settings;
   }
 
   @Override
@@ -59,7 +67,7 @@ public class OrganizationCreationImpl implements OrganizationCreation {
       throw new KeyConflictException(format("Organization key '%s' is already used", key));
     }
 
-    OrganizationDto organization = insertOrganization(dbSession, newOrganization);
+    OrganizationDto organization = insertOrganization(dbSession, newOrganization, false);
     GroupDto group = insertOwnersGroup(dbSession, organization);
     insertDefaultTemplate(dbSession, organization, group);
     addCurrentUserToGroup(dbSession, group, creatorUserId);
@@ -69,6 +77,42 @@ public class OrganizationCreationImpl implements OrganizationCreation {
     return organization;
   }
 
+  @Override
+  public Optional<OrganizationDto> createForUser(DbSession dbSession, UserDto newUser) {
+    if (!isCreatePersonalOrgEnabled()) {
+      return Optional.empty();
+    }
+
+    NewOrganization newOrganization = newOrganizationBuilder()
+      .setKey(organizationValidation.generateKeyFrom(newUser.getLogin()))
+      .setName(toName(newUser.getLogin()))
+      .build();
+    checkState(!organizationKeyIsUsed(dbSession, newOrganization.getKey()),
+      "Can't create organization with key '%s' for new user '%s' because an organization with this key already exists",
+      newOrganization.getKey(),
+      newUser.getLogin());
+
+    OrganizationDto organization = insertOrganization(dbSession, newOrganization, true);
+    GroupDto group = insertOwnersGroup(dbSession, organization);
+    insertDefaultTemplate(dbSession, organization, group);
+    addCurrentUserToGroup(dbSession, group, newUser.getId());
+
+    dbSession.commit();
+
+    return Optional.of(organization);
+  }
+
+  private String toName(String login) {
+    String name = login.substring(0, Math.min(login.length(), OrganizationValidation.NAME_MAX_LENGTH));
+    // should not happen has login can't be less than 2 chars, but we call it for safety
+    organizationValidation.checkName(name);
+    return name;
+  }
+
+  private boolean isCreatePersonalOrgEnabled() {
+    return settings.getBoolean(CorePropertyDefinitions.ORGANIZATIONS_CREATE_PERSONAL_ORG);
+  }
+
   private void validate(NewOrganization newOrganization) {
     requireNonNull(newOrganization, "newOrganization can't be null");
     organizationValidation.checkName(newOrganization.getName());
@@ -78,14 +122,15 @@ public class OrganizationCreationImpl implements OrganizationCreation {
     organizationValidation.checkAvatar(newOrganization.getAvatar());
   }
 
-  private OrganizationDto insertOrganization(DbSession dbSession, NewOrganization newOrganization) {
+  private OrganizationDto insertOrganization(DbSession dbSession, NewOrganization newOrganization, boolean guarded) {
     OrganizationDto res = new OrganizationDto()
       .setUuid(uuidFactory.create())
       .setName(newOrganization.getName())
       .setKey(newOrganization.getKey())
       .setDescription(newOrganization.getDescription())
       .setUrl(newOrganization.getUrl())
-      .setAvatarUrl(newOrganization.getAvatar());
+      .setAvatarUrl(newOrganization.getAvatar())
+      .setGuarded(guarded);
     dbClient.organizationDao().insert(dbSession, res);
     return res;
   }
index be7ffabefe5a278b5fb7c02f42e1fe198ff0b947..688636c5fcf876fc0fc62e380a69226a041ab12f 100644 (file)
@@ -44,6 +44,7 @@ import org.sonar.db.user.UserGroupDto;
 import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.exceptions.ServerException;
 import org.sonar.server.organization.DefaultOrganizationProvider;
+import org.sonar.server.organization.OrganizationCreation;
 import org.sonar.server.user.index.UserIndexer;
 import org.sonar.server.util.Validation;
 
@@ -75,15 +76,17 @@ public class UserUpdater {
   private final UserIndexer userIndexer;
   private final System2 system2;
   private final DefaultOrganizationProvider defaultOrganizationProvider;
+  private final OrganizationCreation organizationCreation;
 
   public UserUpdater(NewUserNotifier newUserNotifier, Settings settings, DbClient dbClient, UserIndexer userIndexer, System2 system2,
-    DefaultOrganizationProvider defaultOrganizationProvider) {
+    DefaultOrganizationProvider defaultOrganizationProvider, OrganizationCreation organizationCreation) {
     this.newUserNotifier = newUserNotifier;
     this.settings = settings;
     this.dbClient = dbClient;
     this.userIndexer = userIndexer;
     this.system2 = system2;
     this.defaultOrganizationProvider = defaultOrganizationProvider;
+    this.organizationCreation = organizationCreation;
   }
 
   public UserDto create(NewUser newUser) {
@@ -358,6 +361,7 @@ public class UserUpdater {
     userDto.setActive(true).setCreatedAt(now).setUpdatedAt(now);
     UserDto res = dbClient.userDao().insert(dbSession, userDto);
     addDefaultGroup(dbSession, userDto);
+    organizationCreation.createForUser(dbSession, userDto);
     dbSession.commit();
     userIndexer.index();
     return res;
index 3fe2d987e68597624bac469cf31c824e173d352d..d1a7cc0f962629d3b1788168121d976c39c778fe 100644 (file)
@@ -41,6 +41,7 @@ import org.sonar.db.user.GroupDto;
 import org.sonar.db.user.UserDto;
 import org.sonar.server.authentication.event.AuthenticationEvent;
 import org.sonar.server.organization.DefaultOrganizationProvider;
+import org.sonar.server.organization.OrganizationCreation;
 import org.sonar.server.organization.TestDefaultOrganizationProvider;
 import org.sonar.server.user.NewUserNotifier;
 import org.sonar.server.user.UserUpdater;
@@ -91,11 +92,12 @@ public class SsoAuthenticatorTest {
 
   private System2 system2 = mock(System2.class);
   private Settings settings = new MapSettings();
+  private OrganizationCreation organizationCreation = mock(OrganizationCreation.class);
 
   private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
   private UserIdentityAuthenticator userIdentityAuthenticator = new UserIdentityAuthenticator(
     db.getDbClient(),
-    new UserUpdater(mock(NewUserNotifier.class), settings, db.getDbClient(), mock(UserIndexer.class), System2.INSTANCE, defaultOrganizationProvider),
+    new UserUpdater(mock(NewUserNotifier.class), settings, db.getDbClient(), mock(UserIndexer.class), System2.INSTANCE, defaultOrganizationProvider, organizationCreation),
     defaultOrganizationProvider);
 
   private HttpServletResponse response = mock(HttpServletResponse.class);
index 15bd4d32c890be17821751db4604d1bc4631fcee..0f17e592ad867f91b5b10ad523bb717e8d6cf2e3 100644 (file)
@@ -36,6 +36,7 @@ import org.sonar.db.organization.OrganizationDto;
 import org.sonar.db.user.GroupDto;
 import org.sonar.db.user.UserDto;
 import org.sonar.server.organization.DefaultOrganizationProvider;
+import org.sonar.server.organization.OrganizationCreation;
 import org.sonar.server.organization.TestDefaultOrganizationProvider;
 import org.sonar.server.user.NewUserNotifier;
 import org.sonar.server.user.UserUpdater;
@@ -75,13 +76,15 @@ public class UserIdentityAuthenticatorTest {
 
   private Settings settings = new MapSettings();
   private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
+  private OrganizationCreation organizationCreation = mock(OrganizationCreation.class);
   private UserUpdater userUpdater = new UserUpdater(
     mock(NewUserNotifier.class),
     settings,
     db.getDbClient(),
     mock(UserIndexer.class),
     System2.INSTANCE,
-    defaultOrganizationProvider);
+    defaultOrganizationProvider,
+      organizationCreation);
   private UserIdentityAuthenticator underTest = new UserIdentityAuthenticator(db.getDbClient(), userUpdater, defaultOrganizationProvider);
   private GroupDto defaultGroup;
 
index 33e817d6a1f7fcab8324d156cab1a11c51dc3659..0933ae201ec7eaa34ec43f49f960ca06a7da3f99 100644 (file)
@@ -24,8 +24,10 @@ import java.util.Optional;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.utils.System2;
 import org.sonar.api.web.UserRole;
+import org.sonar.core.config.CorePropertyDefinitions;
 import org.sonar.core.permission.GlobalPermissions;
 import org.sonar.core.util.UuidFactory;
 import org.sonar.db.DbClient;
@@ -51,6 +53,10 @@ public class OrganizationCreationImplTest {
   private static final long SOME_USER_ID = 1L;
   private static final String SOME_UUID = "org-uuid";
   private static final long SOME_DATE = 12893434L;
+  private static final String A_LOGIN = "a-login";
+  private static final String SLUG_OF_A_LOGIN = "slug-of-a-login";
+  public static final String STRING_64_CHARS = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+
   private OrganizationCreation.NewOrganization FULL_POPULATED_NEW_ORGANIZATION = newOrganizationBuilder()
     .setName("a-name")
     .setKey("a-key")
@@ -72,8 +78,9 @@ public class OrganizationCreationImplTest {
   private DbClient dbClient = dbTester.getDbClient();
   private UuidFactory uuidFactory = mock(UuidFactory.class);
   private OrganizationValidation organizationValidation = mock(OrganizationValidation.class);
+  private MapSettings settings = new MapSettings();
 
-  private OrganizationCreationImpl underTest = new OrganizationCreationImpl(dbClient, system2, uuidFactory, organizationValidation);
+  private OrganizationCreationImpl underTest = new OrganizationCreationImpl(dbClient, system2, uuidFactory, organizationValidation, settings);
 
   @Test
   public void create_throws_NPE_if_NewOrganization_arg_is_null() throws OrganizationCreation.KeyConflictException {
@@ -144,6 +151,7 @@ public class OrganizationCreationImplTest {
     assertThat(organization.getDescription()).isEqualTo(FULL_POPULATED_NEW_ORGANIZATION.getDescription());
     assertThat(organization.getUrl()).isEqualTo(FULL_POPULATED_NEW_ORGANIZATION.getUrl());
     assertThat(organization.getAvatarUrl()).isEqualTo(FULL_POPULATED_NEW_ORGANIZATION.getAvatar());
+     assertThat(organization.isGuarded()).isFalse();
     assertThat(organization.getCreatedAt()).isEqualTo(SOME_DATE);
     assertThat(organization.getUpdatedAt()).isEqualTo(SOME_DATE);
   }
@@ -156,19 +164,7 @@ public class OrganizationCreationImplTest {
 
     underTest.create(dbSession, user.getId(), FULL_POPULATED_NEW_ORGANIZATION);
 
-    OrganizationDto organization = dbClient.organizationDao().selectByKey(dbSession, FULL_POPULATED_NEW_ORGANIZATION.getKey()).get();
-    Optional<GroupDto> groupDtoOptional = dbClient.groupDao().selectByName(dbSession, organization.getUuid(), "Owners");
-    assertThat(groupDtoOptional).isNotEmpty();
-    GroupDto groupDto = groupDtoOptional.get();
-    assertThat(groupDto.getDescription()).isEqualTo("Owners of organization " + FULL_POPULATED_NEW_ORGANIZATION.getName());
-    assertThat(dbClient.groupPermissionDao().selectGlobalPermissionsOfGroup(dbSession, groupDto.getOrganizationUuid(), groupDto.getId()))
-      .containsOnly(GlobalPermissions.ALL.toArray(new String[GlobalPermissions.ALL.size()]));
-    List<UserMembershipDto> members = dbClient.groupMembershipDao().selectMembers(
-      dbSession,
-      UserMembershipQuery.builder().groupId(groupDto.getId()).membership(UserMembershipQuery.IN).build(), 0, Integer.MAX_VALUE);
-    assertThat(members)
-      .extracting(UserMembershipDto::getLogin)
-      .containsOnly(user.getLogin());
+    verifyGroupOwners(user, FULL_POPULATED_NEW_ORGANIZATION.getKey(), FULL_POPULATED_NEW_ORGANIZATION.getName());
   }
 
   @Test
@@ -186,6 +182,7 @@ public class OrganizationCreationImplTest {
     assertThat(organization.getDescription()).isNull();
     assertThat(organization.getUrl()).isNull();
     assertThat(organization.getAvatarUrl()).isNull();
+    assertThat(organization.isGuarded()).isFalse();
   }
 
   @Test
@@ -194,11 +191,120 @@ public class OrganizationCreationImplTest {
 
     underTest.create(dbSession, SOME_USER_ID, FULL_POPULATED_NEW_ORGANIZATION);
 
-    OrganizationDto organization = dbClient.organizationDao().selectByKey(dbSession, FULL_POPULATED_NEW_ORGANIZATION.getKey()).get();
+    verifyDefaultTemplate(FULL_POPULATED_NEW_ORGANIZATION.getKey(), FULL_POPULATED_NEW_ORGANIZATION.getName());
+  }
+
+  @Test
+  public void createForUser_has_no_effect_if_setting_for_feature_is_not_set() {
+    checkSizeOfTables();
+
+    underTest.createForUser(null /* argument is not even read */, null /* argument is not even read */);
+
+    checkSizeOfTables();
+  }
+
+  @Test
+  public void createForUser_has_no_effect_if_setting_for_feature_is_disabled() {
+    enableCreatePersonalOrg(false);
+
+    checkSizeOfTables();
+
+    underTest.createForUser(null /* argument is not even read */, null /* argument is not even read */);
+
+    checkSizeOfTables();
+  }
+
+  private void checkSizeOfTables() {
+    assertThat(dbTester.countRowsOfTable("organizations")).isEqualTo(1);
+    assertThat(dbTester.countRowsOfTable("groups")).isEqualTo(0);
+    assertThat(dbTester.countRowsOfTable("groups_users")).isEqualTo(0);
+    assertThat(dbTester.countRowsOfTable("permission_templates")).isEqualTo(0);
+    assertThat(dbTester.countRowsOfTable("perm_templates_users")).isEqualTo(0);
+    assertThat(dbTester.countRowsOfTable("perm_templates_groups")).isEqualTo(0);
+  }
+
+  @Test
+  public void createForUser_creates_guarded_organization_with_name_and_key_generated_from_login() {
+    UserDto user = dbTester.users().insertUser(A_LOGIN);
+    when(organizationValidation.generateKeyFrom(A_LOGIN)).thenReturn(SLUG_OF_A_LOGIN);
+    mockForSuccessfulInsert(SOME_UUID, SOME_DATE);
+    enableCreatePersonalOrg(true);
+
+    underTest.createForUser(dbSession, user);
+
+    OrganizationDto organization = dbClient.organizationDao().selectByKey(dbSession, SLUG_OF_A_LOGIN).get();
+    assertThat(organization.getUuid()).isEqualTo(SOME_UUID);
+    assertThat(organization.getKey()).isEqualTo(SLUG_OF_A_LOGIN);
+    assertThat(organization.getName()).isEqualTo(user.getLogin());
+    assertThat(organization.getDescription()).isNull();
+    assertThat(organization.getUrl()).isNull();
+    assertThat(organization.getAvatarUrl()).isNull();
+    assertThat(organization.isGuarded()).isTrue();
+    assertThat(organization.getCreatedAt()).isEqualTo(SOME_DATE);
+    assertThat(organization.getUpdatedAt()).isEqualTo(SOME_DATE);
+  }
+
+  @Test
+  public void createForUser_fails_with_ISE_if_organization_with_slug_of_login_already_exists() {
+    UserDto user = dbTester.users().insertUser(A_LOGIN);
+    when(organizationValidation.generateKeyFrom(A_LOGIN)).thenReturn(SLUG_OF_A_LOGIN);
+    dbTester.organizations().insertForKey(SLUG_OF_A_LOGIN);
+    mockForSuccessfulInsert(SOME_UUID, SOME_DATE);
+    enableCreatePersonalOrg(true);
+
+    expectedException.expect(IllegalStateException.class);
+    expectedException.expectMessage("Can't create organization with key '" + SLUG_OF_A_LOGIN + "' for new user '" + A_LOGIN
+      + "' because an organization with this key already exists");
+
+    underTest.createForUser(dbSession, user);
+  }
+
+  @Test
+  public void createForUser_creates_owners_group_with_all_permissions_for_new_organization_and_add_current_user_to_it() throws OrganizationCreation.KeyConflictException {
+    UserDto user = dbTester.users().insertUser(A_LOGIN);
+    when(organizationValidation.generateKeyFrom(A_LOGIN)).thenReturn(SLUG_OF_A_LOGIN);
+    mockForSuccessfulInsert(SOME_UUID, SOME_DATE);
+    enableCreatePersonalOrg(true);
+
+    underTest.createForUser(dbSession, user);
+
+    verifyGroupOwners(user, SLUG_OF_A_LOGIN, A_LOGIN);
+  }
+
+  private void verifyGroupOwners(UserDto user, String organizationKey, String organizationName) {
+    OrganizationDto organization = dbClient.organizationDao().selectByKey(dbSession, organizationKey).get();
+    Optional<GroupDto> groupDtoOptional = dbClient.groupDao().selectByName(dbSession, organization.getUuid(), "Owners");
+    assertThat(groupDtoOptional).isNotEmpty();
+    GroupDto groupDto = groupDtoOptional.get();
+    assertThat(groupDto.getDescription()).isEqualTo("Owners of organization " + organizationName);
+    assertThat(dbClient.groupPermissionDao().selectGlobalPermissionsOfGroup(dbSession, groupDto.getOrganizationUuid(), groupDto.getId()))
+      .containsOnly(GlobalPermissions.ALL.toArray(new String[GlobalPermissions.ALL.size()]));
+    List<UserMembershipDto> members = dbClient.groupMembershipDao().selectMembers(
+      dbSession,
+      UserMembershipQuery.builder().groupId(groupDto.getId()).membership(UserMembershipQuery.IN).build(), 0, Integer.MAX_VALUE);
+    assertThat(members)
+      .extracting(UserMembershipDto::getLogin)
+      .containsOnly(user.getLogin());
+  }
+
+  @Test
+  public void createForUser_creates_default_template_for_new_organization() throws OrganizationCreation.KeyConflictException {
+    UserDto user = dbTester.users().insertUser(A_LOGIN);
+    when(organizationValidation.generateKeyFrom(A_LOGIN)).thenReturn(SLUG_OF_A_LOGIN);
+    mockForSuccessfulInsert(SOME_UUID, SOME_DATE);
+    enableCreatePersonalOrg(true);
+
+    underTest.createForUser(dbSession, user);
+
+    verifyDefaultTemplate(SLUG_OF_A_LOGIN, A_LOGIN);
+  }
+
+  private void verifyDefaultTemplate(String organizationKey, String organizationName) {
+    OrganizationDto organization = dbClient.organizationDao().selectByKey(dbSession, organizationKey).get();
     GroupDto ownersGroup = dbClient.groupDao().selectByName(dbSession, organization.getUuid(), "Owners").get();
     PermissionTemplateDto defaultTemplate = dbClient.permissionTemplateDao().selectByName(dbSession, organization.getUuid(), "default template");
     assertThat(defaultTemplate.getName()).isEqualTo("Default template");
-    assertThat(defaultTemplate.getDescription()).isEqualTo("Default permission template of organization " + FULL_POPULATED_NEW_ORGANIZATION.getName());
+    assertThat(defaultTemplate.getDescription()).isEqualTo("Default permission template of organization " + organizationName);
     DefaultTemplates defaultTemplates = dbClient.organizationDao().getDefaultTemplates(dbSession, organization.getUuid()).get();
     assertThat(defaultTemplates.getProjectUuid()).isEqualTo(defaultTemplate.getUuid());
     assertThat(defaultTemplates.getViewUuid()).isNull();
@@ -209,6 +315,24 @@ public class OrganizationCreationImplTest {
         tuple(0L, UserRole.USER), tuple(0L, UserRole.CODEVIEWER));
   }
 
+  @Test
+  public void createForUser_does_not_fail_if_login_is_too_long_for_an_organization_name() {
+    String login = STRING_64_CHARS + "b";
+    UserDto user = dbTester.users().insertUser(login);
+    when(organizationValidation.generateKeyFrom(login)).thenReturn(SLUG_OF_A_LOGIN);
+    mockForSuccessfulInsert(SOME_UUID, SOME_DATE);
+    enableCreatePersonalOrg(true);
+
+    underTest.createForUser(dbSession, user);
+
+    OrganizationDto organization = dbClient.organizationDao().selectByKey(dbSession, SLUG_OF_A_LOGIN).get();
+    assertThat(organization.getName()).isEqualTo(STRING_64_CHARS);
+  }
+
+  private void enableCreatePersonalOrg(boolean flag) {
+    settings.setProperty(CorePropertyDefinitions.ORGANIZATIONS_CREATE_PERSONAL_ORG, flag);
+  }
+
   private void mockForSuccessfulInsert(String orgUuid, long orgDate) {
     when(uuidFactory.create()).thenReturn(orgUuid);
     when(system2.now()).thenReturn(orgDate);
index a4466e02a202993426fba1e658e896cfebc0252f..46461d96e8f3a586edbd97db66619166d58e6d15 100644 (file)
@@ -89,7 +89,7 @@ public class CreateActionTest {
     .setProperty(ORGANIZATIONS_ANYONE_CAN_CREATE, false);
   private UuidFactory uuidFactory = mock(UuidFactory.class);
   private OrganizationValidation organizationValidation = new OrganizationValidationImpl();
-  private OrganizationCreation organizationCreation = new OrganizationCreationImpl(dbClient, system2, uuidFactory, organizationValidation);
+  private OrganizationCreation organizationCreation = new OrganizationCreationImpl(dbClient, system2, uuidFactory, organizationValidation, settings);
   private CreateAction underTest = new CreateAction(settings, userSession, dbClient, new OrganizationsWsSupport(organizationValidation), organizationValidation, organizationCreation);
   private WsActionTester wsTester = new WsActionTester(underTest);
 
index ccd6f33698d56cf7264c94e49d1fb2b4048d46ec..b444450e5951684aa8ab709a8bfe30be5553cf48 100644 (file)
@@ -43,6 +43,7 @@ import org.sonar.db.user.UserTesting;
 import org.sonar.server.es.EsTester;
 import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.exceptions.ServerException;
+import org.sonar.server.organization.OrganizationCreation;
 import org.sonar.server.organization.TestDefaultOrganizationProvider;
 import org.sonar.server.user.index.UserIndexDefinition;
 import org.sonar.server.user.index.UserIndexer;
@@ -86,7 +87,8 @@ public class UserUpdaterTest {
   private Settings settings = new MapSettings();
   private DbSession session = db.getSession();
   private UserIndexer userIndexer = new UserIndexer(system2, dbClient, es.client());
-  private UserUpdater underTest = new UserUpdater(newUserNotifier, settings, dbClient, userIndexer, system2, TestDefaultOrganizationProvider.from(db));
+  private OrganizationCreation organizationCreation = mock(OrganizationCreation.class);
+  private UserUpdater underTest = new UserUpdater(newUserNotifier, settings, dbClient, userIndexer, system2, TestDefaultOrganizationProvider.from(db), organizationCreation);
 
   @Before
   public void setUp() {
index c8dabb82449ccd8c185bc4335ba772c4caa72715..d0d1ab19647372a5a79448a274228b579997dc25 100644 (file)
@@ -31,6 +31,7 @@ import org.sonar.server.es.EsTester;
 import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.organization.OrganizationCreation;
 import org.sonar.server.organization.TestDefaultOrganizationProvider;
 import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.user.ExternalIdentity;
@@ -46,21 +47,20 @@ import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
 
 public class ChangePasswordActionTest {
-
   @Rule
   public ExpectedException expectedException = ExpectedException.none();
-
   @Rule
   public DbTester db = DbTester.create();
-
   @Rule
   public EsTester esTester = new EsTester(new UserIndexDefinition(new MapSettings()));
-
   @Rule
   public UserSessionRule userSessionRule = UserSessionRule.standalone().logIn();
 
   private UserUpdater userUpdater = new UserUpdater(mock(NewUserNotifier.class), new MapSettings(), db.getDbClient(),
-    new UserIndexer(System2.INSTANCE, db.getDbClient(), esTester.client()), System2.INSTANCE, TestDefaultOrganizationProvider.from(db));
+    new UserIndexer(System2.INSTANCE, db.getDbClient(), esTester.client()),
+    System2.INSTANCE,
+    TestDefaultOrganizationProvider.from(db),
+    mock(OrganizationCreation.class));
 
   private WsTester tester = new WsTester(new UsersWs(new ChangePasswordAction(db.getDbClient(), userUpdater, userSessionRule)));
 
index 567336386266a542196e713dace11c1473576c26..269ca9362202f941cabde5dae57a95bbf0caf63c 100644 (file)
@@ -37,6 +37,7 @@ import org.sonar.db.user.UserDto;
 import org.sonar.server.es.EsTester;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.exceptions.ServerException;
+import org.sonar.server.organization.OrganizationCreation;
 import org.sonar.server.organization.TestDefaultOrganizationProvider;
 import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.user.NewUserNotifier;
@@ -76,9 +77,11 @@ public class CreateActionTest {
   private UserIndex index = new UserIndex(esTester.client());
   private UserIndexer userIndexer = new UserIndexer(system2, db.getDbClient(), esTester.client());
   private GroupDto defaultGroupInDefaultOrg;
+  private OrganizationCreation organizationCreation = mock(OrganizationCreation.class);
 
-  private WsActionTester tester = new WsActionTester(
-    new CreateAction(new UserUpdater(mock(NewUserNotifier.class), settings, db.getDbClient(), userIndexer, system2, TestDefaultOrganizationProvider.from(db)), userSessionRule));
+  private WsActionTester tester = new WsActionTester(new CreateAction(
+    new UserUpdater(mock(NewUserNotifier.class), settings, db.getDbClient(), userIndexer, system2, TestDefaultOrganizationProvider.from(db), organizationCreation),
+    userSessionRule));
 
   @Before
   public void setUp() {
index 56ff753d4e5387978b22e1945535740b914122a2..0fe41a514719e2a86105927ed68ee89ee9d89c32 100644 (file)
@@ -33,6 +33,7 @@ import org.sonar.server.es.EsTester;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.exceptions.NotFoundException;
 import org.sonar.server.organization.DefaultOrganizationProvider;
+import org.sonar.server.organization.OrganizationCreation;
 import org.sonar.server.organization.TestDefaultOrganizationProvider;
 import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.user.NewUserNotifier;
@@ -49,6 +50,8 @@ import static org.sonar.db.user.UserTesting.newUserDto;
 
 public class UpdateActionTest {
 
+  private static final OrganizationCreation ORGANIZATION_CREATION_NOT_USED_FOR_UPDATE = null;
+
   private final Settings settings = new MapSettings().setProperty("sonar.defaultGroup", "sonar-users");
 
   private System2 system2 = new System2();
@@ -73,7 +76,8 @@ public class UpdateActionTest {
 
     userIndexer = new UserIndexer(system2, dbClient, esTester.client());
     tester = new WsTester(new UsersWs(new UpdateAction(
-      new UserUpdater(mock(NewUserNotifier.class), settings, dbClient, userIndexer, system2, defaultOrganizationProvider), userSessionRule,
+      new UserUpdater(mock(NewUserNotifier.class), settings, dbClient, userIndexer, system2, defaultOrganizationProvider, ORGANIZATION_CREATION_NOT_USED_FOR_UPDATE),
+      userSessionRule,
       new UserJsonWriter(userSessionRule), dbClient)));
   }