]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-20082 Set public permissions on managed projects at creation
authorAntoine Vigneau <antoine.vigneau@sonarsource.com>
Mon, 7 Aug 2023 14:34:23 +0000 (16:34 +0200)
committersonartech <sonartech@sonarsource.com>
Tue, 8 Aug 2023 20:03:01 +0000 (20:03 +0000)
server/sonar-webserver-webapi/src/it/java/org/sonar/server/almintegration/ws/azure/ImportAzureProjectActionIT.java
server/sonar-webserver-webapi/src/it/java/org/sonar/server/almintegration/ws/bitbucketcloud/ImportBitbucketCloudRepoActionIT.java
server/sonar-webserver-webapi/src/it/java/org/sonar/server/almintegration/ws/bitbucketserver/ImportBitbucketServerProjectActionIT.java
server/sonar-webserver-webapi/src/it/java/org/sonar/server/almintegration/ws/github/ImportGithubProjectActionIT.java
server/sonar-webserver-webapi/src/it/java/org/sonar/server/almintegration/ws/gitlab/ImportGitLabProjectActionIT.java
server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/queue/ReportSubmitterIT.java
server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ComponentUpdaterIT.java
server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/CreateActionIT.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ComponentUpdater.java

index 3cb3ffb9f389e08b9ee298ba8d8cc6c184cb8929..b70c664b9482e8b70cef5cb54a466c497df72452 100644 (file)
@@ -51,7 +51,9 @@ import org.sonar.server.exceptions.UnauthorizedException;
 import org.sonar.server.favorite.FavoriteUpdater;
 import org.sonar.server.l18n.I18nRule;
 import org.sonar.server.newcodeperiod.NewCodeDefinitionResolver;
+import org.sonar.server.permission.PermissionService;
 import org.sonar.server.permission.PermissionTemplateService;
+import org.sonar.server.permission.PermissionUpdater;
 import org.sonar.server.project.DefaultBranchNameResolver;
 import org.sonar.server.project.ProjectDefaultVisibility;
 import org.sonar.server.project.Visibility;
@@ -93,7 +95,7 @@ public class ImportAzureProjectActionIT {
 
   private final ComponentUpdater componentUpdater = new ComponentUpdater(db.getDbClient(), i18n, System2.INSTANCE,
     mock(PermissionTemplateService.class), new FavoriteUpdater(db.getDbClient()), new TestIndexers(), new SequenceUuidFactory(),
-    defaultBranchNameResolver);
+    defaultBranchNameResolver, mock(PermissionUpdater.class), mock(PermissionService.class));
 
   private final Encryption encryption = mock(Encryption.class);
   private final ImportHelper importHelper = new ImportHelper(db.getDbClient(), userSession);
index 08a147ec483709496da290109c56783488acd070..704cb25bc4d568e52e1161eb7fc337354aa0f151 100644 (file)
@@ -51,7 +51,9 @@ import org.sonar.server.exceptions.UnauthorizedException;
 import org.sonar.server.favorite.FavoriteUpdater;
 import org.sonar.server.l18n.I18nRule;
 import org.sonar.server.newcodeperiod.NewCodeDefinitionResolver;
+import org.sonar.server.permission.PermissionService;
 import org.sonar.server.permission.PermissionTemplateService;
+import org.sonar.server.permission.PermissionUpdater;
 import org.sonar.server.project.DefaultBranchNameResolver;
 import org.sonar.server.project.ProjectDefaultVisibility;
 import org.sonar.server.project.Visibility;
@@ -93,7 +95,7 @@ public class ImportBitbucketCloudRepoActionIT {
   DefaultBranchNameResolver defaultBranchNameResolver = mock(DefaultBranchNameResolver.class);
   private final ComponentUpdater componentUpdater = new ComponentUpdater(db.getDbClient(), i18n, System2.INSTANCE,
     mock(PermissionTemplateService.class), new FavoriteUpdater(db.getDbClient()), new TestIndexers(), new SequenceUuidFactory(),
-    defaultBranchNameResolver);
+    defaultBranchNameResolver, mock(PermissionUpdater.class), mock(PermissionService.class));
 
   private final ImportHelper importHelper = new ImportHelper(db.getDbClient(), userSession);
   private final ProjectKeyGenerator projectKeyGenerator = mock(ProjectKeyGenerator.class);
index 8b674f338f3ecc21cc521d23a01a7c954689cf00..9f8718262de10344cca9a6eef28982fc43574c70 100644 (file)
@@ -55,7 +55,9 @@ import org.sonar.server.exceptions.UnauthorizedException;
 import org.sonar.server.favorite.FavoriteUpdater;
 import org.sonar.server.l18n.I18nRule;
 import org.sonar.server.newcodeperiod.NewCodeDefinitionResolver;
+import org.sonar.server.permission.PermissionService;
 import org.sonar.server.permission.PermissionTemplateService;
+import org.sonar.server.permission.PermissionUpdater;
 import org.sonar.server.project.DefaultBranchNameResolver;
 import org.sonar.server.project.ProjectDefaultVisibility;
 import org.sonar.server.project.Visibility;
@@ -100,7 +102,7 @@ public class ImportBitbucketServerProjectActionIT {
 
   private final ComponentUpdater componentUpdater = new ComponentUpdater(db.getDbClient(), i18n, System2.INSTANCE,
     mock(PermissionTemplateService.class), new FavoriteUpdater(db.getDbClient()), new TestIndexers(), new SequenceUuidFactory(),
-    defaultBranchNameResolver);
+    defaultBranchNameResolver, mock(PermissionUpdater.class), mock(PermissionService.class));
 
   private final ImportHelper importHelper = new ImportHelper(db.getDbClient(), userSession);
   private final ProjectKeyGenerator projectKeyGenerator = mock(ProjectKeyGenerator.class);
index dd35ab3cb4b38942cfa9957318c241216382714f..140d53a9c914b3ee2f8b85dd4554442a5922964f 100644 (file)
 package org.sonar.server.almintegration.ws.github;
 
 import java.util.Optional;
+import java.util.Set;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 import org.sonar.alm.client.github.GithubApplicationClient;
 import org.sonar.alm.client.github.GithubApplicationClientImpl;
+import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.utils.System2;
 import org.sonar.auth.github.GitHubSettings;
@@ -37,6 +39,7 @@ import org.sonar.db.DbSession;
 import org.sonar.db.DbTester;
 import org.sonar.db.alm.setting.AlmSettingDto;
 import org.sonar.db.component.BranchDto;
+import org.sonar.db.component.ResourceTypesRule;
 import org.sonar.db.entity.EntityDto;
 import org.sonar.db.newcodeperiod.NewCodePeriodDto;
 import org.sonar.db.permission.GlobalPermission;
@@ -45,12 +48,22 @@ import org.sonar.db.user.UserDto;
 import org.sonar.server.almintegration.ws.ImportHelper;
 import org.sonar.server.almintegration.ws.ProjectKeyGenerator;
 import org.sonar.server.component.ComponentUpdater;
+import org.sonar.server.es.EsTester;
+import org.sonar.server.es.IndexersImpl;
 import org.sonar.server.es.TestIndexers;
 import org.sonar.server.exceptions.NotFoundException;
 import org.sonar.server.exceptions.UnauthorizedException;
 import org.sonar.server.favorite.FavoriteUpdater;
 import org.sonar.server.newcodeperiod.NewCodeDefinitionResolver;
+import org.sonar.server.permission.GroupPermissionChanger;
+import org.sonar.server.permission.PermissionService;
+import org.sonar.server.permission.PermissionServiceImpl;
 import org.sonar.server.permission.PermissionTemplateService;
+import org.sonar.server.permission.PermissionUpdater;
+import org.sonar.server.permission.UserPermissionChange;
+import org.sonar.server.permission.UserPermissionChanger;
+import org.sonar.server.permission.index.FooIndexDefinition;
+import org.sonar.server.permission.index.PermissionIndexer;
 import org.sonar.server.project.DefaultBranchNameResolver;
 import org.sonar.server.project.ProjectDefaultVisibility;
 import org.sonar.server.project.Visibility;
@@ -92,9 +105,15 @@ public class ImportGithubProjectActionIT {
   @Rule
   public DbTester db = DbTester.create(system2);
   private final PermissionTemplateService permissionTemplateService = mock(PermissionTemplateService.class);
+  public EsTester es = EsTester.createCustom(new FooIndexDefinition());
+  private final PermissionUpdater<UserPermissionChange> userPermissionUpdater = new PermissionUpdater(
+    new IndexersImpl(new PermissionIndexer(db.getDbClient(), es.client())),
+    Set.of(new UserPermissionChanger(db.getDbClient(), new SequenceUuidFactory()),
+      new GroupPermissionChanger(db.getDbClient(), new SequenceUuidFactory())));
+  private final PermissionService permissionService = new PermissionServiceImpl(new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT));
   private final ComponentUpdater componentUpdater = new ComponentUpdater(db.getDbClient(), mock(I18n.class), System2.INSTANCE,
     permissionTemplateService, new FavoriteUpdater(db.getDbClient()), new TestIndexers(), new SequenceUuidFactory(),
-    defaultBranchNameResolver);
+    defaultBranchNameResolver, userPermissionUpdater, permissionService);
 
   private final ImportHelper importHelper = new ImportHelper(db.getDbClient(), userSession);
   private final ProjectKeyGenerator projectKeyGenerator = mock(ProjectKeyGenerator.class);
index e257bcc044ff6793725b5fc6fde8ffce5b54d914..27d1fdd9e8db72656de452cff10bf3d63b92c55c 100644 (file)
@@ -44,7 +44,9 @@ import org.sonar.server.component.ComponentUpdater;
 import org.sonar.server.es.TestIndexers;
 import org.sonar.server.favorite.FavoriteUpdater;
 import org.sonar.server.newcodeperiod.NewCodeDefinitionResolver;
+import org.sonar.server.permission.PermissionService;
 import org.sonar.server.permission.PermissionTemplateService;
+import org.sonar.server.permission.PermissionUpdater;
 import org.sonar.server.project.DefaultBranchNameResolver;
 import org.sonar.server.project.ProjectDefaultVisibility;
 import org.sonar.server.project.Visibility;
@@ -84,7 +86,7 @@ public class ImportGitLabProjectActionIT {
 
   private final ComponentUpdater componentUpdater = new ComponentUpdater(db.getDbClient(), mock(I18n.class), System2.INSTANCE,
     mock(PermissionTemplateService.class), new FavoriteUpdater(db.getDbClient()), new TestIndexers(), new SequenceUuidFactory(),
-    defaultBranchNameResolver);
+    defaultBranchNameResolver, mock(PermissionUpdater.class), mock(PermissionService.class));
 
   private final GitlabHttpClient gitlabHttpClient = mock(GitlabHttpClient.class);
   private final ImportHelper importHelper = new ImportHelper(db.getDbClient(), userSession);
index 6bdf633aba7511a8582a18340f85ce163bfd73ae..d74811ef709529963197090724e7b88635554f4f 100644 (file)
@@ -38,8 +38,8 @@ import org.sonar.db.DbSession;
 import org.sonar.db.DbTester;
 import org.sonar.db.ce.CeTaskTypes;
 import org.sonar.db.component.ComponentDto;
-import org.sonar.db.entity.EntityDto;
 import org.sonar.db.component.ProjectData;
+import org.sonar.db.entity.EntityDto;
 import org.sonar.db.permission.GlobalPermission;
 import org.sonar.db.project.ProjectDto;
 import org.sonar.db.user.UserDto;
@@ -48,7 +48,9 @@ import org.sonar.server.es.TestIndexers;
 import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.favorite.FavoriteUpdater;
+import org.sonar.server.permission.PermissionService;
 import org.sonar.server.permission.PermissionTemplateService;
+import org.sonar.server.permission.PermissionUpdater;
 import org.sonar.server.project.DefaultBranchNameResolver;
 import org.sonar.server.project.ProjectDefaultVisibility;
 import org.sonar.server.project.Visibility;
@@ -93,7 +95,7 @@ public class ReportSubmitterIT {
   private final PermissionTemplateService permissionTemplateService = mock(PermissionTemplateService.class);
 
   private final ComponentUpdater componentUpdater = new ComponentUpdater(db.getDbClient(), mock(I18n.class), mock(System2.class), permissionTemplateService,
-    new FavoriteUpdater(db.getDbClient()), projectIndexers, new SequenceUuidFactory(), defaultBranchNameResolver);
+    new FavoriteUpdater(db.getDbClient()), projectIndexers, new SequenceUuidFactory(), defaultBranchNameResolver, mock(PermissionUpdater.class), mock(PermissionService.class));
   private final BranchSupport ossEditionBranchSupport = new BranchSupport(null);
 
   private final ReportSubmitter underTest = new ReportSubmitter(queue, userSession, componentUpdater, permissionTemplateService, db.getDbClient(), ossEditionBranchSupport,
index 0e72ba37443dd4f3c9f656f3c6537b495c116675..53a3a70a9aecdd2d4afe1af5f1cb24dfdca26462 100644 (file)
@@ -19,7 +19,9 @@
  */
 package org.sonar.server.component;
 
+import java.util.List;
 import java.util.Optional;
+import java.util.Set;
 import org.apache.commons.lang3.StringUtils;
 import org.junit.Before;
 import org.junit.Rule;
@@ -28,20 +30,32 @@ import org.sonar.api.config.Configuration;
 import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.resources.Scopes;
 import org.sonar.api.utils.System2;
+import org.sonar.api.web.UserRole;
 import org.sonar.core.util.SequenceUuidFactory;
 import org.sonar.db.DbSession;
 import org.sonar.db.DbTester;
 import org.sonar.db.component.BranchDto;
 import org.sonar.db.component.BranchType;
 import org.sonar.db.component.ComponentDto;
+import org.sonar.db.component.ResourceTypesRule;
 import org.sonar.db.project.ProjectDto;
 import org.sonar.db.user.UserDto;
+import org.sonar.server.es.EsTester;
 import org.sonar.server.es.Indexers;
+import org.sonar.server.es.IndexersImpl;
 import org.sonar.server.es.TestIndexers;
 import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.favorite.FavoriteUpdater;
 import org.sonar.server.l18n.I18nRule;
+import org.sonar.server.permission.GroupPermissionChanger;
+import org.sonar.server.permission.PermissionService;
+import org.sonar.server.permission.PermissionServiceImpl;
 import org.sonar.server.permission.PermissionTemplateService;
+import org.sonar.server.permission.PermissionUpdater;
+import org.sonar.server.permission.UserPermissionChange;
+import org.sonar.server.permission.UserPermissionChanger;
+import org.sonar.server.permission.index.FooIndexDefinition;
+import org.sonar.server.permission.index.PermissionIndexer;
 import org.sonar.server.project.DefaultBranchNameResolver;
 
 import static java.util.stream.IntStream.rangeClosed;
@@ -63,6 +77,8 @@ public class ComponentUpdaterIT {
 
   private static final String DEFAULT_PROJECT_KEY = "project-key";
   private static final String DEFAULT_PROJECT_NAME = "project-name";
+  private static final String DEFAULT_USER_UUID = "user-uuid";
+  public static final String DEFAULT_USER_LOGIN = "user-login";
 
   private final System2 system2 = System2.INSTANCE;
 
@@ -74,13 +90,18 @@ public class ComponentUpdaterIT {
   private final TestIndexers projectIndexers = new TestIndexers();
   private final PermissionTemplateService permissionTemplateService = mock(PermissionTemplateService.class);
   private final DefaultBranchNameResolver defaultBranchNameResolver = mock(DefaultBranchNameResolver.class);
-
   private final Configuration config = mock(Configuration.class);
+  public EsTester es = EsTester.createCustom(new FooIndexDefinition());
+  private final PermissionUpdater<UserPermissionChange> userPermissionUpdater = new PermissionUpdater(
+    new IndexersImpl(new PermissionIndexer(db.getDbClient(), es.client())),
+    Set.of(new UserPermissionChanger(db.getDbClient(), new SequenceUuidFactory()),
+      new GroupPermissionChanger(db.getDbClient(), new SequenceUuidFactory())));
+  private final PermissionService permissionService = new PermissionServiceImpl(new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT));
 
   private final ComponentUpdater underTest = new ComponentUpdater(db.getDbClient(), i18n, system2,
     permissionTemplateService,
     new FavoriteUpdater(db.getDbClient()),
-    projectIndexers, new SequenceUuidFactory(), defaultBranchNameResolver);
+    projectIndexers, new SequenceUuidFactory(), defaultBranchNameResolver, userPermissionUpdater, permissionService);
 
   @Before
   public void before() {
@@ -203,14 +224,13 @@ public class ComponentUpdaterIT {
 
   @Test
   public void apply_default_permission_template() {
-    String userUuid = "42";
     NewComponent project = NewComponent.newComponentBuilder()
       .setKey(DEFAULT_PROJECT_KEY)
       .setName(DEFAULT_PROJECT_NAME)
       .build();
-    ProjectDto dto = underTest.create(db.getSession(), project, userUuid, "user-login").projectDto();
+    ProjectDto dto = underTest.create(db.getSession(), project, DEFAULT_USER_UUID, DEFAULT_USER_LOGIN).projectDto();
 
-    verify(permissionTemplateService).applyDefaultToNewComponent(db.getSession(), dto, userUuid);
+    verify(permissionTemplateService).applyDefaultToNewComponent(db.getSession(), dto, DEFAULT_USER_UUID);
   }
 
   @Test
@@ -392,13 +412,31 @@ public class ComponentUpdaterIT {
 
   @Test
   public void createWithoutCommit_whenProjectIsManaged_doesntApplyPermissionTemplate() {
-    String userUuid = "42";
+    UserDto userDto = db.users().insertUser();
     NewComponent project = NewComponent.newComponentBuilder()
       .setKey(DEFAULT_PROJECT_KEY)
       .setName(DEFAULT_PROJECT_NAME)
       .build();
-    underTest.createWithoutCommit(db.getSession(), project, userUuid, "user-login", null, true);
+    underTest.createWithoutCommit(db.getSession(), project, userDto.getUuid(), userDto.getLogin(), null, true);
 
     verify(permissionTemplateService, never()).applyDefaultToNewComponent(any(), any(), any());
   }
+
+  @Test
+  public void createWithoutCommit_whenProjectIsManagedAndPrivate_applyPublicPermissionsToCreator() {
+    UserDto userDto = db.users().insertUser();
+    NewComponent newComponent = NewComponent.newComponentBuilder()
+      .setKey(DEFAULT_PROJECT_KEY)
+      .setName(DEFAULT_PROJECT_NAME)
+      .setPrivate(true)
+      .build();
+
+    DbSession session = db.getSession();
+    ComponentCreationData componentCreationData = underTest.createWithoutCommit(session, newComponent, userDto.getUuid(), userDto.getLogin(), null, true);
+
+    List<String> permissions = db.getDbClient().userPermissionDao().selectEntityPermissionsOfUser(session, userDto.getUuid(), componentCreationData.projectDto().getUuid());
+    assertThat(permissions)
+      .containsExactlyInAnyOrder(UserRole.USER, UserRole.CODEVIEWER);
+  }
+
 }
index 75dd6ae7d4b65c7996a66e7fb1636e0e569428e6..0ab89ec8a4f500fe446fc5be252b46bd05c4b8bd 100644 (file)
@@ -45,7 +45,9 @@ import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.favorite.FavoriteUpdater;
 import org.sonar.server.l18n.I18nRule;
 import org.sonar.server.newcodeperiod.NewCodeDefinitionResolver;
+import org.sonar.server.permission.PermissionService;
 import org.sonar.server.permission.PermissionTemplateService;
+import org.sonar.server.permission.PermissionUpdater;
 import org.sonar.server.project.DefaultBranchNameResolver;
 import org.sonar.server.project.ProjectDefaultVisibility;
 import org.sonar.server.project.Visibility;
@@ -107,7 +109,7 @@ public class CreateActionIT {
     new CreateAction(
       db.getDbClient(), userSession,
       new ComponentUpdater(db.getDbClient(), i18n, system2, permissionTemplateService, new FavoriteUpdater(db.getDbClient()),
-        projectIndexers, new SequenceUuidFactory(), defaultBranchNameResolver),
+        projectIndexers, new SequenceUuidFactory(), defaultBranchNameResolver, mock(PermissionUpdater.class), mock(PermissionService.class)),
       projectDefaultVisibility, defaultBranchNameResolver, newCodeDefinitionResolver));
 
   @Before
index 8e95de62c14ca587e608d19d0260a9be6343c5ff..4f870974b1294bf330a51cf0e826a5472b448a62 100644 (file)
@@ -19,7 +19,6 @@
  */
 package org.sonar.server.component;
 
-import com.google.common.annotations.VisibleForTesting;
 import java.util.List;
 import java.util.Locale;
 import java.util.Optional;
@@ -39,13 +38,19 @@ import org.sonar.db.component.ComponentDto;
 import org.sonar.db.portfolio.PortfolioDto;
 import org.sonar.db.portfolio.PortfolioDto.SelectionMode;
 import org.sonar.db.project.ProjectDto;
+import org.sonar.db.user.UserDto;
 import org.sonar.server.es.Indexers;
 import org.sonar.server.favorite.FavoriteUpdater;
+import org.sonar.server.permission.PermissionChange;
+import org.sonar.server.permission.PermissionService;
 import org.sonar.server.permission.PermissionTemplateService;
+import org.sonar.server.permission.PermissionUpdater;
+import org.sonar.server.permission.UserPermissionChange;
 import org.sonar.server.project.DefaultBranchNameResolver;
-import org.springframework.beans.factory.annotation.Autowired;
 
+import static com.google.common.base.Preconditions.checkState;
 import static java.util.Collections.singletonList;
+import static org.sonar.api.web.UserRole.PUBLIC_PERMISSIONS;
 import static org.sonar.core.component.ComponentKeys.ALLOWED_CHARACTERS_MESSAGE;
 import static org.sonar.core.component.ComponentKeys.isValidProjectKey;
 import static org.sonar.server.exceptions.BadRequestException.checkRequest;
@@ -64,11 +69,13 @@ public class ComponentUpdater {
   private final Indexers indexers;
   private final UuidFactory uuidFactory;
   private final DefaultBranchNameResolver defaultBranchNameResolver;
+  private final PermissionUpdater<UserPermissionChange> userPermissionUpdater;
+  private final PermissionService permissionService;
 
-  @Autowired
   public ComponentUpdater(DbClient dbClient, I18n i18n, System2 system2,
     PermissionTemplateService permissionTemplateService, FavoriteUpdater favoriteUpdater,
-    Indexers indexers, UuidFactory uuidFactory, DefaultBranchNameResolver defaultBranchNameResolver) {
+    Indexers indexers, UuidFactory uuidFactory, DefaultBranchNameResolver defaultBranchNameResolver, PermissionUpdater<UserPermissionChange> userPermissionUpdater,
+    PermissionService permissionService) {
     this.dbClient = dbClient;
     this.i18n = i18n;
     this.system2 = system2;
@@ -77,6 +84,8 @@ public class ComponentUpdater {
     this.indexers = indexers;
     this.uuidFactory = uuidFactory;
     this.defaultBranchNameResolver = defaultBranchNameResolver;
+    this.userPermissionUpdater = userPermissionUpdater;
+    this.permissionService = permissionService;
   }
 
   /**
@@ -135,7 +144,9 @@ public class ComponentUpdater {
       dbClient.projectDao().insert(dbSession, projectDto);
       addToFavourites(dbSession, projectDto, userUuid, userLogin);
       mainBranch = createMainBranch(dbSession, componentDto.uuid(), projectDto.getUuid(), mainBranchName);
-      if (!isManaged) {
+      if (isManaged) {
+        applyPublicPermissionsForCreator(dbSession, projectDto, userUuid);
+      } else {
         permissionTemplateService.applyDefaultToNewComponent(dbSession, projectDto, userUuid);
       }
     } else if (isPortfolio(componentDto)) {
@@ -149,6 +160,21 @@ public class ComponentUpdater {
     return new ComponentCreationData(componentDto, portfolioDto, mainBranch, projectDto);
   }
 
+  private void applyPublicPermissionsForCreator(DbSession dbSession, ProjectDto projectDto, @Nullable String userUuid) {
+    if (userUuid != null) {
+      UserDto userDto = dbClient.userDao().selectByUuid(dbSession, userUuid);
+      checkState(userDto != null, "User with uuid '%s' doesn't exist", userUuid);
+      userPermissionUpdater.apply(dbSession,
+        PUBLIC_PERMISSIONS.stream()
+        .map(permission -> toUserPermissionChange(permission, projectDto, userDto))
+        .collect(Collectors.toSet()));
+    }
+  }
+
+  private UserPermissionChange toUserPermissionChange(String permission, ProjectDto projectDto, UserDto userDto) {
+    return new UserPermissionChange(PermissionChange.Operation.ADD, permission, projectDto, userDto, permissionService);
+  }
+
   private void addToFavourites(DbSession dbSession, ProjectDto projectDto, @Nullable String userUuid, @Nullable String userLogin) {
     if (permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(dbSession, projectDto)) {
       favoriteUpdater.add(dbSession, projectDto, userUuid, userLogin, false);