tenant fixes
This commit is contained in:
parent
f6ea1e2b04
commit
1888711fe9
|
@ -3,16 +3,16 @@ package org.opencdmp.authorization;
|
||||||
|
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ConfigurationProperties(prefix = "authorization")
|
@ConfigurationProperties(prefix = "authorization")
|
||||||
public class AuthorizationProperties {
|
public class AuthorizationProperties {
|
||||||
|
|
||||||
private String globalAdminRole;
|
private String globalAdminRole;
|
||||||
|
private String tenantAdminRole;
|
||||||
|
|
||||||
public String getGlobalAdminRole() {
|
public String getGlobalAdminRole() {
|
||||||
return globalAdminRole;
|
return this.globalAdminRole;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setGlobalAdminRole(String globalAdminRole) {
|
public void setGlobalAdminRole(String globalAdminRole) {
|
||||||
|
@ -21,7 +21,7 @@ public class AuthorizationProperties {
|
||||||
private Boolean autoAssignGlobalAdminToNewTenants;
|
private Boolean autoAssignGlobalAdminToNewTenants;
|
||||||
|
|
||||||
public Boolean getAutoAssignGlobalAdminToNewTenants() {
|
public Boolean getAutoAssignGlobalAdminToNewTenants() {
|
||||||
return autoAssignGlobalAdminToNewTenants;
|
return this.autoAssignGlobalAdminToNewTenants;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAutoAssignGlobalAdminToNewTenants(Boolean autoAssignGlobalAdminToNewTenants) {
|
public void setAutoAssignGlobalAdminToNewTenants(Boolean autoAssignGlobalAdminToNewTenants) {
|
||||||
|
@ -31,7 +31,7 @@ public class AuthorizationProperties {
|
||||||
private List<String> allowedTenantRoles;
|
private List<String> allowedTenantRoles;
|
||||||
|
|
||||||
public List<String> getAllowedTenantRoles() {
|
public List<String> getAllowedTenantRoles() {
|
||||||
return allowedTenantRoles;
|
return this.allowedTenantRoles;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAllowedTenantRoles(List<String> allowedTenantRoles) {
|
public void setAllowedTenantRoles(List<String> allowedTenantRoles) {
|
||||||
|
@ -41,10 +41,18 @@ public class AuthorizationProperties {
|
||||||
private List<String> allowedGlobalRoles;
|
private List<String> allowedGlobalRoles;
|
||||||
|
|
||||||
public List<String> getAllowedGlobalRoles() {
|
public List<String> getAllowedGlobalRoles() {
|
||||||
return allowedGlobalRoles;
|
return this.allowedGlobalRoles;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAllowedGlobalRoles(List<String> allowedGlobalRoles) {
|
public void setAllowedGlobalRoles(List<String> allowedGlobalRoles) {
|
||||||
this.allowedGlobalRoles = allowedGlobalRoles;
|
this.allowedGlobalRoles = allowedGlobalRoles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getTenantAdminRole() {
|
||||||
|
return this.tenantAdminRole;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTenantAdminRole(String tenantAdminRole) {
|
||||||
|
this.tenantAdminRole = tenantAdminRole;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,11 +16,11 @@ public class KeycloakResourcesConfiguration {
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeycloakResourcesProperties getProperties() {
|
public KeycloakResourcesProperties getProperties() {
|
||||||
return properties;
|
return this.properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTenantGroupName(String tenantCode) {
|
public String getTenantGroupName(String tenantCode) {
|
||||||
return properties.getTenantGroupsNamingStrategy()
|
return this.properties.getTenantGroupsNamingStrategy()
|
||||||
.replace("{tenantCode}", tenantCode);
|
.replace("{tenantCode}", tenantCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,18 @@
|
||||||
package org.opencdmp.service.keycloak;
|
package org.opencdmp.service.keycloak;
|
||||||
|
|
||||||
import org.opencdmp.convention.ConventionService;
|
|
||||||
import gr.cite.commons.web.keycloak.api.configuration.KeycloakClientConfiguration;
|
|
||||||
import gr.cite.tools.logging.LoggerService;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.keycloak.representations.idm.GroupRepresentation;
|
import org.keycloak.representations.idm.GroupRepresentation;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.opencdmp.convention.ConventionService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class KeycloakServiceImpl implements KeycloakService {
|
public class KeycloakServiceImpl implements KeycloakService {
|
||||||
|
|
||||||
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(KeycloakServiceImpl.class));
|
|
||||||
private final MyKeycloakAdminRestApi api;
|
private final MyKeycloakAdminRestApi api;
|
||||||
private final KeycloakResourcesConfiguration configuration;
|
private final KeycloakResourcesConfiguration configuration;
|
||||||
private final ConventionService conventionService;
|
private final ConventionService conventionService;
|
||||||
|
@ -28,26 +26,26 @@ public class KeycloakServiceImpl implements KeycloakService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addUserToGroup(@NotNull String subjectId, String groupId) {
|
public void addUserToGroup(@NotNull String subjectId, String groupId) {
|
||||||
api.users().addUserToGroup(subjectId, groupId);
|
this.api.users().addUserToGroup(subjectId, groupId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeUserFromGroup(@NotNull String subjectId, String groupId) {
|
public void removeUserFromGroup(@NotNull String subjectId, String groupId) {
|
||||||
api.users().removeUserFromGroup(subjectId, groupId);
|
this.api.users().removeUserFromGroup(subjectId, groupId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addUserToGlobalRoleGroup(String subjectId, String role) {
|
public void addUserToGlobalRoleGroup(String subjectId, String role) {
|
||||||
if (this.configuration.getProperties().getAuthorities() == null) return;
|
if (this.configuration.getProperties().getAuthorities() == null) return;
|
||||||
KeycloakAuthorityProperties properties = this.configuration.getProperties().getAuthorities().getOrDefault(role, null);
|
KeycloakAuthorityProperties properties = this.configuration.getProperties().getAuthorities().getOrDefault(role, null);
|
||||||
if (properties != null) addUserToGroup(subjectId, properties.getGroupId());
|
if (properties != null) this.addUserToGroup(subjectId, properties.getGroupId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeUserGlobalRoleGroup(@NotNull String subjectId, String role) {
|
public void removeUserGlobalRoleGroup(@NotNull String subjectId, String role) {
|
||||||
if (this.configuration.getProperties().getAuthorities() == null) return;
|
if (this.configuration.getProperties().getAuthorities() == null) return;
|
||||||
KeycloakAuthorityProperties properties = this.configuration.getProperties().getAuthorities().getOrDefault(role, null);
|
KeycloakAuthorityProperties properties = this.configuration.getProperties().getAuthorities().getOrDefault(role, null);
|
||||||
if (properties != null) removeUserFromGroup(subjectId, properties.getGroupId());
|
if (properties != null) this.removeUserFromGroup(subjectId, properties.getGroupId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -55,33 +53,33 @@ public class KeycloakServiceImpl implements KeycloakService {
|
||||||
if (this.configuration.getProperties().getAuthorities() == null) return;
|
if (this.configuration.getProperties().getAuthorities() == null) return;
|
||||||
KeycloakTenantAuthorityProperties properties = this.configuration.getProperties().getTenantAuthorities().getOrDefault(tenantRole, null);
|
KeycloakTenantAuthorityProperties properties = this.configuration.getProperties().getTenantAuthorities().getOrDefault(tenantRole, null);
|
||||||
if (properties == null) return;
|
if (properties == null) return;
|
||||||
GroupRepresentation group = api.groups().findGroupByPath(getTenantAuthorityParentPath(properties) + "/" + configuration.getTenantGroupName(tenantCode));
|
GroupRepresentation group = this.api.groups().findGroupByPath(this.getTenantAuthorityParentPath(properties) + "/" + this.configuration.getTenantGroupName(tenantCode));
|
||||||
if (group != null) addUserToGroup(subjectId, group.getId());
|
if (group != null) this.addUserToGroup(subjectId, group.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeUserTenantRoleGroup(String subjectId, String tenantCode, String tenantRole) {
|
public void removeUserTenantRoleGroup(String subjectId, String tenantCode, String tenantRole) {
|
||||||
KeycloakTenantAuthorityProperties properties = this.configuration.getProperties().getTenantAuthorities().getOrDefault(tenantRole, null);
|
KeycloakTenantAuthorityProperties properties = this.configuration.getProperties().getTenantAuthorities().getOrDefault(tenantRole, null);
|
||||||
if (properties == null) return;
|
if (properties == null) return;
|
||||||
GroupRepresentation group = api.groups().findGroupByPath(getTenantAuthorityParentPath(properties) + "/" + configuration.getTenantGroupName(tenantCode));
|
GroupRepresentation group = this.api.groups().findGroupByPath(this.getTenantAuthorityParentPath(properties) + "/" + this.configuration.getTenantGroupName(tenantCode));
|
||||||
if (group != null) removeUserFromGroup(subjectId, group.getId());
|
if (group != null) this.removeUserFromGroup(subjectId, group.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getTenantAuthorityParentPath(KeycloakTenantAuthorityProperties keycloakTenantAuthorityProperties) {
|
private String getTenantAuthorityParentPath(KeycloakTenantAuthorityProperties keycloakTenantAuthorityProperties) {
|
||||||
GroupRepresentation parent = api.groups().findGroupById(keycloakTenantAuthorityProperties.getParent());
|
GroupRepresentation parent = this.api.groups().findGroupById(keycloakTenantAuthorityProperties.getParent());
|
||||||
return parent.getPath();
|
return parent.getPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createTenantGroups(String tenantCode) {
|
public void createTenantGroups(String tenantCode) {
|
||||||
if (this.configuration.getProperties().getTenantAuthorities() == null) return;
|
if (this.configuration.getProperties().getTenantAuthorities() == null) return;
|
||||||
for (Map.Entry<String,KeycloakTenantAuthorityProperties> entry :configuration.getProperties().getTenantAuthorities().entrySet()){
|
for (Map.Entry<String,KeycloakTenantAuthorityProperties> entry : this.configuration.getProperties().getTenantAuthorities().entrySet()){
|
||||||
GroupRepresentation group = new GroupRepresentation();
|
GroupRepresentation group = new GroupRepresentation();
|
||||||
group.setName(configuration.getTenantGroupName(tenantCode));
|
group.setName(this.configuration.getTenantGroupName(tenantCode));
|
||||||
HashMap<String, List<String>> user_attributes = new HashMap<>();
|
HashMap<String, List<String>> user_attributes = new HashMap<>();
|
||||||
if (!this.conventionService.isNullOrEmpty(this.configuration.getProperties().getTenantRoleAttributeName())) user_attributes.put(this.configuration.getProperties().getTenantRoleAttributeName(), List.of(configuration.getTenantRoleAttributeValue(tenantCode, entry.getValue())));
|
if (!this.conventionService.isNullOrEmpty(this.configuration.getProperties().getTenantRoleAttributeName())) user_attributes.put(this.configuration.getProperties().getTenantRoleAttributeName(), List.of(this.configuration.getTenantRoleAttributeValue(tenantCode, entry.getValue())));
|
||||||
group.setAttributes(user_attributes);
|
group.setAttributes(user_attributes);
|
||||||
api.groups().addGroupWithParent(group, entry.getValue().getParent());
|
this.api.groups().addGroupWithParent(group, entry.getValue().getParent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,20 @@
|
||||||
package org.opencdmp.service.tenant;
|
package org.opencdmp.service.tenant;
|
||||||
|
|
||||||
|
import gr.cite.commons.web.authz.service.AuthorizationService;
|
||||||
|
import gr.cite.tools.data.builder.BuilderFactory;
|
||||||
|
import gr.cite.tools.data.deleter.DeleterFactory;
|
||||||
|
import gr.cite.tools.data.query.QueryFactory;
|
||||||
|
import gr.cite.tools.exception.MyApplicationException;
|
||||||
|
import gr.cite.tools.exception.MyForbiddenException;
|
||||||
|
import gr.cite.tools.exception.MyNotFoundException;
|
||||||
|
import gr.cite.tools.exception.MyValidationException;
|
||||||
|
import gr.cite.tools.fieldset.BaseFieldSet;
|
||||||
|
import gr.cite.tools.fieldset.FieldSet;
|
||||||
|
import gr.cite.tools.logging.LoggerService;
|
||||||
|
import gr.cite.tools.logging.MapLogEntry;
|
||||||
import org.opencdmp.authorization.AuthorizationFlags;
|
import org.opencdmp.authorization.AuthorizationFlags;
|
||||||
import org.opencdmp.authorization.AuthorizationProperties;
|
import org.opencdmp.authorization.AuthorizationProperties;
|
||||||
import org.opencdmp.authorization.Permission;
|
import org.opencdmp.authorization.Permission;
|
||||||
import org.opencdmp.commons.XmlHandlingService;
|
|
||||||
import org.opencdmp.commons.enums.IsActive;
|
import org.opencdmp.commons.enums.IsActive;
|
||||||
import org.opencdmp.commons.scope.tenant.TenantScope;
|
import org.opencdmp.commons.scope.tenant.TenantScope;
|
||||||
import org.opencdmp.convention.ConventionService;
|
import org.opencdmp.convention.ConventionService;
|
||||||
|
@ -22,21 +33,7 @@ import org.opencdmp.model.deleter.TenantDeleter;
|
||||||
import org.opencdmp.model.persist.TenantPersist;
|
import org.opencdmp.model.persist.TenantPersist;
|
||||||
import org.opencdmp.query.UserCredentialQuery;
|
import org.opencdmp.query.UserCredentialQuery;
|
||||||
import org.opencdmp.query.UserRoleQuery;
|
import org.opencdmp.query.UserRoleQuery;
|
||||||
import org.opencdmp.service.encryption.EncryptionService;
|
|
||||||
import org.opencdmp.service.keycloak.KeycloakService;
|
import org.opencdmp.service.keycloak.KeycloakService;
|
||||||
import gr.cite.commons.web.authz.service.AuthorizationService;
|
|
||||||
import gr.cite.tools.data.builder.BuilderFactory;
|
|
||||||
import gr.cite.tools.data.deleter.DeleterFactory;
|
|
||||||
import gr.cite.tools.data.query.QueryFactory;
|
|
||||||
import gr.cite.tools.exception.MyApplicationException;
|
|
||||||
import gr.cite.tools.exception.MyForbiddenException;
|
|
||||||
import gr.cite.tools.exception.MyNotFoundException;
|
|
||||||
import gr.cite.tools.exception.MyValidationException;
|
|
||||||
import gr.cite.tools.fieldset.BaseFieldSet;
|
|
||||||
import gr.cite.tools.fieldset.FieldSet;
|
|
||||||
import gr.cite.tools.logging.LoggerService;
|
|
||||||
import gr.cite.tools.logging.MapLogEntry;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.MessageSource;
|
import org.springframework.context.MessageSource;
|
||||||
|
@ -114,7 +111,7 @@ public class TenantServiceImpl implements TenantService {
|
||||||
if (isUpdate) {
|
if (isUpdate) {
|
||||||
data = this.entityManager.find(TenantEntity.class, model.getId());
|
data = this.entityManager.find(TenantEntity.class, model.getId());
|
||||||
if (data == null)
|
if (data == null)
|
||||||
throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getId(), Tenant.class.getSimpleName()}, LocaleContextHolder.getLocale()));
|
throw new MyNotFoundException(this.messageSource.getMessage("General_ItemNotFound", new Object[]{model.getId(), Tenant.class.getSimpleName()}, LocaleContextHolder.getLocale()));
|
||||||
if (!this.conventionService.hashValue(data.getUpdatedAt()).equals(model.getHash()))
|
if (!this.conventionService.hashValue(data.getUpdatedAt()).equals(model.getHash()))
|
||||||
throw new MyValidationException(this.errors.getHashConflict().getCode(), this.errors.getHashConflict().getMessage());
|
throw new MyValidationException(this.errors.getHashConflict().getCode(), this.errors.getHashConflict().getMessage());
|
||||||
} else {
|
} else {
|
||||||
|
@ -147,7 +144,7 @@ public class TenantServiceImpl implements TenantService {
|
||||||
return this.builderFactory.builder(TenantBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).build(BaseFieldSet.build(fields, Tenant._id), data);
|
return this.builderFactory.builder(TenantBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).build(BaseFieldSet.build(fields, Tenant._id), data);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void autoAssignGlobalAdminsToNewTenant(TenantEntity tenant){
|
private void autoAssignGlobalAdminsToNewTenant(TenantEntity tenant) throws InvalidApplicationException {
|
||||||
if (!this.authorizationProperties.getAutoAssignGlobalAdminToNewTenants()) return;
|
if (!this.authorizationProperties.getAutoAssignGlobalAdminToNewTenants()) return;
|
||||||
List<UserRoleEntity> existingItems;
|
List<UserRoleEntity> existingItems;
|
||||||
List<UserCredentialEntity> userCredentialEntities;
|
List<UserCredentialEntity> userCredentialEntities;
|
||||||
|
@ -167,10 +164,10 @@ public class TenantServiceImpl implements TenantService {
|
||||||
UserRoleEntity item = new UserRoleEntity();
|
UserRoleEntity item = new UserRoleEntity();
|
||||||
item.setId(UUID.randomUUID());
|
item.setId(UUID.randomUUID());
|
||||||
item.setUserId(userId);
|
item.setUserId(userId);
|
||||||
item.setRole(this.authorizationProperties.getGlobalAdminRole());
|
item.setRole(this.authorizationProperties.getTenantAdminRole());
|
||||||
item.setCreatedAt(Instant.now());
|
item.setCreatedAt(Instant.now());
|
||||||
this.entityManager.persist(item);
|
this.entityManager.persist(item);
|
||||||
this.keycloakService.addUserToGlobalRoleGroup(userCredential.getExternalId(), this.authorizationProperties.getGlobalAdminRole());
|
this.keycloakService.addUserToTenantRoleGroup(userCredential.getExternalId(), this.tenantScope.getTenantCode(), this.authorizationProperties.getTenantAdminRole());
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
this.tenantScope.removeTempTenant(this.entityManager.getEntityManager());
|
this.tenantScope.removeTempTenant(this.entityManager.getEntityManager());
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
authorization:
|
authorization:
|
||||||
globalAdminRole: Admin
|
globalAdminRole: Admin
|
||||||
|
tenantAdminRole: TenantAdmin
|
||||||
autoAssignGlobalAdminToNewTenants: true
|
autoAssignGlobalAdminToNewTenants: true
|
||||||
allowedTenantRoles:
|
allowedTenantRoles:
|
||||||
- TenantAdmin
|
- TenantAdmin
|
||||||
|
|
Loading…
Reference in New Issue