Merge branch 'dmp-refactoring' of https://code-repo.d4science.org/MaDgiK-CITE/argos into dmp-refactoring
This commit is contained in:
commit
cf9a65ae53
|
@ -9,6 +9,25 @@ import java.util.List;
|
|||
@ConfigurationProperties(prefix = "authorization")
|
||||
public class AuthorizationProperties {
|
||||
|
||||
private String globalAdminRole;
|
||||
|
||||
public String getGlobalAdminRole() {
|
||||
return globalAdminRole;
|
||||
}
|
||||
|
||||
public void setGlobalAdminRole(String globalAdminRole) {
|
||||
this.globalAdminRole = globalAdminRole;
|
||||
}
|
||||
private Boolean autoAssignGlobalAdminToNewTenants;
|
||||
|
||||
public Boolean getAutoAssignGlobalAdminToNewTenants() {
|
||||
return autoAssignGlobalAdminToNewTenants;
|
||||
}
|
||||
|
||||
public void setAutoAssignGlobalAdminToNewTenants(Boolean autoAssignGlobalAdminToNewTenants) {
|
||||
this.autoAssignGlobalAdminToNewTenants = autoAssignGlobalAdminToNewTenants;
|
||||
}
|
||||
|
||||
private List<String> allowedTenantRoles;
|
||||
|
||||
public List<String> getAllowedTenantRoles() {
|
||||
|
|
|
@ -67,6 +67,13 @@ public class TenantScope {
|
|||
this.tenant.set(tenant);
|
||||
this.tenantCode.set(tenantCode);
|
||||
|
||||
entityManager
|
||||
.unwrap(Session.class)
|
||||
.disableFilter(TenantScopedBaseEntity.TENANT_FILTER);
|
||||
|
||||
entityManager
|
||||
.unwrap(Session.class)
|
||||
.disableFilter(TenantScopedBaseEntity.DEFAULT_TENANT_FILTER);
|
||||
if (this.tenant.get() != null || this.isDefaultTenant()) {
|
||||
if(!this.isDefaultTenant()) {
|
||||
entityManager
|
||||
|
@ -84,6 +91,15 @@ public class TenantScope {
|
|||
public void removeTempTenant(EntityManager entityManager) {
|
||||
this.tenant.set(this.initialTenant.get());
|
||||
this.tenantCode.set(this.initialTenantCode.get());
|
||||
|
||||
|
||||
entityManager
|
||||
.unwrap(Session.class)
|
||||
.disableFilter(TenantScopedBaseEntity.TENANT_FILTER);
|
||||
|
||||
entityManager
|
||||
.unwrap(Session.class)
|
||||
.disableFilter(TenantScopedBaseEntity.DEFAULT_TENANT_FILTER);
|
||||
if (this.initialTenant.get() != null || this.isDefaultTenant()) {
|
||||
if(!this.isDefaultTenant()) {
|
||||
entityManager
|
||||
|
|
|
@ -9,6 +9,7 @@ import eu.eudat.commons.scope.user.UserScope;
|
|||
import eu.eudat.data.DescriptionTemplateEntity;
|
||||
import eu.eudat.data.DmpDescriptionTemplateEntity;
|
||||
import eu.eudat.data.DmpEntity;
|
||||
import eu.eudat.data.EntityDoiEntity;
|
||||
import eu.eudat.model.DescriptionTemplate;
|
||||
import eu.eudat.query.utils.BuildSubQueryInput;
|
||||
import eu.eudat.query.utils.QueryUtilsService;
|
||||
|
@ -53,6 +54,8 @@ public class DescriptionTemplateQuery extends QueryBase<DescriptionTemplateEntit
|
|||
|
||||
private Instant after;
|
||||
|
||||
private DmpDescriptionTemplateQuery dmpDescriptionTemplateQuery;
|
||||
|
||||
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
|
||||
|
||||
public DescriptionTemplateQuery like(String value) {
|
||||
|
@ -200,6 +203,11 @@ public class DescriptionTemplateQuery extends QueryBase<DescriptionTemplateEntit
|
|||
return this;
|
||||
}
|
||||
|
||||
public DescriptionTemplateQuery dmpDescriptionTemplateSubQuery(DmpDescriptionTemplateQuery value) {
|
||||
this.dmpDescriptionTemplateQuery = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DescriptionTemplateQuery authorize(EnumSet<AuthorizationFlags> values) {
|
||||
this.authorize = values;
|
||||
return this;
|
||||
|
@ -327,6 +335,11 @@ public class DescriptionTemplateQuery extends QueryBase<DescriptionTemplateEntit
|
|||
predicates.add(afterClause);
|
||||
}
|
||||
|
||||
if (this.dmpDescriptionTemplateQuery != null) {
|
||||
QueryContext<DmpDescriptionTemplateEntity, UUID> subQuery = this.applySubQuery(this.dmpDescriptionTemplateQuery, queryContext, UUID.class, dmpDescriptionTemplateEntityRoot -> dmpDescriptionTemplateEntityRoot.get(DmpDescriptionTemplateEntity._descriptionTemplateGroupId));
|
||||
predicates.add(queryContext.CriteriaBuilder.in(queryContext.Root.get(DescriptionTemplateEntity._groupId)).value(subQuery.Query));
|
||||
}
|
||||
|
||||
if (!predicates.isEmpty()) {
|
||||
Predicate[] predicatesArray = predicates.toArray(new Predicate[0]);
|
||||
return queryContext.CriteriaBuilder.and(predicatesArray);
|
||||
|
|
|
@ -1,22 +1,18 @@
|
|||
package eu.eudat.service.keycloak;
|
||||
|
||||
import org.springframework.boot.context.properties.bind.ConstructorBinding;
|
||||
|
||||
public class KeycloakAuthorityProperties {
|
||||
|
||||
private final String groupId, groupTitle;
|
||||
private String groupId;
|
||||
|
||||
@ConstructorBinding
|
||||
public KeycloakAuthorityProperties(String groupId, String groupTitle) {
|
||||
this.groupId = groupId;
|
||||
this.groupTitle = groupTitle;
|
||||
public KeycloakAuthorityProperties() {
|
||||
}
|
||||
|
||||
public String getGroupId() {
|
||||
return groupId;
|
||||
}
|
||||
|
||||
public String getGroupTitle() {
|
||||
return groupTitle;
|
||||
public void setGroupId(String groupId) {
|
||||
this.groupId = groupId;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,4 +19,14 @@ public class KeycloakResourcesConfiguration {
|
|||
return properties;
|
||||
}
|
||||
|
||||
public String getTenantGroupName(String tenantCode) {
|
||||
return properties.getTenantGroupsNamingStrategy()
|
||||
.replace("{tenantCode}", tenantCode);
|
||||
}
|
||||
|
||||
public String getTenantRoleAttributeValue(String tenantCode, String key) {
|
||||
return properties.getTenantAuthorities().get(key).getRoleAttributeValueStrategy()
|
||||
.replace("{tenantCode}", tenantCode);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,15 +10,41 @@ import java.util.HashMap;
|
|||
@ConditionalOnProperty(prefix = "keycloak-resources", name = "enabled", havingValue = "true")
|
||||
public class KeycloakResourcesProperties {
|
||||
|
||||
private final HashMap<String, KeycloakAuthorityProperties> authorities;
|
||||
|
||||
@ConstructorBinding
|
||||
public KeycloakResourcesProperties(HashMap<String, KeycloakAuthorityProperties> authorities) {
|
||||
this.authorities = authorities;
|
||||
}
|
||||
private HashMap<String, KeycloakAuthorityProperties> authorities;
|
||||
private HashMap<String, KeycloakTenantAuthorityProperties> tenantAuthorities;
|
||||
|
||||
private String tenantGroupsNamingStrategy;
|
||||
private String tenantRoleAttributeName;
|
||||
|
||||
public HashMap<String, KeycloakAuthorityProperties> getAuthorities() {
|
||||
return authorities;
|
||||
}
|
||||
|
||||
public void setAuthorities(HashMap<String, KeycloakAuthorityProperties> authorities) {
|
||||
this.authorities = authorities;
|
||||
}
|
||||
|
||||
public HashMap<String, KeycloakTenantAuthorityProperties> getTenantAuthorities() {
|
||||
return tenantAuthorities;
|
||||
}
|
||||
|
||||
public void setTenantAuthorities(HashMap<String, KeycloakTenantAuthorityProperties> tenantAuthorities) {
|
||||
this.tenantAuthorities = tenantAuthorities;
|
||||
}
|
||||
|
||||
public String getTenantGroupsNamingStrategy() {
|
||||
return tenantGroupsNamingStrategy;
|
||||
}
|
||||
|
||||
public void setTenantGroupsNamingStrategy(String tenantGroupsNamingStrategy) {
|
||||
this.tenantGroupsNamingStrategy = tenantGroupsNamingStrategy;
|
||||
}
|
||||
|
||||
public String getTenantRoleAttributeName() {
|
||||
return tenantRoleAttributeName;
|
||||
}
|
||||
|
||||
public void setTenantRoleAttributeName(String tenantRoleAttributeName) {
|
||||
this.tenantRoleAttributeName = tenantRoleAttributeName;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
package eu.eudat.service.keycloak;
|
||||
|
||||
public enum KeycloakRole {
|
||||
|
||||
Admin, User
|
||||
|
||||
}
|
|
@ -1,17 +1,23 @@
|
|||
package eu.eudat.service.keycloak;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.keycloak.representations.idm.GroupRepresentation;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface KeycloakService {
|
||||
|
||||
void addUserToGroup(UUID subjectId, String groupId);
|
||||
void removeUserFromGroup(@NotNull UUID subjectId, String groupId);
|
||||
void addUserToGroup(UUID subjectId, KeycloakRole role);
|
||||
void removeUserFromGroup(@NotNull UUID subjectId, KeycloakRole role);
|
||||
void assignClientRoleToUser(UUID subjectId, String clientId, KeycloakRole role);
|
||||
void removeClientRoleFromUser(UUID subjectId, String clientId, KeycloakRole role);
|
||||
void addUserToGroup(@NotNull String subjectId, String groupId);
|
||||
|
||||
void removeUserFromGroup(@NotNull String subjectId, String groupId);
|
||||
|
||||
void addUserToGlobalRoleGroup(String subjectId, String role);
|
||||
void removeUserGlobalRoleGroup(@NotNull String subjectId, String role);
|
||||
|
||||
void addUserToTenantRoleGroup(String subjectId, String tenantCode, String tenantRole);
|
||||
|
||||
void removeUserTenantRoleGroup(String subjectId, String tenantCode, String tenantRole);
|
||||
|
||||
void createTenantGroups(String tenantCode);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import gr.cite.commons.web.keycloak.api.configuration.KeycloakClientConfiguratio
|
|||
import gr.cite.tools.logging.LoggerService;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.keycloak.representations.idm.GroupRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
@ -27,56 +26,83 @@ public class KeycloakServiceImpl implements KeycloakService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void addUserToGroup(@NotNull UUID subjectId, String groupId) {
|
||||
api.users().addUserToGroup(subjectId.toString(), groupId);
|
||||
public void addUserToGroup(@NotNull String subjectId, String groupId) {
|
||||
api.users().addUserToGroup(subjectId, groupId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeUserFromGroup(@NotNull UUID subjectId, String groupId) {
|
||||
api.users().removeUserFromGroup(subjectId.toString(), groupId);
|
||||
public void removeUserFromGroup(@NotNull String subjectId, String groupId) {
|
||||
api.users().removeUserFromGroup(subjectId, groupId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addUserToGroup(UUID subjectId, KeycloakRole role) {
|
||||
KeycloakAuthorityProperties properties = this.configuration.getProperties().getAuthorities().get(role.name());
|
||||
if (properties != null)
|
||||
addUserToGroup(subjectId, properties.getGroupId());
|
||||
public void addUserToGlobalRoleGroup(String subjectId, String role) {
|
||||
KeycloakAuthorityProperties properties = this.configuration.getProperties().getAuthorities().get(role);
|
||||
if (properties != null) addUserToGroup(subjectId, properties.getGroupId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeUserFromGroup(@NotNull UUID subjectId, KeycloakRole role) {
|
||||
KeycloakAuthorityProperties properties = this.configuration.getProperties().getAuthorities().get(role.name());
|
||||
public void removeUserGlobalRoleGroup(@NotNull String subjectId, String role) {
|
||||
KeycloakAuthorityProperties properties = this.configuration.getProperties().getAuthorities().get(role);
|
||||
if (properties != null)
|
||||
removeUserFromGroup(subjectId, properties.getGroupId());
|
||||
}
|
||||
//
|
||||
// @Override
|
||||
// public void assignClientRoleToUser(UUID subjectId, String clientId, KeycloakRole role) {
|
||||
// if (clientId == null)
|
||||
// clientId = clientConfiguration.getProperties().getClientId();
|
||||
// UserRepresentation user = api.users().findUserById(subjectId.toString());
|
||||
// user.getClientRoles().computeIfAbsent(clientId, k -> new ArrayList<>());
|
||||
// Set<String> clientRoles = new HashSet<>(Set.copyOf(user.getClientRoles().get(clientId)));
|
||||
// clientRoles.add(role.name());
|
||||
// user.getClientRoles().get(clientId).clear();
|
||||
// user.getClientRoles().get(clientId).addAll(clientRoles);
|
||||
// api.users().updateUser(subjectId.toString(), user);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void removeClientRoleFromUser(UUID subjectId, String clientId, KeycloakRole role) {
|
||||
// if (clientId == null) clientId = clientConfiguration.getProperties().getClientId();
|
||||
// UserRepresentation user = api.users().findUserById(subjectId.toString());
|
||||
// user.getClientRoles().computeIfAbsent(clientId, k -> new ArrayList<>());
|
||||
// Set<String> clientRoles = new HashSet<>(Set.copyOf(user.getClientRoles().get(clientId)));
|
||||
// clientRoles.remove(role.name());
|
||||
// user.getClientRoles().get(clientId).clear();
|
||||
// user.getClientRoles().get(clientId).addAll(clientRoles);
|
||||
// api.users().updateUser(subjectId.toString(), user);
|
||||
// }
|
||||
//
|
||||
// public List<GroupRepresentation> getUserGroups(UUID subjectId) {
|
||||
// return api.users().getGroups(subjectId.toString());
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void assignClientRoleToUser(UUID subjectId, String clientId, KeycloakRole role) {
|
||||
if (clientId == null)
|
||||
clientId = clientConfiguration.getProperties().getClientId();
|
||||
UserRepresentation user = api.users().findUserById(subjectId.toString());
|
||||
user.getClientRoles().computeIfAbsent(clientId, k -> new ArrayList<>());
|
||||
Set<String> clientRoles = new HashSet<>(Set.copyOf(user.getClientRoles().get(clientId)));
|
||||
clientRoles.add(role.name());
|
||||
user.getClientRoles().get(clientId).clear();
|
||||
user.getClientRoles().get(clientId).addAll(clientRoles);
|
||||
api.users().updateUser(subjectId.toString(), user);
|
||||
public void addUserToTenantRoleGroup(String subjectId, String tenantCode, String tenantRole) {
|
||||
GroupRepresentation group = api.groups().findGroupByPath(getTenantAuthorityParentPath(tenantRole) + "/" + configuration.getTenantGroupName(tenantCode));
|
||||
addUserToGroup(subjectId, group.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeClientRoleFromUser(UUID subjectId, String clientId, KeycloakRole role) {
|
||||
if (clientId == null) clientId = clientConfiguration.getProperties().getClientId();
|
||||
UserRepresentation user = api.users().findUserById(subjectId.toString());
|
||||
user.getClientRoles().computeIfAbsent(clientId, k -> new ArrayList<>());
|
||||
Set<String> clientRoles = new HashSet<>(Set.copyOf(user.getClientRoles().get(clientId)));
|
||||
clientRoles.remove(role.name());
|
||||
user.getClientRoles().get(clientId).clear();
|
||||
user.getClientRoles().get(clientId).addAll(clientRoles);
|
||||
api.users().updateUser(subjectId.toString(), user);
|
||||
public void removeUserTenantRoleGroup(String subjectId, String tenantCode, String tenantRole) {
|
||||
GroupRepresentation group = api.groups().findGroupByPath(getTenantAuthorityParentPath(tenantRole) + "/" + configuration.getTenantGroupName(tenantCode));
|
||||
removeUserFromGroup(subjectId, group.getId());
|
||||
}
|
||||
|
||||
private String getTenantAuthorityParentPath(String tenantRole) {
|
||||
GroupRepresentation parent = api.groups().findGroupById(configuration.getProperties().getTenantAuthorities().get(tenantRole).getParent());
|
||||
return parent.getPath();
|
||||
}
|
||||
|
||||
public List<GroupRepresentation> getUserGroups(UUID subjectId) {
|
||||
return api.users().getGroups(subjectId.toString());
|
||||
@Override
|
||||
public void createTenantGroups(String tenantCode) {
|
||||
for (Map.Entry<String,KeycloakTenantAuthorityProperties> entry :configuration.getProperties().getTenantAuthorities().entrySet()){
|
||||
GroupRepresentation group = new GroupRepresentation();
|
||||
group.setName(configuration.getTenantGroupName(tenantCode));
|
||||
HashMap<String, List<String>> user_attributes = new HashMap<>();
|
||||
user_attributes.put(this.configuration.getProperties().getTenantRoleAttributeName(), List.of(configuration.getTenantRoleAttributeValue(tenantCode, entry.getKey())));
|
||||
group.setAttributes(user_attributes);
|
||||
api.groups().addGroupWithParent(group, configuration.getProperties().getTenantAuthorities().get(entry.getKey()).getParent());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
package eu.eudat.service.keycloak;
|
||||
|
||||
public class KeycloakTenantAuthorityProperties {
|
||||
|
||||
private String parent;
|
||||
private String roleAttributeValueStrategy;
|
||||
|
||||
public KeycloakTenantAuthorityProperties() {
|
||||
}
|
||||
|
||||
public String getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public void setParent(String parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public String getRoleAttributeValueStrategy() {
|
||||
return roleAttributeValueStrategy;
|
||||
}
|
||||
|
||||
public void setRoleAttributeValueStrategy(String roleAttributeValueStrategy) {
|
||||
this.roleAttributeValueStrategy = roleAttributeValueStrategy;
|
||||
}
|
||||
}
|
|
@ -279,7 +279,15 @@ public class MetricsServiceImpl implements MetricsService {
|
|||
}
|
||||
|
||||
private double calculateDoiedDatasets(boolean forNexus) {
|
||||
return 0;
|
||||
DescriptionQuery descriptionQuery = this.queryFactory.query(DescriptionQuery.class).statuses(DescriptionStatus.Finalized).isActive(IsActive.Active);
|
||||
if (forNexus)
|
||||
descriptionQuery.createdAfter(_config.getNexusDate());
|
||||
DmpQuery dmpQuery = this.queryFactory.query(DmpQuery.class).isActive(IsActive.Active);
|
||||
EntityDoiQuery entityDoiQuery = this.queryFactory.query(EntityDoiQuery.class).types(EntityType.DMP).isActive(IsActive.Active);
|
||||
dmpQuery.entityDoiSubQuery(entityDoiQuery);
|
||||
descriptionQuery.dmpSubQuery(dmpQuery);
|
||||
descriptionQuery.setDistinct(true);
|
||||
return descriptionQuery.count();
|
||||
}
|
||||
|
||||
private double calculateDraftTemplates(boolean forNexus) {
|
||||
|
@ -297,11 +305,13 @@ public class MetricsServiceImpl implements MetricsService {
|
|||
}
|
||||
|
||||
private double calculateUsedTemplates(boolean forNexus) {
|
||||
DmpDescriptionTemplateQuery dmpDescriptionTemplateQuery = this.queryFactory.query(DmpDescriptionTemplateQuery.class).isActive(IsActive.Active);
|
||||
dmpDescriptionTemplateQuery.setDistinct(true);
|
||||
DescriptionTemplateQuery descriptionTemplateQuery = this.queryFactory.query(DescriptionTemplateQuery.class).isActive(IsActive.Active);
|
||||
descriptionTemplateQuery.setDistinct(true);
|
||||
if (forNexus)
|
||||
dmpDescriptionTemplateQuery.after(_config.getNexusDate());
|
||||
return dmpDescriptionTemplateQuery.count();
|
||||
descriptionTemplateQuery.after(_config.getNexusDate());
|
||||
DmpDescriptionTemplateQuery dmpDescriptionTemplateQuery = this.queryFactory.query(DmpDescriptionTemplateQuery.class);
|
||||
descriptionTemplateQuery.dmpDescriptionTemplateSubQuery(dmpDescriptionTemplateQuery);
|
||||
return descriptionTemplateQuery.count();
|
||||
}
|
||||
|
||||
private double calculateActiveUsers() {
|
||||
|
|
|
@ -1,25 +1,34 @@
|
|||
package eu.eudat.service.tenant;
|
||||
|
||||
import eu.eudat.authorization.AuthorizationFlags;
|
||||
import eu.eudat.authorization.AuthorizationProperties;
|
||||
import eu.eudat.authorization.Permission;
|
||||
import eu.eudat.commons.XmlHandlingService;
|
||||
import eu.eudat.commons.enums.IsActive;
|
||||
import eu.eudat.commons.scope.tenant.TenantScope;
|
||||
import eu.eudat.commons.types.tenant.*;
|
||||
import eu.eudat.convention.ConventionService;
|
||||
import eu.eudat.data.TenantEntity;
|
||||
import eu.eudat.data.TenantEntityManager;
|
||||
import eu.eudat.data.UserCredentialEntity;
|
||||
import eu.eudat.data.UserRoleEntity;
|
||||
import eu.eudat.errorcode.ErrorThesaurusProperties;
|
||||
import eu.eudat.integrationevent.outbox.tenantremoval.TenantRemovalIntegrationEvent;
|
||||
import eu.eudat.integrationevent.outbox.tenantremoval.TenantRemovalIntegrationEventHandler;
|
||||
import eu.eudat.integrationevent.outbox.tenanttouched.TenantTouchedIntegrationEvent;
|
||||
import eu.eudat.integrationevent.outbox.tenanttouched.TenantTouchedIntegrationEventHandler;
|
||||
import eu.eudat.model.Tenant;
|
||||
import eu.eudat.model.UserCredential;
|
||||
import eu.eudat.model.builder.TenantBuilder;
|
||||
import eu.eudat.model.deleter.TenantDeleter;
|
||||
import eu.eudat.model.deleter.UserRoleDeleter;
|
||||
import eu.eudat.model.persist.TenantPersist;
|
||||
import eu.eudat.model.persist.tenantconfig.*;
|
||||
import eu.eudat.model.tenantconfig.TenantSource;
|
||||
import eu.eudat.query.UserCredentialQuery;
|
||||
import eu.eudat.query.UserRoleQuery;
|
||||
import eu.eudat.service.encryption.EncryptionService;
|
||||
import eu.eudat.service.keycloak.KeycloakService;
|
||||
import eu.eudat.service.responseutils.ResponseUtilsService;
|
||||
import gr.cite.commons.web.authz.service.AuthorizationService;
|
||||
import gr.cite.tools.data.builder.BuilderFactory;
|
||||
|
@ -73,6 +82,11 @@ public class TenantServiceImpl implements TenantService {
|
|||
private final TenantProperties properties;
|
||||
private final TenantTouchedIntegrationEventHandler tenantTouchedIntegrationEventHandler;
|
||||
private final TenantRemovalIntegrationEventHandler tenantRemovalIntegrationEventHandler;
|
||||
private final KeycloakService keycloakService;
|
||||
private final AuthorizationProperties authorizationProperties;
|
||||
private final TenantScope tenantScope;
|
||||
private final QueryFactory queryFactory;
|
||||
|
||||
|
||||
@Autowired
|
||||
public TenantServiceImpl(
|
||||
|
@ -84,7 +98,7 @@ public class TenantServiceImpl implements TenantService {
|
|||
MessageSource messageSource,
|
||||
XmlHandlingService xmlHandlingService,
|
||||
ErrorThesaurusProperties errors,
|
||||
EncryptionService encryptionService, TenantProperties properties, TenantTouchedIntegrationEventHandler tenantTouchedIntegrationEventHandler, TenantRemovalIntegrationEventHandler tenantRemovalIntegrationEventHandler) {
|
||||
EncryptionService encryptionService, TenantProperties properties, TenantTouchedIntegrationEventHandler tenantTouchedIntegrationEventHandler, TenantRemovalIntegrationEventHandler tenantRemovalIntegrationEventHandler, KeycloakService keycloakService, AuthorizationProperties authorizationProperties, TenantScope tenantScope, QueryFactory queryFactory) {
|
||||
this.entityManager = entityManager;
|
||||
this.authorizationService = authorizationService;
|
||||
this.deleterFactory = deleterFactory;
|
||||
|
@ -97,6 +111,10 @@ public class TenantServiceImpl implements TenantService {
|
|||
this.properties = properties;
|
||||
this.tenantTouchedIntegrationEventHandler = tenantTouchedIntegrationEventHandler;
|
||||
this.tenantRemovalIntegrationEventHandler = tenantRemovalIntegrationEventHandler;
|
||||
this.keycloakService = keycloakService;
|
||||
this.authorizationProperties = authorizationProperties;
|
||||
this.tenantScope = tenantScope;
|
||||
this.queryFactory = queryFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -131,6 +149,11 @@ public class TenantServiceImpl implements TenantService {
|
|||
else this.entityManager.persist(data);
|
||||
|
||||
this.entityManager.flush();
|
||||
|
||||
if (!isUpdate) {
|
||||
this.keycloakService.createTenantGroups(data.getCode());
|
||||
this.autoAssignGlobalAdminsToNewTenant(data);
|
||||
}
|
||||
|
||||
TenantTouchedIntegrationEvent tenantTouchedIntegrationEvent = new TenantTouchedIntegrationEvent();
|
||||
tenantTouchedIntegrationEvent.setId(data.getId());
|
||||
|
@ -139,6 +162,39 @@ public class TenantServiceImpl implements TenantService {
|
|||
|
||||
return this.builderFactory.builder(TenantBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).build(BaseFieldSet.build(fields, Tenant._id), data);
|
||||
}
|
||||
|
||||
private void autoAssignGlobalAdminsToNewTenant(TenantEntity tenant){
|
||||
if (!this.authorizationProperties.getAutoAssignGlobalAdminToNewTenants()) return;
|
||||
List<UserRoleEntity> existingItems;
|
||||
List<UserCredentialEntity> userCredentialEntities;
|
||||
try {
|
||||
this.tenantScope.setTempTenant(this.entityManager.getEntityManager(), null, this.tenantScope.getDefaultTenantCode());
|
||||
|
||||
existingItems = this.queryFactory.query(UserRoleQuery.class).tenantIsSet(false).roles(this.authorizationProperties.getGlobalAdminRole()).collect();
|
||||
userCredentialEntities = this.queryFactory.query(UserCredentialQuery.class).userIds(existingItems.stream().map(UserRoleEntity::getUserId).distinct().toList()).collect();
|
||||
} finally {
|
||||
this.tenantScope.removeTempTenant(this.entityManager.getEntityManager());
|
||||
}
|
||||
try {
|
||||
this.tenantScope.setTempTenant(this.entityManager.getEntityManager(), tenant.getId(), tenant.getCode());
|
||||
for (UUID userId : existingItems.stream().map(UserRoleEntity::getUserId).distinct().toList()) {
|
||||
UserCredentialEntity userCredential = userCredentialEntities.stream().filter(x-> !this.conventionService.isNullOrEmpty(x.getExternalId()) && x.getUserId().equals(userId)).findFirst().orElse(null);
|
||||
if (userCredential == null) continue;
|
||||
UserRoleEntity item = new UserRoleEntity();
|
||||
item.setId(UUID.randomUUID());
|
||||
item.setUserId(userId);
|
||||
item.setRole(this.authorizationProperties.getGlobalAdminRole());
|
||||
item.setCreatedAt(Instant.now());
|
||||
this.entityManager.persist(item);
|
||||
this.keycloakService.addUserToGlobalRoleGroup(userCredential.getExternalId(), this.authorizationProperties.getGlobalAdminRole());
|
||||
}
|
||||
} finally {
|
||||
this.tenantScope.removeTempTenant(this.entityManager.getEntityManager());
|
||||
}
|
||||
|
||||
this.entityManager.flush();
|
||||
|
||||
}
|
||||
|
||||
private @NotNull TenantConfigEntity buildConfigEntity(TenantConfigPersist persist) throws InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
|
||||
TenantConfigEntity data = new TenantConfigEntity();
|
||||
|
|
|
@ -29,7 +29,6 @@ import eu.eudat.integrationevent.outbox.notification.NotifyIntegrationEvent;
|
|||
import eu.eudat.integrationevent.outbox.notification.NotifyIntegrationEventHandler;
|
||||
import eu.eudat.integrationevent.outbox.userremoval.UserRemovalIntegrationEventHandler;
|
||||
import eu.eudat.integrationevent.outbox.usertouched.UserTouchedIntegrationEventHandler;
|
||||
import eu.eudat.model.Tenant;
|
||||
import eu.eudat.model.User;
|
||||
import eu.eudat.model.UserContactInfo;
|
||||
import eu.eudat.model.UserCredential;
|
||||
|
@ -41,7 +40,6 @@ import eu.eudat.model.persist.actionconfirmation.RemoveCredentialRequestPersist;
|
|||
import eu.eudat.query.*;
|
||||
import eu.eudat.service.actionconfirmation.ActionConfirmationService;
|
||||
import eu.eudat.service.elastic.ElasticService;
|
||||
import eu.eudat.service.keycloak.KeycloakRole;
|
||||
import eu.eudat.service.keycloak.KeycloakService;
|
||||
import gr.cite.commons.web.authz.service.AuthorizationService;
|
||||
import gr.cite.tools.data.builder.BuilderFactory;
|
||||
|
@ -252,7 +250,7 @@ public class UserServiceImpl implements UserService {
|
|||
throw new MyApplicationException("Currently cannot update roles for this user");
|
||||
if (userCredentials.getFirst().getExternalId() == null)
|
||||
throw new MyApplicationException("Currently cannot update roles for this user");
|
||||
UUID subjectId = UUID.fromString(userCredentials.getFirst().getExternalId());
|
||||
String subjectId = userCredentials.getFirst().getExternalId();
|
||||
|
||||
this.applyGlobalRoles(data.getId(), subjectId, model);
|
||||
|
||||
|
@ -266,33 +264,39 @@ public class UserServiceImpl implements UserService {
|
|||
return this.builderFactory.builder(UserBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).build(BaseFieldSet.build(fields, User._id), data);
|
||||
}
|
||||
|
||||
private void applyGlobalRoles(UUID userId, UUID subjectId, UserRolePatchPersist model) throws InvalidApplicationException {
|
||||
List<UserRoleEntity> existingItems = this.queryFactory.query(UserRoleQuery.class).userIds(userId).tenantIsSet(false).roles(this.authorizationProperties.getAllowedGlobalRoles()).collect();
|
||||
List<UUID> foundIds = new ArrayList<>();
|
||||
for (String roleName : model.getRoles().stream().filter(x-> x != null && !x.isBlank() && this.authorizationProperties.getAllowedGlobalRoles().contains(x)).distinct().toList()) {
|
||||
UserRoleEntity item = existingItems.stream().filter(x-> x.getRole().equals(roleName)).findFirst().orElse(null);
|
||||
if (item == null) {
|
||||
item = new UserRoleEntity();
|
||||
item.setId(UUID.randomUUID());
|
||||
item.setUserId(userId);
|
||||
item.setRole(roleName);
|
||||
item.setCreatedAt(Instant.now());
|
||||
this.entityManager.persist(item);
|
||||
this.keycloakService.addUserToGroup(subjectId, KeycloakRole.valueOf(roleName));
|
||||
private void applyGlobalRoles(UUID userId, String subjectId, UserRolePatchPersist model) throws InvalidApplicationException {
|
||||
try {
|
||||
this.tenantScope.setTempTenant(this.entityManager.getEntityManager(), null, this.tenantScope.getDefaultTenantCode());
|
||||
|
||||
List<UserRoleEntity> existingItems = this.queryFactory.query(UserRoleQuery.class).userIds(userId).tenantIsSet(false).roles(this.authorizationProperties.getAllowedGlobalRoles()).collect();
|
||||
List<UUID> foundIds = new ArrayList<>();
|
||||
for (String roleName : model.getRoles().stream().filter(x -> x != null && !x.isBlank() && this.authorizationProperties.getAllowedGlobalRoles().contains(x)).distinct().toList()) {
|
||||
UserRoleEntity item = existingItems.stream().filter(x -> x.getRole().equals(roleName)).findFirst().orElse(null);
|
||||
if (item == null) {
|
||||
item = new UserRoleEntity();
|
||||
item.setId(UUID.randomUUID());
|
||||
item.setUserId(userId);
|
||||
item.setRole(roleName);
|
||||
item.setCreatedAt(Instant.now());
|
||||
this.entityManager.persist(item);
|
||||
this.keycloakService.addUserToGlobalRoleGroup(subjectId, roleName);
|
||||
}
|
||||
foundIds.add(item.getId());
|
||||
}
|
||||
foundIds.add(item.getId());
|
||||
|
||||
this.entityManager.flush();
|
||||
|
||||
List<UserRoleEntity> toDelete = existingItems.stream().filter(x -> foundIds.stream().noneMatch(y -> y.equals(x.getId()))).collect(Collectors.toList());
|
||||
toDelete.forEach(x -> this.keycloakService.removeUserGlobalRoleGroup(subjectId, x.getRole()));
|
||||
this.deleterFactory.deleter(UserRoleDeleter.class).deleteAndSave(toDelete);
|
||||
|
||||
this.entityManager.flush();
|
||||
} finally {
|
||||
this.tenantScope.removeTempTenant(this.entityManager.getEntityManager());
|
||||
}
|
||||
|
||||
this.entityManager.flush();
|
||||
|
||||
List<UserRoleEntity> toDelete = existingItems.stream().filter(x-> foundIds.stream().noneMatch(y-> y.equals(x.getId()))).collect(Collectors.toList());
|
||||
toDelete.forEach(x -> this.keycloakService.removeUserFromGroup(subjectId, KeycloakRole.valueOf(x.getRole())));
|
||||
this.deleterFactory.deleter(UserRoleDeleter.class).deleteAndSave(toDelete);
|
||||
|
||||
this.entityManager.flush();
|
||||
}
|
||||
|
||||
private void applyTenantRoles(UUID userId, UUID subjectId, UserRolePatchPersist model) throws InvalidApplicationException {
|
||||
private void applyTenantRoles(UUID userId, String subjectId, UserRolePatchPersist model) throws InvalidApplicationException {
|
||||
if (!tenantScope.isSet()) throw new MyForbiddenException("tenant scope required");
|
||||
|
||||
UserRoleQuery userRoleQuery = this.queryFactory.query(UserRoleQuery.class).userIds(userId).roles(this.authorizationProperties.getAllowedTenantRoles());
|
||||
|
@ -311,7 +315,7 @@ public class UserServiceImpl implements UserService {
|
|||
item.setCreatedAt(Instant.now());
|
||||
item.setTenantId(this.tenantScope.getTenant());
|
||||
this.entityManager.persist(item);
|
||||
this.keycloakService.addUserToGroup(subjectId, KeycloakRole.valueOf(roleName));
|
||||
this.keycloakService.addUserToTenantRoleGroup(subjectId, this.tenantScope.getTenantCode(), roleName);
|
||||
}
|
||||
foundIds.add(item.getId());
|
||||
}
|
||||
|
@ -319,7 +323,13 @@ public class UserServiceImpl implements UserService {
|
|||
this.entityManager.flush();
|
||||
|
||||
List<UserRoleEntity> toDelete = existingItems.stream().filter(x-> foundIds.stream().noneMatch(y-> y.equals(x.getId()))).collect(Collectors.toList());
|
||||
toDelete.forEach(x -> this.keycloakService.removeUserFromGroup(subjectId, KeycloakRole.valueOf(x.getRole())));
|
||||
toDelete.forEach(x -> {
|
||||
try {
|
||||
this.keycloakService.removeUserTenantRoleGroup(subjectId, this.tenantScope.getTenantCode(), x.getRole());
|
||||
} catch (InvalidApplicationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
this.deleterFactory.deleter(UserRoleDeleter.class).deleteAndSave(toDelete);
|
||||
|
||||
this.entityManager.flush();
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
authorization:
|
||||
globalAdminRole: Admin
|
||||
autoAssignGlobalAdminToNewTenants: true
|
||||
allowedTenantRoles:
|
||||
- TenantAdmin
|
||||
- TenantUser
|
||||
|
|
|
@ -1,14 +1,21 @@
|
|||
keycloak-resources:
|
||||
tenantGroupsNamingStrategy: 'tenant-{tenantCode}'
|
||||
tenantRoleAttributeName: 'tenant_role'
|
||||
authorities:
|
||||
User:
|
||||
groupId: a04fd333-f127-449e-8fc2-0626570a3899
|
||||
groupTitle: role-user
|
||||
Admin:
|
||||
groupId: 299f18fe-e271-4625-a4c1-9c3eb313b2ea
|
||||
groupTitle: role-admin
|
||||
Manager:
|
||||
groupId: 1753f7a7-cedb-4ad4-ae5f-96fe9bdabe3e
|
||||
groupTitle: role-manager
|
||||
DescriptionTemplateEditor:
|
||||
groupId: b0ea3cf3-21b0-4c6b-9c42-fb09f0e09dbb
|
||||
groupTitle: role-description-template-editor
|
||||
tenantAuthorities:
|
||||
TenantAdmin:
|
||||
parent: 1e650f57-8b7c-4f32-bf5b-e1a9147c597b
|
||||
roleAttributeValueStrategy: 'TenantAdmin:{tenantCode}'
|
||||
TenantUser:
|
||||
parent: c7057c4d-e7dc-49ef-aa5d-02ad3a22bff8
|
||||
roleAttributeValueStrategy: 'TenantUser:{tenantCode}'
|
||||
TenantManager:
|
||||
parent: d111bb2f-b4a6-4de7-ad22-5151ee1a508b
|
||||
roleAttributeValueStrategy: 'TenantManager:{tenantCode}'
|
||||
TenantDescriptionTemplateEditor:
|
||||
parent: 55cf7b17-c025-4065-8906-49f9f430f038
|
||||
roleAttributeValueStrategy: 'TenantDescriptionTemplateEditor:{tenantCode}'
|
|
@ -1,10 +1,10 @@
|
|||
keycloak-client:
|
||||
serverUrl: ${KEYCLOAK_API_SERVER_URL:}
|
||||
realm: ${KEYCLOAK_API_REALM:}
|
||||
username: ${KEYCLOAK_API_USERNAME:}
|
||||
password: ${KEYCLOAK_API_PASSWORD:}
|
||||
clientId: ${KEYCLOAK_API_CLIENT_ID:}
|
||||
clientSecret: ${KEYCLOAK_API_CLIENT_SECRET:}
|
||||
serverUrl: ${KEYCLOAK_API_SERVER_URL}
|
||||
realm: ${KEYCLOAK_API_REALM}
|
||||
username: ${KEYCLOAK_API_USERNAME}
|
||||
password: ${KEYCLOAK_API_PASSWORD}
|
||||
clientId: ${KEYCLOAK_API_CLIENT_ID}
|
||||
clientSecret: ${KEYCLOAK_API_CLIENT_SECRET}
|
||||
|
||||
keycloak-resources:
|
||||
authorities: null
|
|
@ -11,7 +11,7 @@ CREATE TABLE IF NOT EXISTS public."ant_Annotation"
|
|||
"entity_type" character varying(512) COLLATE pg_catalog."default" NOT NULL,
|
||||
"anchor" character varying(512) COLLATE pg_catalog."default",
|
||||
"payload" text COLLATE pg_catalog."default",
|
||||
"tenant" uuid NOT NULL,
|
||||
"tenant" uuid NULL,
|
||||
"created_at" timestamp without time zone NOT NULL,
|
||||
"updated_at" timestamp without time zone NOT NULL,
|
||||
"is_active" smallint NOT NULL,
|
||||
|
|
Loading…
Reference in New Issue