package gr.cite.annotation.web.interceptors; import gr.cite.commons.web.oidc.principal.CurrentPrincipalResolver; import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractor; import gr.cite.annotation.common.JsonHandlingService; import gr.cite.annotation.common.lock.LockByKeyManager; import gr.cite.annotation.common.scope.user.UserScope; import gr.cite.annotation.data.UserCredentialEntity; import gr.cite.annotation.model.UserCredential; import gr.cite.annotation.query.UserCredentialQuery; import gr.cite.tools.data.query.QueryFactory; import gr.cite.tools.exception.MyForbiddenException; import gr.cite.tools.fieldset.BaseFieldSet; import gr.cite.tools.logging.LoggerService; import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.lang.NonNull; import org.springframework.stereotype.Component; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.ui.ModelMap; import org.springframework.web.context.request.WebRequest; import org.springframework.web.context.request.WebRequestInterceptor; import java.util.UUID; @Component public class UserInterceptor implements WebRequestInterceptor { private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(UserInterceptor.class)); private final UserScope userScope; private final ClaimExtractor claimExtractor; private final CurrentPrincipalResolver currentPrincipalResolver; private final UserInterceptorCacheService userInterceptorCacheService; private final QueryFactory queryFactory; @PersistenceContext public EntityManager entityManager; @Autowired public UserInterceptor( UserScope userScope, ClaimExtractor claimExtractor, CurrentPrincipalResolver currentPrincipalResolver, UserInterceptorCacheService userInterceptorCacheService, QueryFactory queryFactory) { this.userScope = userScope; this.currentPrincipalResolver = currentPrincipalResolver; this.claimExtractor = claimExtractor; this.userInterceptorCacheService = userInterceptorCacheService; this.queryFactory = queryFactory; } @Override public void preHandle(WebRequest request) { UUID userId = null; if (this.currentPrincipalResolver.currentPrincipal().isAuthenticated()) { String subjectId = this.claimExtractor.subjectString(this.currentPrincipalResolver.currentPrincipal()); if (subjectId == null || subjectId.isBlank()) throw new MyForbiddenException("Empty subjects not allowed"); UserInterceptorCacheService.UserInterceptorCacheValue cacheValue = this.userInterceptorCacheService.lookup(this.userInterceptorCacheService.buildKey(subjectId)); if (cacheValue != null) { userId = cacheValue.getUserId(); } else { userId = this.findExistingUserFromDbForce(subjectId); cacheValue = new UserInterceptorCacheService.UserInterceptorCacheValue(subjectId, userId); this.userInterceptorCacheService.put(cacheValue); } } this.userScope.setUserId(userId); } private UUID findExistingUserFromDbForce(String subjectId){ UserCredentialEntity userCredential = this.queryFactory.query(UserCredentialQuery.class).externalIds(subjectId).firstAs(new BaseFieldSet().ensure(UserCredential._user)); if (userCredential != null) { return userCredential.getUserId(); } else { throw new MyForbiddenException("User not created try again."); } } @Override public void postHandle(@NonNull WebRequest request, ModelMap model) { this.userScope.setUserId(null); } @Override public void afterCompletion(@NonNull WebRequest request, Exception ex) { } }