Skip to content

Commit

Permalink
SONAR-9551 Use view templates for applications
Browse files Browse the repository at this point in the history
  • Loading branch information
julienlancelot committed Jul 31, 2017
1 parent c2cf8d0 commit 3aa22c8
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 43 deletions.
Expand Up @@ -29,6 +29,7 @@


import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Preconditions.checkState;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static org.sonar.db.component.ComponentTesting.newApplication;
import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto; import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
import static org.sonar.db.component.ComponentTesting.newPublicProjectDto; import static org.sonar.db.component.ComponentTesting.newPublicProjectDto;
import static org.sonar.db.component.ComponentTesting.newView; import static org.sonar.db.component.ComponentTesting.newView;
Expand Down Expand Up @@ -133,6 +134,14 @@ public ComponentDto insertView(OrganizationDto organizationDto, String uuid) {
return insertComponentImpl(newView(organizationDto, uuid), false, noExtraConfiguration()); return insertComponentImpl(newView(organizationDto, uuid), false, noExtraConfiguration());
} }


public ComponentDto insertApplication(OrganizationDto organizationDto) {
return insertComponentImpl(newApplication(organizationDto), false, noExtraConfiguration());
}

public ComponentDto insertApplication(OrganizationDto organizationDto, Consumer<ComponentDto> dtoPopulator) {
return insertComponentImpl(newApplication(organizationDto), false, dtoPopulator);
}

private static <T> Consumer<T> noExtraConfiguration() { private static <T> Consumer<T> noExtraConfiguration() {
return (t) -> { return (t) -> {
}; };
Expand Down
Expand Up @@ -153,6 +153,11 @@ private static ComponentDto newView(String organizationUuid, String uuid) {
.setQualifier(Qualifiers.VIEW); .setQualifier(Qualifiers.VIEW);
} }


public static ComponentDto newApplication(OrganizationDto organizationDto) {
return newView(organizationDto.getUuid(), Uuids.createFast())
.setQualifier(Qualifiers.APP);
}

public static ComponentDto newProjectCopy(String uuid, ComponentDto project, ComponentDto view) { public static ComponentDto newProjectCopy(String uuid, ComponentDto project, ComponentDto view) {
checkNotNull(project.getId(), "The project need to be persisted before creating this technical project."); checkNotNull(project.getId(), "The project need to be persisted before creating this technical project.");
return newChildComponent(uuid, view, view) return newChildComponent(uuid, view, view)
Expand Down
Expand Up @@ -205,14 +205,16 @@ private PermissionTemplateDto findTemplate(DbSession dbSession, String organizat


String qualifier = component.qualifier(); String qualifier = component.qualifier();
DefaultTemplatesResolverImpl.ResolvedDefaultTemplates resolvedDefaultTemplates = defaultTemplatesResolver.resolve(defaultTemplates); DefaultTemplatesResolverImpl.ResolvedDefaultTemplates resolvedDefaultTemplates = defaultTemplatesResolver.resolve(defaultTemplates);
if (Qualifiers.PROJECT.equals(qualifier)) { switch (qualifier) {
return dbClient.permissionTemplateDao().selectByUuid(dbSession, resolvedDefaultTemplates.getProject()); case Qualifiers.PROJECT:
} else if (Qualifiers.VIEW.equals(qualifier)) { return dbClient.permissionTemplateDao().selectByUuid(dbSession, resolvedDefaultTemplates.getProject());
String viewDefaultTemplateUuid = resolvedDefaultTemplates.getView().orElseThrow( case Qualifiers.VIEW:
() -> new IllegalStateException("Attempt to create a view when Governance plugin is not installed")); case Qualifiers.APP:
return dbClient.permissionTemplateDao().selectByUuid(dbSession, viewDefaultTemplateUuid); String viewDefaultTemplateUuid = resolvedDefaultTemplates.getView().orElseThrow(
} else { () -> new IllegalStateException("Attempt to create a view when Governance plugin is not installed"));
throw new IllegalArgumentException(format("Qualifier '%s' is not supported", qualifier)); return dbClient.permissionTemplateDao().selectByUuid(dbSession, viewDefaultTemplateUuid);
default:
throw new IllegalArgumentException(format("Qualifier '%s' is not supported", qualifier));
} }
} }


Expand Down
Expand Up @@ -42,6 +42,7 @@
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import static org.sonar.api.resources.Qualifiers.APP;
import static org.sonar.api.resources.Qualifiers.VIEW; import static org.sonar.api.resources.Qualifiers.VIEW;


public class ComponentUpdaterTest { public class ComponentUpdaterTest {
Expand All @@ -67,7 +68,7 @@ public class ComponentUpdaterTest {
projectIndexers); projectIndexers);


@Test @Test
public void should_persist_and_index_when_creating_project() throws Exception { public void persist_and_index_when_creating_project() throws Exception {
NewComponent project = NewComponent.newComponentBuilder() NewComponent project = NewComponent.newComponentBuilder()
.setKey(DEFAULT_PROJECT_KEY) .setKey(DEFAULT_PROJECT_KEY)
.setName(DEFAULT_PROJECT_NAME) .setName(DEFAULT_PROJECT_NAME)
Expand Down Expand Up @@ -96,7 +97,7 @@ public void should_persist_and_index_when_creating_project() throws Exception {
} }


@Test @Test
public void should_persist_private_flag_true_when_creating_project() throws Exception { public void persist_private_flag_true_when_creating_project() throws Exception {
OrganizationDto organization = db.organizations().insert(); OrganizationDto organization = db.organizations().insert();
NewComponent project = NewComponent.newComponentBuilder() NewComponent project = NewComponent.newComponentBuilder()
.setKey(DEFAULT_PROJECT_KEY) .setKey(DEFAULT_PROJECT_KEY)
Expand All @@ -110,7 +111,7 @@ public void should_persist_private_flag_true_when_creating_project() throws Exce
} }


@Test @Test
public void should_persist_private_flag_false_when_creating_project() throws Exception { public void persist_private_flag_false_when_creating_project() throws Exception {
OrganizationDto organization = db.organizations().insert(); OrganizationDto organization = db.organizations().insert();
NewComponent project = NewComponent.newComponentBuilder() NewComponent project = NewComponent.newComponentBuilder()
.setKey(DEFAULT_PROJECT_KEY) .setKey(DEFAULT_PROJECT_KEY)
Expand Down Expand Up @@ -138,7 +139,43 @@ public void create_project_with_branch() throws Exception {
} }


@Test @Test
public void should_apply_default_permission_template() throws Exception { public void persist_and_index_when_creating_view() {
NewComponent view = NewComponent.newComponentBuilder()
.setKey("view-key")
.setName("view-name")
.setQualifier(VIEW)
.setOrganizationUuid(db.getDefaultOrganization().getUuid())
.build();

ComponentDto returned = underTest.create(db.getSession(), view, null);

ComponentDto loaded = db.getDbClient().componentDao().selectOrFailByUuid(db.getSession(), returned.uuid());
assertThat(loaded.getKey()).isEqualTo("view-key");
assertThat(loaded.name()).isEqualTo("view-name");
assertThat(loaded.qualifier()).isEqualTo("VW");
verify(projectIndexers).hasBeenCalled(loaded.uuid(), ProjectIndexer.Cause.PROJECT_CREATION);
}

@Test
public void create_application() {
NewComponent view = NewComponent.newComponentBuilder()
.setKey("app-key")
.setName("app-name")
.setQualifier(APP)
.setOrganizationUuid(db.getDefaultOrganization().getUuid())
.build();

ComponentDto returned = underTest.create(db.getSession(), view, null);

ComponentDto loaded = db.getDbClient().componentDao().selectByKey(db.getSession(), returned.key()).get();
assertThat(loaded.getKey()).isEqualTo("app-key");
assertThat(loaded.name()).isEqualTo("app-name");
assertThat(loaded.qualifier()).isEqualTo("APP");
verify(projectIndexers).hasBeenCalled(loaded.uuid(), ProjectIndexer.Cause.PROJECT_CREATION);
}

@Test
public void apply_default_permission_template() throws Exception {
int userId = 42; int userId = 42;
NewComponent project = NewComponent.newComponentBuilder() NewComponent project = NewComponent.newComponentBuilder()
.setKey(DEFAULT_PROJECT_KEY) .setKey(DEFAULT_PROJECT_KEY)
Expand All @@ -151,7 +188,7 @@ public void should_apply_default_permission_template() throws Exception {
} }


@Test @Test
public void should_add_project_to_user_favorites_if_project_creator_is_defined_in_permission_template() throws Exception { public void add_project_to_user_favorites_if_project_creator_is_defined_in_permission_template() throws Exception {
UserDto userDto = db.users().insertUser(); UserDto userDto = db.users().insertUser();
NewComponent project = NewComponent.newComponentBuilder() NewComponent project = NewComponent.newComponentBuilder()
.setKey(DEFAULT_PROJECT_KEY) .setKey(DEFAULT_PROJECT_KEY)
Expand Down Expand Up @@ -268,23 +305,4 @@ public void fail_to_create_new_component_on_invalid_branch() {
.build(), .build(),
null); null);
} }

@Test
public void persist_and_index_when_creating_view() {
NewComponent view = NewComponent.newComponentBuilder()
.setKey("view-key")
.setName("view-name")
.setQualifier(VIEW)
.setOrganizationUuid(db.getDefaultOrganization().getUuid())
.build();

ComponentDto returned = underTest.create(db.getSession(), view, null);

ComponentDto loaded = db.getDbClient().componentDao().selectOrFailByUuid(db.getSession(), returned.uuid());
assertThat(loaded.getKey()).isEqualTo("view-key");
assertThat(loaded.name()).isEqualTo("view-name");
assertThat(loaded.qualifier()).isEqualTo("VW");
assertThat(projectIndexers.hasBeenCalled(loaded.uuid(), ProjectIndexer.Cause.PROJECT_CREATION)).isTrue();
}

} }
Expand Up @@ -45,6 +45,8 @@
import static java.util.Collections.singletonList; import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION; import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;
import static org.sonar.db.permission.OrganizationPermission.ADMINISTER;
import static org.sonar.db.permission.OrganizationPermission.PROVISION_PROJECTS;


public class PermissionTemplateServiceTest { public class PermissionTemplateServiceTest {


Expand Down Expand Up @@ -258,14 +260,14 @@ public void applyDefault_inserts_permissions_to_ProjectCreator_but_USER_and_CODE
ComponentDto publicProject = dbTester.components().insertPublicProject(organization); ComponentDto publicProject = dbTester.components().insertPublicProject(organization);
UserDto user = dbTester.users().insertUser(); UserDto user = dbTester.users().insertUser();
ProjectPermissions.ALL ProjectPermissions.ALL
.forEach(perm -> dbTester.permissionTemplates().addProjectCreatorToTemplate(permissionTemplate, perm)); .forEach(perm -> dbTester.permissionTemplates().addProjectCreatorToTemplate(permissionTemplate, perm));
dbTester.permissionTemplates().addProjectCreatorToTemplate(permissionTemplate, "p1"); dbTester.permissionTemplates().addProjectCreatorToTemplate(permissionTemplate, "p1");
dbTester.organizations().setDefaultTemplates(organization, permissionTemplate.getUuid(), null); dbTester.organizations().setDefaultTemplates(organization, permissionTemplate.getUuid(), null);


underTest.applyDefault(session, organization.getUuid(), publicProject, user.getId()); underTest.applyDefault(session, organization.getUuid(), publicProject, user.getId());


assertThat(selectProjectPermissionsOfUser(user, publicProject)) assertThat(selectProjectPermissionsOfUser(user, publicProject))
.containsOnly("p1", UserRole.ADMIN, UserRole.ISSUE_ADMIN, GlobalPermissions.SCAN_EXECUTION); .containsOnly("p1", UserRole.ADMIN, UserRole.ISSUE_ADMIN, GlobalPermissions.SCAN_EXECUTION);
} }


@Test @Test
Expand All @@ -285,6 +287,100 @@ public void applyDefault_inserts_any_permissions_to_ProjectCreator_when_applying
.containsOnly("p1", UserRole.USER, UserRole.CODEVIEWER, UserRole.ADMIN, UserRole.ISSUE_ADMIN, GlobalPermissions.SCAN_EXECUTION); .containsOnly("p1", UserRole.USER, UserRole.CODEVIEWER, UserRole.ADMIN, UserRole.ISSUE_ADMIN, GlobalPermissions.SCAN_EXECUTION);
} }


@Test
public void apply_template_on_view() {
OrganizationDto organization = dbTester.organizations().insert();
ComponentDto view = dbTester.components().insertView(organization);
PermissionTemplateDto permissionTemplate = dbTester.permissionTemplates().insertTemplate(organization);
GroupDto group = dbTester.users().insertGroup(organization);
dbTester.permissionTemplates().addGroupToTemplate(permissionTemplate, group, ADMINISTER.getKey());
dbTester.permissionTemplates().addGroupToTemplate(permissionTemplate, group, PROVISION_PROJECTS.getKey());
dbTester.organizations().setDefaultTemplates(organization, permissionTemplate.getUuid(), null);

underTest.applyDefault(session, organization.getUuid(), view, null);

assertThat(selectProjectPermissionsOfGroup(organization, group, view))
.containsOnly(ADMINISTER.getKey(), PROVISION_PROJECTS.getKey());
}

@Test
public void apply_default_template_on_view() {
OrganizationDto organization = dbTester.organizations().insert();
ComponentDto view = dbTester.components().insertView(organization);
PermissionTemplateDto projectPermissionTemplate = dbTester.permissionTemplates().insertTemplate(organization);
PermissionTemplateDto viewPermissionTemplate = dbTester.permissionTemplates().insertTemplate(organization);
GroupDto group = dbTester.users().insertGroup(organization);
dbTester.permissionTemplates().addGroupToTemplate(viewPermissionTemplate, group, ADMINISTER.getKey());
dbTester.permissionTemplates().addGroupToTemplate(viewPermissionTemplate, group, PROVISION_PROJECTS.getKey());
dbTester.organizations().setDefaultTemplates(organization, projectPermissionTemplate.getUuid(), viewPermissionTemplate.getUuid());

underTest.applyDefault(session, organization.getUuid(), view, null);

assertThat(selectProjectPermissionsOfGroup(organization, group, view))
.containsOnly(ADMINISTER.getKey(), PROVISION_PROJECTS.getKey());
}

@Test
public void apply_project_default_template_on_view_when_no_view_default_template() {
OrganizationDto organization = dbTester.organizations().insert();
ComponentDto view = dbTester.components().insertView(organization);
PermissionTemplateDto projectPermissionTemplate = dbTester.permissionTemplates().insertTemplate(organization);
GroupDto group = dbTester.users().insertGroup(organization);
dbTester.permissionTemplates().addGroupToTemplate(projectPermissionTemplate, group, PROVISION_PROJECTS.getKey());
dbTester.organizations().setDefaultTemplates(organization, projectPermissionTemplate.getUuid(), null);

underTest.applyDefault(session, organization.getUuid(), view, null);

assertThat(selectProjectPermissionsOfGroup(organization, group, view)).containsOnly(PROVISION_PROJECTS.getKey());
}

@Test
public void apply_template_on_applications() {
OrganizationDto organization = dbTester.organizations().insert();
ComponentDto application = dbTester.components().insertApplication(organization);
PermissionTemplateDto permissionTemplate = dbTester.permissionTemplates().insertTemplate(organization);
GroupDto group = dbTester.users().insertGroup(organization);
dbTester.permissionTemplates().addGroupToTemplate(permissionTemplate, group, ADMINISTER.getKey());
dbTester.permissionTemplates().addGroupToTemplate(permissionTemplate, group, PROVISION_PROJECTS.getKey());
dbTester.organizations().setDefaultTemplates(organization, permissionTemplate.getUuid(), null);

underTest.applyDefault(session, organization.getUuid(), application, null);

assertThat(selectProjectPermissionsOfGroup(organization, group, application))
.containsOnly(ADMINISTER.getKey(), PROVISION_PROJECTS.getKey());
}

@Test
public void apply_default_view_template_on_application() {
OrganizationDto organization = dbTester.organizations().insert();
ComponentDto application = dbTester.components().insertApplication(organization);
PermissionTemplateDto projectPermissionTemplate = dbTester.permissionTemplates().insertTemplate(organization);
PermissionTemplateDto viewPermissionTemplate = dbTester.permissionTemplates().insertTemplate(organization);
GroupDto group = dbTester.users().insertGroup(organization);
dbTester.permissionTemplates().addGroupToTemplate(viewPermissionTemplate, group, ADMINISTER.getKey());
dbTester.permissionTemplates().addGroupToTemplate(viewPermissionTemplate, group, PROVISION_PROJECTS.getKey());
dbTester.organizations().setDefaultTemplates(organization, projectPermissionTemplate.getUuid(), viewPermissionTemplate.getUuid());

underTest.applyDefault(session, organization.getUuid(), application, null);

assertThat(selectProjectPermissionsOfGroup(organization, group, application))
.containsOnly(ADMINISTER.getKey(), PROVISION_PROJECTS.getKey());
}

@Test
public void apply_project_default_template_on_application_when_no_application_default_template() {
OrganizationDto organization = dbTester.organizations().insert();
ComponentDto application = dbTester.components().insertApplication(organization);
PermissionTemplateDto projectPermissionTemplate = dbTester.permissionTemplates().insertTemplate(organization);
GroupDto group = dbTester.users().insertGroup(organization);
dbTester.permissionTemplates().addGroupToTemplate(projectPermissionTemplate, group, PROVISION_PROJECTS.getKey());
dbTester.organizations().setDefaultTemplates(organization, projectPermissionTemplate.getUuid(), null);

underTest.applyDefault(session, organization.getUuid(), application, null);

assertThat(selectProjectPermissionsOfGroup(organization, group, application)).containsOnly(PROVISION_PROJECTS.getKey());
}

@Test @Test
public void apply_permission_template() { public void apply_permission_template() {
OrganizationDto organization = dbTester.organizations().insert(); OrganizationDto organization = dbTester.organizations().insert();
Expand Down
Expand Up @@ -20,24 +20,31 @@
package org.sonar.server.permission.ws.template; package org.sonar.server.permission.ws.template;


import org.junit.rules.ExternalResource; import org.junit.rules.ExternalResource;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.ResourceType; import org.sonar.api.resources.ResourceType;
import org.sonar.api.resources.ResourceTypeTree; import org.sonar.api.resources.ResourceTypeTree;
import org.sonar.api.resources.ResourceTypes; import org.sonar.api.resources.ResourceTypes;
import org.sonar.db.organization.DefaultTemplates; import org.sonar.db.organization.DefaultTemplates;


import static org.sonar.api.resources.Qualifiers.APP;
import static org.sonar.api.resources.Qualifiers.PROJECT;
import static org.sonar.api.resources.Qualifiers.VIEW;

public class DefaultTemplatesResolverRule extends ExternalResource implements DefaultTemplatesResolver { public class DefaultTemplatesResolverRule extends ExternalResource implements DefaultTemplatesResolver {
private static final DefaultTemplatesResolver WITH_VIEWS = new DefaultTemplatesResolverImpl( private static final DefaultTemplatesResolver WITH_GOV = new DefaultTemplatesResolverImpl(
new ResourceTypes(new ResourceTypeTree[] { new ResourceTypes(new ResourceTypeTree[] {
ResourceTypeTree.builder() ResourceTypeTree.builder()
.addType(ResourceType.builder(Qualifiers.PROJECT).build()) .addType(ResourceType.builder(PROJECT).build())
.build(),
ResourceTypeTree.builder()
.addType(ResourceType.builder(VIEW).build())
.build(), .build(),
ResourceTypeTree.builder() ResourceTypeTree.builder()
.addType(ResourceType.builder(Qualifiers.VIEW).build()) .addType(ResourceType.builder(APP).build())
.build()})); .build()
private static final DefaultTemplatesResolver WITHOUT_VIEWS = new DefaultTemplatesResolverImpl( }));
private static final DefaultTemplatesResolver WITHOUT_GOV = new DefaultTemplatesResolverImpl(
new ResourceTypes(new ResourceTypeTree[] {ResourceTypeTree.builder() new ResourceTypes(new ResourceTypeTree[] {ResourceTypeTree.builder()
.addType(ResourceType.builder(Qualifiers.PROJECT).build()) .addType(ResourceType.builder(PROJECT).build())
.build()})); .build()}));


private final boolean governanceInitiallyInstalled; private final boolean governanceInitiallyInstalled;
Expand Down Expand Up @@ -72,8 +79,8 @@ public static DefaultTemplatesResolverRule withGovernance() {
@Override @Override
public DefaultTemplatesResolverImpl.ResolvedDefaultTemplates resolve(DefaultTemplates defaultTemplates) { public DefaultTemplatesResolverImpl.ResolvedDefaultTemplates resolve(DefaultTemplates defaultTemplates) {
if (governanceInstalled) { if (governanceInstalled) {
return WITH_VIEWS.resolve(defaultTemplates); return WITH_GOV.resolve(defaultTemplates);
} }
return WITHOUT_VIEWS.resolve(defaultTemplates); return WITHOUT_GOV.resolve(defaultTemplates);
} }
} }

0 comments on commit 3aa22c8

Please sign in to comment.