package eu.eudat.services.operations; import eu.eudat.builders.entity.CredentialBuilder; import eu.eudat.builders.entity.UserInfoBuilder; import eu.eudat.builders.entity.UserTokenBuilder; import eu.eudat.builders.model.models.PrincipalBuilder; import eu.eudat.entities.Credential; import eu.eudat.entities.UserInfo; import eu.eudat.entities.UserRole; import eu.eudat.entities.UserToken; import eu.eudat.models.criteria.UserInfoCriteria; import eu.eudat.models.login.Credentials; import eu.eudat.models.loginprovider.LoginProviderUser; import eu.eudat.models.security.Principal; import eu.eudat.security.validators.TokenValidatorFactoryImpl; import eu.eudat.services.ApiContext; import eu.eudat.types.Authorities; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.*; @Service("authenticationService") public class AuthenticationServiceImpl implements AuthenticationService { private ApiContext apiContext; private Environment environment; @Autowired public AuthenticationServiceImpl(ApiContext apiContext, Environment environment) { this.environment = environment; this.apiContext = apiContext; } 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); } private Principal Touch(UserToken token) { if (token == null || token.getExpiresAt().before(new Date())) return null; UserInfo user = this.apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(token.getUser().getId()); if (user == null) return null; Principal principal = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(PrincipalBuilder.class) .id(user.getId()).token(token.getToken()) .expiresAt(token.getExpiresAt()).name(user.getName()) .build(); List userRoles = apiContext.getOperationsContext().getDatabaseRepository().getUserRoleDao().getUserRoles(user); for (UserRole item : userRoles) { if (principal.getAuthz() == null) principal.setAuthorities(new HashSet<>()); principal.getAuthz().add(Authorities.fromInteger(item.getRole())); } return principal; } public Principal Touch(Credentials credentials) { Credential credential = this.apiContext.getOperationsContext().getDatabaseRepository().getCredentialDao().getLoggedInCredentials(credentials); if (credential == null && credentials.getUsername().equals(environment.getProperty("autouser.root.username"))) { try { credential = this.autoCreateUser(credentials.getUsername(), credentials.getSecret()); } catch (Exception e) { e.printStackTrace(); 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(addADay(new Date())) .build(); userToken = apiContext.getOperationsContext().getDatabaseRepository().getUserTokenDao().createOrUpdate(userToken); return this.Touch(userToken); } public Principal Touch(LoginProviderUser profile) { UserInfoCriteria criteria = new UserInfoCriteria(); criteria.setEmail(profile.getEmail()); UserInfo userInfo = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().asQueryable().withHint("userInfo").where((builder, root) -> builder.equal(root.get("email"), profile.getEmail())).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); } final Credential credential = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(CredentialBuilder.class) .id(UUID.randomUUID()).creationTime(new Date()).status(1) .lastUpdateTime(new Date()).provider((int) profile.getProvider().getValue()) .secret(profile.getSecret()).externalId(profile.getId()) .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()) .authorization_level((short) 1).usertype((short) 1) .build(); userInfo = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().createOrUpdate(userInfo); credential.setPublicValue(userInfo.getName()); 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 { userInfo.setLastloggedin(new Date()); 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()); 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(addADay(new Date())).issuedAt(new Date()) .build(); apiContext.getOperationsContext().getDatabaseRepository().getUserTokenDao().createOrUpdate(userToken); return Touch(userToken.getToken()); } private 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; } @Transactional private 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) .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) .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); } }