Skip to content

Commit 9d9ddfd

Browse files
allow users to edit access to their projects (#498)
* allow users to edit access to their projects * hide user access component if user is not allowed to use it * address code smells * more code smells
1 parent 76dd628 commit 9d9ddfd

File tree

5 files changed

+37
-18
lines changed

5 files changed

+37
-18
lines changed

project-management-infrastructure/src/main/java/life/qbic/projectmanagement/infrastructure/project/ProjectRepositoryImpl.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public void add(Project project) {
7474
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
7575
QbicUserDetails details = (QbicUserDetails) authentication.getPrincipal();
7676
projectAccessService.grant(details.getUserId(), project.getId(),
77-
List.of(READ, WRITE));
77+
List.of(READ, WRITE, ADMINISTRATION));//administration of this project, only
7878
projectAccessService.grantToAuthority(ADMIN.auth(), project.getId(), ADMIN.permissions());
7979
projectAccessService.grantToAuthority(PROJECT_MANAGER.auth(), project.getId(),
8080
PROJECT_MANAGER.permissions());

user-interface/src/main/java/life/qbic/datamanager/security/UserPermissionsImpl.java

+7-3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ public class UserPermissionsImpl implements UserPermissions {
1212

1313
final AclPermissionEvaluator aclPermissionEvaluator;
1414

15+
private static final String projectTargetType = "life.qbic.projectmanagement.domain.model.project.Project";
16+
1517
public UserPermissionsImpl(@Autowired
1618
AclPermissionEvaluator aclPermissionEvaluator) {
1719
this.aclPermissionEvaluator = aclPermissionEvaluator;
@@ -21,16 +23,18 @@ public UserPermissionsImpl(@Autowired
2123
public boolean readProject(ProjectId projectId) {
2224
return aclPermissionEvaluator.hasPermission(
2325
SecurityContextHolder.getContext().getAuthentication(), projectId,
24-
"life.qbic.projectmanagement.domain.model.project.Project", "READ");
26+
projectTargetType, "READ");
2527
}
2628

2729
@Override
2830
public boolean changeProjectAccess(ProjectId projectId) {
2931
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
3032
boolean hasReadPermission = aclPermissionEvaluator.hasPermission(authentication, projectId,
31-
"life.qbic.projectmanagement.domain.model.project.Project", "READ");
33+
projectTargetType, "READ");
34+
boolean hasCreatedProject = aclPermissionEvaluator.hasPermission(authentication, projectId,
35+
projectTargetType, "ADMINISTRATION");
3236
boolean canChangeAclAccess = authentication.getAuthorities().stream()
3337
.anyMatch(it -> it.getAuthority().equals("acl:change-access"));
34-
return (hasReadPermission && canChangeAclAccess);
38+
return (hasReadPermission && (canChangeAclAccess || hasCreatedProject));
3539
}
3640
}

user-interface/src/main/java/life/qbic/datamanager/views/navigation/ProjectSideNavigationComponent.java

+19-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package life.qbic.datamanager.views.navigation;
22

3+
import static java.util.Objects.requireNonNull;
34
import static org.slf4j.LoggerFactory.getLogger;
45

56
import com.vaadin.flow.component.Component;
@@ -27,6 +28,7 @@
2728
import java.util.Objects;
2829
import java.util.Optional;
2930
import life.qbic.application.commons.ApplicationException;
31+
import life.qbic.datamanager.security.UserPermissions;
3032
import life.qbic.datamanager.views.AppRoutes.Projects;
3133
import life.qbic.datamanager.views.Context;
3234
import life.qbic.datamanager.views.projects.overview.ProjectOverviewMain;
@@ -63,14 +65,17 @@ public class ProjectSideNavigationComponent extends Div implements
6365
private final Div content;
6466
private final transient ProjectInformationService projectInformationService;
6567
private final transient ExperimentInformationService experimentInformationService;
68+
private final transient UserPermissions userPermissions;
6669
private Context context = new Context();
6770

6871
public ProjectSideNavigationComponent(
6972
@Autowired ProjectInformationService projectInformationService,
70-
@Autowired ExperimentInformationService experimentInformationService) {
73+
@Autowired ExperimentInformationService experimentInformationService,
74+
@Autowired UserPermissions userPermissions) {
7175
content = new Div();
7276
Objects.requireNonNull(projectInformationService);
7377
Objects.requireNonNull(experimentInformationService);
78+
this.userPermissions = requireNonNull(userPermissions, "userPermissions must not be null");
7479
addClassName("project-navigation-drawer");
7580
this.projectInformationService = projectInformationService;
7681
this.experimentInformationService = experimentInformationService;
@@ -95,8 +100,10 @@ public void beforeEnter(BeforeEnterEvent beforeEnterEvent) {
95100
var project = loadProject(parsedProjectId);
96101
List<Experiment> experiments = loadExperimentsForProject(project);
97102
List<ProjectPreview> lastModifiedProjects = retrieveLastModifiedProjects();
98-
content.add(generateNavigationSections(project, lastModifiedProjects, experiments).toArray(
99-
Component[]::new));
103+
boolean canUserAdministrate = userPermissions.changeProjectAccess(parsedProjectId);
104+
content.add(
105+
generateNavigationSections(project, lastModifiedProjects, experiments, canUserAdministrate)
106+
.toArray(Component[]::new));
100107
}
101108

102109
private Project loadProject(ProjectId id) {
@@ -116,19 +123,19 @@ private List<ProjectPreview> retrieveLastModifiedProjects() {
116123
}
117124

118125
private static List<Div> generateNavigationSections(Project project,
119-
List<ProjectPreview> lastModifiedProjects, List<Experiment> experiments) {
120-
Div projectSection = createProjectSection(project, lastModifiedProjects);
126+
List<ProjectPreview> lastModifiedProjects, List<Experiment> experiments, boolean canUserAdministrate) {
127+
Div projectSection = createProjectSection(project, lastModifiedProjects, canUserAdministrate);
121128
Div experimentSection = createExperimentSection(project.getId().value(), experiments);
122129
return List.of(projectSection, experimentSection);
123130
}
124131

125132
private static Div createProjectSection(Project project,
126-
List<ProjectPreview> lastModifiedProjects) {
133+
List<ProjectPreview> lastModifiedProjects, boolean canUserAdministrate) {
127134
Div projectSection = new Div();
128135
projectSection.add(createProjectHeader(),
129136
createProjectSelection(project.getProjectIntent().projectTitle().title(),
130137
lastModifiedProjects),
131-
generateSectionDivider(), createProjectItems(project.getId().value()));
138+
generateSectionDivider(), createProjectItems(project.getId().value(), canUserAdministrate));
132139
projectSection.addClassName("project-section");
133140
return projectSection;
134141
}
@@ -187,9 +194,12 @@ private static Span generateSectionDivider() {
187194
return sectionDivider;
188195
}
189196

190-
private static Div createProjectItems(String projectId) {
197+
private static Div createProjectItems(String projectId, boolean canUserAdministrate) {
191198
Div projectItems = new Div();
192-
projectItems.add(createProjectSummaryLink(projectId), createProjectUsers(projectId));
199+
projectItems.add(createProjectSummaryLink(projectId));
200+
if(canUserAdministrate) {
201+
projectItems.add(createProjectUsers(projectId));
202+
}
193203
projectItems.addClassName("project-items");
194204
return projectItems;
195205
}

user-interface/src/main/java/life/qbic/datamanager/views/projects/project/ProjectMainLayout.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import com.vaadin.flow.router.PageTitle;
99
import java.util.Objects;
1010
import life.qbic.datamanager.security.LogoutService;
11+
import life.qbic.datamanager.security.UserPermissions;
1112
import life.qbic.datamanager.views.Context;
1213
import life.qbic.datamanager.views.general.DataManagerMenu;
1314
import life.qbic.datamanager.views.navigation.ProjectSideNavigationComponent;
@@ -34,19 +35,21 @@ public class ProjectMainLayout extends AppLayout implements BeforeEnterObserver
3435
private final ProjectSideNavigationComponent projectSideNavigationComponent;
3536
private final DataManagerMenu dataManagerMenu;
3637
private final transient ProjectInformationService projectInformationService;
38+
3739
private Context context = new Context();
3840
private final Span projectTitle = new Span();
3941

4042
public ProjectMainLayout(@Autowired LogoutService logoutService,
4143
ProjectInformationService projectInformationService,
42-
ExperimentInformationService experimentInformationService) {
44+
ExperimentInformationService experimentInformationService,
45+
@Autowired UserPermissions userPermissions) {
4346
Objects.requireNonNull(logoutService);
4447
Objects.requireNonNull(projectInformationService);
4548
Objects.requireNonNull(experimentInformationService);
4649
this.projectInformationService = projectInformationService;
4750
this.projectSideNavigationComponent = new ProjectSideNavigationComponent(
4851
projectInformationService,
49-
experimentInformationService);
52+
experimentInformationService, userPermissions);
5053
dataManagerMenu = new DataManagerMenu(logoutService);
5154
addToNavbar(createDrawerToggleAndTitleBar(), dataManagerMenu);
5255
addClassName("project-main-layout");

user-interface/src/main/java/life/qbic/datamanager/views/projects/project/experiments/ExperimentMainLayout.java

+5-3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import java.util.Objects;
1717
import life.qbic.application.commons.ApplicationException;
1818
import life.qbic.datamanager.security.LogoutService;
19+
import life.qbic.datamanager.security.UserPermissions;
1920
import life.qbic.datamanager.views.Context;
2021
import life.qbic.datamanager.views.general.DataManagerMenu;
2122
import life.qbic.datamanager.views.navigation.ProjectSideNavigationComponent;
@@ -52,15 +53,16 @@ public class ExperimentMainLayout extends AppLayout implements BeforeEnterObserv
5253

5354
public ExperimentMainLayout(@Autowired LogoutService logoutService,
5455
@Autowired ProjectInformationService projectInformationService,
55-
@Autowired ExperimentInformationService experimentInformationService) {
56+
@Autowired ExperimentInformationService experimentInformationService,
57+
@Autowired UserPermissions userPermissions) {
5658
Objects.requireNonNull(logoutService);
5759
Objects.requireNonNull(projectInformationService);
5860
Objects.requireNonNull(experimentInformationService);
5961
this.dataManagerMenu = new DataManagerMenu(logoutService);
6062
this.experimentInformationService = experimentInformationService;
6163
this.projectSideNavigationComponent = new ProjectSideNavigationComponent(
62-
projectInformationService,
63-
experimentInformationService);
64+
projectInformationService, experimentInformationService,
65+
userPermissions);
6466
initializeNavbar();
6567
initializeAppDrawer();
6668
addClassName("experiment-main-layout");

0 commit comments

Comments
 (0)