task #9088 Authorization model should be changed to be Permission based
This commit is contained in:
parent
419c4d64f8
commit
7ed111e936
|
@ -21,6 +21,11 @@
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>gr.cite</groupId>
|
||||||
|
<artifactId>oidc-authz</artifactId>
|
||||||
|
<version>2.1.0</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package eu.eudat.authorization;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
|
|
||||||
|
public enum AuthorizationFlags {
|
||||||
|
None, Permission, Owner;
|
||||||
|
public static final EnumSet<AuthorizationFlags> OwnerOrPermission = EnumSet.of(Owner, Permission);
|
||||||
|
public static final EnumSet<AuthorizationFlags> OwnerOrPermissionOrIndicator = EnumSet.of(Owner, Permission);
|
||||||
|
public static final EnumSet<AuthorizationFlags> OwnerOrPermissionOrIndicatorOrIndicatorAccess = EnumSet.of(Owner, Permission);
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
package eu.eudat.authorization;
|
||||||
|
|
||||||
|
import gr.cite.commons.web.authz.policy.AuthorizationRequirement;
|
||||||
|
|
||||||
|
public class OwnedAuthorizationRequirement implements AuthorizationRequirement {
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package eu.eudat.authorization;
|
||||||
|
|
||||||
|
import gr.cite.commons.web.authz.policy.AuthorizationResource;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class OwnedResource extends AuthorizationResource {
|
||||||
|
private List<UUID> userIds;
|
||||||
|
|
||||||
|
public OwnedResource(UUID userId) {
|
||||||
|
this(List.of(userId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public OwnedResource(List<UUID> userIds) {
|
||||||
|
this.userIds = userIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<UUID> getUserIds() {
|
||||||
|
return userIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserIds(List<UUID> userIds) {
|
||||||
|
this.userIds = userIds;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package eu.eudat.authorization;
|
||||||
|
|
||||||
|
public final class Permission {
|
||||||
|
|
||||||
|
//DescriptionTemplateType
|
||||||
|
public static String BrowseDescriptionTemplateType = "BrowseDescriptionTemplateType";
|
||||||
|
public static String EditDescriptionTemplateType = "EditDescriptionTemplateType";
|
||||||
|
public static String DeleteDescriptionTemplateType = "DeleteDescriptionTemplateType";
|
||||||
|
|
||||||
|
// UI Pages
|
||||||
|
public static String ViewDescriptionTemplateTypePage = "ViewDescriptionTemplateTypePage";
|
||||||
|
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package eu.eudat.commons.scope;
|
package eu.eudat.commons.scope.user;
|
||||||
|
|
||||||
import gr.cite.tools.logging.LoggerService;
|
import gr.cite.tools.logging.LoggerService;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
|
@ -1,6 +1,8 @@
|
||||||
package eu.eudat.model.censorship;
|
package eu.eudat.model.censorship;
|
||||||
|
|
||||||
|
import eu.eudat.authorization.Permission;
|
||||||
import eu.eudat.convention.ConventionService;
|
import eu.eudat.convention.ConventionService;
|
||||||
|
import gr.cite.commons.web.authz.service.AuthorizationService;
|
||||||
import gr.cite.tools.fieldset.FieldSet;
|
import gr.cite.tools.fieldset.FieldSet;
|
||||||
import gr.cite.tools.logging.DataLogEntry;
|
import gr.cite.tools.logging.DataLogEntry;
|
||||||
import gr.cite.tools.logging.LoggerService;
|
import gr.cite.tools.logging.LoggerService;
|
||||||
|
@ -14,15 +16,17 @@ import org.springframework.stereotype.Component;
|
||||||
public class DescriptionTemplateTypeCensor extends BaseCensor{
|
public class DescriptionTemplateTypeCensor extends BaseCensor{
|
||||||
|
|
||||||
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(DescriptionTemplateTypeCensor.class));
|
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(DescriptionTemplateTypeCensor.class));
|
||||||
|
protected final AuthorizationService authService;
|
||||||
public DescriptionTemplateTypeCensor(ConventionService conventionService) {
|
public DescriptionTemplateTypeCensor(ConventionService conventionService, AuthorizationService authService) {
|
||||||
super(conventionService);
|
super(conventionService);
|
||||||
|
this.authService = authService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void censor(FieldSet fields) {
|
public void censor(FieldSet fields) {
|
||||||
logger.debug(new DataLogEntry("censoring fields", fields));
|
logger.debug(new DataLogEntry("censoring fields", fields));
|
||||||
if (fields.isEmpty())
|
if (fields.isEmpty()) return;
|
||||||
return;
|
|
||||||
|
this.authService.authorizeForce(Permission.BrowseDescriptionTemplateType);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -329,6 +329,12 @@
|
||||||
<version>2.1.0</version>
|
<version>2.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>gr.cite</groupId>
|
||||||
|
<artifactId>oidc-authz</artifactId>
|
||||||
|
<version>2.1.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<profiles>
|
<profiles>
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
package eu.eudat.authorization;
|
||||||
|
|
||||||
|
import eu.eudat.commons.scope.user.UserScope;
|
||||||
|
import gr.cite.commons.web.authz.handler.AuthorizationHandler;
|
||||||
|
import gr.cite.commons.web.authz.handler.AuthorizationHandlerContext;
|
||||||
|
import gr.cite.commons.web.authz.policy.AuthorizationRequirement;
|
||||||
|
import gr.cite.commons.web.oidc.principal.MyPrincipal;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component("ownedAuthorizationHandler")
|
||||||
|
public class OwnedAuthorizationHandler extends AuthorizationHandler<OwnedAuthorizationRequirement> {
|
||||||
|
|
||||||
|
private final UserScope userScope;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public OwnedAuthorizationHandler(UserScope userScope) {
|
||||||
|
this.userScope = userScope;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int handleRequirement(AuthorizationHandlerContext context, Object resource, AuthorizationRequirement requirement) {
|
||||||
|
OwnedAuthorizationRequirement req = (OwnedAuthorizationRequirement) requirement;
|
||||||
|
|
||||||
|
OwnedResource rs = (OwnedResource) resource;
|
||||||
|
|
||||||
|
boolean isAuthenticated = ((MyPrincipal) context.getPrincipal()).isAuthenticated();
|
||||||
|
if (!isAuthenticated) return ACCESS_NOT_DETERMINED;
|
||||||
|
|
||||||
|
if (this.userScope.getUserIdSafe() == null) return ACCESS_NOT_DETERMINED;
|
||||||
|
|
||||||
|
if (rs != null && rs.getUserIds() != null && rs.getUserIds().contains(this.userScope.getUserIdSafe())) return ACCESS_GRANTED;
|
||||||
|
|
||||||
|
return ACCESS_NOT_DETERMINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends AuthorizationRequirement> supporting() {
|
||||||
|
return OwnedAuthorizationRequirement.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,6 +1,16 @@
|
||||||
package eu.eudat.configurations;
|
package eu.eudat.configurations;
|
||||||
|
|
||||||
|
|
||||||
|
import eu.eudat.authorization.OwnedAuthorizationHandler;
|
||||||
|
import eu.eudat.authorization.OwnedAuthorizationRequirement;
|
||||||
|
import eu.eudat.authorization.OwnedResource;
|
||||||
|
import gr.cite.commons.web.authz.handler.AuthorizationHandler;
|
||||||
|
import gr.cite.commons.web.authz.handler.PermissionClientAuthorizationHandler;
|
||||||
|
import gr.cite.commons.web.authz.policy.AuthorizationRequirement;
|
||||||
|
import gr.cite.commons.web.authz.policy.AuthorizationRequirementMapper;
|
||||||
|
import gr.cite.commons.web.authz.policy.AuthorizationResource;
|
||||||
|
import gr.cite.commons.web.authz.policy.resolver.AuthorizationPolicyConfigurer;
|
||||||
|
import gr.cite.commons.web.authz.policy.resolver.AuthorizationPolicyResolverStrategy;
|
||||||
import gr.cite.commons.web.oidc.configuration.WebSecurityProperties;
|
import gr.cite.commons.web.oidc.configuration.WebSecurityProperties;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
@ -17,6 +27,7 @@ import org.springframework.security.web.authentication.preauth.AbstractPreAuthen
|
||||||
|
|
||||||
import jakarta.servlet.Filter;
|
import jakarta.servlet.Filter;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
@ -27,14 +38,17 @@ public class SecurityConfiguration {
|
||||||
private final WebSecurityProperties webSecurityProperties;
|
private final WebSecurityProperties webSecurityProperties;
|
||||||
private final AuthenticationManagerResolver<HttpServletRequest> authenticationManagerResolver;
|
private final AuthenticationManagerResolver<HttpServletRequest> authenticationManagerResolver;
|
||||||
private final Filter apiKeyFilter;
|
private final Filter apiKeyFilter;
|
||||||
|
private final OwnedAuthorizationHandler ownedAuthorizationHandler;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public SecurityConfiguration(WebSecurityProperties webSecurityProperties,
|
public SecurityConfiguration(WebSecurityProperties webSecurityProperties,
|
||||||
@Qualifier("tokenAuthenticationResolver") AuthenticationManagerResolver<HttpServletRequest> authenticationManagerResolver,
|
@Qualifier("tokenAuthenticationResolver") AuthenticationManagerResolver<HttpServletRequest> authenticationManagerResolver,
|
||||||
@Qualifier("apiKeyFilter") Filter apiKeyFilter) {
|
@Qualifier("apiKeyFilter") Filter apiKeyFilter,
|
||||||
|
@Qualifier("ownedAuthorizationHandler") OwnedAuthorizationHandler ownedAuthorizationHandler) {
|
||||||
this.webSecurityProperties = webSecurityProperties;
|
this.webSecurityProperties = webSecurityProperties;
|
||||||
this.authenticationManagerResolver = authenticationManagerResolver;
|
this.authenticationManagerResolver = authenticationManagerResolver;
|
||||||
this.apiKeyFilter = apiKeyFilter;
|
this.apiKeyFilter = apiKeyFilter;
|
||||||
|
this.ownedAuthorizationHandler = ownedAuthorizationHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
@ -52,60 +66,61 @@ public class SecurityConfiguration {
|
||||||
return tempHttp.build();
|
return tempHttp.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Bean
|
@Bean
|
||||||
// AuthorizationPolicyConfigurer authorizationPolicyConfigurer() {
|
AuthorizationPolicyConfigurer authorizationPolicyConfigurer() {
|
||||||
// return new AuthorizationPolicyConfigurer() {
|
return new AuthorizationPolicyConfigurer() {
|
||||||
//
|
|
||||||
// @Override
|
@Override
|
||||||
// public AuthorizationPolicyResolverStrategy strategy() {
|
public AuthorizationPolicyResolverStrategy strategy() {
|
||||||
// return AuthorizationPolicyResolverStrategy.STRICT_CONSENSUS_BASED;
|
return AuthorizationPolicyResolverStrategy.STRICT_CONSENSUS_BASED;
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// //Here you can register your custom authorization handlers, which will get used as well as the existing ones
|
//Here you can register your custom authorization handlers, which will get used as well as the existing ones
|
||||||
// //This is optional and can be omitted
|
//This is optional and can be omitted
|
||||||
// //If not set / set to null, only the default authorization handlers will be used
|
//If not set / set to null, only the default authorization handlers will be used
|
||||||
// @Override
|
@Override
|
||||||
// public List<AuthorizationHandler<? extends AuthorizationRequirement>> addCustomHandlers() {
|
public List<AuthorizationHandler<? extends AuthorizationRequirement>> addCustomHandlers() {
|
||||||
// return null;
|
return List.of( ownedAuthorizationHandler);
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// //Here you can register your custom authorization requirements (if any)
|
//Here you can register your custom authorization requirements (if any)
|
||||||
// //This is optional and can be omitted
|
//This is optional and can be omitted
|
||||||
// //If not set / set to null, only the default authorization requirements will be used
|
//If not set / set to null, only the default authorization requirements will be used
|
||||||
// @Override
|
@Override
|
||||||
// public List<? extends AuthorizationRequirement> extendRequirements() {
|
public List<? extends AuthorizationRequirement> extendRequirements() {
|
||||||
// return List.of(
|
return List.of(
|
||||||
//// new TimeOfDayAuthorizationRequirement(new TimeOfDay("08:00","16:00"), true)
|
// new TimeOfDayAuthorizationRequirement(new TimeOfDay("08:00","16:00"), true)
|
||||||
// );
|
);
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// //Here you can select handlers you want to disable by providing the classes they are implemented by
|
//Here you can select handlers you want to disable by providing the classes they are implemented by
|
||||||
// //You can disable any handler (including any custom one)
|
//You can disable any handler (including any custom one)
|
||||||
// //This is optional and can be omitted
|
//This is optional and can be omitted
|
||||||
// //If not set / set to null, all the handlers will be invoked, based on their requirement support
|
//If not set / set to null, all the handlers will be invoked, based on their requirement support
|
||||||
// //In the example below, the default client handler will be ignored by the resolver
|
//In the example below, the default client handler will be ignored by the resolver
|
||||||
// @Override
|
@Override
|
||||||
// public List<Class<? extends AuthorizationHandler<? extends AuthorizationRequirement>>> disableHandlers() {
|
public List<Class<? extends AuthorizationHandler<? extends AuthorizationRequirement>>> disableHandlers() {
|
||||||
// return List.of(PermissionClientAuthorizationHandler.class);
|
return List.of(PermissionClientAuthorizationHandler.class);
|
||||||
// }
|
}
|
||||||
// };
|
};
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// @Bean
|
@Bean
|
||||||
// AuthorizationRequirementMapper authorizationRequirementMapper() {
|
AuthorizationRequirementMapper authorizationRequirementMapper() {
|
||||||
// return new AuthorizationRequirementMapper() {
|
return new AuthorizationRequirementMapper() {
|
||||||
// @Override
|
@Override
|
||||||
// public AuthorizationRequirement map(AuthorizationResource resource, boolean matchAll, String[] permissions) {
|
public AuthorizationRequirement map(AuthorizationResource resource, boolean matchAll, String[] permissions) {
|
||||||
// Class<?> type = resource.getClass();
|
Class<?> type = resource.getClass();
|
||||||
// if (!AuthorizationResource.class.isAssignableFrom(type)) throw new IllegalArgumentException("resource");
|
if (!AuthorizationResource.class.isAssignableFrom(type)) throw new IllegalArgumentException("resource");
|
||||||
//
|
|
||||||
// if (OwnedResource.class.equals(type)) {
|
if (OwnedResource.class.equals(type)) {
|
||||||
// return new OwnedAuthorizationRequirement();
|
return new OwnedAuthorizationRequirement();
|
||||||
// }
|
}
|
||||||
// throw new IllegalArgumentException("resource");
|
throw new IllegalArgumentException("resource");
|
||||||
// }
|
}
|
||||||
// };
|
};
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
|
||||||
private String[] buildAntPatterns(Set<String> endpoints) {
|
private String[] buildAntPatterns(Set<String> endpoints) {
|
||||||
if (endpoints == null) {
|
if (endpoints == null) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package eu.eudat.configurations;
|
package eu.eudat.configurations;
|
||||||
|
|
||||||
import eu.eudat.commons.scope.UserScope;
|
import eu.eudat.commons.scope.user.UserScope;
|
||||||
import eu.eudat.interceptors.UserInterceptor;
|
import eu.eudat.interceptors.UserInterceptor;
|
||||||
import eu.eudat.logic.handlers.PrincipalArgumentResolver;
|
import eu.eudat.logic.handlers.PrincipalArgumentResolver;
|
||||||
import eu.eudat.logic.services.ApiContext;
|
import eu.eudat.logic.services.ApiContext;
|
||||||
|
|
|
@ -55,7 +55,8 @@ public class PrincipalController {
|
||||||
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._authenticatedAt),
|
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._authenticatedAt),
|
||||||
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._expiresAt),
|
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._expiresAt),
|
||||||
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._more),
|
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._more),
|
||||||
Account._roles);
|
Account._roles,
|
||||||
|
Account._permissions);
|
||||||
}
|
}
|
||||||
|
|
||||||
MyPrincipal principal = this.currentPrincipalResolver.currentPrincipal();
|
MyPrincipal principal = this.currentPrincipalResolver.currentPrincipal();
|
||||||
|
|
|
@ -3,16 +3,14 @@ package eu.eudat.interceptors;
|
||||||
|
|
||||||
import eu.eudat.commons.enums.ProviderType;
|
import eu.eudat.commons.enums.ProviderType;
|
||||||
import eu.eudat.commons.enums.Status;
|
import eu.eudat.commons.enums.Status;
|
||||||
import eu.eudat.commons.scope.UserScope;
|
import eu.eudat.commons.scope.user.UserScope;
|
||||||
import eu.eudat.data.CredentialEntity;
|
import eu.eudat.data.CredentialEntity;
|
||||||
import eu.eudat.data.entities.UserInfo;
|
import eu.eudat.data.entities.UserInfo;
|
||||||
import eu.eudat.data.entities.UserRole;
|
import eu.eudat.data.entities.UserRole;
|
||||||
import eu.eudat.exceptions.security.NullEmailException;
|
import eu.eudat.exceptions.security.NullEmailException;
|
||||||
import eu.eudat.query.CredentialQuery;
|
|
||||||
import eu.eudat.types.Authorities;
|
import eu.eudat.types.Authorities;
|
||||||
import gr.cite.commons.web.oidc.principal.CurrentPrincipalResolver;
|
import gr.cite.commons.web.oidc.principal.CurrentPrincipalResolver;
|
||||||
import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractor;
|
import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractor;
|
||||||
import gr.cite.tools.data.query.QueryFactory;
|
|
||||||
import gr.cite.tools.exception.MyApplicationException;
|
import gr.cite.tools.exception.MyApplicationException;
|
||||||
import gr.cite.tools.logging.LoggerService;
|
import gr.cite.tools.logging.LoggerService;
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
|
@ -72,6 +70,7 @@ public class UserInterceptor implements WebRequestInterceptor {
|
||||||
UUID userId = null;
|
UUID userId = null;
|
||||||
if (this.currentPrincipalResolver.currentPrincipal().isAuthenticated()) {
|
if (this.currentPrincipalResolver.currentPrincipal().isAuthenticated()) {
|
||||||
String subjectId = this.claimExtractor.subjectString(this.currentPrincipalResolver.currentPrincipal());
|
String subjectId = this.claimExtractor.subjectString(this.currentPrincipalResolver.currentPrincipal());
|
||||||
|
var aa = this.claimExtractor.roles(this.currentPrincipalResolver.currentPrincipal());
|
||||||
UserInterceptorCacheService.UserInterceptorCacheValue cacheValue = this.userInterceptorCacheService.lookup(this.userInterceptorCacheService.buildKey(subjectId));
|
UserInterceptorCacheService.UserInterceptorCacheValue cacheValue = this.userInterceptorCacheService.lookup(this.userInterceptorCacheService.buildKey(subjectId));
|
||||||
if (cacheValue != null) {
|
if (cacheValue != null) {
|
||||||
userId = cacheValue.getUserId();
|
userId = cacheValue.getUserId();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package eu.eudat.logic.handlers;
|
package eu.eudat.logic.handlers;
|
||||||
|
|
||||||
import eu.eudat.commons.scope.UserScope;
|
import eu.eudat.commons.scope.user.UserScope;
|
||||||
import eu.eudat.exceptions.security.UnauthorisedException;
|
import eu.eudat.exceptions.security.UnauthorisedException;
|
||||||
import eu.eudat.logic.security.claims.ClaimedAuthorities;
|
import eu.eudat.logic.security.claims.ClaimedAuthorities;
|
||||||
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
|
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
|
||||||
|
|
|
@ -139,6 +139,9 @@ public class Account {
|
||||||
public final static String _principal = "principal";
|
public final static String _principal = "principal";
|
||||||
private PrincipalInfo principal;
|
private PrincipalInfo principal;
|
||||||
|
|
||||||
|
public final static String _permissions = "permissions";
|
||||||
|
private List<String> permissions;
|
||||||
|
|
||||||
public PrincipalInfo getPrincipal() {
|
public PrincipalInfo getPrincipal() {
|
||||||
return principal;
|
return principal;
|
||||||
}
|
}
|
||||||
|
@ -162,4 +165,16 @@ public class Account {
|
||||||
public void setRoles(List<Integer> roles) {
|
public void setRoles(List<Integer> roles) {
|
||||||
this.roles = roles;
|
this.roles = roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setAuthenticated(Boolean authenticated) {
|
||||||
|
isAuthenticated = authenticated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getPermissions() {
|
||||||
|
return permissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPermissions(List<String> permissions) {
|
||||||
|
this.permissions = permissions;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package eu.eudat.models.v2;
|
package eu.eudat.models.v2;
|
||||||
|
|
||||||
import eu.eudat.commons.scope.UserScope;
|
import eu.eudat.commons.scope.user.UserScope;
|
||||||
import eu.eudat.data.entities.UserInfo;
|
import eu.eudat.data.entities.UserInfo;
|
||||||
import eu.eudat.data.entities.UserRole;
|
import eu.eudat.data.entities.UserRole;
|
||||||
import eu.eudat.logic.services.ApiContext;
|
import eu.eudat.logic.services.ApiContext;
|
||||||
import eu.eudat.types.Authorities;
|
import gr.cite.commons.web.authz.configuration.AuthorizationConfiguration;
|
||||||
import gr.cite.commons.web.oidc.principal.CurrentPrincipalResolver;
|
import gr.cite.commons.web.oidc.principal.CurrentPrincipalResolver;
|
||||||
import gr.cite.commons.web.oidc.principal.MyPrincipal;
|
import gr.cite.commons.web.oidc.principal.MyPrincipal;
|
||||||
import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractor;
|
import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractor;
|
||||||
|
@ -24,11 +24,13 @@ public class AccountBuilder {
|
||||||
private final ClaimExtractor claimExtractor;
|
private final ClaimExtractor claimExtractor;
|
||||||
private final Set<String> excludeMoreClaim;
|
private final Set<String> excludeMoreClaim;
|
||||||
private final CurrentPrincipalResolver currentPrincipalResolver;
|
private final CurrentPrincipalResolver currentPrincipalResolver;
|
||||||
|
private final AuthorizationConfiguration authorizationConfiguration;
|
||||||
private final ApiContext apiContext;
|
private final ApiContext apiContext;
|
||||||
private final UserScope userScope;
|
private final UserScope userScope;
|
||||||
public AccountBuilder(ClaimExtractor claimExtractor, CurrentPrincipalResolver currentPrincipalResolver, ApiContext apiContext, UserScope userScope) {
|
public AccountBuilder(ClaimExtractor claimExtractor, CurrentPrincipalResolver currentPrincipalResolver, AuthorizationConfiguration authorizationConfiguration, ApiContext apiContext, UserScope userScope) {
|
||||||
this.claimExtractor = claimExtractor;
|
this.claimExtractor = claimExtractor;
|
||||||
this.currentPrincipalResolver = currentPrincipalResolver;
|
this.currentPrincipalResolver = currentPrincipalResolver;
|
||||||
|
this.authorizationConfiguration = authorizationConfiguration;
|
||||||
this.apiContext = apiContext;
|
this.apiContext = apiContext;
|
||||||
this.userScope = userScope;
|
this.userScope = userScope;
|
||||||
this.excludeMoreClaim = Set.of(
|
this.excludeMoreClaim = Set.of(
|
||||||
|
@ -93,6 +95,11 @@ public class AccountBuilder {
|
||||||
model.getRoles().add(item.getRole());
|
model.getRoles().add(item.getRole());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (fields.hasField(Account._permissions)) {
|
||||||
|
List<String> roles = claimExtractor.roles(currentPrincipalResolver.currentPrincipal());
|
||||||
|
Set<String> permissions = authorizationConfiguration.permissionsOfRoles(roles);
|
||||||
|
model.setPermissions(new ArrayList<>(permissions));
|
||||||
|
}
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ spring:
|
||||||
config:
|
config:
|
||||||
import: optional:classpath:config/app.env[.properties], optional:file:../config/app.env[.properties],
|
import: optional:classpath:config/app.env[.properties], optional:file:../config/app.env[.properties],
|
||||||
optional:classpath:config/db.yml[.yml], optional:classpath:config/db-${spring.profiles.active}.yml[.yml], optional:file:../config/db-${spring.profiles.active}.yml[.yml],
|
optional:classpath:config/db.yml[.yml], optional:classpath:config/db-${spring.profiles.active}.yml[.yml], optional:file:../config/db-${spring.profiles.active}.yml[.yml],
|
||||||
|
optional:classpath:config/permissions.yml[.yml], optional:classpath:config/permissions-${spring.profiles.active}.yml[.yml], optional:file:../config/permissions-${spring.profiles.active}.yml[.yml],
|
||||||
optional:classpath:config/security.yml[.yml], optional:classpath:config/security-${spring.profiles.active}.yml[.yml], optional:file:../config/security-${spring.profiles.active}.yml[.yml],
|
optional:classpath:config/security.yml[.yml], optional:classpath:config/security-${spring.profiles.active}.yml[.yml], optional:file:../config/security-${spring.profiles.active}.yml[.yml],
|
||||||
optional:classpath:config/server.yml[.yml], optional:classpath:config/server-${spring.profiles.active}.yml[.yml], optional:file:../config/server-${spring.profiles.active}.yml[.yml],
|
optional:classpath:config/server.yml[.yml], optional:classpath:config/server-${spring.profiles.active}.yml[.yml], optional:file:../config/server-${spring.profiles.active}.yml[.yml],
|
||||||
optional:classpath:config/logging.yml[.yml], optional:classpath:config/logging-${spring.profiles.active}.yml[.yml], optional:file:../config/logging-${spring.profiles.active}.yml[.yml],
|
optional:classpath:config/logging.yml[.yml], optional:classpath:config/logging-${spring.profiles.active}.yml[.yml], optional:file:../config/logging-${spring.profiles.active}.yml[.yml],
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
permissions:
|
||||||
|
extendedClaims: [ ]
|
||||||
|
policies:
|
||||||
|
# Users
|
||||||
|
BrowseDescriptionTemplateType:
|
||||||
|
roles:
|
||||||
|
- Admin
|
||||||
|
clients: [ ]
|
||||||
|
allowAnonymous: true
|
||||||
|
allowAuthenticated: false
|
||||||
|
EditDescriptionTemplateType:
|
||||||
|
roles:
|
||||||
|
- Admin
|
||||||
|
clients: [ ]
|
||||||
|
allowAnonymous: false
|
||||||
|
allowAuthenticated: false
|
||||||
|
DeleteDescriptionTemplateType:
|
||||||
|
roles:
|
||||||
|
- Admin
|
||||||
|
claims: [ ]
|
||||||
|
clients: [ ]
|
||||||
|
allowAnonymous: false
|
||||||
|
allowAuthenticated: false
|
||||||
|
|
||||||
|
# ViewPage Permissions
|
||||||
|
ViewDatasetPage:
|
||||||
|
roles:
|
||||||
|
- Admin
|
||||||
|
clients: [ ]
|
||||||
|
allowAnonymous: false
|
||||||
|
allowAuthenticated: false
|
|
@ -0,0 +1,10 @@
|
||||||
|
export enum AppPermission {
|
||||||
|
//DescriptionTemplateType
|
||||||
|
BrowseDescriptionTemplateType = "BrowseDescriptionTemplateType",
|
||||||
|
EditDescriptionTemplateType = "EditDescriptionTemplateType",
|
||||||
|
DeleteDescriptionTemplateType = "DeleteDescriptionTemplateType",
|
||||||
|
|
||||||
|
// UI Pages
|
||||||
|
ViewDescriptionTemplateTypePage = "ViewDescriptionTemplateTypePage"
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
import { AppRole } from "@app/core/common/enum/app-role";
|
import { AppRole } from "@app/core/common/enum/app-role";
|
||||||
|
import { AppPermission } from "@app/core/common/enum/permission.enum";
|
||||||
import { Guid } from "@common/types/guid";
|
import { Guid } from "@common/types/guid";
|
||||||
|
|
||||||
export interface AppAccount {
|
export interface AppAccount {
|
||||||
isAuthenticated: boolean;
|
isAuthenticated: boolean;
|
||||||
// permissions: AppPermission[];
|
// permissions: AppPermission[];
|
||||||
roles: AppRole[];
|
roles: AppRole[];
|
||||||
|
permissions: AppPermission[];
|
||||||
principal: AppPrincipalInfo;
|
principal: AppPrincipalInfo;
|
||||||
profile: UserProfileInfo;
|
profile: UserProfileInfo;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,8 +14,12 @@ import { KeycloakEventType, KeycloakService } from 'keycloak-angular';
|
||||||
import { NgZone } from '@angular/core';
|
import { NgZone } from '@angular/core';
|
||||||
import { PrincipalService } from '../http/principal.service';
|
import { PrincipalService } from '../http/principal.service';
|
||||||
import { AppRole } from '@app/core/common/enum/app-role';
|
import { AppRole } from '@app/core/common/enum/app-role';
|
||||||
|
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
||||||
|
|
||||||
|
export interface ResolutionContext {
|
||||||
|
roles: AppRole[];
|
||||||
|
permissions: AppPermission[];
|
||||||
|
}
|
||||||
export interface AuthenticationState {
|
export interface AuthenticationState {
|
||||||
loginStatus: LoginStatus;
|
loginStatus: LoginStatus;
|
||||||
}
|
}
|
||||||
|
@ -303,4 +307,37 @@ export class AuthService extends BaseService {
|
||||||
this.zone.run(() => this.router.navigate([returnUrl]));
|
this.zone.run(() => this.router.navigate([returnUrl]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public hasPermission(permission: AppPermission): boolean {
|
||||||
|
// if (!this.installationConfiguration.appServiceEnabled) { return true; } //TODO: maybe reconsider
|
||||||
|
return this.evaluatePermission(this.appAccount?.permissions || [], permission);
|
||||||
|
|
||||||
|
}
|
||||||
|
private evaluatePermission(availablePermissions: string[], permissionToCheck: string): boolean {
|
||||||
|
if (!permissionToCheck) { return false; }
|
||||||
|
if (this.hasRole(AppRole.Admin)) { return true; }
|
||||||
|
return availablePermissions.map(x => x.toLowerCase()).includes(permissionToCheck.toLowerCase());
|
||||||
|
}
|
||||||
|
public hasAnyPermission(permissions: AppPermission[]): boolean {
|
||||||
|
if (!permissions) { return false; }
|
||||||
|
return permissions.filter((p) => this.hasPermission(p)).length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public authorize(context: ResolutionContext): boolean {
|
||||||
|
|
||||||
|
if (!context || this.hasRole(AppRole.Admin)) { return true; }
|
||||||
|
|
||||||
|
let roleAuthorized = false;
|
||||||
|
if (context.roles && context.roles.length > 0) {
|
||||||
|
roleAuthorized = this.hasAnyRole(context.roles);
|
||||||
|
}
|
||||||
|
|
||||||
|
let permissionAuthorized = false;
|
||||||
|
if (context.permissions && context.permissions.length > 0) {
|
||||||
|
permissionAuthorized = this.hasAnyPermission(context.permissions);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (roleAuthorized || permissionAuthorized) { return true; }
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue