add CredentialData
This commit is contained in:
parent
04381aec20
commit
d1cad30fcb
|
@ -0,0 +1,5 @@
|
||||||
|
package eu.eudat.authorization;
|
||||||
|
|
||||||
|
public class ClaimNames {
|
||||||
|
public static final String ExternalProviderName = "ExternalProviderName";
|
||||||
|
}
|
|
@ -3,15 +3,15 @@ package eu.eudat.commons.types.usercredential;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class UserCredentialDataEntity {
|
public class UserCredentialDataEntity {
|
||||||
private List<String> providers;
|
private List<String> externalProviderNames;
|
||||||
private String email;
|
private String email;
|
||||||
|
|
||||||
public List<String> getProviders() {
|
public List<String> getExternalProviderNames() {
|
||||||
return providers;
|
return externalProviderNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setProviders(List<String> providers) {
|
public void setExternalProviderNames(List<String> externalProviderNames) {
|
||||||
this.providers = providers;
|
this.externalProviderNames = externalProviderNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getEmail() {
|
public String getEmail() {
|
||||||
|
|
|
@ -25,14 +25,12 @@ import org.springframework.context.ApplicationContext;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
public class InboxRepositoryImpl implements InboxRepository {
|
public class InboxRepositoryImpl implements InboxRepository {
|
||||||
|
|
||||||
protected final ApplicationContext applicationContext;
|
protected final ApplicationContext applicationContext;
|
||||||
private final Random random = new Random();
|
|
||||||
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(InboxRepositoryImpl.class));
|
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(InboxRepositoryImpl.class));
|
||||||
private final JsonHandlingService jsonHandlingService;
|
private final JsonHandlingService jsonHandlingService;
|
||||||
private final InboxProperties inboxProperties;
|
private final InboxProperties inboxProperties;
|
||||||
|
@ -85,18 +83,18 @@ public class InboxRepositoryImpl implements InboxRepository {
|
||||||
transaction.commit();
|
transaction.commit();
|
||||||
} catch (OptimisticLockException ex) {
|
} catch (OptimisticLockException ex) {
|
||||||
// we get this if/when someone else already modified the notifications. We want to essentially ignore this, and keep working
|
// we get this if/when someone else already modified the notifications. We want to essentially ignore this, and keep working
|
||||||
this.logger.debug("Concurrency exception getting queue inbox. Skipping: {} ", ex.getMessage());
|
logger.debug("Concurrency exception getting queue inbox. Skipping: {} ", ex.getMessage());
|
||||||
if (transaction != null) transaction.rollback();
|
if (transaction != null) transaction.rollback();
|
||||||
candidate = null;
|
candidate = null;
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
this.logger.error("Problem getting list of queue inbox. Skipping: {}", ex.getMessage(), ex);
|
logger.error("Problem getting list of queue inbox. Skipping: {}", ex.getMessage(), ex);
|
||||||
if (transaction != null) transaction.rollback();
|
if (transaction != null) transaction.rollback();
|
||||||
candidate = null;
|
candidate = null;
|
||||||
} finally {
|
} finally {
|
||||||
if (entityManager != null) entityManager.close();
|
if (entityManager != null) entityManager.close();
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
this.logger.error("Problem getting list of queue inbox. Skipping: {}", ex.getMessage(), ex);
|
logger.error("Problem getting list of queue inbox. Skipping: {}", ex.getMessage(), ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return candidate;
|
return candidate;
|
||||||
|
|
|
@ -47,7 +47,7 @@ public class UserCredentialDataBuilder extends BaseBuilder<UserCredentialData, U
|
||||||
for (UserCredentialDataEntity d : data) {
|
for (UserCredentialDataEntity d : data) {
|
||||||
UserCredentialData m = new UserCredentialData();
|
UserCredentialData m = new UserCredentialData();
|
||||||
if (fields.hasField(this.asIndexer(UserCredentialData._email))) m.setEmail(d.getEmail());
|
if (fields.hasField(this.asIndexer(UserCredentialData._email))) m.setEmail(d.getEmail());
|
||||||
if (fields.hasField(this.asIndexer(UserCredentialData._providers))) m.setProviders(d.getProviders());
|
if (fields.hasField(this.asIndexer(UserCredentialData._externalProviderNames))) m.setExternalProviderNames(d.getExternalProviderNames());
|
||||||
models.add(m);
|
models.add(m);
|
||||||
}
|
}
|
||||||
this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0));
|
this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0));
|
||||||
|
|
|
@ -3,17 +3,17 @@ package eu.eudat.model.usercredential;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class UserCredentialData {
|
public class UserCredentialData {
|
||||||
private List<String> providers;
|
private List<String> externalProviderNames;
|
||||||
public static final String _providers = "providers";
|
public static final String _externalProviderNames = "externalProviderNames";
|
||||||
private String email;
|
private String email;
|
||||||
public static final String _email = "email";
|
public static final String _email = "email";
|
||||||
|
|
||||||
public List<String> getProviders() {
|
public List<String> getExternalProviderNames() {
|
||||||
return providers;
|
return externalProviderNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setProviders(List<String> providers) {
|
public void setExternalProviderNames(List<String> externalProviderNames) {
|
||||||
this.providers = providers;
|
this.externalProviderNames = externalProviderNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getEmail() {
|
public String getEmail() {
|
||||||
|
|
|
@ -177,6 +177,8 @@ public class UserCredentialQuery extends QueryBase<UserCredentialEntity> {
|
||||||
else if (item.prefix(UserCredential._user)) return UserCredentialEntity._userId;
|
else if (item.prefix(UserCredential._user)) return UserCredentialEntity._userId;
|
||||||
else if (item.match(UserCredential._user)) return UserCredentialEntity._userId;
|
else if (item.match(UserCredential._user)) return UserCredentialEntity._userId;
|
||||||
else if (item.match(UserCredential._createdAt) ) return UserCredentialEntity._createdAt;
|
else if (item.match(UserCredential._createdAt) ) return UserCredentialEntity._createdAt;
|
||||||
|
else if (item.match(UserCredential._data) ) return UserCredentialEntity._data;
|
||||||
|
else if (item.prefix(UserCredential._data) ) return UserCredentialEntity._data;
|
||||||
else return null;
|
else return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,6 +189,7 @@ public class UserCredentialQuery extends QueryBase<UserCredentialEntity> {
|
||||||
item.setExternalId(QueryBase.convertSafe(tuple, columns, UserCredentialEntity._externalId, String.class));
|
item.setExternalId(QueryBase.convertSafe(tuple, columns, UserCredentialEntity._externalId, String.class));
|
||||||
item.setUserId(QueryBase.convertSafe(tuple, columns, UserCredentialEntity._userId, UUID.class));
|
item.setUserId(QueryBase.convertSafe(tuple, columns, UserCredentialEntity._userId, UUID.class));
|
||||||
item.setCreatedAt(QueryBase.convertSafe(tuple, columns, UserCredentialEntity._createdAt, Instant.class));
|
item.setCreatedAt(QueryBase.convertSafe(tuple, columns, UserCredentialEntity._createdAt, Instant.class));
|
||||||
|
item.setData(QueryBase.convertSafe(tuple, columns, UserCredentialEntity._data, String.class));
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
package eu.eudat.interceptors;
|
package eu.eudat.interceptors;
|
||||||
|
|
||||||
|
|
||||||
|
import eu.eudat.authorization.ClaimNames;
|
||||||
import eu.eudat.commons.JsonHandlingService;
|
import eu.eudat.commons.JsonHandlingService;
|
||||||
import eu.eudat.commons.enums.ContactInfoType;
|
import eu.eudat.commons.enums.ContactInfoType;
|
||||||
import eu.eudat.commons.enums.IsActive;
|
import eu.eudat.commons.enums.IsActive;
|
||||||
import eu.eudat.commons.lock.LockByKeyManager;
|
import eu.eudat.commons.lock.LockByKeyManager;
|
||||||
import eu.eudat.commons.scope.user.UserScope;
|
import eu.eudat.commons.scope.user.UserScope;
|
||||||
import eu.eudat.commons.types.user.AdditionalInfoEntity;
|
import eu.eudat.commons.types.user.AdditionalInfoEntity;
|
||||||
|
import eu.eudat.commons.types.usercredential.UserCredentialDataEntity;
|
||||||
import eu.eudat.data.UserContactInfoEntity;
|
import eu.eudat.data.UserContactInfoEntity;
|
||||||
import eu.eudat.data.UserCredentialEntity;
|
import eu.eudat.data.UserCredentialEntity;
|
||||||
import eu.eudat.data.UserEntity;
|
import eu.eudat.data.UserEntity;
|
||||||
|
@ -14,7 +16,9 @@ import eu.eudat.data.UserRoleEntity;
|
||||||
import eu.eudat.model.UserContactInfo;
|
import eu.eudat.model.UserContactInfo;
|
||||||
import eu.eudat.model.UserCredential;
|
import eu.eudat.model.UserCredential;
|
||||||
import eu.eudat.model.UserRole;
|
import eu.eudat.model.UserRole;
|
||||||
import eu.eudat.query.*;
|
import eu.eudat.query.UserContactInfoQuery;
|
||||||
|
import eu.eudat.query.UserCredentialQuery;
|
||||||
|
import eu.eudat.query.UserRoleQuery;
|
||||||
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.data.query.QueryFactory;
|
||||||
|
@ -23,6 +27,7 @@ import gr.cite.tools.fieldset.BaseFieldSet;
|
||||||
import gr.cite.tools.logging.LoggerService;
|
import gr.cite.tools.logging.LoggerService;
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
import jakarta.persistence.PersistenceContext;
|
import jakarta.persistence.PersistenceContext;
|
||||||
|
import org.apache.commons.validator.routines.EmailValidator;
|
||||||
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.lang.NonNull;
|
import org.springframework.lang.NonNull;
|
||||||
|
@ -35,14 +40,11 @@ import org.springframework.ui.ModelMap;
|
||||||
import org.springframework.web.context.request.WebRequest;
|
import org.springframework.web.context.request.WebRequest;
|
||||||
import org.springframework.web.context.request.WebRequestInterceptor;
|
import org.springframework.web.context.request.WebRequestInterceptor;
|
||||||
|
|
||||||
import javax.management.InvalidApplicationException;
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.Semaphore;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class UserInterceptor implements WebRequestInterceptor {
|
public class UserInterceptor implements WebRequestInterceptor {
|
||||||
|
@ -86,13 +88,13 @@ public class UserInterceptor implements WebRequestInterceptor {
|
||||||
if (subjectId == null || subjectId.isBlank()) throw new MyForbiddenException("Empty subjects not allowed");
|
if (subjectId == null || subjectId.isBlank()) throw new MyForbiddenException("Empty subjects not allowed");
|
||||||
|
|
||||||
UserInterceptorCacheService.UserInterceptorCacheValue cacheValue = this.userInterceptorCacheService.lookup(this.userInterceptorCacheService.buildKey(subjectId));
|
UserInterceptorCacheService.UserInterceptorCacheValue cacheValue = this.userInterceptorCacheService.lookup(this.userInterceptorCacheService.buildKey(subjectId));
|
||||||
if (cacheValue != null && emailExistsToUser(cacheValue.getEmails()) && userRolesSynced(cacheValue.getRoles())) {
|
if (cacheValue != null && emailExistsToPrincipal(cacheValue.getProviderEmail()) && userRolesSynced(cacheValue.getRoles()) && providerExistsToPrincipal(cacheValue.getExternalProviderNames())) {
|
||||||
userId = cacheValue.getUserId();
|
userId = cacheValue.getUserId();
|
||||||
} else {
|
} else {
|
||||||
boolean usedResource = false;
|
boolean usedResource = false;
|
||||||
try {
|
try {
|
||||||
usedResource = this.lockByKeyManager.tryLock(subjectId, 5000, TimeUnit.MILLISECONDS);
|
usedResource = this.lockByKeyManager.tryLock(subjectId, 5000, TimeUnit.MILLISECONDS);
|
||||||
String email = this.claimExtractor.email(this.currentPrincipalResolver.currentPrincipal());
|
String email = this.getEmailFromClaims();
|
||||||
|
|
||||||
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
|
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
|
||||||
definition.setName(UUID.randomUUID().toString());
|
definition.setName(UUID.randomUUID().toString());
|
||||||
|
@ -101,14 +103,18 @@ public class UserInterceptor implements WebRequestInterceptor {
|
||||||
TransactionStatus status = null;
|
TransactionStatus status = null;
|
||||||
try {
|
try {
|
||||||
status = transactionManager.getTransaction(definition);
|
status = transactionManager.getTransaction(definition);
|
||||||
|
|
||||||
userId = this.findExistingUserFromDb(subjectId);
|
userId = this.findExistingUserFromDb(subjectId);
|
||||||
boolean isNewUser = userId == null;
|
boolean isNewUser = userId == null;
|
||||||
if (isNewUser) {
|
if (isNewUser) {
|
||||||
UserEntity user = this.addNewUser(subjectId, email);
|
UserEntity user = this.addNewUser(subjectId, email);
|
||||||
userId = user.getId();
|
userId = user.getId();
|
||||||
}
|
}
|
||||||
|
this.entityManager.flush();
|
||||||
|
|
||||||
if (!isNewUser) this.syncUserWithClaims(userId);
|
if (!isNewUser){
|
||||||
|
this.syncUserWithClaims(userId, subjectId);
|
||||||
|
}
|
||||||
|
|
||||||
this.entityManager.flush();
|
this.entityManager.flush();
|
||||||
transactionManager.commit(status);
|
transactionManager.commit(status);
|
||||||
|
@ -118,9 +124,13 @@ public class UserInterceptor implements WebRequestInterceptor {
|
||||||
}
|
}
|
||||||
|
|
||||||
cacheValue = new UserInterceptorCacheService.UserInterceptorCacheValue(subjectId, userId);
|
cacheValue = new UserInterceptorCacheService.UserInterceptorCacheValue(subjectId, userId);
|
||||||
cacheValue.setEmails(new ArrayList<>());
|
cacheValue.setRoles(this.getRolesFromClaims());
|
||||||
if (email != null && !email.isBlank()) cacheValue.getEmails().add(email);
|
if (email != null && !email.isBlank()) cacheValue.setProviderEmail(email);
|
||||||
cacheValue.setRoles(claimExtractor.roles(currentPrincipalResolver.currentPrincipal()));
|
UserCredentialEntity userCredential = this.queryFactory.query(UserCredentialQuery.class).externalIds(subjectId).firstAs(new BaseFieldSet().ensure(UserCredential._data));
|
||||||
|
if (userCredential != null && userCredential.getData() != null){
|
||||||
|
UserCredentialDataEntity userCredentialDataEntity = this.jsonHandlingService.fromJsonSafe(UserCredentialDataEntity.class, userCredential.getData());
|
||||||
|
if (userCredentialDataEntity != null) cacheValue.setExternalProviderNames(userCredentialDataEntity.getExternalProviderNames());
|
||||||
|
}
|
||||||
|
|
||||||
this.userInterceptorCacheService.put(cacheValue);
|
this.userInterceptorCacheService.put(cacheValue);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -132,11 +142,10 @@ public class UserInterceptor implements WebRequestInterceptor {
|
||||||
this.userScope.setUserId(userId);
|
this.userScope.setUserId(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void syncUserWithClaims(UUID userId){
|
private void syncUserWithClaims(UUID userId, String subjectId){
|
||||||
List<String> existingUserEmails = this.collectUserEmails(userId);
|
List<String> existingUserEmails = this.collectUserEmails(userId);
|
||||||
List<String> existingUserRoles = this.collectUserRoles(userId);
|
if (!this.containsPrincipalEmail(existingUserEmails)){
|
||||||
if (!this.emailExistsToUser(existingUserEmails)){
|
String email = this.getEmailFromClaims();
|
||||||
String email = this.claimExtractor.email(this.currentPrincipalResolver.currentPrincipal());
|
|
||||||
long contactUsedByOthersCount = this.queryFactory.query(UserContactInfoQuery.class).excludedUserIds(userId).types(ContactInfoType.Email).values(email).count();
|
long contactUsedByOthersCount = this.queryFactory.query(UserContactInfoQuery.class).excludedUserIds(userId).types(ContactInfoType.Email).values(email).count();
|
||||||
if (contactUsedByOthersCount > 0) {
|
if (contactUsedByOthersCount > 0) {
|
||||||
logger.warn("user contact exists to other user" + email);
|
logger.warn("user contact exists to other user" + email);
|
||||||
|
@ -148,9 +157,37 @@ public class UserInterceptor implements WebRequestInterceptor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<String> existingUserRoles = this.collectUserRoles(userId);
|
||||||
if (!this.userRolesSynced(existingUserRoles)){
|
if (!this.userRolesSynced(existingUserRoles)){
|
||||||
this.syncRoles(userId);
|
this.syncRoles(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UserCredentialEntity userCredential = this.queryFactory.query(UserCredentialQuery.class).externalIds(subjectId).first();
|
||||||
|
if (userCredential == null) {
|
||||||
|
throw new MyForbiddenException("UserCredential not found");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
boolean updatedUserCredential = false;
|
||||||
|
UserCredentialDataEntity userCredentialDataEntity = this.jsonHandlingService.fromJsonSafe(UserCredentialDataEntity.class, userCredential.getData());
|
||||||
|
if (userCredentialDataEntity == null) userCredentialDataEntity = new UserCredentialDataEntity();
|
||||||
|
if (userCredentialDataEntity.getExternalProviderNames() == null) userCredentialDataEntity.setExternalProviderNames(new ArrayList<>());
|
||||||
|
|
||||||
|
String email = this.getEmailFromClaims();
|
||||||
|
String provider = this.getProviderFromClaims();
|
||||||
|
|
||||||
|
if (email != null && !email.equalsIgnoreCase(userCredentialDataEntity.getEmail())) {
|
||||||
|
userCredentialDataEntity.setEmail(email);
|
||||||
|
updatedUserCredential = true;
|
||||||
|
}
|
||||||
|
if (provider != null && !provider.isBlank() && userCredentialDataEntity.getExternalProviderNames().stream().noneMatch(provider::equalsIgnoreCase)) {
|
||||||
|
userCredentialDataEntity.getExternalProviderNames().add(provider);
|
||||||
|
updatedUserCredential = true;
|
||||||
|
}
|
||||||
|
if (updatedUserCredential) {
|
||||||
|
userCredential.setData(this.jsonHandlingService.toJsonSafe(userCredentialDataEntity));
|
||||||
|
this.entityManager.persist(userCredential);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private UUID findExistingUserFromDb(String subjectId){
|
private UUID findExistingUserFromDb(String subjectId){
|
||||||
|
@ -158,7 +195,7 @@ public class UserInterceptor implements WebRequestInterceptor {
|
||||||
if (userCredential != null) {
|
if (userCredential != null) {
|
||||||
return userCredential.getUserId();
|
return userCredential.getUserId();
|
||||||
} else {
|
} else {
|
||||||
String email = this.claimExtractor.email(this.currentPrincipalResolver.currentPrincipal());
|
String email = this.getEmailFromClaims();
|
||||||
if (email != null && !email.isBlank()) {
|
if (email != null && !email.isBlank()) {
|
||||||
UserContactInfoEntity userContactInfo = this.queryFactory.query(UserContactInfoQuery.class).types(ContactInfoType.Email).values(email).firstAs(new BaseFieldSet().ensure(UserContactInfo._user));
|
UserContactInfoEntity userContactInfo = this.queryFactory.query(UserContactInfoQuery.class).types(ContactInfoType.Email).values(email).firstAs(new BaseFieldSet().ensure(UserContactInfo._user));
|
||||||
if (userContactInfo != null) {
|
if (userContactInfo != null) {
|
||||||
|
@ -174,14 +211,17 @@ public class UserInterceptor implements WebRequestInterceptor {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void syncRoles(UUID userId){
|
private List<String> getRolesFromClaims(){
|
||||||
List<String> claimsRoles = claimExtractor.roles(currentPrincipalResolver.currentPrincipal());
|
List<String> claimsRoles = claimExtractor.roles(currentPrincipalResolver.currentPrincipal());
|
||||||
if (claimsRoles == null) claimsRoles = new ArrayList<>();
|
if (claimsRoles == null) claimsRoles = new ArrayList<>();
|
||||||
claimsRoles = claimsRoles.stream().filter(x-> x != null && !x.isBlank()).distinct().toList();
|
claimsRoles = claimsRoles.stream().filter(x-> x != null && !x.isBlank()).distinct().toList();
|
||||||
|
return claimsRoles;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void syncRoles(UUID userId){
|
||||||
List<UserRoleEntity> existingUserRoles = this.queryFactory.query(UserRoleQuery.class).userIds(userId).collect();
|
List<UserRoleEntity> existingUserRoles = this.queryFactory.query(UserRoleQuery.class).userIds(userId).collect();
|
||||||
List<UUID> foundRoles = new ArrayList<>();
|
List<UUID> foundRoles = new ArrayList<>();
|
||||||
for (String claimRole : claimsRoles) {
|
for (String claimRole : this.getRolesFromClaims()) {
|
||||||
UserRoleEntity roleEntity = existingUserRoles.stream().filter(x-> x.getRole().equals(claimRole)).findFirst().orElse(null);
|
UserRoleEntity roleEntity = existingUserRoles.stream().filter(x-> x.getRole().equals(claimRole)).findFirst().orElse(null);
|
||||||
if (roleEntity == null) {
|
if (roleEntity == null) {
|
||||||
roleEntity = this.buildRole(userId, claimRole);
|
roleEntity = this.buildRole(userId, claimRole);
|
||||||
|
@ -206,17 +246,26 @@ public class UserInterceptor implements WebRequestInterceptor {
|
||||||
return items == null ? new ArrayList<>() : items.stream().map(UserContactInfoEntity::getValue).toList();
|
return items == null ? new ArrayList<>() : items.stream().map(UserContactInfoEntity::getValue).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean emailExistsToUser(List<String> existingUserEmails){
|
private boolean containsPrincipalEmail(List<String> existingUserEmails){
|
||||||
String email = this.claimExtractor.email(this.currentPrincipalResolver.currentPrincipal());
|
String email = this.getEmailFromClaims();
|
||||||
return email == null || email.isBlank() ||
|
return email == null || email.isBlank() ||
|
||||||
(existingUserEmails != null && existingUserEmails.stream().anyMatch(email::equals));
|
(existingUserEmails != null && existingUserEmails.stream().anyMatch(email::equals));
|
||||||
}
|
}
|
||||||
|
private boolean emailExistsToPrincipal(String existingUserEmail){
|
||||||
|
String email = this.getEmailFromClaims();
|
||||||
|
return email == null || email.isBlank() || email.equalsIgnoreCase(existingUserEmail);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean providerExistsToPrincipal(List<String> principalCredentialProviders){
|
||||||
|
String provider = this.getProviderFromClaims();
|
||||||
|
return provider == null || provider.isBlank() ||
|
||||||
|
(principalCredentialProviders != null && principalCredentialProviders.stream().anyMatch(provider::equalsIgnoreCase));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private boolean userRolesSynced(List<String> existingUserRoles){
|
private boolean userRolesSynced(List<String> existingUserRoles){
|
||||||
List<String> claimsRoles = claimExtractor.roles(currentPrincipalResolver.currentPrincipal());
|
List<String> claimsRoles = this.getRolesFromClaims();
|
||||||
if (claimsRoles == null) claimsRoles = new ArrayList<>();
|
|
||||||
if (existingUserRoles == null) existingUserRoles = new ArrayList<>();
|
if (existingUserRoles == null) existingUserRoles = new ArrayList<>();
|
||||||
claimsRoles = claimsRoles.stream().filter(x-> x != null && !x.isBlank()).distinct().toList();
|
|
||||||
existingUserRoles = existingUserRoles.stream().filter(x-> x != null && !x.isBlank()).distinct().toList();
|
existingUserRoles = existingUserRoles.stream().filter(x-> x != null && !x.isBlank()).distinct().toList();
|
||||||
if (claimsRoles.size() != existingUserRoles.size()) return false;
|
if (claimsRoles.size() != existingUserRoles.size()) return false;
|
||||||
|
|
||||||
|
@ -226,8 +275,28 @@ public class UserInterceptor implements WebRequestInterceptor {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getEmailFromClaims(){
|
||||||
|
String email = this.claimExtractor.email(this.currentPrincipalResolver.currentPrincipal());
|
||||||
|
if (email == null || email.isBlank() || !EmailValidator.getInstance().isValid(email)) return null;
|
||||||
|
return email.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getProviderFromClaims(){
|
||||||
|
String provider = this.claimExtractor.asString(this.currentPrincipalResolver.currentPrincipal(), ClaimNames.ExternalProviderName);
|
||||||
|
if (provider == null || provider.isBlank()) return null;
|
||||||
|
return provider.trim();
|
||||||
|
}
|
||||||
|
|
||||||
private UserCredentialEntity buildCredential(UUID userId, String subjectId){
|
private UserCredentialEntity buildCredential(UUID userId, String subjectId){
|
||||||
UserCredentialEntity data = new UserCredentialEntity();
|
UserCredentialEntity data = new UserCredentialEntity();
|
||||||
|
UserCredentialDataEntity userCredentialDataEntity = new UserCredentialDataEntity();
|
||||||
|
|
||||||
|
String email = this.getEmailFromClaims();
|
||||||
|
String provider = this.getProviderFromClaims();
|
||||||
|
if (email != null && !email.isBlank()) userCredentialDataEntity.setEmail(email);
|
||||||
|
if (provider != null && !provider.isBlank()) userCredentialDataEntity.setExternalProviderNames(List.of(provider));
|
||||||
|
data.setData(this.jsonHandlingService.toJsonSafe(userCredentialDataEntity));
|
||||||
|
|
||||||
data.setId(UUID.randomUUID());
|
data.setId(UUID.randomUUID());
|
||||||
data.setUserId(userId);
|
data.setUserId(userId);
|
||||||
data.setCreatedAt(Instant.now());
|
data.setCreatedAt(Instant.now());
|
||||||
|
@ -258,7 +327,7 @@ public class UserInterceptor implements WebRequestInterceptor {
|
||||||
|
|
||||||
|
|
||||||
private UserEntity addNewUser(String subjectId, String email){
|
private UserEntity addNewUser(String subjectId, String email){
|
||||||
List<String> roles = claimExtractor.roles(currentPrincipalResolver.currentPrincipal());
|
List<String> roles = this.getRolesFromClaims();
|
||||||
String name = this.claimExtractor.name(this.currentPrincipalResolver.currentPrincipal());
|
String name = this.claimExtractor.name(this.currentPrincipalResolver.currentPrincipal());
|
||||||
|
|
||||||
UserEntity user = new UserEntity();
|
UserEntity user = new UserEntity();
|
||||||
|
@ -267,7 +336,7 @@ public class UserInterceptor implements WebRequestInterceptor {
|
||||||
user.setCreatedAt(Instant.now());
|
user.setCreatedAt(Instant.now());
|
||||||
user.setUpdatedAt(Instant.now());
|
user.setUpdatedAt(Instant.now());
|
||||||
user.setIsActive(IsActive.Active);
|
user.setIsActive(IsActive.Active);
|
||||||
user.setAdditionalInfo(this.jsonHandlingService.toJsonSafe(new AdditionalInfoEntity()));
|
user.setAdditionalInfo(this.jsonHandlingService.toJsonSafe(new AdditionalInfoEntity())); //TODO
|
||||||
this.entityManager.persist(user);
|
this.entityManager.persist(user);
|
||||||
|
|
||||||
UserCredentialEntity credential = this.buildCredential(user.getId(), subjectId);
|
UserCredentialEntity credential = this.buildCredential(user.getId(), subjectId);
|
||||||
|
|
|
@ -35,7 +35,8 @@ public class UserInterceptorCacheService extends CacheService<UserInterceptorCac
|
||||||
private String subjectId;
|
private String subjectId;
|
||||||
private UUID userId;
|
private UUID userId;
|
||||||
private List<String> roles;
|
private List<String> roles;
|
||||||
private List<String> emails;
|
private String providerEmail;
|
||||||
|
private List<String> externalProviderNames;
|
||||||
|
|
||||||
public UUID getUserId() {
|
public UUID getUserId() {
|
||||||
return userId;
|
return userId;
|
||||||
|
@ -53,12 +54,20 @@ public class UserInterceptorCacheService extends CacheService<UserInterceptorCac
|
||||||
this.roles = roles;
|
this.roles = roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getEmails() {
|
public String getProviderEmail() {
|
||||||
return emails;
|
return providerEmail;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEmails(List<String> emails) {
|
public void setProviderEmail(String providerEmail) {
|
||||||
this.emails = emails;
|
this.providerEmail = providerEmail;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getExternalProviderNames() {
|
||||||
|
return externalProviderNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExternalProviderNames(List<String> externalProviderNames) {
|
||||||
|
this.externalProviderNames = externalProviderNames;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,3 +37,5 @@ idpclient:
|
||||||
- type: azp
|
- type: azp
|
||||||
Authorities:
|
Authorities:
|
||||||
- type: authorities
|
- type: authorities
|
||||||
|
ExternalProviderName:
|
||||||
|
- type: identity_provider
|
|
@ -8,6 +8,7 @@ BEGIN
|
||||||
(
|
(
|
||||||
id uuid NOT NULL,
|
id uuid NOT NULL,
|
||||||
"user" uuid NOT NULL,
|
"user" uuid NOT NULL,
|
||||||
|
"data" character varying NULL,
|
||||||
external_id character varying(512) NOT NULL,
|
external_id character varying(512) NOT NULL,
|
||||||
created_at timestamp without time zone NOT NULL,
|
created_at timestamp without time zone NOT NULL,
|
||||||
PRIMARY KEY (id),
|
PRIMARY KEY (id),
|
||||||
|
|
Loading…
Reference in New Issue