package eu.eudat.logic.services.operations.authentication; import com.fasterxml.jackson.core.JsonProcessingException; import eu.eudat.data.entities.Credential; import eu.eudat.data.entities.UserInfo; import eu.eudat.data.entities.UserRole; import eu.eudat.data.entities.UserToken; import eu.eudat.exceptions.security.NullEmailException; import eu.eudat.logic.builders.entity.CredentialBuilder; import eu.eudat.logic.builders.entity.UserInfoBuilder; import eu.eudat.logic.builders.entity.UserTokenBuilder; import eu.eudat.logic.security.validators.TokenValidatorFactoryImpl; import eu.eudat.logic.services.ApiContext; import eu.eudat.models.data.login.Credentials; import eu.eudat.models.data.loginprovider.LoginProviderUser; import eu.eudat.models.data.security.Principal; import eu.eudat.types.Authorities; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.env.Environment; import org.springframework.transaction.annotation.Transactional; import java.sql.Timestamp; import java.time.Instant; import java.time.LocalDateTime; import java.util.*; public abstract class AbstractAuthenticationService implements AuthenticationService { private static final Logger logger = LoggerFactory.getLogger(AbstractAuthenticationService.class); protected ApiContext apiContext; protected Environment environment; public AbstractAuthenticationService(ApiContext apiContext, Environment environment) { this.apiContext = apiContext; this.environment = environment; } protected Date addADay(Date date) { Date dt = new Date(); Calendar c = Calendar.getInstance(); c.setTime(dt); c.add(Calendar.DATE, 1); dt = c.getTime(); return dt; } abstract Principal Touch(UserToken token); @Transactional protected Credential autoCreateUser(String username, String password) { if (!environment.getProperty("autouser.root.username").equals(username) || !environment.getProperty("autouser.root.password").equals(password)) return null; UserInfo userInfo = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserInfoBuilder.class) .name(username).email(environment.getProperty("autouser.root.email")).created(new Date()) .lastloggedin(new Date()).authorization_level((short) 1).usertype((short) 1).userStatus((short)0) .build(); userInfo = this.apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().createOrUpdate(userInfo); UserRole role = new UserRole(); role.setRole(Authorities.ADMIN.getValue()); role.setUserInfo(userInfo); this.apiContext.getOperationsContext().getDatabaseRepository().getUserRoleDao().createOrUpdate(role); Credential credential = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(CredentialBuilder.class) .id(UUID.randomUUID()).userInfo(userInfo).publicValue(username).secret(password) .provider((int) TokenValidatorFactoryImpl.LoginProvider.NATIVELOGIN.getValue()) .creationTime(new Date()).lastUpdateTime(new Date()).status(0) .build(); return this.apiContext.getOperationsContext().getDatabaseRepository().getCredentialDao().createOrUpdate(credential); } public Principal Touch(UUID token) { UserToken tokenEntry = this.apiContext.getOperationsContext().getDatabaseRepository().getUserTokenDao().find(token); if (tokenEntry == null || tokenEntry.getExpiresAt().before(new Date())) return null; return this.Touch(tokenEntry); } public void Logout(UUID token) { UserToken tokenEntry = this.apiContext.getOperationsContext().getDatabaseRepository().getUserTokenDao().find(token); this.apiContext.getOperationsContext().getDatabaseRepository().getUserTokenDao().delete(tokenEntry); } public Principal Touch(Credentials credentials) throws NullEmailException { Credential credential = this.apiContext.getOperationsContext().getDatabaseRepository().getCredentialDao().getLoggedInCredentials(credentials.getUsername(), credentials.getSecret(), TokenValidatorFactoryImpl.LoginProvider.NATIVELOGIN.getValue()); if (credential == null && credentials.getUsername().equals(environment.getProperty("autouser.root.username"))) { try { credential = this.autoCreateUser(credentials.getUsername(), credentials.getSecret()); } catch (Exception e) { logger.error(e.getMessage(), e); return null; } } if (credential == null) return null; UserToken userToken = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserTokenBuilder.class) .issuedAt(new Date()).user(credential.getUserInfo()) .token(UUID.randomUUID()).expiresAt(Timestamp.valueOf(LocalDateTime.now().plusDays(10))) .build(); userToken = apiContext.getOperationsContext().getDatabaseRepository().getUserTokenDao().createOrUpdate(userToken); return this.Touch(userToken); } public Principal Touch(LoginProviderUser profile) throws NullEmailException { UserInfo userInfo;// = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().asQueryable().withHint("userInfo").where((builder, root) -> builder.and(builder.equal(root.get("email"), profile.getEmail()), builder.equal(root.get("userStatus"), 0))).getSingleOrDefault(); //if (userInfo == null) { Optional optionalCredential = Optional.ofNullable(apiContext.getOperationsContext().getDatabaseRepository().getCredentialDao() .asQueryable().withHint("credentialUserInfo") .where((builder, root) -> builder.and(builder.equal(root.get("provider"), profile.getProvider().getValue()), builder.equal(root.get("externalId"), profile.getId()))) .getSingleOrDefault()); userInfo = optionalCredential.map(Credential::getUserInfo).orElse(null); if (userInfo != null) { if (userInfo.getUserStatus() == 1) { userInfo = null; } } //} if (userInfo == null) { userInfo = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().asQueryable().withHint("userInfo").where((builder, root) -> builder.and(builder.equal(root.get("email"), profile.getEmail()), builder.equal(root.get("userStatus"), 0))).getSingleOrDefault(); } final Credential credential = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(CredentialBuilder.class) .id(UUID.randomUUID()) .creationTime(new Date()) .status(1) .lastUpdateTime(new Date()) .provider(profile.getProvider().getValue()) .secret(profile.getSecret()) .externalId(profile.getId()) .email(profile.getEmail()) .build(); if (userInfo == null) { userInfo = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserInfoBuilder.class) .name(profile.getName()).verified_email(profile.getIsVerified()) .email(profile.getEmail()).created(new Date()).lastloggedin(new Date()) .additionalinfo("{\"data\":{\"avatar\":{\"url\":\"" + profile.getAvatarUrl() + "\"},\"zenodoToken\":\"" + profile.getZenodoId() + "\", \"expirationDate\": \"" + Instant.now().plusSeconds((profile.getZenodoExpire() != null ? profile.getZenodoExpire(): 0)).toEpochMilli() + "\", \"zenodoRefresh\": \"" + profile.getZenodoRefresh() + (profile.getProvider() == TokenValidatorFactoryImpl.LoginProvider.ZENODO ? "\", \"zenodoEmail\": \"" + profile.getEmail() : "") +"\"}}") .authorization_level((short) 1).usertype((short) 1).userStatus((short)0) .build(); userInfo = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().createOrUpdate(userInfo); credential.setPublicValue(userInfo.getName()); credential.setEmail(userInfo.getEmail()); credential.setUserInfo(userInfo); apiContext.getOperationsContext().getDatabaseRepository().getCredentialDao().createOrUpdate(credential); UserRole role = new UserRole(); role.setRole(Authorities.USER.getValue()); role.setUserInfo(userInfo); apiContext.getOperationsContext().getDatabaseRepository().getUserRoleDao().createOrUpdate(role); } else { Map additionalInfo = null; try { additionalInfo = userInfo.getAdditionalinfo() != null ? apiContext.getObjectMapper().readValue(userInfo.getAdditionalinfo(), HashMap.class) : new HashMap<>(); if (profile.getAvatarUrl() != null && !profile.getAvatarUrl().isEmpty() && !profile.getAvatarUrl().equals("null")) { additionalInfo.put("avatarUrl", profile.getAvatarUrl()); } if (profile.getZenodoId() != null && !profile.getZenodoId().isEmpty() && !profile.getZenodoId().equals("null")) { additionalInfo.put("zenodoToken", profile.getZenodoId()); } if (profile.getZenodoExpire() != null) { additionalInfo.put("expirationDate", Instant.now().plusSeconds(profile.getZenodoExpire()).toEpochMilli()); } if (profile.getZenodoRefresh() != null) { additionalInfo.put("zenodoRefresh", profile.getZenodoRefresh()); } if (profile.getProvider() == TokenValidatorFactoryImpl.LoginProvider.ZENODO) { additionalInfo.put("zenodoEmail", profile.getEmail()); } userInfo.setLastloggedin(new Date()); userInfo.setAdditionalinfo(apiContext.getObjectMapper().writeValueAsString(additionalInfo)); } catch (JsonProcessingException e) { logger.error(e.getLocalizedMessage(), e); } Set credentials = userInfo.getCredentials(); if (credentials.contains(credential)) { Credential oldCredential = credentials.stream().filter(item -> credential.getProvider().equals(item.getProvider())).findFirst().get(); credential.setId(oldCredential.getId()); } else { credential.setUserInfo(userInfo); credential.setId(UUID.randomUUID()); credential.setPublicValue(userInfo.getName()); credential.setEmail(userInfo.getEmail()); apiContext.getOperationsContext().getDatabaseRepository().getCredentialDao().createOrUpdate(credential); userInfo.getCredentials().add(credential); } userInfo = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().createOrUpdate(userInfo); } UserToken userToken = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserTokenBuilder.class) .token(UUID.randomUUID()).user(userInfo) .expiresAt(Timestamp.valueOf(LocalDateTime.now().plusDays(10))).issuedAt(new Date()) .build(); apiContext.getOperationsContext().getDatabaseRepository().getUserTokenDao().createOrUpdate(userToken); return Touch(userToken.getToken()); } }