Skip to content

Commit c2acec1

Browse files
committed
Fixes #546
1 parent ac794b4 commit c2acec1

File tree

3 files changed

+31
-9
lines changed

3 files changed

+31
-9
lines changed

client/src/utils/UserRole.js

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ export const markAndFilterRoles = (user, allRoles, locale, multiple, separator,
135135
role.value = role.id;
136136
deriveApplicationAttributes(role, locale, multiple, separator);
137137
});
138-
if (!isUserAllowed(AUTHORITIES.INSTITUTION_ADMIN, user)) {
138+
if (!user.superUser) {
139139
const userRoles = user.userRoles;
140140
userRoles.forEach(userRole => {
141141
userRole.isUserRole = true;
@@ -171,7 +171,13 @@ export const allowedAuthoritiesForInvitation = (user, selectedRoles) => {
171171
return Object.keys(AUTHORITIES);
172172

173173
}
174-
if (user.institutionAdmin && !isEmpty(user.applications)) {
174+
//Return only the AUTHORITIES where the user has the correct authority per selectedRole
175+
const userRolesForSelectedRoles = selectedRoles
176+
.map(role => role.isUserRole ? role.role : role)
177+
.map(role => user.userRoles.find(userRole => userRole.role.id === role.id))
178+
.filter(userRole => !isEmpty(userRole));
179+
//If the user is an institutionAdmin but is also a regular inviter or manager of this role, then filter the authorities
180+
if (user.institutionAdmin && !isEmpty(user.applications) && userRolesForSelectedRoles.length === 0) {
175181
return Object.keys(AUTHORITIES)
176182
.filter(authority => authority !== AUTHORITIES.SUPER_USER);
177183
}
@@ -183,11 +189,6 @@ export const allowedAuthoritiesForInvitation = (user, selectedRoles) => {
183189
return Object.keys(AUTHORITIES)
184190
.filter(auth => AUTHORITIES_HIERARCHY[auth] > AUTHORITIES_HIERARCHY[authority]);
185191
}
186-
//Return only the AUTHORITIES where the user has the correct authority per selectedRole
187-
const userRolesForSelectedRoles = selectedRoles
188-
.map(role => role.isUserRole ? role.role : role)
189-
.map(role => user.userRoles.find(userRole => userRole.role.id === role.id))
190-
.filter(userRole => !isEmpty(userRole));
191192
const leastImportantAuthority = userRolesForSelectedRoles
192193
.reduce((acc, userRole) => {
193194
if (AUTHORITIES_HIERARCHY[userRole.authority] < AUTHORITIES_HIERARCHY[acc]) {

server/src/main/java/invite/security/UserPermissions.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,12 @@ public static void assertValidInvitation(User user, Authority intendedAuthority,
7878
}
7979
//For all roles verify that the user has a higher authority then the one requested for all off the roles
8080
boolean allowed = roles.stream()
81-
.allMatch(role -> mayInviteByApplication(userRoles, intendedAuthority, role) ||
82-
mayInviteByAuthority(userRoles, intendedAuthority, role));
81+
.allMatch(role -> {
82+
boolean mayInviteByInstitutionAdmin = user.isInstitutionAdmin() && user.getOrganizationGUID().equals(role.getOrganizationGUID());
83+
boolean mayInviteByApplication = mayInviteByApplication(userRoles, intendedAuthority, role);
84+
boolean mayInviteByAuthority = mayInviteByAuthority(userRoles, intendedAuthority, role);
85+
return mayInviteByInstitutionAdmin || mayInviteByApplication || mayInviteByAuthority;
86+
});
8387
if (!allowed) {
8488
throw new UserRestrictionException();
8589
}

server/src/test/java/invite/security/UserPermissionsTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,23 @@ void assertNoRoleAccess() {
145145
assertThrows(UserRestrictionException.class, () -> UserPermissions.assertRoleAccess(user, role, Authority.INVITER));
146146
}
147147

148+
@Test
149+
void institutionAdminWithRegularRole() {
150+
String organizationGUID = UUID.randomUUID().toString();
151+
User user = new User();
152+
user.setOrganizationGUID(organizationGUID);
153+
user.setInstitutionAdmin(true);
154+
//May invite users for this role because of organization GUID
155+
Role role = new Role("institution-admin-role", "description", application(organizationGUID, EntityType.SAML20_SP), 365, false, false);
156+
role.setId(random.nextLong());
157+
role.setOrganizationGUID(organizationGUID);
158+
//May invite users for this role because of role membership
159+
Role manager = new Role("manager-role", "description", application(UUID.randomUUID().toString(), EntityType.SAML20_SP), 365, false, false);
160+
manager.setId(random.nextLong());
161+
user.addUserRole(new UserRole(Authority.MANAGER, manager));
162+
UserPermissions.assertValidInvitation(user, Authority.INVITER, List.of(role, manager));
163+
}
164+
148165
@Test
149166
void nullPointerHygiene() {
150167
assertThrows(UserRestrictionException.class, () -> UserPermissions.assertSuperUser(null));

0 commit comments

Comments
 (0)