Skip to content

Commit 7f21778

Browse files
fix(core): periodic update of roles
Update roles in periodic configurable intervals in the scope of minutes.
1 parent 65520d8 commit 7f21778

File tree

5 files changed

+55
-0
lines changed

5 files changed

+55
-0
lines changed

perun-base/src/main/java/cz/metacentrum/perun/core/api/CoreConfig.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ public void initBeansUtils() {
100100
private boolean enforceMfa;
101101
private int idpLoginValidity;
102102
private List<String> idpLoginValidityExceptions;
103+
private int roleUpdateInterval;
103104

104105
public int getGroupMaxConcurentGroupsToSynchronize() {
105106
return groupMaxConcurentGroupsToSynchronize;
@@ -856,4 +857,12 @@ public Set<String> getBlockedLogins() {
856857

857858
return blockedLogins;
858859
}
860+
861+
public int getRoleUpdateInterval() {
862+
return roleUpdateInterval;
863+
}
864+
865+
public void setRoleUpdateInterval(int roleUpdateInterval) {
866+
this.roleUpdateInterval = roleUpdateInterval;
867+
}
859868
}

perun-base/src/main/java/cz/metacentrum/perun/core/api/PerunPrincipal.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ public class PerunPrincipal {
2020
private User user;
2121
// Contains principal's roles together with objects which specifies the role, e.g. VOADMIN -> list contains VO names
2222
private volatile AuthzRoles authzRoles = new AuthzRoles();
23+
// Time of the last update of roles
24+
private long rolesUpdatedAt = System.currentTimeMillis();
2325
// Map contains additional attributes, e.g. from authentication system
2426
private Map<String, String> additionalInformations = new HashMap<String, String>();
2527
// Specifies if the principal has initialized authZResolver
@@ -75,6 +77,7 @@ public String toString() {
7577
.append("user='").append((user != null ? user : "null")).append("', ")
7678
.append("extSourceName='").append(extSourceName).append("', ")
7779
.append("authzRoles='").append(authzRoles).append("', ")
80+
.append("rolesUpdatedAt='").append(rolesUpdatedAt).append("' ")
7881
.append("authzInitialized='").append(authzInitialized).append("']").toString();
7982
}
8083

@@ -142,6 +145,14 @@ public void setExtSourceLoa(int extSourceLoa) {
142145
this.extSourceLoa = extSourceLoa;
143146
}
144147

148+
public long getRolesUpdatedAt() {
149+
return rolesUpdatedAt;
150+
}
151+
152+
public void setRolesUpdatedAt(long rolesUpdatedAt) {
153+
this.rolesUpdatedAt = rolesUpdatedAt;
154+
}
155+
145156
@Override
146157
public int hashCode() {
147158
final int prime = 31;

perun-base/src/main/resources/perun-base.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
<property name="enginePrincipals" value="#{'${perun.engine.principals}'.split('\s*,\s*')}"/>
2222
<property name="generatedLoginNamespaces" value="#{'${perun.loginNamespace.generated}'.split('\s*,\s*')}"/>
2323
<property name="groupSynchronizationInterval" value="${perun.group.synchronization.interval}"/>
24+
<property name="roleUpdateInterval" value="${perun.roleUpdateInterval}"/>
2425
<property name="groupSynchronizationTimeout" value="${perun.group.synchronization.timeout}"/>
2526
<property name="groupStructureSynchronizationInterval" value="${perun.group.structure.synchronization.interval}"/>
2627
<property name="groupStructureSynchronizationTimeout" value="${perun.group.structure.synchronization.timeout}"/>
@@ -148,6 +149,7 @@
148149
<prop key="perun.instanceName">LOCAL</prop>
149150
<prop key="perun.allowedCorsDomains"></prop>
150151
<prop key="perun.queryTimeout">-1</prop>
152+
<prop key="perun.roleUpdateInterval">5</prop>
151153
<prop key="perun.defaultLoa.idp">2</prop>
152154
<prop key="perun.attributesToSearchUsersAndMembersBy">urn:perun:user:attribute-def:def:preferredMail, urn:perun:member:attribute-def:def:mail</prop>
153155
<prop key="perun.attributesToAnonymize"></prop>

perun-core/src/main/java/cz/metacentrum/perun/core/blImpl/AuthzResolverBlImpl.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@
9696
import java.util.Map;
9797
import java.util.Objects;
9898
import java.util.Set;
99+
import java.util.concurrent.TimeUnit;
99100
import java.util.function.BiFunction;
100101
import java.util.function.Function;
101102
import java.util.stream.Collectors;
@@ -139,6 +140,8 @@ public static boolean authorized(PerunSession sess, String policyDefinition, Lis
139140
refreshAuthz(sess);
140141
}
141142

143+
periodicCheckAuthz(sess);
144+
142145
// If the user has no roles, deny access
143146
if (sess.getPerunPrincipal().getRoles() == null) {
144147
return false;
@@ -163,6 +166,20 @@ public static boolean authorized(PerunSession sess, String policyDefinition, Lis
163166
return resolveAuthorization(sess, policyRoles, mapOfBeans);
164167
}
165168

169+
/**
170+
* If the last check was earlier than the set interval then updates the roles.
171+
*
172+
* @param sess session
173+
*/
174+
private static void periodicCheckAuthz(PerunSession sess) {
175+
if (System.currentTimeMillis() - sess.getPerunPrincipal().getRolesUpdatedAt() >= TimeUnit.MINUTES.toMillis(BeansUtils.getCoreConfig().getRoleUpdateInterval())) {
176+
log.debug("Periodic update authz roles for session {}.", sess);
177+
178+
refreshAuthz(sess);
179+
sess.getPerunPrincipal().setRolesUpdatedAt(System.currentTimeMillis());
180+
}
181+
}
182+
166183
/**
167184
* Checks authorization according to MFA rules.
168185
*
@@ -272,6 +289,8 @@ public static boolean authorizedToManageRole(PerunSession sess, PerunBean object
272289
refreshAuthz(sess);
273290
}
274291

292+
periodicCheckAuthz(sess);
293+
275294
// If the user has no roles, deny access
276295
if (sess.getPerunPrincipal().getRoles() == null) {
277296
return false;
@@ -303,6 +322,8 @@ public static boolean authorizedToReadRole(PerunSession sess, PerunBean object,
303322
refreshAuthz(sess);
304323
}
305324

325+
periodicCheckAuthz(sess);
326+
306327
// If the user has no roles, deny access
307328
if (sess.getPerunPrincipal().getRoles() == null) {
308329
return false;
@@ -1854,6 +1875,8 @@ private static boolean hasAccessByDefault(PerunSession sess, AttributeAction act
18541875
refreshAuthz(sess);
18551876
}
18561877

1878+
periodicCheckAuthz(sess);
1879+
18571880
if (sess.getPerunPrincipal().getRoles() == null || sess.getPerunPrincipal().getRoles().isEmpty()) {
18581881
return false;
18591882
}

perun-core/src/test/java/cz/metacentrum/perun/core/api/AuthzResolverIntegrationTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,6 +1082,7 @@ public void isAuthorizedForAttributeAssociatedReadRole() throws Exception {
10821082
PerunPrincipal mockedPerunPrincipal = mock(PerunPrincipal.class, RETURNS_DEEP_STUBS);
10831083
when(mockedPerunPrincipal.isAuthzInitialized()).thenReturn(true);
10841084
when(mockedPerunPrincipal.getRoles()).thenReturn(new AuthzRoles(Role.GROUPOBSERVER, group));
1085+
when(mockedPerunPrincipal.getRolesUpdatedAt()).thenReturn(System.currentTimeMillis());
10851086
when(mockedPerunPrincipal.getUser()).thenReturn(sessionUser);
10861087
when(mockedPerunPrincipal.getUserId()).thenReturn(sessionUser.getId());
10871088

@@ -1115,6 +1116,7 @@ public void isNotAuthorizedForAttributeAssociatedReadRoleWriteAction() throws Ex
11151116
PerunSessionImpl testSession = new PerunSessionImpl(sess.getPerun(), mockedPerunPrincipal, sess.getPerunClient());
11161117

11171118
when(mockedPerunPrincipal.getRoles()).thenReturn(new AuthzRoles(Role.GROUPADMIN, group));
1119+
when(mockedPerunPrincipal.getRolesUpdatedAt()).thenReturn(System.currentTimeMillis());
11181120
assertTrue(AuthzResolver.isAuthorizedForAttribute(testSession, AttributeAction.WRITE, attrDef, group, false));
11191121

11201122
when(mockedPerunPrincipal.getRoles()).thenReturn(new AuthzRoles(Role.GROUPOBSERVER, group));
@@ -1141,6 +1143,7 @@ public void isAuthorizedByDefault() throws Exception {
11411143
PerunPrincipal mockedPerunPrincipal = mock(PerunPrincipal.class, RETURNS_DEEP_STUBS);
11421144
when(mockedPerunPrincipal.isAuthzInitialized()).thenReturn(true);
11431145
when(mockedPerunPrincipal.getRoles()).thenReturn(new AuthzRoles(Role.PERUNOBSERVER));
1146+
when(mockedPerunPrincipal.getRolesUpdatedAt()).thenReturn(System.currentTimeMillis());
11441147
when(mockedPerunPrincipal.getUser()).thenReturn(sessionUser);
11451148
when(mockedPerunPrincipal.getUserId()).thenReturn(sessionUser.getId());
11461149

@@ -1196,6 +1199,7 @@ public void setRoleGroupAdminSucceedsForVoAdmin() throws Exception {
11961199
PerunPrincipal mockedPerunPrincipal = mock(PerunPrincipal.class, RETURNS_DEEP_STUBS);
11971200
when(mockedPerunPrincipal.isAuthzInitialized()).thenReturn(true);
11981201
when(mockedPerunPrincipal.getRoles()).thenReturn(new AuthzRoles(Role.VOADMIN, testVo));
1202+
when(mockedPerunPrincipal.getRolesUpdatedAt()).thenReturn(System.currentTimeMillis());
11991203

12001204
PerunSession testSession = new PerunSessionImpl(sess.getPerun(), mockedPerunPrincipal, sess.getPerunClient());
12011205

@@ -1215,6 +1219,7 @@ public void setRoleGroupAdminFailsWithoutSufficientRole() throws Exception {
12151219
PerunPrincipal mockedPerunPrincipal = mock(PerunPrincipal.class, RETURNS_DEEP_STUBS);
12161220
when(mockedPerunPrincipal.isAuthzInitialized()).thenReturn(true);
12171221
when(mockedPerunPrincipal.getRoles()).thenReturn(new AuthzRoles(Role.VOADMIN, otherVo));
1222+
when(mockedPerunPrincipal.getRolesUpdatedAt()).thenReturn(System.currentTimeMillis());
12181223

12191224
PerunSession testSession = new PerunSessionImpl(sess.getPerun(), mockedPerunPrincipal, sess.getPerunClient());
12201225

@@ -1243,6 +1248,7 @@ public void getVoAdminGroupsWithProperRights() throws Exception {
12431248
PerunPrincipal mockedPerunPrincipal = mock(PerunPrincipal.class, RETURNS_DEEP_STUBS);
12441249
when(mockedPerunPrincipal.isAuthzInitialized()).thenReturn(true);
12451250
when(mockedPerunPrincipal.getRoles()).thenReturn(new AuthzRoles(Role.VOADMIN, testVo));
1251+
when(mockedPerunPrincipal.getRolesUpdatedAt()).thenReturn(System.currentTimeMillis());
12461252
PerunSession testSession = new PerunSessionImpl(sess.getPerun(), mockedPerunPrincipal, sess.getPerunClient());
12471253

12481254
AuthzResolver.setRole(testSession, testGroup, testVo, Role.VOADMIN);
@@ -1262,6 +1268,7 @@ public void getVoAdminGroupsWithInsufficientRights() throws Exception {
12621268
PerunPrincipal mockedPerunPrincipal = mock(PerunPrincipal.class, RETURNS_DEEP_STUBS);
12631269
when(mockedPerunPrincipal.isAuthzInitialized()).thenReturn(true);
12641270
when(mockedPerunPrincipal.getRoles()).thenReturn(new AuthzRoles());
1271+
when(mockedPerunPrincipal.getRolesUpdatedAt()).thenReturn(System.currentTimeMillis());
12651272
PerunSession testSession = new PerunSessionImpl(sess.getPerun(), mockedPerunPrincipal, sess.getPerunClient());
12661273

12671274
AuthzResolver.setRole(sess, testGroup, testVo, Role.VOADMIN);
@@ -1279,6 +1286,7 @@ public void getVoDirectRichAdminsWithProperRights() throws Exception {
12791286
PerunPrincipal mockedPerunPrincipal = mock(PerunPrincipal.class, RETURNS_DEEP_STUBS);
12801287
when(mockedPerunPrincipal.isAuthzInitialized()).thenReturn(true);
12811288
when(mockedPerunPrincipal.getRoles()).thenReturn(new AuthzRoles(Role.VOADMIN, testVo));
1289+
when(mockedPerunPrincipal.getRolesUpdatedAt()).thenReturn(System.currentTimeMillis());
12821290
PerunSession testSession = new PerunSessionImpl(sess.getPerun(), mockedPerunPrincipal, sess.getPerunClient());
12831291

12841292
AuthzResolver.setRole(testSession, testUser, testVo, Role.VOADMIN);
@@ -1299,6 +1307,7 @@ public void getVoDirectRichAdminsWithInsufficientRights() throws Exception {
12991307
PerunPrincipal mockedPerunPrincipal = mock(PerunPrincipal.class, RETURNS_DEEP_STUBS);
13001308
when(mockedPerunPrincipal.isAuthzInitialized()).thenReturn(true);
13011309
when(mockedPerunPrincipal.getRoles()).thenReturn(new AuthzRoles());
1310+
when(mockedPerunPrincipal.getRolesUpdatedAt()).thenReturn(System.currentTimeMillis());
13021311
PerunSession testSession = new PerunSessionImpl(sess.getPerun(), mockedPerunPrincipal, sess.getPerunClient());
13031312

13041313
AuthzResolver.setRole(sess, testUser, testVo, Role.VOADMIN);
@@ -1321,6 +1330,7 @@ public void getVoRichAdminsWithProperRights() throws Exception {
13211330
PerunPrincipal mockedPerunPrincipal = mock(PerunPrincipal.class, RETURNS_DEEP_STUBS);
13221331
when(mockedPerunPrincipal.isAuthzInitialized()).thenReturn(true);
13231332
when(mockedPerunPrincipal.getRoles()).thenReturn(new AuthzRoles(Role.VOADMIN, testVo));
1333+
when(mockedPerunPrincipal.getRolesUpdatedAt()).thenReturn(System.currentTimeMillis());
13241334
PerunSession testSession = new PerunSessionImpl(sess.getPerun(), mockedPerunPrincipal, sess.getPerunClient());
13251335

13261336
AuthzResolver.setRole(testSession, testUser, testVo, Role.VOADMIN);

0 commit comments

Comments
 (0)