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>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>gr.cite</groupId>
|
||||
<artifactId>oidc-authz</artifactId>
|
||||
<version>2.1.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<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 org.slf4j.LoggerFactory;
|
|
@ -1,6 +1,8 @@
|
|||
package eu.eudat.model.censorship;
|
||||
|
||||
import eu.eudat.authorization.Permission;
|
||||
import eu.eudat.convention.ConventionService;
|
||||
import gr.cite.commons.web.authz.service.AuthorizationService;
|
||||
import gr.cite.tools.fieldset.FieldSet;
|
||||
import gr.cite.tools.logging.DataLogEntry;
|
||||
import gr.cite.tools.logging.LoggerService;
|
||||
|
@ -14,15 +16,17 @@ import org.springframework.stereotype.Component;
|
|||
public class DescriptionTemplateTypeCensor extends BaseCensor{
|
||||
|
||||
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(DescriptionTemplateTypeCensor.class));
|
||||
|
||||
public DescriptionTemplateTypeCensor(ConventionService conventionService) {
|
||||
protected final AuthorizationService authService;
|
||||
public DescriptionTemplateTypeCensor(ConventionService conventionService, AuthorizationService authService) {
|
||||
super(conventionService);
|
||||
this.authService = authService;
|
||||
}
|
||||
|
||||
public void censor(FieldSet fields) {
|
||||
logger.debug(new DataLogEntry("censoring fields", fields));
|
||||
if (fields.isEmpty())
|
||||
return;
|
||||
if (fields.isEmpty()) return;
|
||||
|
||||
this.authService.authorizeForce(Permission.BrowseDescriptionTemplateType);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -329,6 +329,12 @@
|
|||
<version>2.1.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>gr.cite</groupId>
|
||||
<artifactId>oidc-authz</artifactId>
|
||||
<version>2.1.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<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;
|
||||
|
||||
|
||||
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 org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
|
@ -17,24 +27,28 @@ import org.springframework.security.web.authentication.preauth.AbstractPreAuthen
|
|||
|
||||
import jakarta.servlet.Filter;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
public class SecurityConfiguration {
|
||||
public class SecurityConfiguration {
|
||||
|
||||
private final WebSecurityProperties webSecurityProperties;
|
||||
private final AuthenticationManagerResolver<HttpServletRequest> authenticationManagerResolver;
|
||||
private final Filter apiKeyFilter;
|
||||
private final OwnedAuthorizationHandler ownedAuthorizationHandler;
|
||||
|
||||
@Autowired
|
||||
public SecurityConfiguration(WebSecurityProperties webSecurityProperties,
|
||||
@Qualifier("tokenAuthenticationResolver") AuthenticationManagerResolver<HttpServletRequest> authenticationManagerResolver,
|
||||
@Qualifier("apiKeyFilter") Filter apiKeyFilter) {
|
||||
@Qualifier("tokenAuthenticationResolver") AuthenticationManagerResolver<HttpServletRequest> authenticationManagerResolver,
|
||||
@Qualifier("apiKeyFilter") Filter apiKeyFilter,
|
||||
@Qualifier("ownedAuthorizationHandler") OwnedAuthorizationHandler ownedAuthorizationHandler) {
|
||||
this.webSecurityProperties = webSecurityProperties;
|
||||
this.authenticationManagerResolver = authenticationManagerResolver;
|
||||
this.apiKeyFilter = apiKeyFilter;
|
||||
this.ownedAuthorizationHandler = ownedAuthorizationHandler;
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
@ -52,60 +66,61 @@ public class SecurityConfiguration {
|
|||
return tempHttp.build();
|
||||
}
|
||||
|
||||
// @Bean
|
||||
// AuthorizationPolicyConfigurer authorizationPolicyConfigurer() {
|
||||
// return new AuthorizationPolicyConfigurer() {
|
||||
//
|
||||
// @Override
|
||||
// public AuthorizationPolicyResolverStrategy strategy() {
|
||||
// return AuthorizationPolicyResolverStrategy.STRICT_CONSENSUS_BASED;
|
||||
// }
|
||||
//
|
||||
// //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
|
||||
// //If not set / set to null, only the default authorization handlers will be used
|
||||
// @Override
|
||||
// public List<AuthorizationHandler<? extends AuthorizationRequirement>> addCustomHandlers() {
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// //Here you can register your custom authorization requirements (if any)
|
||||
// //This is optional and can be omitted
|
||||
// //If not set / set to null, only the default authorization requirements will be used
|
||||
// @Override
|
||||
// public List<? extends AuthorizationRequirement> extendRequirements() {
|
||||
// return List.of(
|
||||
//// 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
|
||||
// //You can disable any handler (including any custom one)
|
||||
// //This is optional and can be omitted
|
||||
// //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
|
||||
// @Override
|
||||
// public List<Class<? extends AuthorizationHandler<? extends AuthorizationRequirement>>> disableHandlers() {
|
||||
// return List.of(PermissionClientAuthorizationHandler.class);
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
//
|
||||
// @Bean
|
||||
// AuthorizationRequirementMapper authorizationRequirementMapper() {
|
||||
// return new AuthorizationRequirementMapper() {
|
||||
// @Override
|
||||
// public AuthorizationRequirement map(AuthorizationResource resource, boolean matchAll, String[] permissions) {
|
||||
// Class<?> type = resource.getClass();
|
||||
// if (!AuthorizationResource.class.isAssignableFrom(type)) throw new IllegalArgumentException("resource");
|
||||
//
|
||||
// if (OwnedResource.class.equals(type)) {
|
||||
// return new OwnedAuthorizationRequirement();
|
||||
// }
|
||||
// throw new IllegalArgumentException("resource");
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
@Bean
|
||||
AuthorizationPolicyConfigurer authorizationPolicyConfigurer() {
|
||||
return new AuthorizationPolicyConfigurer() {
|
||||
|
||||
@Override
|
||||
public AuthorizationPolicyResolverStrategy strategy() {
|
||||
return AuthorizationPolicyResolverStrategy.STRICT_CONSENSUS_BASED;
|
||||
}
|
||||
|
||||
//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
|
||||
//If not set / set to null, only the default authorization handlers will be used
|
||||
@Override
|
||||
public List<AuthorizationHandler<? extends AuthorizationRequirement>> addCustomHandlers() {
|
||||
return List.of( ownedAuthorizationHandler);
|
||||
}
|
||||
|
||||
//Here you can register your custom authorization requirements (if any)
|
||||
//This is optional and can be omitted
|
||||
//If not set / set to null, only the default authorization requirements will be used
|
||||
@Override
|
||||
public List<? extends AuthorizationRequirement> extendRequirements() {
|
||||
return List.of(
|
||||
// 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
|
||||
//You can disable any handler (including any custom one)
|
||||
//This is optional and can be omitted
|
||||
//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
|
||||
@Override
|
||||
public List<Class<? extends AuthorizationHandler<? extends AuthorizationRequirement>>> disableHandlers() {
|
||||
return List.of(PermissionClientAuthorizationHandler.class);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
AuthorizationRequirementMapper authorizationRequirementMapper() {
|
||||
return new AuthorizationRequirementMapper() {
|
||||
@Override
|
||||
public AuthorizationRequirement map(AuthorizationResource resource, boolean matchAll, String[] permissions) {
|
||||
Class<?> type = resource.getClass();
|
||||
if (!AuthorizationResource.class.isAssignableFrom(type)) throw new IllegalArgumentException("resource");
|
||||
|
||||
if (OwnedResource.class.equals(type)) {
|
||||
return new OwnedAuthorizationRequirement();
|
||||
}
|
||||
throw new IllegalArgumentException("resource");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private String[] buildAntPatterns(Set<String> endpoints) {
|
||||
if (endpoints == null) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
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.logic.handlers.PrincipalArgumentResolver;
|
||||
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._expiresAt),
|
||||
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._more),
|
||||
Account._roles);
|
||||
Account._roles,
|
||||
Account._permissions);
|
||||
}
|
||||
|
||||
MyPrincipal principal = this.currentPrincipalResolver.currentPrincipal();
|
||||
|
|
|
@ -3,16 +3,14 @@ package eu.eudat.interceptors;
|
|||
|
||||
import eu.eudat.commons.enums.ProviderType;
|
||||
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.entities.UserInfo;
|
||||
import eu.eudat.data.entities.UserRole;
|
||||
import eu.eudat.exceptions.security.NullEmailException;
|
||||
import eu.eudat.query.CredentialQuery;
|
||||
import eu.eudat.types.Authorities;
|
||||
import gr.cite.commons.web.oidc.principal.CurrentPrincipalResolver;
|
||||
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.logging.LoggerService;
|
||||
import jakarta.persistence.EntityManager;
|
||||
|
@ -72,6 +70,7 @@ public class UserInterceptor implements WebRequestInterceptor {
|
|||
UUID userId = null;
|
||||
if (this.currentPrincipalResolver.currentPrincipal().isAuthenticated()) {
|
||||
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));
|
||||
if (cacheValue != null) {
|
||||
userId = cacheValue.getUserId();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
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.logic.security.claims.ClaimedAuthorities;
|
||||
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
|
||||
|
|
|
@ -139,6 +139,9 @@ public class Account {
|
|||
public final static String _principal = "principal";
|
||||
private PrincipalInfo principal;
|
||||
|
||||
public final static String _permissions = "permissions";
|
||||
private List<String> permissions;
|
||||
|
||||
public PrincipalInfo getPrincipal() {
|
||||
return principal;
|
||||
}
|
||||
|
@ -162,4 +165,16 @@ public class Account {
|
|||
public void setRoles(List<Integer> 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;
|
||||
|
||||
import eu.eudat.commons.scope.UserScope;
|
||||
import eu.eudat.commons.scope.user.UserScope;
|
||||
import eu.eudat.data.entities.UserInfo;
|
||||
import eu.eudat.data.entities.UserRole;
|
||||
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.MyPrincipal;
|
||||
import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractor;
|
||||
|
@ -24,11 +24,13 @@ public class AccountBuilder {
|
|||
private final ClaimExtractor claimExtractor;
|
||||
private final Set<String> excludeMoreClaim;
|
||||
private final CurrentPrincipalResolver currentPrincipalResolver;
|
||||
private final AuthorizationConfiguration authorizationConfiguration;
|
||||
private final ApiContext apiContext;
|
||||
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.currentPrincipalResolver = currentPrincipalResolver;
|
||||
this.authorizationConfiguration = authorizationConfiguration;
|
||||
this.apiContext = apiContext;
|
||||
this.userScope = userScope;
|
||||
this.excludeMoreClaim = Set.of(
|
||||
|
@ -93,6 +95,11 @@ public class AccountBuilder {
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ spring:
|
|||
config:
|
||||
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/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/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],
|
||||
|
|
|
@ -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 { AppPermission } from "@app/core/common/enum/permission.enum";
|
||||
import { Guid } from "@common/types/guid";
|
||||
|
||||
export interface AppAccount {
|
||||
isAuthenticated: boolean;
|
||||
// permissions: AppPermission[];
|
||||
roles: AppRole[];
|
||||
permissions: AppPermission[];
|
||||
principal: AppPrincipalInfo;
|
||||
profile: UserProfileInfo;
|
||||
}
|
||||
|
|
|
@ -14,8 +14,12 @@ import { KeycloakEventType, KeycloakService } from 'keycloak-angular';
|
|||
import { NgZone } from '@angular/core';
|
||||
import { PrincipalService } from '../http/principal.service';
|
||||
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 {
|
||||
loginStatus: LoginStatus;
|
||||
}
|
||||
|
@ -303,4 +307,37 @@ export class AuthService extends BaseService {
|
|||
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