authn refactor
This commit is contained in:
parent
8b05ee1d0f
commit
968f45d5b3
|
@ -0,0 +1,35 @@
|
||||||
|
package eu.eudat.commons.scope;
|
||||||
|
|
||||||
|
import gr.cite.tools.logging.LoggerService;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.context.annotation.RequestScope;
|
||||||
|
|
||||||
|
import javax.management.InvalidApplicationException;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@RequestScope
|
||||||
|
public class UserScope {
|
||||||
|
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(UserScope.class));
|
||||||
|
private final AtomicReference<UUID> userId = new AtomicReference<>();
|
||||||
|
|
||||||
|
public Boolean isSet() {
|
||||||
|
return this.userId.get() != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getUserId() throws InvalidApplicationException {
|
||||||
|
if (this.userId.get() == null) throw new InvalidApplicationException("user not set");
|
||||||
|
return this.userId.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getUserIdSafe() {
|
||||||
|
return this.userId.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserId(UUID userId) {
|
||||||
|
this.userId.set(userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -22,6 +22,10 @@
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||||
|
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>dmp-backend</groupId>
|
<groupId>dmp-backend</groupId>
|
||||||
<artifactId>queryable</artifactId>
|
<artifactId>queryable</artifactId>
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
package eu.eudat.data.dao.entities.security;
|
|
||||||
|
|
||||||
import eu.eudat.data.dao.DatabaseAccessLayer;
|
|
||||||
import eu.eudat.data.entities.UserToken;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
|
|
||||||
public interface UserTokenDao extends DatabaseAccessLayer<UserToken, UUID> {
|
|
||||||
|
|
||||||
UserToken createOrUpdate(UserToken item);
|
|
||||||
|
|
||||||
UserToken find(UUID id);
|
|
||||||
|
|
||||||
void delete(UserToken token);
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
package eu.eudat.data.dao.entities.security;
|
|
||||||
|
|
||||||
import eu.eudat.data.dao.DatabaseAccess;
|
|
||||||
import eu.eudat.data.dao.databaselayer.service.DatabaseService;
|
|
||||||
import eu.eudat.data.entities.UserToken;
|
|
||||||
import eu.eudat.queryable.QueryableList;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
|
|
||||||
|
|
||||||
@Component("userTokenDao")
|
|
||||||
public class UserTokenDaoImpl extends DatabaseAccess<UserToken> implements UserTokenDao {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public UserTokenDaoImpl(DatabaseService<UserToken> databaseService) {
|
|
||||||
super(databaseService);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserToken createOrUpdate(UserToken item) {
|
|
||||||
return this.getDatabaseService().createOrUpdate(item, UserToken.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserToken find(UUID id) {
|
|
||||||
return this.getDatabaseService().getQueryable(UserToken.class).where((builder, root) -> builder.equal(root.get("token"), id)).getSingleOrDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void delete(UserToken userToken) {
|
|
||||||
this.getDatabaseService().delete(userToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public QueryableList<UserToken> asQueryable() {
|
|
||||||
return this.getDatabaseService().getQueryable(UserToken.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompletableFuture<UserToken> createOrUpdateAsync(UserToken item) {
|
|
||||||
return CompletableFuture.supplyAsync(() -> this.createOrUpdate(item));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserToken find(UUID id, String hint) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -22,33 +22,46 @@ public class Credential implements DataEntity<Credential, UUID> {
|
||||||
@Id
|
@Id
|
||||||
@Column(name = "\"Id\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)")
|
@Column(name = "\"Id\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)")
|
||||||
private UUID id;
|
private UUID id;
|
||||||
|
public final static String _id = "id";
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "\"UserId\"", nullable = false)
|
@JoinColumn(name = "\"UserId\"", nullable = false)
|
||||||
private UserInfo userInfo;
|
private UserInfo userInfo;
|
||||||
|
public final static String _userInfo = "userInfo"; //TODO: Authn
|
||||||
|
|
||||||
@Column(name = "\"Status\"", nullable = false)
|
@Column(name = "\"Status\"", nullable = false)
|
||||||
private Integer status;
|
private Integer status;
|
||||||
|
public final static String _status = "status";
|
||||||
|
|
||||||
@Column(name = "\"Provider\"", nullable = false)
|
@Column(name = "\"Provider\"", nullable = false)
|
||||||
private Integer provider;
|
private Integer provider;
|
||||||
|
public final static String _provider = "provider";
|
||||||
|
|
||||||
@Column(name = "\"Public\"", nullable = false)
|
@Column(name = "\"Public\"", nullable = false)
|
||||||
private String publicValue;
|
private String publicValue;
|
||||||
|
public final static String _publicValue = "public";
|
||||||
|
|
||||||
@Column(name = "\"Email\"")
|
@Column(name = "\"Email\"")
|
||||||
private String email;
|
private String email;
|
||||||
|
public final static String _email = "email";
|
||||||
|
|
||||||
@Column(name = "\"Secret\"", nullable = false)
|
@Column(name = "\"Secret\"", nullable = false)
|
||||||
private String secret;
|
private String secret;
|
||||||
|
public final static String _secret = "secret";
|
||||||
|
|
||||||
@Column(name = "\"CreationTime\"", nullable = false)
|
@Column(name = "\"CreationTime\"", nullable = false)
|
||||||
@Convert(converter = DateToUTCConverter.class)
|
@Convert(converter = DateToUTCConverter.class)
|
||||||
private Date creationTime;
|
private Date creationTime;
|
||||||
|
public final static String _creationTime = "creationTime";
|
||||||
|
|
||||||
@Column(name = "\"LastUpdateTime\"", nullable = false)
|
@Column(name = "\"LastUpdateTime\"", nullable = false)
|
||||||
@Convert(converter = DateToUTCConverter.class)
|
@Convert(converter = DateToUTCConverter.class)
|
||||||
private Date lastUpdateTime;
|
private Date lastUpdateTime;
|
||||||
|
public final static String _lastUpdateTime = "lastUpdateTime";
|
||||||
|
|
||||||
@Column(name = "\"ExternalId\"", nullable = false)
|
@Column(name = "\"ExternalId\"", nullable = false)
|
||||||
private String externalId;
|
private String externalId;
|
||||||
|
public final static String _externalId = "externalId";
|
||||||
|
|
||||||
public UUID getId() {
|
public UUID getId() {
|
||||||
return id;
|
return id;
|
||||||
|
|
|
@ -24,40 +24,50 @@ public class UserInfo implements DataEntity<UserInfo, UUID> {
|
||||||
@GenericGenerator(name = "uuid2", strategy = "uuid2")
|
@GenericGenerator(name = "uuid2", strategy = "uuid2")
|
||||||
@Column(name = "id", updatable = false, nullable = false, columnDefinition = "BINARY(16)")
|
@Column(name = "id", updatable = false, nullable = false, columnDefinition = "BINARY(16)")
|
||||||
private UUID id;
|
private UUID id;
|
||||||
|
public final static String _id = "id";
|
||||||
|
|
||||||
|
|
||||||
@Column(name = "email")
|
@Column(name = "email")
|
||||||
private String email = null;
|
private String email = null;
|
||||||
|
public final static String _email = "email";
|
||||||
|
|
||||||
@Column(name = "authorization_level", nullable = false)
|
@Column(name = "authorization_level", nullable = false)
|
||||||
private Short authorization_level; //0 admin, 1 user
|
private Short authorization_level; //0 admin, 1 user
|
||||||
|
public final static String _authorization_level = "authorization_level";
|
||||||
|
|
||||||
@Column(name = "usertype", nullable = false)
|
@Column(name = "usertype", nullable = false)
|
||||||
private Short usertype; // 0 internal, 1 external
|
private Short usertype; // 0 internal, 1 external
|
||||||
|
public final static String _usertype = "usertype";
|
||||||
|
|
||||||
@Column(name = "userstatus", nullable = false)
|
@Column(name = "userstatus", nullable = false)
|
||||||
private Short userStatus; // 0 active, 1 inactive
|
private Short userStatus; // 0 active, 1 inactive
|
||||||
|
public final static String _userStatus = "userStatus";
|
||||||
|
|
||||||
@Column(name = "verified_email", nullable = true)
|
@Column(name = "verified_email", nullable = true)
|
||||||
private Boolean verified_email = null;
|
private Boolean verified_email = null;
|
||||||
|
public final static String _verified_email = "verified_email";
|
||||||
|
|
||||||
@Column(name = "name", nullable = true)
|
@Column(name = "name", nullable = true)
|
||||||
private String name = null;
|
private String name = null;
|
||||||
|
public final static String _name = "name";
|
||||||
|
|
||||||
|
|
||||||
@Column(name = "created", nullable = false)
|
@Column(name = "created", nullable = false)
|
||||||
@Convert(converter = DateToUTCConverter.class)
|
@Convert(converter = DateToUTCConverter.class)
|
||||||
private Date created = null;
|
private Date created = null;
|
||||||
|
public final static String _created = "created";
|
||||||
|
|
||||||
|
|
||||||
@Column(name = "lastloggedin", nullable = true)
|
@Column(name = "lastloggedin", nullable = true)
|
||||||
@Convert(converter = DateToUTCConverter.class)
|
@Convert(converter = DateToUTCConverter.class)
|
||||||
private Date lastloggedin = null;
|
private Date lastloggedin = null;
|
||||||
|
public final static String _lastloggedin = "lastloggedin";
|
||||||
|
|
||||||
|
|
||||||
@Type(eu.eudat.configurations.typedefinition.XMLType.class)
|
@Type(eu.eudat.configurations.typedefinition.XMLType.class)
|
||||||
@Column(name = "additionalinfo", nullable = true)
|
@Column(name = "additionalinfo", nullable = true)
|
||||||
private String additionalinfo;
|
private String additionalinfo;
|
||||||
|
public final static String _additionalinfo = "additionalinfo";
|
||||||
|
|
||||||
@OneToMany(fetch = FetchType.LAZY)
|
@OneToMany(fetch = FetchType.LAZY)
|
||||||
@JoinTable(name = "\"UserDMP\"",
|
@JoinTable(name = "\"UserDMP\"",
|
||||||
|
|
|
@ -1,82 +0,0 @@
|
||||||
package eu.eudat.data.entities;
|
|
||||||
|
|
||||||
import eu.eudat.data.converters.DateToUTCConverter;
|
|
||||||
import eu.eudat.data.entities.helpers.EntityBinder;
|
|
||||||
import eu.eudat.queryable.queryableentity.DataEntity;
|
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
@Table(name = "\"UserToken\"")
|
|
||||||
public class UserToken implements DataEntity<UserToken, UUID> {
|
|
||||||
|
|
||||||
@Id
|
|
||||||
@Column(name = "\"Token\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)")
|
|
||||||
private UUID token;
|
|
||||||
|
|
||||||
@OneToOne(fetch = FetchType.EAGER)
|
|
||||||
@JoinColumn(name = "\"UserId\"", nullable = false)
|
|
||||||
private UserInfo user;
|
|
||||||
|
|
||||||
@Column(name = "\"IssuedAt\"", nullable = false)
|
|
||||||
@Convert(converter = DateToUTCConverter.class)
|
|
||||||
private Date issuedAt = null;
|
|
||||||
|
|
||||||
|
|
||||||
@Column(name = "\"ExpiresAt\"", nullable = false)
|
|
||||||
@Convert(converter = DateToUTCConverter.class)
|
|
||||||
private Date expiresAt = null;
|
|
||||||
|
|
||||||
public UUID getToken() {
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setToken(UUID token) {
|
|
||||||
this.token = token;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserInfo getUser() {
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUser(UserInfo user) {
|
|
||||||
this.user = user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getIssuedAt() {
|
|
||||||
return issuedAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIssuedAt(Date issuedAt) {
|
|
||||||
this.issuedAt = issuedAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getExpiresAt() {
|
|
||||||
return expiresAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setExpiresAt(Date expiresAt) {
|
|
||||||
this.expiresAt = expiresAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void update(UserToken entity) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UUID getKeys() {
|
|
||||||
return this.token;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserToken buildFromTuple(List<Tuple> tuple, List<String> fields, String base) {
|
|
||||||
String currentBase = base.isEmpty() ? "" : base + ".";
|
|
||||||
if (fields.contains(currentBase + "token")) this.token = EntityBinder.fromTuple(tuple, currentBase + "token");
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -137,6 +137,11 @@
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
<artifactId>jackson-databind</artifactId>
|
<artifactId>jackson-databind</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||||
|
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||||
|
<version>2.13.3</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.fasterxml.jackson.module</groupId>
|
<groupId>com.fasterxml.jackson.module</groupId>
|
||||||
|
@ -304,6 +309,11 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!--CITE DEPENDENCIES-->
|
<!--CITE DEPENDENCIES-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>gr.cite</groupId>
|
||||||
|
<artifactId>oidc-authn</artifactId>
|
||||||
|
<version>2.1.0</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>gr.cite</groupId>
|
<groupId>gr.cite</groupId>
|
||||||
<artifactId>data-tools</artifactId>
|
<artifactId>data-tools</artifactId>
|
||||||
|
|
|
@ -63,6 +63,10 @@
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
<artifactId>jackson-annotations</artifactId>
|
<artifactId>jackson-annotations</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||||
|
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
|
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
|
||||||
<!--<dependency>
|
<!--<dependency>
|
||||||
|
@ -117,26 +121,6 @@
|
||||||
<version>3.0.0</version>
|
<version>3.0.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- facebook Login -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.social</groupId>
|
|
||||||
<artifactId>spring-social-facebook</artifactId>
|
|
||||||
<version>2.0.3.RELEASE</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- linkedin Login -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.social</groupId>
|
|
||||||
<artifactId>spring-social-linkedin</artifactId>
|
|
||||||
<version>1.0.2.RELEASE</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- tweeter login-->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.social</groupId>
|
|
||||||
<artifactId>spring-social-twitter</artifactId>
|
|
||||||
<version>1.1.2.RELEASE</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||||
|
|
|
@ -1,17 +1,36 @@
|
||||||
package eu.eudat;
|
package eu.eudat;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.json.JsonMapper;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
import eu.eudat.data.BaseEntity;
|
import eu.eudat.data.BaseEntity;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
||||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Primary;
|
||||||
import org.springframework.scheduling.annotation.EnableAsync;
|
import org.springframework.scheduling.annotation.EnableAsync;
|
||||||
|
|
||||||
@SpringBootApplication(scanBasePackages = {"eu.eudat", "eu.eudat.depositinterface", "gr.cite"})
|
@SpringBootApplication(scanBasePackages = {
|
||||||
|
"eu.eudat",
|
||||||
|
"eu.eudat.depositinterface",
|
||||||
|
"gr.cite",
|
||||||
|
"gr.cite.tools",
|
||||||
|
"gr.cite.commons"
|
||||||
|
})
|
||||||
@EnableAsync
|
@EnableAsync
|
||||||
public class EuDatApplication extends SpringBootServletInitializer {
|
public class EuDatApplication extends SpringBootServletInitializer {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@Primary
|
||||||
|
public ObjectMapper primaryObjectMapper() {
|
||||||
|
return JsonMapper.builder().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||||
|
.addModule(new JavaTimeModule()).build();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
|
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
|
||||||
return builder.sources(EuDatApplication.class);
|
return builder.sources(EuDatApplication.class);
|
||||||
|
|
|
@ -27,7 +27,7 @@ public class ResponsesCache {
|
||||||
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public CacheManager cacheManager() {
|
public CacheManager cacheManager5() {
|
||||||
logger.info("Loading ResponsesCache...");
|
logger.info("Loading ResponsesCache...");
|
||||||
SimpleCacheManager simpleCacheManager = new SimpleCacheManager();
|
SimpleCacheManager simpleCacheManager = new SimpleCacheManager();
|
||||||
List<CaffeineCache> caches = new ArrayList<CaffeineCache>();
|
List<CaffeineCache> caches = new ArrayList<CaffeineCache>();
|
||||||
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
package eu.eudat.configurations;
|
||||||
|
|
||||||
|
|
||||||
|
import gr.cite.commons.web.oidc.configuration.WebSecurityProperties;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.authentication.AuthenticationManagerResolver;
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||||
|
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
|
||||||
|
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||||
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
|
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;
|
||||||
|
|
||||||
|
import jakarta.servlet.Filter;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableWebSecurity
|
||||||
|
public class SecurityConfiguration {
|
||||||
|
|
||||||
|
private final WebSecurityProperties webSecurityProperties;
|
||||||
|
private final AuthenticationManagerResolver<HttpServletRequest> authenticationManagerResolver;
|
||||||
|
private final Filter apiKeyFilter;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public SecurityConfiguration(WebSecurityProperties webSecurityProperties,
|
||||||
|
@Qualifier("tokenAuthenticationResolver") AuthenticationManagerResolver<HttpServletRequest> authenticationManagerResolver,
|
||||||
|
@Qualifier("apiKeyFilter") Filter apiKeyFilter) {
|
||||||
|
this.webSecurityProperties = webSecurityProperties;
|
||||||
|
this.authenticationManagerResolver = authenticationManagerResolver;
|
||||||
|
this.apiKeyFilter = apiKeyFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||||
|
HttpSecurity tempHttp = http
|
||||||
|
.csrf(AbstractHttpConfigurer::disable)
|
||||||
|
.cors(httpSecurityCorsConfigurer -> {})
|
||||||
|
.headers(httpSecurityHeadersConfigurer -> httpSecurityHeadersConfigurer.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable))
|
||||||
|
.addFilterBefore(apiKeyFilter, AbstractPreAuthenticatedProcessingFilter.class)
|
||||||
|
.authorizeHttpRequests(authRequest ->
|
||||||
|
authRequest.requestMatchers(buildAntPatterns(webSecurityProperties.getAllowedEndpoints())).anonymous()
|
||||||
|
.requestMatchers(buildAntPatterns(webSecurityProperties.getAuthorizedEndpoints())).authenticated())
|
||||||
|
.sessionManagement( sessionManagementConfigurer-> sessionManagementConfigurer.sessionCreationPolicy(SessionCreationPolicy.NEVER))
|
||||||
|
.oauth2ResourceServer(oauth2 -> oauth2.authenticationManagerResolver(authenticationManagerResolver));
|
||||||
|
return tempHttp.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Bean
|
||||||
|
// AuthorizationPolicyConfigurer authorizationPolicyConfigurer() {
|
||||||
|
// return new AuthorizationPolicyConfigurer() {
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public AuthorizationPolicyResolverStrategy strategy() {
|
||||||
|
// return AuthorizationPolicyResolverStrategy.STRICT_CONSENSUS_BASED;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// //Here you can register your custom authorization handlers, which will get used as well as the existing ones
|
||||||
|
// //This is optional and can be omitted
|
||||||
|
// //If not set / set to null, only the default authorization handlers will be used
|
||||||
|
// @Override
|
||||||
|
// public List<AuthorizationHandler<? extends AuthorizationRequirement>> addCustomHandlers() {
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// //Here you can register your custom authorization requirements (if any)
|
||||||
|
// //This is optional and can be omitted
|
||||||
|
// //If not set / set to null, only the default authorization requirements will be used
|
||||||
|
// @Override
|
||||||
|
// public List<? extends AuthorizationRequirement> extendRequirements() {
|
||||||
|
// return List.of(
|
||||||
|
//// new TimeOfDayAuthorizationRequirement(new TimeOfDay("08:00","16:00"), true)
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// //Here you can select handlers you want to disable by providing the classes they are implemented by
|
||||||
|
// //You can disable any handler (including any custom one)
|
||||||
|
// //This is optional and can be omitted
|
||||||
|
// //If not set / set to null, all the handlers will be invoked, based on their requirement support
|
||||||
|
// //In the example below, the default client handler will be ignored by the resolver
|
||||||
|
// @Override
|
||||||
|
// public List<Class<? extends AuthorizationHandler<? extends AuthorizationRequirement>>> disableHandlers() {
|
||||||
|
// return List.of(PermissionClientAuthorizationHandler.class);
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Bean
|
||||||
|
// AuthorizationRequirementMapper authorizationRequirementMapper() {
|
||||||
|
// return new AuthorizationRequirementMapper() {
|
||||||
|
// @Override
|
||||||
|
// public AuthorizationRequirement map(AuthorizationResource resource, boolean matchAll, String[] permissions) {
|
||||||
|
// Class<?> type = resource.getClass();
|
||||||
|
// if (!AuthorizationResource.class.isAssignableFrom(type)) throw new IllegalArgumentException("resource");
|
||||||
|
//
|
||||||
|
// if (OwnedResource.class.equals(type)) {
|
||||||
|
// return new OwnedAuthorizationRequirement();
|
||||||
|
// }
|
||||||
|
// throw new IllegalArgumentException("resource");
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
private String[] buildAntPatterns(Set<String> endpoints) {
|
||||||
|
if (endpoints == null) {
|
||||||
|
return new String[0];
|
||||||
|
}
|
||||||
|
return endpoints.stream()
|
||||||
|
.filter(endpoint -> endpoint != null && !endpoint.isBlank())
|
||||||
|
.map(endpoint -> "/" + stripUnnecessaryCharacters(endpoint) + "/**")
|
||||||
|
.toArray(String[]::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String stripUnnecessaryCharacters(String endpoint) {
|
||||||
|
endpoint = endpoint.strip();
|
||||||
|
if (endpoint.startsWith("/")) {
|
||||||
|
endpoint = endpoint.substring(1);
|
||||||
|
}
|
||||||
|
if (endpoint.endsWith("/")) {
|
||||||
|
endpoint = endpoint.substring(0, endpoint.length() - 1);
|
||||||
|
}
|
||||||
|
return endpoint;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,11 @@
|
||||||
package eu.eudat.configurations;
|
package eu.eudat.configurations;
|
||||||
|
|
||||||
import eu.eudat.controllers.interceptors.RequestInterceptor;
|
import eu.eudat.commons.scope.UserScope;
|
||||||
|
import eu.eudat.interceptors.UserInterceptor;
|
||||||
import eu.eudat.logic.handlers.PrincipalArgumentResolver;
|
import eu.eudat.logic.handlers.PrincipalArgumentResolver;
|
||||||
import eu.eudat.logic.services.ApiContext;
|
import eu.eudat.logic.services.ApiContext;
|
||||||
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
|
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
|
||||||
|
import gr.cite.commons.web.oidc.principal.CurrentPrincipalResolver;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.scheduling.annotation.EnableAsync;
|
import org.springframework.scheduling.annotation.EnableAsync;
|
||||||
|
@ -23,22 +25,29 @@ public class WebMVCConfiguration implements WebMvcConfigurer {
|
||||||
|
|
||||||
private AuthenticationService verifiedUserAuthenticationService;
|
private AuthenticationService verifiedUserAuthenticationService;
|
||||||
private AuthenticationService nonVerifiedUserAuthenticationService;
|
private AuthenticationService nonVerifiedUserAuthenticationService;
|
||||||
|
private final UserInterceptor userInterceptor;
|
||||||
|
private final UserScope userScope;
|
||||||
|
private final CurrentPrincipalResolver currentPrincipalResolver;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public WebMVCConfiguration(ApiContext apiContext, AuthenticationService verifiedUserAuthenticationService, AuthenticationService nonVerifiedUserAuthenticationService) {
|
public WebMVCConfiguration(ApiContext apiContext, AuthenticationService verifiedUserAuthenticationService, AuthenticationService nonVerifiedUserAuthenticationService, UserInterceptor userInterceptor, UserScope userScope, CurrentPrincipalResolver currentPrincipalResolver) {
|
||||||
this.apiContext = apiContext;
|
this.apiContext = apiContext;
|
||||||
this.verifiedUserAuthenticationService = verifiedUserAuthenticationService;
|
this.verifiedUserAuthenticationService = verifiedUserAuthenticationService;
|
||||||
this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService;
|
this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService;
|
||||||
|
this.userInterceptor = userInterceptor;
|
||||||
|
this.userScope = userScope;
|
||||||
|
this.currentPrincipalResolver = currentPrincipalResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@Override
|
@Override
|
||||||
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
|
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
|
||||||
argumentResolvers.add(new PrincipalArgumentResolver(verifiedUserAuthenticationService, nonVerifiedUserAuthenticationService));
|
argumentResolvers.add(new PrincipalArgumentResolver(verifiedUserAuthenticationService, nonVerifiedUserAuthenticationService, userScope, currentPrincipalResolver));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addInterceptors(InterceptorRegistry registry) {
|
public void addInterceptors(InterceptorRegistry registry) {
|
||||||
// registry.addInterceptor(new RequestInterceptor(this.apiContext.getHelpersService().getLoggerService()));
|
// registry.addInterceptor(new RequestInterceptor(this.apiContext.getHelpersService().getLoggerService()));
|
||||||
|
registry.addWebRequestInterceptor(userInterceptor).order(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,6 @@ package eu.eudat.controllers;
|
||||||
import eu.eudat.exceptions.emailconfirmation.HasConfirmedEmailException;
|
import eu.eudat.exceptions.emailconfirmation.HasConfirmedEmailException;
|
||||||
import eu.eudat.exceptions.emailconfirmation.TokenExpiredException;
|
import eu.eudat.exceptions.emailconfirmation.TokenExpiredException;
|
||||||
import eu.eudat.logic.managers.EmailConfirmationManager;
|
import eu.eudat.logic.managers.EmailConfirmationManager;
|
||||||
import eu.eudat.logic.security.CustomAuthenticationProvider;
|
|
||||||
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
|
|
||||||
import eu.eudat.models.data.helpers.responses.ResponseItem;
|
import eu.eudat.models.data.helpers.responses.ResponseItem;
|
||||||
import eu.eudat.models.data.security.Principal;
|
import eu.eudat.models.data.security.Principal;
|
||||||
import eu.eudat.types.ApiMessageCode;
|
import eu.eudat.types.ApiMessageCode;
|
||||||
|
@ -17,7 +15,7 @@ import jakarta.transaction.Transactional;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@CrossOrigin
|
@CrossOrigin
|
||||||
@RequestMapping(value = "api/emailConfirmation")
|
@RequestMapping(value = "/api/emailConfirmation/")
|
||||||
public class EmailConfirmation {
|
public class EmailConfirmation {
|
||||||
|
|
||||||
private EmailConfirmationManager emailConfirmationManager;
|
private EmailConfirmationManager emailConfirmationManager;
|
||||||
|
|
|
@ -2,10 +2,7 @@ package eu.eudat.controllers;
|
||||||
|
|
||||||
import eu.eudat.exceptions.emailconfirmation.HasConfirmedEmailException;
|
import eu.eudat.exceptions.emailconfirmation.HasConfirmedEmailException;
|
||||||
import eu.eudat.exceptions.emailconfirmation.TokenExpiredException;
|
import eu.eudat.exceptions.emailconfirmation.TokenExpiredException;
|
||||||
import eu.eudat.logic.managers.EmailConfirmationManager;
|
|
||||||
import eu.eudat.logic.managers.MergeEmailConfirmationManager;
|
import eu.eudat.logic.managers.MergeEmailConfirmationManager;
|
||||||
import eu.eudat.logic.security.CustomAuthenticationProvider;
|
|
||||||
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
|
|
||||||
import eu.eudat.models.data.helpers.responses.ResponseItem;
|
import eu.eudat.models.data.helpers.responses.ResponseItem;
|
||||||
import eu.eudat.models.data.security.Principal;
|
import eu.eudat.models.data.security.Principal;
|
||||||
import eu.eudat.models.data.userinfo.UserMergeRequestModel;
|
import eu.eudat.models.data.userinfo.UserMergeRequestModel;
|
||||||
|
|
|
@ -1,53 +1,17 @@
|
||||||
package eu.eudat.controllers;
|
package eu.eudat.controllers;
|
||||||
|
|
||||||
|
|
||||||
import eu.eudat.exceptions.security.ExpiredTokenException;
|
|
||||||
import eu.eudat.exceptions.security.NonValidTokenException;
|
|
||||||
import eu.eudat.exceptions.security.NullEmailException;
|
|
||||||
import eu.eudat.logic.managers.MetricsManager;
|
|
||||||
import eu.eudat.logic.managers.UserManager;
|
|
||||||
import eu.eudat.logic.proxy.config.configloaders.ConfigLoader;
|
import eu.eudat.logic.proxy.config.configloaders.ConfigLoader;
|
||||||
import eu.eudat.logic.security.CustomAuthenticationProvider;
|
|
||||||
import eu.eudat.logic.security.customproviders.ConfigurableProvider.models.ConfigurableProvidersModel;
|
import eu.eudat.logic.security.customproviders.ConfigurableProvider.models.ConfigurableProvidersModel;
|
||||||
import eu.eudat.logic.security.validators.b2access.B2AccessTokenValidator;
|
|
||||||
import eu.eudat.logic.security.validators.b2access.helpers.B2AccessRequest;
|
|
||||||
import eu.eudat.logic.security.validators.b2access.helpers.B2AccessResponseToken;
|
|
||||||
import eu.eudat.logic.security.validators.configurableProvider.ConfigurableProviderTokenValidator;
|
|
||||||
import eu.eudat.logic.security.validators.configurableProvider.helpers.ConfigurableProviderRequest;
|
|
||||||
import eu.eudat.logic.security.validators.configurableProvider.helpers.ConfigurableProviderResponseToken;
|
|
||||||
import eu.eudat.logic.security.validators.linkedin.LinkedInTokenValidator;
|
|
||||||
import eu.eudat.logic.security.validators.linkedin.helpers.LinkedInRequest;
|
|
||||||
import eu.eudat.logic.security.validators.linkedin.helpers.LinkedInResponseToken;
|
|
||||||
import eu.eudat.logic.security.validators.openaire.OpenAIRETokenValidator;
|
|
||||||
import eu.eudat.logic.security.validators.openaire.helpers.OpenAIRERequest;
|
|
||||||
import eu.eudat.logic.security.validators.openaire.helpers.OpenAIREResponseToken;
|
|
||||||
import eu.eudat.logic.security.validators.orcid.ORCIDTokenValidator;
|
|
||||||
import eu.eudat.logic.security.validators.orcid.helpers.ORCIDRequest;
|
|
||||||
import eu.eudat.logic.security.validators.orcid.helpers.ORCIDResponseToken;
|
|
||||||
import eu.eudat.logic.security.validators.twitter.TwitterTokenValidator;
|
|
||||||
import eu.eudat.logic.security.validators.zenodo.ZenodoTokenValidator;
|
|
||||||
import eu.eudat.logic.security.validators.zenodo.helpers.ZenodoRequest;
|
|
||||||
import eu.eudat.logic.security.validators.zenodo.helpers.ZenodoResponseToken;
|
|
||||||
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
|
|
||||||
import eu.eudat.models.data.helpers.responses.ResponseItem;
|
import eu.eudat.models.data.helpers.responses.ResponseItem;
|
||||||
import eu.eudat.models.data.login.Credentials;
|
|
||||||
import eu.eudat.models.data.login.LoginInfo;
|
|
||||||
import eu.eudat.models.data.principal.PrincipalModel;
|
|
||||||
import eu.eudat.models.data.security.Principal;
|
|
||||||
import eu.eudat.types.ApiMessageCode;
|
import eu.eudat.types.ApiMessageCode;
|
||||||
import eu.eudat.types.MetricNames;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
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.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.social.oauth1.OAuthToken;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import jakarta.transaction.Transactional;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.security.GeneralSecurityException;
|
|
||||||
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@CrossOrigin
|
@CrossOrigin
|
||||||
|
@ -55,124 +19,14 @@ import java.security.GeneralSecurityException;
|
||||||
public class Login {
|
public class Login {
|
||||||
private static final Logger logger = LoggerFactory.getLogger(Login.class);
|
private static final Logger logger = LoggerFactory.getLogger(Login.class);
|
||||||
|
|
||||||
private CustomAuthenticationProvider customAuthenticationProvider;
|
|
||||||
private AuthenticationService nonVerifiedUserAuthenticationService;
|
|
||||||
private TwitterTokenValidator twitterTokenValidator;
|
|
||||||
private B2AccessTokenValidator b2AccessTokenValidator;
|
|
||||||
private ORCIDTokenValidator orcidTokenValidator;
|
|
||||||
private LinkedInTokenValidator linkedInTokenValidator;
|
|
||||||
private OpenAIRETokenValidator openAIRETokenValidator;
|
|
||||||
private ConfigurableProviderTokenValidator configurableProviderTokenValidator;
|
|
||||||
private ZenodoTokenValidator zenodoTokenValidator;
|
|
||||||
private ConfigLoader configLoader;
|
private ConfigLoader configLoader;
|
||||||
private final MetricsManager metricsManager;
|
|
||||||
|
|
||||||
// private Logger logger;
|
|
||||||
|
|
||||||
private UserManager userManager;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public Login(CustomAuthenticationProvider customAuthenticationProvider,
|
public Login(
|
||||||
AuthenticationService nonVerifiedUserAuthenticationService, TwitterTokenValidator twitterTokenValidator,
|
ConfigLoader configLoader) {
|
||||||
B2AccessTokenValidator b2AccessTokenValidator, ORCIDTokenValidator orcidTokenValidator,
|
|
||||||
LinkedInTokenValidator linkedInTokenValidator, OpenAIRETokenValidator openAIRETokenValidator,
|
|
||||||
ConfigurableProviderTokenValidator configurableProviderTokenValidator, ZenodoTokenValidator zenodoTokenValidator,
|
|
||||||
ConfigLoader configLoader, UserManager userManager,
|
|
||||||
MetricsManager metricsManager) {
|
|
||||||
this.customAuthenticationProvider = customAuthenticationProvider;
|
|
||||||
this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService;
|
|
||||||
this.twitterTokenValidator = twitterTokenValidator;
|
|
||||||
this.b2AccessTokenValidator = b2AccessTokenValidator;
|
|
||||||
this.orcidTokenValidator = orcidTokenValidator;
|
|
||||||
this.linkedInTokenValidator = linkedInTokenValidator;
|
|
||||||
this.openAIRETokenValidator = openAIRETokenValidator;
|
|
||||||
this.configurableProviderTokenValidator = configurableProviderTokenValidator;
|
|
||||||
this.zenodoTokenValidator = zenodoTokenValidator;
|
|
||||||
this.configLoader = configLoader;
|
this.configLoader = configLoader;
|
||||||
this.userManager = userManager;
|
|
||||||
this.metricsManager = metricsManager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
@RequestMapping(method = RequestMethod.POST, value = {"/externallogin"}, consumes = "application/json", produces = "application/json")
|
|
||||||
public @ResponseBody
|
|
||||||
ResponseEntity<ResponseItem<PrincipalModel>> externallogin(@RequestBody LoginInfo credentials) throws GeneralSecurityException, NullEmailException {
|
|
||||||
logger.info("Trying To Login With " + credentials.getProvider());
|
|
||||||
metricsManager.increaseValue(MetricNames.USERS, 1, MetricNames.LOGGEDIN);
|
|
||||||
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<PrincipalModel>().payload(customAuthenticationProvider.authenticate(credentials)).status(ApiMessageCode.SUCCESS_MESSAGE));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
@RequestMapping(method = RequestMethod.POST, value = {"/nativelogin"}, consumes = "application/json", produces = "application/json")
|
|
||||||
public @ResponseBody
|
|
||||||
ResponseEntity<ResponseItem<PrincipalModel>> nativelogin(@RequestBody Credentials credentials) throws NullEmailException {
|
|
||||||
logger.info(credentials.getUsername() + " Trying To Login");
|
|
||||||
metricsManager.increaseValue(MetricNames.USERS, 1, MetricNames.LOGGEDIN);
|
|
||||||
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<PrincipalModel>().payload(userManager.authenticate(this.nonVerifiedUserAuthenticationService, credentials)).status(ApiMessageCode.SUCCESS_MESSAGE));
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.GET, value = {"/twitterRequestToken"}, produces = "application/json")
|
|
||||||
public @ResponseBody
|
|
||||||
ResponseEntity<ResponseItem<OAuthToken>> twitterRequestToken() {
|
|
||||||
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<OAuthToken>().payload(this.twitterTokenValidator.getRequestToken()).status(ApiMessageCode.NO_MESSAGE));
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.POST, value = {"/linkedInRequestToken"}, produces = "application/json", consumes = "application/json")
|
|
||||||
public @ResponseBody
|
|
||||||
ResponseEntity<ResponseItem<LinkedInResponseToken>> linkedInRequestToken(@RequestBody LinkedInRequest linkedInRequest) {
|
|
||||||
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<LinkedInResponseToken>().payload(this.linkedInTokenValidator.getAccessToken(linkedInRequest)).status(ApiMessageCode.NO_MESSAGE));
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.POST, value = {"/b2AccessRequestToken"}, produces = "application/json", consumes = "application/json")
|
|
||||||
public @ResponseBody
|
|
||||||
ResponseEntity<ResponseItem<B2AccessResponseToken>> b2AccessRequestToken(@RequestBody B2AccessRequest b2AccessRequest) {
|
|
||||||
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<B2AccessResponseToken>().payload(this.b2AccessTokenValidator.getAccessToken(b2AccessRequest)).status(ApiMessageCode.NO_MESSAGE));
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.POST, value = {"/orcidRequestToken"}, produces = "application/json", consumes = "application/json")
|
|
||||||
public @ResponseBody
|
|
||||||
ResponseEntity<ResponseItem<ORCIDResponseToken>> ORCIDRequestToken(@RequestBody ORCIDRequest orcidRequest) {
|
|
||||||
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<ORCIDResponseToken>().payload(this.orcidTokenValidator.getAccessToken(orcidRequest)).status(ApiMessageCode.NO_MESSAGE));
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.POST, value = {"/openAireRequestToken"}, produces = "application/json", consumes = "application/json")
|
|
||||||
public @ResponseBody
|
|
||||||
ResponseEntity<ResponseItem<OpenAIREResponseToken>> openAIRERequestToken(@RequestBody OpenAIRERequest openAIRERequest) {
|
|
||||||
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<OpenAIREResponseToken>().payload(this.openAIRETokenValidator.getAccessToken(openAIRERequest)).status(ApiMessageCode.NO_MESSAGE));
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.POST, value = {"/configurableProviderRequestToken"}, produces = "application/json", consumes = "application/json")
|
|
||||||
public @ResponseBody
|
|
||||||
ResponseEntity<ResponseItem<ConfigurableProviderResponseToken>> configurableProviderRequestToken(@RequestBody ConfigurableProviderRequest configurableProviderRequest) {
|
|
||||||
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<ConfigurableProviderResponseToken>().payload(this.configurableProviderTokenValidator.getAccessToken(configurableProviderRequest)).status(ApiMessageCode.NO_MESSAGE));
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.POST, value = {"/zenodoRequestToken"}, produces = "application/json", consumes = "application/json")
|
|
||||||
public @ResponseBody
|
|
||||||
ResponseEntity<ResponseItem<ZenodoResponseToken>> ZenodoRequestToken(@RequestBody ZenodoRequest zenodoRequest) {
|
|
||||||
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<ZenodoResponseToken>().payload(this.zenodoTokenValidator.getAccessToken(zenodoRequest)).status(ApiMessageCode.NO_MESSAGE));
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.POST, value = {"/me"}, consumes = "application/json", produces = "application/json")
|
|
||||||
public @ResponseBody
|
|
||||||
ResponseEntity<ResponseItem<PrincipalModel>> authMe(Principal principal) throws NullEmailException {
|
|
||||||
logger.info(principal + " Getting Me");
|
|
||||||
Principal principal1 = this.nonVerifiedUserAuthenticationService.Touch(principal.getToken());
|
|
||||||
PrincipalModel principalModel = PrincipalModel.fromEntity(principal1);
|
|
||||||
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<PrincipalModel>().payload(principalModel).status(ApiMessageCode.NO_MESSAGE));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
@RequestMapping(method = RequestMethod.POST, value = {"/logout"}, consumes = "application/json", produces = "application/json")
|
|
||||||
public @ResponseBody
|
|
||||||
ResponseEntity<ResponseItem<Principal>> logout(Principal principal) {
|
|
||||||
this.nonVerifiedUserAuthenticationService.Logout(principal.getToken());
|
|
||||||
logger.info(principal + " Logged Out");
|
|
||||||
metricsManager.decreaseValue(MetricNames.USERS, 1, MetricNames.LOGGEDIN);
|
|
||||||
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<Principal>().status(ApiMessageCode.NO_MESSAGE));
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.GET, value = {"/configurableLogin"}, consumes = "application/json", produces = "application/json")
|
@RequestMapping(method = RequestMethod.GET, value = {"/configurableLogin"}, consumes = "application/json", produces = "application/json")
|
||||||
public @ResponseBody
|
public @ResponseBody
|
||||||
ResponseEntity<ResponseItem<ConfigurableProvidersModel>> getConfigurableProviders() {
|
ResponseEntity<ResponseItem<ConfigurableProvidersModel>> getConfigurableProviders() {
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
package eu.eudat.controllers;
|
|
||||||
|
|
||||||
import eu.eudat.logic.security.CustomAuthenticationProvider;
|
|
||||||
import eu.eudat.logic.security.validators.TokenValidatorFactoryImpl;
|
|
||||||
import eu.eudat.logic.services.ApiContext;
|
|
||||||
import eu.eudat.models.data.login.LoginInfo;
|
|
||||||
import eu.eudat.models.data.principal.PrincipalModel;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
|
|
||||||
import java.security.GeneralSecurityException;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
@CrossOrigin
|
|
||||||
@RequestMapping(value = {"/api/auth/saml2"})
|
|
||||||
public class Saml2PostBinding extends BaseController {
|
|
||||||
|
|
||||||
private CustomAuthenticationProvider customAuthenticationProvider;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public Saml2PostBinding(ApiContext apiContext, CustomAuthenticationProvider customAuthenticationProvider) {
|
|
||||||
super(apiContext);
|
|
||||||
this.customAuthenticationProvider = customAuthenticationProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.POST, value = {"/postBinding"}, consumes = "application/x-www-form-urlencoded")
|
|
||||||
public @ResponseBody
|
|
||||||
ResponseEntity<Void> verify(@RequestParam(value = "SAMLResponse") String SAMLResponse, @RequestParam(value = "RelayState") String RelayState) throws GeneralSecurityException {
|
|
||||||
|
|
||||||
Map<String, String> map = Arrays.stream(RelayState.split("&")).map(s -> s.split("=")).collect(Collectors.toMap(e -> e[0], e -> e[1]));
|
|
||||||
|
|
||||||
LoginInfo loginInfo = new LoginInfo();
|
|
||||||
loginInfo.setTicket(SAMLResponse);
|
|
||||||
loginInfo.setProvider(TokenValidatorFactoryImpl.LoginProvider.CONFIGURABLE.getValue());
|
|
||||||
Map<String, String> providerId = new HashMap<>();
|
|
||||||
providerId.put("configurableLoginId", map.get("configurableLoginId"));
|
|
||||||
loginInfo.setData(providerId);
|
|
||||||
|
|
||||||
PrincipalModel principal = this.customAuthenticationProvider.authenticate(loginInfo);
|
|
||||||
|
|
||||||
return ResponseEntity.status(HttpStatus.FOUND).header(HttpHeaders.LOCATION, "http://localhost:4200/login/external/saml?token=" + principal.getToken().toString()).build();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
package eu.eudat.controllers.v2;
|
||||||
|
|
||||||
|
import eu.eudat.models.data.dataset.DatasetOverviewModel;
|
||||||
|
import eu.eudat.models.data.helpers.responses.ResponseItem;
|
||||||
|
import eu.eudat.models.v2.AccountBuilder;
|
||||||
|
import eu.eudat.types.ApiMessageCode;
|
||||||
|
import gr.cite.commons.web.oidc.principal.CurrentPrincipalResolver;
|
||||||
|
import gr.cite.commons.web.oidc.principal.MyPrincipal;
|
||||||
|
import gr.cite.tools.auditing.AuditService;
|
||||||
|
import gr.cite.tools.fieldset.BaseFieldSet;
|
||||||
|
import gr.cite.tools.fieldset.FieldSet;
|
||||||
|
import gr.cite.tools.logging.LoggerService;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import eu.eudat.models.v2.Account;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@CrossOrigin
|
||||||
|
@RequestMapping(value = { "/api/principal/" })
|
||||||
|
public class PrincipalController {
|
||||||
|
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(PrincipalController.class));
|
||||||
|
private final AuditService auditService;
|
||||||
|
|
||||||
|
private final CurrentPrincipalResolver currentPrincipalResolver;
|
||||||
|
private final AccountBuilder accountBuilder;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public PrincipalController(
|
||||||
|
CurrentPrincipalResolver currentPrincipalResolver,
|
||||||
|
AccountBuilder accountBuilder,
|
||||||
|
AuditService auditService) {
|
||||||
|
this.currentPrincipalResolver = currentPrincipalResolver;
|
||||||
|
this.accountBuilder = accountBuilder;
|
||||||
|
this.auditService = auditService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(path = "me", method = RequestMethod.GET )
|
||||||
|
public ResponseEntity<?> me(FieldSet fieldSet) {
|
||||||
|
logger.debug("me");
|
||||||
|
|
||||||
|
if (fieldSet == null || fieldSet.isEmpty()) {
|
||||||
|
fieldSet = new BaseFieldSet(
|
||||||
|
Account._isAuthenticated,
|
||||||
|
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._subject),
|
||||||
|
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._userId),
|
||||||
|
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._name),
|
||||||
|
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._scope),
|
||||||
|
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._client),
|
||||||
|
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._issuedAt),
|
||||||
|
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._notBefore),
|
||||||
|
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._authenticatedAt),
|
||||||
|
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._expiresAt),
|
||||||
|
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._more),
|
||||||
|
Account._roles);
|
||||||
|
}
|
||||||
|
|
||||||
|
MyPrincipal principal = this.currentPrincipalResolver.currentPrincipal();
|
||||||
|
|
||||||
|
Account me = this.accountBuilder.build(fieldSet, principal);
|
||||||
|
|
||||||
|
//this.auditService.track(AuditableAction.Principal_Lookup);
|
||||||
|
//auditService.trackIdentity(AuditableAction.IdentityTracking_Action);
|
||||||
|
|
||||||
|
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<Account>().status(ApiMessageCode.NO_MESSAGE).payload(me));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,245 @@
|
||||||
|
package eu.eudat.interceptors;
|
||||||
|
|
||||||
|
|
||||||
|
import eu.eudat.commons.scope.UserScope;
|
||||||
|
import eu.eudat.data.entities.Credential;
|
||||||
|
import eu.eudat.data.entities.UserInfo;
|
||||||
|
import eu.eudat.data.entities.UserRole;
|
||||||
|
import eu.eudat.exceptions.security.NullEmailException;
|
||||||
|
import eu.eudat.types.Authorities;
|
||||||
|
import gr.cite.commons.web.oidc.principal.CurrentPrincipalResolver;
|
||||||
|
import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractor;
|
||||||
|
import gr.cite.tools.exception.MyApplicationException;
|
||||||
|
import gr.cite.tools.logging.LoggerService;
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
|
import jakarta.persistence.PersistenceContext;
|
||||||
|
import jakarta.persistence.Tuple;
|
||||||
|
import jakarta.persistence.TypedQuery;
|
||||||
|
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||||
|
import jakarta.persistence.criteria.CriteriaQuery;
|
||||||
|
import jakarta.persistence.criteria.Root;
|
||||||
|
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.transaction.TransactionDefinition;
|
||||||
|
import org.springframework.transaction.TransactionStatus;
|
||||||
|
import org.springframework.transaction.support.DefaultTransactionDefinition;
|
||||||
|
import org.springframework.ui.ModelMap;
|
||||||
|
import org.springframework.web.context.request.ServletWebRequest;
|
||||||
|
import org.springframework.web.context.request.WebRequest;
|
||||||
|
import org.springframework.web.context.request.WebRequestInterceptor;
|
||||||
|
|
||||||
|
import javax.management.InvalidApplicationException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
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 PlatformTransactionManager transactionManager;
|
||||||
|
private final UserInterceptorCacheService userInterceptorCacheService;
|
||||||
|
@PersistenceContext
|
||||||
|
public EntityManager entityManager;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public UserInterceptor(
|
||||||
|
UserScope userScope,
|
||||||
|
ClaimExtractor claimExtractor,
|
||||||
|
CurrentPrincipalResolver currentPrincipalResolver,
|
||||||
|
PlatformTransactionManager transactionManager,
|
||||||
|
UserInterceptorCacheService userInterceptorCacheService
|
||||||
|
) {
|
||||||
|
this.userScope = userScope;
|
||||||
|
this.currentPrincipalResolver = currentPrincipalResolver;
|
||||||
|
this.claimExtractor = claimExtractor;
|
||||||
|
this.transactionManager = transactionManager;
|
||||||
|
this.userInterceptorCacheService = userInterceptorCacheService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preHandle(WebRequest request) throws InvalidApplicationException {
|
||||||
|
UUID userId = null;
|
||||||
|
if (this.currentPrincipalResolver.currentPrincipal().isAuthenticated()) {
|
||||||
|
String subjectId = this.claimExtractor.subjectString(this.currentPrincipalResolver.currentPrincipal());
|
||||||
|
|
||||||
|
UserInterceptorCacheService.UserInterceptorCacheValue cacheValue = this.userInterceptorCacheService.lookup(this.userInterceptorCacheService.buildKey(subjectId));
|
||||||
|
if (cacheValue != null) {
|
||||||
|
userId = cacheValue.getUserId();
|
||||||
|
} else {
|
||||||
|
userId = this.getUserIdFromDatabaseBySubject(subjectId);
|
||||||
|
if (userId == null ) {
|
||||||
|
String email = this.claimExtractor.email(this.currentPrincipalResolver.currentPrincipal());
|
||||||
|
if (email != null && !email.isBlank()) {
|
||||||
|
userId = this.getUserIdFromDatabaseByEmail(email);
|
||||||
|
userId = this.createOrUpdateUser(subjectId, userId);
|
||||||
|
} else {
|
||||||
|
boolean checkMailNull = ((ServletWebRequest) request).getRequest().getServletPath().toLowerCase(Locale.ROOT).startsWith("/api/emailConfirmation".toLowerCase(Locale.ROOT));
|
||||||
|
if (!checkMailNull) throw new NullEmailException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userId != null) this.userInterceptorCacheService.put(new UserInterceptorCacheService.UserInterceptorCacheValue(subjectId, userId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.userScope.setUserId(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private UUID getUserIdFromDatabaseBySubject(String subjectId) {
|
||||||
|
CriteriaBuilder credentialCriteriaBuilder = this.entityManager.getCriteriaBuilder();
|
||||||
|
CriteriaQuery<Tuple> credentialQuery = credentialCriteriaBuilder.createQuery(Tuple.class);
|
||||||
|
Root<Credential> credentialRoot = credentialQuery.from(Credential.class);
|
||||||
|
credentialQuery.where(
|
||||||
|
credentialCriteriaBuilder.and(
|
||||||
|
credentialCriteriaBuilder.equal(credentialRoot.get(Credential._externalId), subjectId),
|
||||||
|
credentialCriteriaBuilder.equal(credentialRoot.get(Credential._status), 1), //TODO: Authn
|
||||||
|
credentialCriteriaBuilder.equal(credentialRoot.get(Credential._provider), 128)
|
||||||
|
));
|
||||||
|
|
||||||
|
credentialQuery.multiselect(credentialRoot.get(Credential._userInfo).get(UserInfo._id).alias(UserInfo._id));
|
||||||
|
|
||||||
|
List<Tuple> results = this.entityManager.createQuery(credentialQuery).getResultList();
|
||||||
|
return this.getUUIDFromTuple(results, UserInfo._id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private UUID getUserIdFromDatabaseByEmail(String email) {
|
||||||
|
CriteriaBuilder emailCriteriaBuilder = this.entityManager.getCriteriaBuilder();
|
||||||
|
CriteriaQuery<Tuple> emailQuery = emailCriteriaBuilder.createQuery(Tuple.class);
|
||||||
|
Root<UserInfo> emailRoot = emailQuery.from(UserInfo.class);
|
||||||
|
emailQuery.where(
|
||||||
|
emailCriteriaBuilder.and(
|
||||||
|
emailCriteriaBuilder.equal(emailRoot.get(UserInfo._email), email),
|
||||||
|
emailCriteriaBuilder.equal(emailRoot.get(UserInfo._userStatus), 0) //TODO: Authn
|
||||||
|
));
|
||||||
|
|
||||||
|
emailQuery.multiselect(emailRoot.get(UserInfo._id).alias(UserInfo._id));
|
||||||
|
|
||||||
|
List<Tuple> results = this.entityManager.createQuery(emailQuery).getResultList();
|
||||||
|
return this.getUUIDFromTuple(results, UserInfo._id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private UUID getUUIDFromTuple(List<Tuple> results, String field){
|
||||||
|
if (results.size() > 0) {//TODO: Authn
|
||||||
|
Object o;
|
||||||
|
try {
|
||||||
|
o = results.get(0).get(field);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (o == null) return null;
|
||||||
|
try {
|
||||||
|
return UUID.class.cast(o);
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private UUID createOrUpdateUser(String subjectId, UUID userId) {
|
||||||
|
String name = this.claimExtractor.name(this.currentPrincipalResolver.currentPrincipal());
|
||||||
|
String emailVerified = this.claimExtractor.emailVerified(this.currentPrincipalResolver.currentPrincipal());
|
||||||
|
String email = this.claimExtractor.email(this.currentPrincipalResolver.currentPrincipal());
|
||||||
|
if (name == null) name = subjectId;
|
||||||
|
|
||||||
|
UserInfo user = null;
|
||||||
|
UserRole userRole = null;
|
||||||
|
boolean isUpdateUser = userId != null;
|
||||||
|
if (!isUpdateUser) {
|
||||||
|
|
||||||
|
user = new UserInfo();
|
||||||
|
user.setId(UUID.randomUUID());
|
||||||
|
user.setVerified_email("true".equals(emailVerified));//TODO: Authn
|
||||||
|
user.setName(name);
|
||||||
|
user.setEmail(email);
|
||||||
|
user.setCreated(new Date());
|
||||||
|
user.setLastloggedin(new Date());
|
||||||
|
user.setLastloggedin(new Date());
|
||||||
|
user.setAuthorization_level((short) 1);//TODO: Authn
|
||||||
|
user.setUsertype((short) 1);
|
||||||
|
user.setUserStatus((short) 0);
|
||||||
|
// user.setAdditionalinfo("{\"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() : "") +"\"}}");
|
||||||
|
user.setAdditionalinfo("{\"data\":{\"avatar\":{\"url\":\"\"},\"zenodoToken\":\"\", \"expirationDate\": \"\", \"zenodoRefresh\": \"\", \"zenodoEmail\": \"\"}}"); //TODO: Authn
|
||||||
|
|
||||||
|
userRole = new UserRole();
|
||||||
|
userRole.setId(UUID.randomUUID());
|
||||||
|
userRole.setUserInfo(user);
|
||||||
|
userRole.setRole(Authorities.USER.getValue());
|
||||||
|
} else {
|
||||||
|
CriteriaBuilder emailCriteriaBuilder = this.entityManager.getCriteriaBuilder();
|
||||||
|
CriteriaQuery<UserInfo> userQuery = emailCriteriaBuilder.createQuery(UserInfo.class);
|
||||||
|
Root<UserInfo> userRoot = userQuery.from(UserInfo.class);
|
||||||
|
userQuery.where(
|
||||||
|
emailCriteriaBuilder.and(
|
||||||
|
emailCriteriaBuilder.equal(userRoot.get(UserInfo._id), userId),
|
||||||
|
emailCriteriaBuilder.equal(userRoot.get(UserInfo._userStatus), 0) //TODO: Authn
|
||||||
|
));
|
||||||
|
userQuery.select(userRoot);
|
||||||
|
TypedQuery<UserInfo> q = this.entityManager.createQuery(userQuery);
|
||||||
|
List<UserInfo> userInfos = q.getResultList();
|
||||||
|
if (userInfos == null || userInfos.size() < 1) {
|
||||||
|
throw new MyApplicationException("Can not found user " + userId);
|
||||||
|
}
|
||||||
|
user = userInfos.get(0);
|
||||||
|
user.setAdditionalinfo("{\"data\":{\"avatar\":{\"url\":\"\"},\"zenodoToken\":\"\", \"expirationDate\": \"\", \"zenodoRefresh\": \"\", \"zenodoEmail\": \"\"}}"); //TODO: Authn
|
||||||
|
}
|
||||||
|
|
||||||
|
Credential credential = new Credential();
|
||||||
|
credential.setId(UUID.randomUUID());
|
||||||
|
credential.setUserInfo(user);
|
||||||
|
credential.setSecret(subjectId);
|
||||||
|
credential.setCreationTime(new Date());
|
||||||
|
credential.setLastUpdateTime(new Date());
|
||||||
|
credential.setStatus(1);
|
||||||
|
credential.setProvider(128);//TODO: Authn
|
||||||
|
credential.setExternalId(subjectId);
|
||||||
|
credential.setEmail(email);
|
||||||
|
credential.setPublicValue(email);
|
||||||
|
|
||||||
|
|
||||||
|
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
|
||||||
|
definition.setName(UUID.randomUUID().toString());
|
||||||
|
definition.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
|
||||||
|
definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
|
||||||
|
TransactionStatus status = null;
|
||||||
|
try {
|
||||||
|
status = transactionManager.getTransaction(definition);
|
||||||
|
if (!isUpdateUser) {
|
||||||
|
user = this.entityManager.merge(user);
|
||||||
|
this.entityManager.flush();
|
||||||
|
userRole.setUserInfo(user);
|
||||||
|
credential.setUserInfo(user);
|
||||||
|
this.entityManager.merge(userRole);
|
||||||
|
this.entityManager.merge(credential);
|
||||||
|
} else {
|
||||||
|
this.entityManager.persist(user);
|
||||||
|
this.entityManager.persist(credential);
|
||||||
|
}
|
||||||
|
this.entityManager.flush();
|
||||||
|
transactionManager.commit(status);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
if (status != null) transactionManager.rollback(status);
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
return user.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postHandle(@NonNull WebRequest request, ModelMap model) {
|
||||||
|
this.userScope.setUserId(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterCompletion(@NonNull WebRequest request, Exception ex) {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package eu.eudat.interceptors;
|
||||||
|
|
||||||
|
import gr.cite.tools.cache.CacheOptions;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ConfigurationProperties(prefix = "cache.user-by-subject-id")
|
||||||
|
public class UserInterceptorCacheOptions extends CacheOptions {
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
package eu.eudat.interceptors;
|
||||||
|
|
||||||
|
import eu.eudat.convention.ConventionService;
|
||||||
|
import gr.cite.tools.cache.CacheService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.event.EventListener;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class UserInterceptorCacheService extends CacheService<UserInterceptorCacheService.UserInterceptorCacheValue> {
|
||||||
|
|
||||||
|
public static class UserInterceptorCacheValue {
|
||||||
|
|
||||||
|
public UserInterceptorCacheValue() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserInterceptorCacheValue(String subjectId, UUID userId) {
|
||||||
|
this.subjectId = subjectId;
|
||||||
|
this.userId = userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String subjectId;
|
||||||
|
|
||||||
|
public String getSubjectId() {
|
||||||
|
return subjectId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSubjectId(String subjectId) {
|
||||||
|
this.subjectId = subjectId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private UUID userId;
|
||||||
|
|
||||||
|
public UUID getUserId() {
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserId(UUID userId) {
|
||||||
|
this.userId = userId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final ConventionService conventionService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public UserInterceptorCacheService(UserInterceptorCacheOptions options, ConventionService conventionService) {
|
||||||
|
super(options);
|
||||||
|
this.conventionService = conventionService;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @EventListener //TODO: Authn
|
||||||
|
// public void handleUserTouchedEvent(UserTouchedEvent event) {
|
||||||
|
// if (!this.conventionService.isNullOrEmpty(event.getSubjectId()))
|
||||||
|
// this.evict(this.buildKey(event.getSubjectId()));
|
||||||
|
// if (!this.conventionService.isNullOrEmpty(event.getPreviousSubjectId()))
|
||||||
|
// this.evict(this.buildKey(event.getPreviousSubjectId()));
|
||||||
|
// }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<UserInterceptorCacheValue> valueClass() {
|
||||||
|
return UserInterceptorCacheValue.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String keyOf(UserInterceptorCacheValue value) {
|
||||||
|
return this.buildKey(value.getSubjectId());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String buildKey(String subject) {
|
||||||
|
HashMap<String, String> keyParts = new HashMap<>();
|
||||||
|
keyParts.put("$subject$", subject);
|
||||||
|
return this.generateKey(keyParts);
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,7 +24,6 @@ public class BuilderFactoryImpl implements BuilderFactory {
|
||||||
if (tClass.equals(RegistryCriteriaBuilder.class)) return (T) new RegistryCriteriaBuilder();
|
if (tClass.equals(RegistryCriteriaBuilder.class)) return (T) new RegistryCriteriaBuilder();
|
||||||
if (tClass.equals(UserInfoBuilder.class)) return (T) new UserInfoBuilder();
|
if (tClass.equals(UserInfoBuilder.class)) return (T) new UserInfoBuilder();
|
||||||
if (tClass.equals(UserRoleBuilder.class)) return (T) new UserRoleBuilder();
|
if (tClass.equals(UserRoleBuilder.class)) return (T) new UserRoleBuilder();
|
||||||
if (tClass.equals(UserTokenBuilder.class)) return (T) new UserTokenBuilder();
|
|
||||||
if (tClass.equals(ResearcherBuilder.class)) return (T) new ResearcherBuilder();
|
if (tClass.equals(ResearcherBuilder.class)) return (T) new ResearcherBuilder();
|
||||||
if (tClass.equals(ExternalDatasetCriteriaBuilder.class)) return (T) new ExternalDatasetCriteriaBuilder();
|
if (tClass.equals(ExternalDatasetCriteriaBuilder.class)) return (T) new ExternalDatasetCriteriaBuilder();
|
||||||
if (tClass.equals(RecentActivityDataBuilder.class)) return (T) new RecentActivityDataBuilder();
|
if (tClass.equals(RecentActivityDataBuilder.class)) return (T) new RecentActivityDataBuilder();
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
package eu.eudat.logic.builders.entity;
|
|
||||||
|
|
||||||
import eu.eudat.logic.builders.Builder;
|
|
||||||
import eu.eudat.data.entities.UserInfo;
|
|
||||||
import eu.eudat.data.entities.UserToken;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by ikalyvas on 2/15/2018.
|
|
||||||
*/
|
|
||||||
public class UserTokenBuilder extends Builder<UserToken> {
|
|
||||||
|
|
||||||
private UUID token;
|
|
||||||
|
|
||||||
private UserInfo user;
|
|
||||||
|
|
||||||
private Date issuedAt;
|
|
||||||
|
|
||||||
private Date expiresAt;
|
|
||||||
|
|
||||||
public UserTokenBuilder token(UUID token) {
|
|
||||||
this.token = token;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserTokenBuilder user(UserInfo user) {
|
|
||||||
this.user = user;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserTokenBuilder issuedAt(Date issuedAt) {
|
|
||||||
this.issuedAt = issuedAt;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserTokenBuilder expiresAt(Date expiresAt) {
|
|
||||||
this.expiresAt = expiresAt;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserToken build() {
|
|
||||||
UserToken userToken = new UserToken();
|
|
||||||
userToken.setExpiresAt(expiresAt);
|
|
||||||
userToken.setToken(token);
|
|
||||||
userToken.setUser(user);
|
|
||||||
userToken.setIssuedAt(issuedAt);
|
|
||||||
return userToken;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +1,13 @@
|
||||||
package eu.eudat.logic.handlers;
|
package eu.eudat.logic.handlers;
|
||||||
|
|
||||||
|
import eu.eudat.commons.scope.UserScope;
|
||||||
import eu.eudat.exceptions.security.UnauthorisedException;
|
import eu.eudat.exceptions.security.UnauthorisedException;
|
||||||
import eu.eudat.logic.security.claims.ClaimedAuthorities;
|
import eu.eudat.logic.security.claims.ClaimedAuthorities;
|
||||||
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
|
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
|
||||||
import eu.eudat.models.data.security.Principal;
|
import eu.eudat.models.data.security.Principal;
|
||||||
import eu.eudat.types.Authorities;
|
import eu.eudat.types.Authorities;
|
||||||
import org.apache.catalina.connector.RequestFacade;
|
import gr.cite.commons.web.oidc.principal.CurrentPrincipalResolver;
|
||||||
import org.apache.tomcat.util.buf.MessageBytes;
|
import gr.cite.commons.web.oidc.principal.MyPrincipal;
|
||||||
import org.springframework.core.MethodParameter;
|
import org.springframework.core.MethodParameter;
|
||||||
import org.springframework.web.bind.support.WebDataBinderFactory;
|
import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||||
import org.springframework.web.context.request.NativeWebRequest;
|
import org.springframework.web.context.request.NativeWebRequest;
|
||||||
|
@ -14,6 +15,7 @@ import org.springframework.web.context.request.ServletWebRequest;
|
||||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||||
|
|
||||||
|
import javax.management.InvalidApplicationException;
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
@ -22,10 +24,14 @@ public final class PrincipalArgumentResolver implements HandlerMethodArgumentRes
|
||||||
|
|
||||||
private AuthenticationService verifiedUserAuthenticationService;
|
private AuthenticationService verifiedUserAuthenticationService;
|
||||||
private AuthenticationService nonVerifiedUserAuthenticationService;
|
private AuthenticationService nonVerifiedUserAuthenticationService;
|
||||||
|
private final UserScope userScope;
|
||||||
public PrincipalArgumentResolver(AuthenticationService verifiedUserAuthenticationService, AuthenticationService nonVerifiedUserAuthenticationService) {
|
private final CurrentPrincipalResolver currentPrincipalResolver;
|
||||||
|
|
||||||
|
public PrincipalArgumentResolver(AuthenticationService verifiedUserAuthenticationService, AuthenticationService nonVerifiedUserAuthenticationService, UserScope userScope, CurrentPrincipalResolver currentPrincipalResolver) {
|
||||||
this.verifiedUserAuthenticationService = verifiedUserAuthenticationService;
|
this.verifiedUserAuthenticationService = verifiedUserAuthenticationService;
|
||||||
this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService;
|
this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService;
|
||||||
|
this.userScope = userScope;
|
||||||
|
this.currentPrincipalResolver = currentPrincipalResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -35,8 +41,8 @@ public final class PrincipalArgumentResolver implements HandlerMethodArgumentRes
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
|
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
|
||||||
String token = nativeWebRequest.getHeader("AuthToken");
|
MyPrincipal claimsPrincipal = this.currentPrincipalResolver.currentPrincipal();
|
||||||
|
|
||||||
boolean checkMailNull = ((ServletWebRequest) nativeWebRequest).getRequest().getRequestURI().startsWith("/api/emailConfirmation");
|
boolean checkMailNull = ((ServletWebRequest) nativeWebRequest).getRequest().getRequestURI().startsWith("/api/emailConfirmation");
|
||||||
AuthenticationService authenticationService = checkMailNull ? this.nonVerifiedUserAuthenticationService : this.verifiedUserAuthenticationService;
|
AuthenticationService authenticationService = checkMailNull ? this.nonVerifiedUserAuthenticationService : this.verifiedUserAuthenticationService;
|
||||||
|
|
||||||
|
@ -44,18 +50,24 @@ public final class PrincipalArgumentResolver implements HandlerMethodArgumentRes
|
||||||
List<Authorities> claimList = claimsAnnotation.map(annotation -> Arrays.asList(((ClaimedAuthorities) annotation).claims())).orElse(Authorities.all());
|
List<Authorities> claimList = claimsAnnotation.map(annotation -> Arrays.asList(((ClaimedAuthorities) annotation).claims())).orElse(Authorities.all());
|
||||||
if (claimList.size() == 1 && claimList.get(0).equals(Authorities.ANONYMOUS)) {
|
if (claimList.size() == 1 && claimList.get(0).equals(Authorities.ANONYMOUS)) {
|
||||||
return new Principal();
|
return new Principal();
|
||||||
} else if (claimList.contains(Authorities.ANONYMOUS) && token == null) {
|
} else if (claimList.contains(Authorities.ANONYMOUS) && !claimsPrincipal.isAuthenticated()) {
|
||||||
return new Principal();
|
return new Principal();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token == null) throw new UnauthorisedException("Authentication Information Is Missing");
|
if (!claimsPrincipal.isAuthenticated()) throw new UnauthorisedException("Authentication Information Is Missing");
|
||||||
UUID authToken;
|
Principal principal;
|
||||||
try {
|
if (checkMailNull){
|
||||||
authToken = UUID.fromString(token);
|
principal = authenticationService.Touch(claimsPrincipal);
|
||||||
} catch (IllegalArgumentException ex) {
|
} else {
|
||||||
throw new UnauthorisedException("Authentication Information Is Missing");
|
UUID userId;
|
||||||
|
try{
|
||||||
|
userId = checkMailNull ? null : this.userScope.getUserId();
|
||||||
|
} catch (InvalidApplicationException e) {
|
||||||
|
throw new UnauthorisedException("Authentication Information Is Missing");
|
||||||
|
}
|
||||||
|
principal = authenticationService.Touch(userId);
|
||||||
}
|
}
|
||||||
Principal principal = authenticationService.Touch(authToken);
|
|
||||||
if (principal == null) throw new UnauthorisedException("Authentication Information Missing");
|
if (principal == null) throw new UnauthorisedException("Authentication Information Missing");
|
||||||
if (!claimList.contains(Authorities.ANONYMOUS) && !principal.isAuthorized(claimList))
|
if (!claimList.contains(Authorities.ANONYMOUS) && !principal.isAuthorized(claimList))
|
||||||
throw new UnauthorisedException("You are not Authorized For this Action");
|
throw new UnauthorisedException("You are not Authorized For this Action");
|
||||||
|
|
|
@ -3,14 +3,11 @@ package eu.eudat.logic.managers;
|
||||||
import eu.eudat.data.entities.Credential;
|
import eu.eudat.data.entities.Credential;
|
||||||
import eu.eudat.data.entities.EmailConfirmation;
|
import eu.eudat.data.entities.EmailConfirmation;
|
||||||
import eu.eudat.data.entities.UserInfo;
|
import eu.eudat.data.entities.UserInfo;
|
||||||
import eu.eudat.data.entities.UserToken;
|
|
||||||
import eu.eudat.exceptions.emailconfirmation.HasConfirmedEmailException;
|
import eu.eudat.exceptions.emailconfirmation.HasConfirmedEmailException;
|
||||||
import eu.eudat.exceptions.emailconfirmation.TokenExpiredException;
|
import eu.eudat.exceptions.emailconfirmation.TokenExpiredException;
|
||||||
import eu.eudat.logic.services.ApiContext;
|
import eu.eudat.logic.services.ApiContext;
|
||||||
import eu.eudat.logic.services.operations.DatabaseRepository;
|
import eu.eudat.logic.services.operations.DatabaseRepository;
|
||||||
import eu.eudat.models.data.security.Principal;
|
import eu.eudat.models.data.security.Principal;
|
||||||
import eu.eudat.queryable.QueryableList;
|
|
||||||
import eu.eudat.queryable.jpa.predicates.OrderByPredicate;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@ -53,7 +50,7 @@ public class EmailConfirmationManager {
|
||||||
databaseRepository.getCredentialDao().createOrUpdate(credential);
|
databaseRepository.getCredentialDao().createOrUpdate(credential);
|
||||||
UserInfo oldUser = databaseRepository.getUserInfoDao().asQueryable().where((builder, root) -> builder.equal(root.get("email"), loginConfirmationEmail.getEmail())).getSingle();
|
UserInfo oldUser = databaseRepository.getUserInfoDao().asQueryable().where((builder, root) -> builder.equal(root.get("email"), loginConfirmationEmail.getEmail())).getSingle();
|
||||||
mergeNewUserToOld(user, oldUser);
|
mergeNewUserToOld(user, oldUser);
|
||||||
expireUserToken(user);
|
// expireUserToken(user); //TODO: Authn
|
||||||
databaseRepository.getLoginConfirmationEmailDao().createOrUpdate(loginConfirmationEmail);
|
databaseRepository.getLoginConfirmationEmailDao().createOrUpdate(loginConfirmationEmail);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -87,14 +84,4 @@ public class EmailConfirmationManager {
|
||||||
credential.setUserInfo(oldUser);
|
credential.setUserInfo(oldUser);
|
||||||
databaseRepository.getCredentialDao().createOrUpdate(credential);
|
databaseRepository.getCredentialDao().createOrUpdate(credential);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void expireUserToken(UserInfo user) {
|
|
||||||
UserToken userToken = databaseRepository.getUserTokenDao().asQueryable()
|
|
||||||
.where((builder, root) -> builder.equal(root.get("user"), user))
|
|
||||||
.orderBy((builder, root) -> builder.desc(root.get("issuedAt")))
|
|
||||||
.take(1)
|
|
||||||
.getSingle();
|
|
||||||
userToken.setExpiresAt(new Date());
|
|
||||||
databaseRepository.getUserTokenDao().createOrUpdate(userToken);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import eu.eudat.data.entities.Credential;
|
||||||
import eu.eudat.data.entities.EmailConfirmation;
|
import eu.eudat.data.entities.EmailConfirmation;
|
||||||
import eu.eudat.data.entities.UserDMP;
|
import eu.eudat.data.entities.UserDMP;
|
||||||
import eu.eudat.data.entities.UserInfo;
|
import eu.eudat.data.entities.UserInfo;
|
||||||
import eu.eudat.data.entities.UserToken;
|
|
||||||
import eu.eudat.elastic.criteria.DmpCriteria;
|
import eu.eudat.elastic.criteria.DmpCriteria;
|
||||||
import eu.eudat.elastic.entities.Collaborator;
|
import eu.eudat.elastic.entities.Collaborator;
|
||||||
import eu.eudat.elastic.entities.Dmp;
|
import eu.eudat.elastic.entities.Dmp;
|
||||||
|
@ -14,23 +13,17 @@ import eu.eudat.exceptions.emailconfirmation.TokenExpiredException;
|
||||||
import eu.eudat.logic.services.ApiContext;
|
import eu.eudat.logic.services.ApiContext;
|
||||||
import eu.eudat.logic.services.operations.DatabaseRepository;
|
import eu.eudat.logic.services.operations.DatabaseRepository;
|
||||||
import eu.eudat.models.data.security.Principal;
|
import eu.eudat.models.data.security.Principal;
|
||||||
import eu.eudat.queryable.QueryableList;
|
|
||||||
import eu.eudat.queryable.jpa.predicates.OrderByPredicate;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
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.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonParseException;
|
|
||||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
import jakarta.transaction.Transactional;
|
import jakarta.transaction.Transactional;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class MergeEmailConfirmationManager {
|
public class MergeEmailConfirmationManager {
|
||||||
|
@ -66,7 +59,7 @@ public class MergeEmailConfirmationManager {
|
||||||
|
|
||||||
// Checks if mail is used by another user. If it is, merges the new the old.
|
// Checks if mail is used by another user. If it is, merges the new the old.
|
||||||
mergeNewUserToOld(user, userToBeMerged, Integer.valueOf((String) map.get("provider")));
|
mergeNewUserToOld(user, userToBeMerged, Integer.valueOf((String) map.get("provider")));
|
||||||
expireUserToken(userToBeMerged);
|
//expireUserToken(userToBeMerged); //TODO: Authn
|
||||||
loginConfirmationEmail.setIsConfirmed(true);
|
loginConfirmationEmail.setIsConfirmed(true);
|
||||||
databaseRepository.getLoginConfirmationEmailDao().createOrUpdate(loginConfirmationEmail);
|
databaseRepository.getLoginConfirmationEmailDao().createOrUpdate(loginConfirmationEmail);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -143,13 +136,4 @@ public class MergeEmailConfirmationManager {
|
||||||
});
|
});
|
||||||
databaseRepository.getUserInfoDao().createOrUpdate(oldUser);
|
databaseRepository.getUserInfoDao().createOrUpdate(oldUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void expireUserToken(UserInfo user) {
|
|
||||||
UserToken userToken = databaseRepository.getUserTokenDao().asQueryable()
|
|
||||||
.where((builder, root) -> builder.equal(root.get("user"), user))
|
|
||||||
.orderBy((builder, root) -> builder.desc(root.get("issuedAt")))
|
|
||||||
.take(1).toList().get(0);
|
|
||||||
userToken.setExpiresAt(new Date());
|
|
||||||
databaseRepository.getUserTokenDao().createOrUpdate(userToken);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,10 +5,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import eu.eudat.data.entities.Credential;
|
import eu.eudat.data.entities.Credential;
|
||||||
import eu.eudat.data.entities.EmailConfirmation;
|
import eu.eudat.data.entities.EmailConfirmation;
|
||||||
import eu.eudat.data.entities.UserInfo;
|
import eu.eudat.data.entities.UserInfo;
|
||||||
import eu.eudat.data.entities.UserToken;
|
|
||||||
import eu.eudat.exceptions.emailconfirmation.HasConfirmedEmailException;
|
import eu.eudat.exceptions.emailconfirmation.HasConfirmedEmailException;
|
||||||
import eu.eudat.exceptions.emailconfirmation.TokenExpiredException;
|
import eu.eudat.exceptions.emailconfirmation.TokenExpiredException;
|
||||||
import eu.eudat.logic.builders.entity.UserTokenBuilder;
|
|
||||||
import eu.eudat.logic.services.ApiContext;
|
import eu.eudat.logic.services.ApiContext;
|
||||||
import eu.eudat.logic.services.operations.DatabaseRepository;
|
import eu.eudat.logic.services.operations.DatabaseRepository;
|
||||||
import eu.eudat.models.data.security.Principal;
|
import eu.eudat.models.data.security.Principal;
|
||||||
|
@ -18,10 +16,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import jakarta.transaction.Transactional;
|
import jakarta.transaction.Transactional;
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class UnlinkEmailConfirmationManager {
|
public class UnlinkEmailConfirmationManager {
|
||||||
|
|
|
@ -133,13 +133,6 @@ public class UserManager {
|
||||||
.createOrUpdate(userInfo);
|
.createOrUpdate(userInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PrincipalModel authenticate(AuthenticationService authenticationServiceImpl, Credentials credentials) throws NullEmailException {
|
|
||||||
Principal principal = authenticationServiceImpl.Touch(credentials);
|
|
||||||
if (principal == null) throw new UnauthorisedException("Could not Sign In User");
|
|
||||||
PrincipalModel principalModel = PrincipalModel.fromEntity(principal);
|
|
||||||
return principalModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DataTableData<UserListingModel> getCollaboratorsPaged(UserInfoTableRequestItem userInfoTableRequestItem, Principal principal) throws Exception {
|
public DataTableData<UserListingModel> getCollaboratorsPaged(UserInfoTableRequestItem userInfoTableRequestItem, Principal principal) throws Exception {
|
||||||
UserInfoDao userInfoDao = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao();
|
UserInfoDao userInfoDao = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao();
|
||||||
QueryableList<UserInfo> users = userInfoDao.getWithCriteria(userInfoTableRequestItem.getCriteria());
|
QueryableList<UserInfo> users = userInfoDao.getWithCriteria(userInfoTableRequestItem.getCriteria());
|
||||||
|
@ -154,7 +147,7 @@ public class UserManager {
|
||||||
return dataTableData;
|
return dataTableData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerDOIToken(DOIRequest doiRequest, Principal principal) throws IOException {
|
public void registerDOIToken(DOIRequest doiRequest, Principal principal) throws IOException { //TODO: Authn
|
||||||
ZenodoResponseToken responseToken = this.zenodoCustomProvider.getAccessToken(ZenodoAccessType.AUTHORIZATION_CODE,
|
ZenodoResponseToken responseToken = this.zenodoCustomProvider.getAccessToken(ZenodoAccessType.AUTHORIZATION_CODE,
|
||||||
doiRequest.getZenodoRequest().getCode(), this.environment.getProperty("zenodo.login.client_id"),
|
doiRequest.getZenodoRequest().getCode(), this.environment.getProperty("zenodo.login.client_id"),
|
||||||
this.environment.getProperty("zenodo.login.client_secret"), doiRequest.getRedirectUri());
|
this.environment.getProperty("zenodo.login.client_secret"), doiRequest.getRedirectUri());
|
||||||
|
@ -219,8 +212,9 @@ public class UserManager {
|
||||||
return new UserProfile().fromDataModel(user);
|
return new UserProfile().fromDataModel(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long countActiveUsers(){
|
public Long countActiveUsers(){ //TODO: Authn
|
||||||
return apiContext.getOperationsContext().getDatabaseRepository().getUserTokenDao().asQueryable().where(((builder, root) -> builder.greaterThan(root.get("expiresAt"), new Date()))).count();
|
return 0L;
|
||||||
|
//return apiContext.getOperationsContext().getDatabaseRepository().getUserTokenDao().asQueryable().where(((builder, root) -> builder.greaterThan(root.get("expiresAt"), new Date()))).count();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long countAllUsers(){
|
public Long countAllUsers(){
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
package eu.eudat.logic.security;
|
|
||||||
|
|
||||||
import eu.eudat.exceptions.security.NonValidTokenException;
|
|
||||||
import eu.eudat.exceptions.security.NullEmailException;
|
|
||||||
import eu.eudat.exceptions.security.UnauthorisedException;
|
|
||||||
import eu.eudat.models.data.login.LoginInfo;
|
|
||||||
import eu.eudat.models.data.principal.PrincipalModel;
|
|
||||||
import eu.eudat.models.data.security.Principal;
|
|
||||||
import eu.eudat.logic.security.validators.TokenValidatorFactory;
|
|
||||||
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
|
|
||||||
import net.shibboleth.utilities.java.support.resolver.ResolverException;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.security.GeneralSecurityException;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class CustomAuthenticationProvider {
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(CustomAuthenticationProvider.class);
|
|
||||||
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private TokenValidatorFactory tokenValidatorFactory;
|
|
||||||
|
|
||||||
public PrincipalModel authenticate(LoginInfo credentials) throws GeneralSecurityException, NullEmailException {
|
|
||||||
String token = credentials.getTicket();
|
|
||||||
try {
|
|
||||||
Principal principal = this.tokenValidatorFactory.getProvider(credentials.getProvider()).validateToken(credentials);
|
|
||||||
return (principal != null) ? PrincipalModel.fromEntity(principal) : null;
|
|
||||||
} catch (NonValidTokenException e) {
|
|
||||||
logger.error("Could not validate a user by his token! Reason: " + e.getMessage(), e);
|
|
||||||
throw new UnauthorisedException("Token validation failed - Not a valid token");
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.error(e.getMessage(), e);
|
|
||||||
throw new UnauthorisedException("IO Exeption");
|
|
||||||
} catch (NullEmailException e) {
|
|
||||||
logger.error(e.getMessage(), e);
|
|
||||||
throw new NullEmailException();
|
|
||||||
} catch (ResolverException | ComponentInitializationException e){
|
|
||||||
logger.error(e.getMessage(), e);
|
|
||||||
throw new GeneralSecurityException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package eu.eudat.logic.security.customproviders.B2Access;
|
|
||||||
|
|
||||||
import eu.eudat.logic.security.validators.b2access.helpers.B2AccessResponseToken;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by ikalyvas on 2/22/2018.
|
|
||||||
*/
|
|
||||||
public interface B2AccessCustomProvider {
|
|
||||||
B2AccessUser getUser(String accessToken);
|
|
||||||
|
|
||||||
B2AccessResponseToken getAccessToken(String code, String redirectUri, String clientId, String clientSecret);
|
|
||||||
}
|
|
|
@ -1,76 +0,0 @@
|
||||||
package eu.eudat.logic.security.customproviders.B2Access;
|
|
||||||
|
|
||||||
import eu.eudat.logic.security.validators.b2access.helpers.B2AccessResponseToken;
|
|
||||||
import org.apache.commons.codec.binary.Base64;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
import org.springframework.http.HttpEntity;
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.http.HttpMethod;
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import org.springframework.util.LinkedMultiValueMap;
|
|
||||||
import org.springframework.util.MultiValueMap;
|
|
||||||
import org.springframework.web.client.RestTemplate;
|
|
||||||
|
|
||||||
import java.nio.charset.Charset;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Component("b2AccessCustomProvider")
|
|
||||||
public class B2AccessCustomProviderImpl implements B2AccessCustomProvider {
|
|
||||||
|
|
||||||
private Environment environment;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public B2AccessCustomProviderImpl(Environment environment) {
|
|
||||||
this.environment = environment;
|
|
||||||
}
|
|
||||||
|
|
||||||
public B2AccessUser getUser(String accessToken) {
|
|
||||||
RestTemplate restTemplate = new RestTemplate();
|
|
||||||
HttpHeaders headers = this.createBearerAuthHeaders(accessToken);
|
|
||||||
HttpEntity<String> entity = new HttpEntity<>(headers);
|
|
||||||
|
|
||||||
Map<String, Object> values = restTemplate.exchange(this.environment.getProperty("b2access.externallogin.user_info_url"), HttpMethod.GET, entity, Map.class).getBody();
|
|
||||||
B2AccessUser b2AccessUser = new B2AccessUser();
|
|
||||||
b2AccessUser.setEmail((String)values.get("email"));
|
|
||||||
b2AccessUser.setId((String)values.get("urn:oid:2.5.4.49"));
|
|
||||||
b2AccessUser.setName((String)values.get("name"));
|
|
||||||
return b2AccessUser;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public B2AccessResponseToken getAccessToken(String code, String redirectUri, String clientId, String clientSecret) {
|
|
||||||
RestTemplate template = new RestTemplate();
|
|
||||||
HttpHeaders headers = this.createBasicAuthHeaders(clientId, clientSecret);
|
|
||||||
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
|
|
||||||
|
|
||||||
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
|
|
||||||
map.add("code", code);
|
|
||||||
map.add("grant_type", "authorization_code");
|
|
||||||
map.add("redirect_uri", redirectUri);
|
|
||||||
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);
|
|
||||||
|
|
||||||
Map<String, Object> values = template.postForObject(this.environment.getProperty("b2access.externallogin.access_token_url"), request, Map.class);
|
|
||||||
B2AccessResponseToken b2AccessResponseToken = new B2AccessResponseToken();
|
|
||||||
b2AccessResponseToken.setAccessToken((String) values.get("access_token"));
|
|
||||||
return b2AccessResponseToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
private HttpHeaders createBasicAuthHeaders(String username, String password) {
|
|
||||||
return new HttpHeaders() {{
|
|
||||||
String auth = username + ":" + password;
|
|
||||||
byte[] encodedAuth = Base64.encodeBase64(
|
|
||||||
auth.getBytes(Charset.forName("US-ASCII")));
|
|
||||||
String authHeader = "Basic " + new String(encodedAuth);
|
|
||||||
set("Authorization", authHeader);
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
|
|
||||||
private HttpHeaders createBearerAuthHeaders(String accessToken) {
|
|
||||||
return new HttpHeaders() {{
|
|
||||||
String authHeader = "Bearer " + new String(accessToken);
|
|
||||||
set("Authorization", authHeader);
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
package eu.eudat.logic.security.customproviders.B2Access;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by ikalyvas on 2/22/2018.
|
|
||||||
*/
|
|
||||||
public class B2AccessUser {
|
|
||||||
private String id;
|
|
||||||
private String name;
|
|
||||||
private String email;
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(String id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getEmail() {
|
|
||||||
return email;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEmail(String email) {
|
|
||||||
this.email = email;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
package eu.eudat.logic.security.customproviders.ConfigurableProvider;
|
|
||||||
|
|
||||||
import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.oauth2.Oauth2ConfigurableProviderUserSettings;
|
|
||||||
import eu.eudat.logic.security.validators.configurableProvider.helpers.ConfigurableProviderResponseToken;
|
|
||||||
|
|
||||||
public interface ConfigurableProviderCustomProvider {
|
|
||||||
|
|
||||||
ConfigurableProviderResponseToken getAccessToken(String code, String redirectUri, String clientId, String clientSecret, String accessTokenUrl, String grantType, String access_token, String expires_in);
|
|
||||||
|
|
||||||
ConfigurableProviderUser getUser(String accessToken, Oauth2ConfigurableProviderUserSettings user);
|
|
||||||
}
|
|
|
@ -1,61 +0,0 @@
|
||||||
package eu.eudat.logic.security.customproviders.ConfigurableProvider;
|
|
||||||
|
|
||||||
import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.oauth2.Oauth2ConfigurableProviderUserSettings;
|
|
||||||
import eu.eudat.logic.security.validators.configurableProvider.helpers.ConfigurableProviderResponseToken;
|
|
||||||
import org.springframework.http.HttpEntity;
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.http.HttpMethod;
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import org.springframework.util.LinkedMultiValueMap;
|
|
||||||
import org.springframework.util.MultiValueMap;
|
|
||||||
import org.springframework.web.client.RestTemplate;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Component("configurableProviderCustomProvider")
|
|
||||||
public class ConfigurableProviderCustomProviderImpl implements ConfigurableProviderCustomProvider {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ConfigurableProviderResponseToken getAccessToken(String code, String redirectUri, String clientId, String clientSecret, String accessTokenUrl,
|
|
||||||
String grantType, String access_token, String expires_in) {
|
|
||||||
RestTemplate template = new RestTemplate();
|
|
||||||
HttpHeaders headers = new HttpHeaders();
|
|
||||||
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
|
|
||||||
|
|
||||||
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
|
|
||||||
|
|
||||||
map.add("grant_type", grantType);
|
|
||||||
map.add("code", code);
|
|
||||||
map.add("redirect_uri", redirectUri);
|
|
||||||
map.add("client_id", clientId);
|
|
||||||
map.add("client_secret", clientSecret);
|
|
||||||
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
|
|
||||||
|
|
||||||
Map<String, Object> values = template.postForObject(accessTokenUrl, request, Map.class);
|
|
||||||
ConfigurableProviderResponseToken responseToken = new ConfigurableProviderResponseToken();
|
|
||||||
responseToken.setAccessToken((String) values.get(access_token));
|
|
||||||
if (expires_in != null && !expires_in.isEmpty()) {
|
|
||||||
responseToken.setExpiresIn((Integer) values.get(expires_in));
|
|
||||||
}
|
|
||||||
|
|
||||||
return responseToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ConfigurableProviderUser getUser(String accessToken, Oauth2ConfigurableProviderUserSettings user) {
|
|
||||||
RestTemplate restTemplate = new RestTemplate();
|
|
||||||
HttpHeaders headers = this.createBearerAuthHeaders(accessToken);
|
|
||||||
HttpEntity<String> entity = new HttpEntity<>(headers);
|
|
||||||
|
|
||||||
Map<String, Object> values = restTemplate.exchange(user.getUser_info_url(), HttpMethod.GET, entity, Map.class).getBody();
|
|
||||||
return new ConfigurableProviderUser().getConfigurableProviderUser(values, user);
|
|
||||||
}
|
|
||||||
|
|
||||||
private HttpHeaders createBearerAuthHeaders(String accessToken) {
|
|
||||||
return new HttpHeaders() {{
|
|
||||||
String authHeader = "Bearer " + accessToken;
|
|
||||||
set("Authorization", authHeader);
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
package eu.eudat.logic.security.customproviders.ConfigurableProvider;
|
|
||||||
|
|
||||||
import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.oauth2.Oauth2ConfigurableProviderUserSettings;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class ConfigurableProviderUser {
|
|
||||||
private String id;
|
|
||||||
private String name;
|
|
||||||
private String email;
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
public void setId(String id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getEmail() {
|
|
||||||
return email;
|
|
||||||
}
|
|
||||||
public void setEmail(String email) {
|
|
||||||
this.email = email;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConfigurableProviderUser getConfigurableProviderUser(Map data, Oauth2ConfigurableProviderUserSettings user) {
|
|
||||||
if (user.getId() != null && !user.getId().isEmpty())
|
|
||||||
this.id = (String) data.get(user.getId());
|
|
||||||
if (user.getName() != null && !user.getName().isEmpty())
|
|
||||||
this.name = (String) data.get(user.getName());
|
|
||||||
if (user.getEmail() != null && !user.getEmail().isEmpty())
|
|
||||||
this.email = (String) data.get(user.getEmail());
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
package eu.eudat.logic.security.customproviders.LinkedIn;
|
|
||||||
|
|
||||||
import eu.eudat.logic.security.validators.linkedin.helpers.LinkedInResponseToken;
|
|
||||||
|
|
||||||
public interface LinkedInCustomProvider {
|
|
||||||
|
|
||||||
LinkedInUser getUser(String accessToken);
|
|
||||||
|
|
||||||
LinkedInResponseToken getAccessToken(String code, String redirectUri, String clientId, String clientSecret);
|
|
||||||
}
|
|
|
@ -1,67 +0,0 @@
|
||||||
package eu.eudat.logic.security.customproviders.LinkedIn;
|
|
||||||
|
|
||||||
import eu.eudat.logic.security.validators.linkedin.helpers.LinkedInResponseToken;
|
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
import org.springframework.http.HttpEntity;
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.http.HttpMethod;
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import org.springframework.util.LinkedMultiValueMap;
|
|
||||||
import org.springframework.util.MultiValueMap;
|
|
||||||
import org.springframework.web.client.RestTemplate;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Component("LinkedInCustomProvider")
|
|
||||||
public class LinkedInCustomProviderImpl implements LinkedInCustomProvider {
|
|
||||||
|
|
||||||
private Environment environment;
|
|
||||||
|
|
||||||
public LinkedInCustomProviderImpl(Environment environment) {
|
|
||||||
this.environment = environment;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LinkedInUser getUser(String accessToken) {
|
|
||||||
RestTemplate restTemplate = new RestTemplate();
|
|
||||||
HttpHeaders headers = this.createBearerAuthHeaders(accessToken);
|
|
||||||
HttpEntity<String> entity = new HttpEntity<>(headers);
|
|
||||||
|
|
||||||
Map profileValues = restTemplate.exchange(this.environment.getProperty("linkedin.login.user_info_url"), HttpMethod.GET, entity, Map.class).getBody();
|
|
||||||
Map emailValues = restTemplate.exchange(this.environment.getProperty("linkedin.login.user_email"), HttpMethod.GET, entity, Map.class).getBody();
|
|
||||||
LinkedInUser linkedInUser = new LinkedInUser();
|
|
||||||
linkedInUser.setEmail((String)emailValues.get("email"));
|
|
||||||
linkedInUser.setName((String)profileValues.get("localizedFirstName"));
|
|
||||||
linkedInUser.setId((String)profileValues.get("id"));
|
|
||||||
return linkedInUser;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LinkedInResponseToken getAccessToken(String code, String redirectUri, String clientId, String clientSecret) {
|
|
||||||
RestTemplate template = new RestTemplate();
|
|
||||||
HttpHeaders headers = new HttpHeaders();
|
|
||||||
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
|
|
||||||
|
|
||||||
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
|
|
||||||
|
|
||||||
map.add("grant_type", "authorization_code");
|
|
||||||
map.add("code", code);
|
|
||||||
map.add("redirect_uri", redirectUri);
|
|
||||||
map.add("client_id", clientId);
|
|
||||||
map.add("client_secret", clientSecret);
|
|
||||||
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);
|
|
||||||
|
|
||||||
Map<String, Object> values = template.postForObject(this.environment.getProperty("linkedin.login.access_token_url"), request, Map.class);
|
|
||||||
LinkedInResponseToken linkedInResponseToken = new LinkedInResponseToken();
|
|
||||||
linkedInResponseToken.setAccessToken((String) values.get("access_token"));
|
|
||||||
linkedInResponseToken.setExpiresIn((Integer) values.get("expires_in"));
|
|
||||||
|
|
||||||
return linkedInResponseToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
private HttpHeaders createBearerAuthHeaders(String accessToken) {
|
|
||||||
return new HttpHeaders() {{
|
|
||||||
String authHeader = "Bearer " + new String(accessToken);
|
|
||||||
set("Authorization", authHeader);
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
package eu.eudat.logic.security.customproviders.LinkedIn;
|
|
||||||
|
|
||||||
public class LinkedInUser {
|
|
||||||
private String id;
|
|
||||||
private String name;
|
|
||||||
private String email;
|
|
||||||
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
public void setId(String id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getEmail() {
|
|
||||||
return email;
|
|
||||||
}
|
|
||||||
public void setEmail(String email) {
|
|
||||||
this.email = email;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
package eu.eudat.logic.security.customproviders.ORCID;
|
|
||||||
|
|
||||||
import eu.eudat.logic.security.validators.orcid.helpers.ORCIDResponseToken;
|
|
||||||
|
|
||||||
public interface ORCIDCustomProvider {
|
|
||||||
ORCIDResponseToken getAccessToken(String code, String redirectUri, String clientId, String clientSecret);
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
package eu.eudat.logic.security.customproviders.ORCID;
|
|
||||||
|
|
||||||
import eu.eudat.logic.security.validators.orcid.helpers.ORCIDResponseToken;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
import org.springframework.http.HttpEntity;
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import org.springframework.util.LinkedMultiValueMap;
|
|
||||||
import org.springframework.util.MultiValueMap;
|
|
||||||
import org.springframework.web.client.RestTemplate;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Component("ORCIDCustomProvider")
|
|
||||||
public class ORCIDCustomProviderImpl implements ORCIDCustomProvider {
|
|
||||||
|
|
||||||
private Environment environment;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public ORCIDCustomProviderImpl(Environment environment) {
|
|
||||||
this.environment = environment;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ORCIDResponseToken getAccessToken(String code, String redirectUri, String clientId, String clientSecret) {
|
|
||||||
RestTemplate restTemplate = new RestTemplate();
|
|
||||||
HttpHeaders headers = new HttpHeaders();
|
|
||||||
headers.set("accept", "application/json");
|
|
||||||
|
|
||||||
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
|
|
||||||
map.add("client_id", this.environment.getProperty("orcid.login.client_id"));
|
|
||||||
map.add("client_secret", this.environment.getProperty("orcid.login.client_secret"));
|
|
||||||
map.add("grant_type", "authorization_code");
|
|
||||||
map.add("code", code);
|
|
||||||
map.add("redirect_uri", redirectUri);
|
|
||||||
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);
|
|
||||||
|
|
||||||
Map<String, Object> values = restTemplate.postForObject(this.environment.getProperty("orcid.login.access_token_url"), request, Map.class);
|
|
||||||
ORCIDResponseToken orcidResponseToken = new ORCIDResponseToken();
|
|
||||||
orcidResponseToken.setOrcidId((String) values.get("orcid"));
|
|
||||||
orcidResponseToken.setName((String) values.get("name"));
|
|
||||||
orcidResponseToken.setAccessToken((String) values.get("access_token"));
|
|
||||||
|
|
||||||
return orcidResponseToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
private HttpHeaders createBearerAuthHeaders(String accessToken) {
|
|
||||||
return new HttpHeaders() {{
|
|
||||||
String authHeader = "Bearer " + accessToken;
|
|
||||||
set("Authorization", authHeader);
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
package eu.eudat.logic.security.customproviders.ORCID;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class ORCIDUser {
|
|
||||||
private String orcidId;
|
|
||||||
private String name;
|
|
||||||
private String email;
|
|
||||||
|
|
||||||
public String getOrcidId() {
|
|
||||||
return orcidId;
|
|
||||||
}
|
|
||||||
public void setOrcidId(String orcidId) {
|
|
||||||
this.orcidId = orcidId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getEmail() {
|
|
||||||
return email;
|
|
||||||
}
|
|
||||||
public void setEmail(String email) {
|
|
||||||
this.email = email;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public ORCIDUser getOrcidUser(Object data) {
|
|
||||||
this.orcidId = (String) ((Map) data).get("orcidId");
|
|
||||||
this.name = (String) ((Map) data).get("name");
|
|
||||||
this.email = (String) ((Map) data).get("email");
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
package eu.eudat.logic.security.customproviders.OpenAIRE;
|
|
||||||
|
|
||||||
import eu.eudat.logic.security.validators.openaire.helpers.OpenAIREResponseToken;
|
|
||||||
|
|
||||||
public interface OpenAIRECustomProvider {
|
|
||||||
|
|
||||||
OpenAIREResponseToken getAccessToken(String code, String redirectUri, String clientId, String clientSecret);
|
|
||||||
|
|
||||||
OpenAIREUser getUser(String accessToken);
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
package eu.eudat.logic.security.customproviders.OpenAIRE;
|
|
||||||
|
|
||||||
import eu.eudat.logic.security.validators.openaire.helpers.OpenAIREResponseToken;
|
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
import org.springframework.http.HttpEntity;
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.http.HttpMethod;
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import org.springframework.util.LinkedMultiValueMap;
|
|
||||||
import org.springframework.util.MultiValueMap;
|
|
||||||
import org.springframework.web.client.RestTemplate;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Component("openAIRECustomProvider")
|
|
||||||
public class OpenAIRECustomProviderImpl implements OpenAIRECustomProvider {
|
|
||||||
|
|
||||||
private Environment environment;
|
|
||||||
|
|
||||||
public OpenAIRECustomProviderImpl(Environment environment) {
|
|
||||||
this.environment = environment;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OpenAIREUser getUser(String accessToken) {
|
|
||||||
RestTemplate restTemplate = new RestTemplate();
|
|
||||||
HttpHeaders headers = this.createBearerAuthHeaders(accessToken);
|
|
||||||
HttpEntity<String> entity = new HttpEntity<>(headers);
|
|
||||||
|
|
||||||
Map<String, Object> values = restTemplate.exchange(this.environment.getProperty("openaire.login.user_info_url"), HttpMethod.GET, entity, Map.class).getBody();
|
|
||||||
return new OpenAIREUser().getOpenAIREUser(values);
|
|
||||||
}
|
|
||||||
|
|
||||||
public OpenAIREResponseToken getAccessToken(String code, String redirectUri, String clientId, String clientSecret) {
|
|
||||||
RestTemplate template = new RestTemplate();
|
|
||||||
HttpHeaders headers = new HttpHeaders();
|
|
||||||
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
|
|
||||||
|
|
||||||
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
|
|
||||||
|
|
||||||
map.add("grant_type", "authorization_code");
|
|
||||||
map.add("code", code);
|
|
||||||
map.add("redirect_uri", redirectUri);
|
|
||||||
map.add("client_id", clientId);
|
|
||||||
map.add("client_secret", clientSecret);
|
|
||||||
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);
|
|
||||||
|
|
||||||
Map<String, Object> values = template.postForObject(this.environment.getProperty("openaire.login.access_token_url"), request, Map.class);
|
|
||||||
OpenAIREResponseToken openAIREResponseToken = new OpenAIREResponseToken();
|
|
||||||
openAIREResponseToken.setAccessToken((String) values.get("access_token"));
|
|
||||||
openAIREResponseToken.setExpiresIn((Integer) values.get("expires_in"));
|
|
||||||
|
|
||||||
return openAIREResponseToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
private HttpHeaders createBearerAuthHeaders(String accessToken) {
|
|
||||||
return new HttpHeaders() {{
|
|
||||||
String authHeader = "Bearer " + accessToken;
|
|
||||||
set("Authorization", authHeader);
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
package eu.eudat.logic.security.customproviders.OpenAIRE;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class OpenAIREUser {
|
|
||||||
private String id;
|
|
||||||
private String name;
|
|
||||||
private String email;
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
public void setId(String id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getEmail() {
|
|
||||||
return email;
|
|
||||||
}
|
|
||||||
public void setEmail(String email) {
|
|
||||||
this.email = email;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OpenAIREUser getOpenAIREUser(Object data) {
|
|
||||||
this.id = (String) ((Map) data).get("sub");
|
|
||||||
this.name = (String) ((Map) data).get("name");
|
|
||||||
this.email = (String) ((Map) data).get("email");
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,5 @@
|
||||||
package eu.eudat.logic.security.customproviders.Zenodo;
|
package eu.eudat.logic.security.customproviders.Zenodo;
|
||||||
|
|
||||||
import eu.eudat.logic.security.validators.orcid.helpers.ORCIDResponseToken;
|
|
||||||
import eu.eudat.logic.security.validators.zenodo.helpers.ZenodoResponseToken;
|
import eu.eudat.logic.security.validators.zenodo.helpers.ZenodoResponseToken;
|
||||||
|
|
||||||
public interface ZenodoCustomProvider {
|
public interface ZenodoCustomProvider {
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package eu.eudat.logic.security.customproviders.Zenodo;
|
package eu.eudat.logic.security.customproviders.Zenodo;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import eu.eudat.logic.security.validators.orcid.helpers.ORCIDResponseToken;
|
|
||||||
import eu.eudat.logic.security.validators.zenodo.helpers.ZenodoResponseToken;
|
import eu.eudat.logic.security.validators.zenodo.helpers.ZenodoResponseToken;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
package eu.eudat.logic.security.validators;
|
|
||||||
|
|
||||||
import eu.eudat.exceptions.security.NonValidTokenException;
|
|
||||||
import eu.eudat.exceptions.security.NullEmailException;
|
|
||||||
import eu.eudat.models.data.login.LoginInfo;
|
|
||||||
import eu.eudat.models.data.security.Principal;
|
|
||||||
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
|
|
||||||
import net.shibboleth.utilities.java.support.resolver.ResolverException;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.security.GeneralSecurityException;
|
|
||||||
|
|
||||||
public interface TokenValidator {
|
|
||||||
|
|
||||||
Principal validateToken(LoginInfo credentials) throws NonValidTokenException, IOException, GeneralSecurityException, NullEmailException, ResolverException, ComponentInitializationException;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
package eu.eudat.logic.security.validators;
|
|
||||||
|
|
||||||
|
|
||||||
public interface TokenValidatorFactory {
|
|
||||||
TokenValidator getProvider(TokenValidatorFactoryImpl.LoginProvider provider);
|
|
||||||
}
|
|
|
@ -1,120 +0,0 @@
|
||||||
package eu.eudat.logic.security.validators;
|
|
||||||
|
|
||||||
import eu.eudat.logic.proxy.config.configloaders.ConfigLoader;
|
|
||||||
import eu.eudat.logic.security.customproviders.B2Access.B2AccessCustomProvider;
|
|
||||||
import eu.eudat.logic.security.customproviders.ConfigurableProvider.ConfigurableProviderCustomProvider;
|
|
||||||
import eu.eudat.logic.security.customproviders.LinkedIn.LinkedInCustomProvider;
|
|
||||||
import eu.eudat.logic.security.customproviders.ORCID.ORCIDCustomProvider;
|
|
||||||
import eu.eudat.logic.security.customproviders.OpenAIRE.OpenAIRECustomProvider;
|
|
||||||
import eu.eudat.logic.security.customproviders.Zenodo.ZenodoCustomProvider;
|
|
||||||
import eu.eudat.logic.security.validators.b2access.B2AccessTokenValidator;
|
|
||||||
import eu.eudat.logic.security.validators.configurableProvider.ConfigurableProviderTokenValidator;
|
|
||||||
import eu.eudat.logic.security.validators.facebook.FacebookTokenValidator;
|
|
||||||
import eu.eudat.logic.security.validators.google.GoogleTokenValidator;
|
|
||||||
import eu.eudat.logic.security.validators.linkedin.LinkedInTokenValidator;
|
|
||||||
import eu.eudat.logic.security.validators.openaire.OpenAIRETokenValidator;
|
|
||||||
import eu.eudat.logic.security.validators.orcid.ORCIDTokenValidator;
|
|
||||||
import eu.eudat.logic.security.validators.twitter.TwitterTokenValidator;
|
|
||||||
import eu.eudat.logic.security.validators.zenodo.ZenodoTokenValidator;
|
|
||||||
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
|
|
||||||
@Service("tokenValidatorFactory")
|
|
||||||
public class TokenValidatorFactoryImpl implements TokenValidatorFactory {
|
|
||||||
public enum LoginProvider {
|
|
||||||
GOOGLE(1), FACEBOOK(2), TWITTER(3), LINKEDIN(4), NATIVELOGIN(5), B2_ACCESS(6), ORCID(7), OPENAIRE(8), CONFIGURABLE(9), ZENODO(10);
|
|
||||||
|
|
||||||
private int value;
|
|
||||||
|
|
||||||
private LoginProvider(int value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LoginProvider fromInteger(int value) {
|
|
||||||
switch (value) {
|
|
||||||
case 1:
|
|
||||||
return GOOGLE;
|
|
||||||
case 2:
|
|
||||||
return FACEBOOK;
|
|
||||||
case 3:
|
|
||||||
return TWITTER;
|
|
||||||
case 4:
|
|
||||||
return LINKEDIN;
|
|
||||||
case 5:
|
|
||||||
return NATIVELOGIN;
|
|
||||||
case 6:
|
|
||||||
return B2_ACCESS;
|
|
||||||
case 7:
|
|
||||||
return ORCID;
|
|
||||||
case 8:
|
|
||||||
return OPENAIRE;
|
|
||||||
case 9:
|
|
||||||
return CONFIGURABLE;
|
|
||||||
case 10:
|
|
||||||
return ZENODO;
|
|
||||||
default:
|
|
||||||
throw new RuntimeException("Unsupported LoginProvider");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Environment environment;
|
|
||||||
private AuthenticationService nonVerifiedUserAuthenticationService;
|
|
||||||
private B2AccessCustomProvider b2AccessCustomProvider;
|
|
||||||
private ORCIDCustomProvider orcidCustomProvider;
|
|
||||||
private LinkedInCustomProvider linkedInCustomProvider;
|
|
||||||
private OpenAIRECustomProvider openAIRECustomProvider;
|
|
||||||
private ConfigurableProviderCustomProvider configurableProviderCustomProvider;
|
|
||||||
private ConfigLoader configLoader;
|
|
||||||
private ZenodoCustomProvider zenodoCustomProvider;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public TokenValidatorFactoryImpl(
|
|
||||||
Environment environment,
|
|
||||||
AuthenticationService nonVerifiedUserAuthenticationService, B2AccessCustomProvider b2AccessCustomProvider,
|
|
||||||
ORCIDCustomProvider orcidCustomProvider, LinkedInCustomProvider linkedInCustomProvider, OpenAIRECustomProvider openAIRECustomProvider,
|
|
||||||
ConfigurableProviderCustomProvider configurableProviderCustomProvider, ConfigLoader configLoader,
|
|
||||||
ZenodoCustomProvider zenodoCustomProvider) {
|
|
||||||
this.environment = environment;
|
|
||||||
this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService;
|
|
||||||
this.b2AccessCustomProvider = b2AccessCustomProvider;
|
|
||||||
this.orcidCustomProvider = orcidCustomProvider;
|
|
||||||
this.linkedInCustomProvider = linkedInCustomProvider;
|
|
||||||
this.openAIRECustomProvider = openAIRECustomProvider;
|
|
||||||
this.configurableProviderCustomProvider = configurableProviderCustomProvider;
|
|
||||||
this.configLoader = configLoader;
|
|
||||||
this.zenodoCustomProvider = zenodoCustomProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TokenValidator getProvider(LoginProvider provider) {
|
|
||||||
switch (provider) {
|
|
||||||
case GOOGLE:
|
|
||||||
return new GoogleTokenValidator(this.environment, this.nonVerifiedUserAuthenticationService);
|
|
||||||
case FACEBOOK:
|
|
||||||
return new FacebookTokenValidator(this.environment, this.nonVerifiedUserAuthenticationService);
|
|
||||||
case LINKEDIN:
|
|
||||||
return new LinkedInTokenValidator(this.environment, this.nonVerifiedUserAuthenticationService, linkedInCustomProvider);
|
|
||||||
case TWITTER:
|
|
||||||
return new TwitterTokenValidator(this.environment, this.nonVerifiedUserAuthenticationService);
|
|
||||||
case B2_ACCESS:
|
|
||||||
return new B2AccessTokenValidator(this.environment, this.nonVerifiedUserAuthenticationService, this.b2AccessCustomProvider);
|
|
||||||
case ORCID:
|
|
||||||
return new ORCIDTokenValidator(this.environment, this.nonVerifiedUserAuthenticationService, this.orcidCustomProvider);
|
|
||||||
case OPENAIRE:
|
|
||||||
return new OpenAIRETokenValidator(this.environment, this.nonVerifiedUserAuthenticationService, this.openAIRECustomProvider);
|
|
||||||
case CONFIGURABLE:
|
|
||||||
return new ConfigurableProviderTokenValidator(this.configurableProviderCustomProvider, this.nonVerifiedUserAuthenticationService, this.configLoader);
|
|
||||||
case ZENODO:
|
|
||||||
return new ZenodoTokenValidator(this.environment, this.nonVerifiedUserAuthenticationService, this.zenodoCustomProvider);
|
|
||||||
default:
|
|
||||||
throw new RuntimeException("Login Provider Not Implemented");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
package eu.eudat.logic.security.validators.b2access;
|
|
||||||
|
|
||||||
import eu.eudat.exceptions.security.NonValidTokenException;
|
|
||||||
import eu.eudat.exceptions.security.NullEmailException;
|
|
||||||
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
|
|
||||||
import eu.eudat.models.data.login.LoginInfo;
|
|
||||||
import eu.eudat.models.data.loginprovider.LoginProviderUser;
|
|
||||||
import eu.eudat.models.data.security.Principal;
|
|
||||||
import eu.eudat.logic.security.customproviders.B2Access.B2AccessCustomProvider;
|
|
||||||
import eu.eudat.logic.security.customproviders.B2Access.B2AccessUser;
|
|
||||||
import eu.eudat.logic.security.validators.TokenValidator;
|
|
||||||
import eu.eudat.logic.security.validators.b2access.helpers.B2AccessRequest;
|
|
||||||
import eu.eudat.logic.security.validators.b2access.helpers.B2AccessResponseToken;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.security.GeneralSecurityException;
|
|
||||||
|
|
||||||
@Component("b2AccessTokenValidator ")
|
|
||||||
public class B2AccessTokenValidator implements TokenValidator {
|
|
||||||
|
|
||||||
private B2AccessCustomProvider b2AccessCustomProvider;
|
|
||||||
private AuthenticationService nonVerifiedUserAuthenticationService;
|
|
||||||
private Environment environment;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public B2AccessTokenValidator(Environment environment, AuthenticationService nonVerifiedUserAuthenticationService, B2AccessCustomProvider b2AccessCustomProvider) {
|
|
||||||
this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService;
|
|
||||||
this.environment = environment;
|
|
||||||
this.b2AccessCustomProvider = b2AccessCustomProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Principal validateToken(LoginInfo credentials) throws NonValidTokenException, IOException, GeneralSecurityException, NullEmailException {
|
|
||||||
B2AccessUser b2AccessUser = this.b2AccessCustomProvider.getUser(credentials.getTicket());
|
|
||||||
LoginProviderUser user = new LoginProviderUser();
|
|
||||||
user.setId(b2AccessUser.getId());
|
|
||||||
user.setEmail(b2AccessUser.getEmail());
|
|
||||||
user.setName(b2AccessUser.getName());
|
|
||||||
user.setProvider(credentials.getProvider());
|
|
||||||
user.setSecret(credentials.getTicket());
|
|
||||||
return this.nonVerifiedUserAuthenticationService.Touch(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
public B2AccessResponseToken getAccessToken(B2AccessRequest b2AccessRequest) {
|
|
||||||
return this.b2AccessCustomProvider.getAccessToken(b2AccessRequest.getCode(), this.environment.getProperty("b2access.externallogin.redirect_uri")
|
|
||||||
, this.environment.getProperty("b2access.externallogin.clientid")
|
|
||||||
, this.environment.getProperty("b2access.externallogin.clientSecret"));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
package eu.eudat.logic.security.validators.b2access.helpers;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by ikalyvas on 2/22/2018.
|
|
||||||
*/
|
|
||||||
public class B2AccessRequest {
|
|
||||||
private String code;
|
|
||||||
|
|
||||||
public String getCode() {
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCode(String code) {
|
|
||||||
this.code = code;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
package eu.eudat.logic.security.validators.b2access.helpers;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by ikalyvas on 2/22/2018.
|
|
||||||
*/
|
|
||||||
public class B2AccessResponseToken {
|
|
||||||
private String accessToken;
|
|
||||||
|
|
||||||
public String getAccessToken() {
|
|
||||||
return accessToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAccessToken(String accessToken) {
|
|
||||||
this.accessToken = accessToken;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,139 +0,0 @@
|
||||||
package eu.eudat.logic.security.validators.configurableProvider;
|
|
||||||
|
|
||||||
import eu.eudat.exceptions.security.NullEmailException;
|
|
||||||
import eu.eudat.logic.proxy.config.configloaders.ConfigLoader;
|
|
||||||
|
|
||||||
import eu.eudat.logic.security.customproviders.ConfigurableProvider.ConfigurableProviderCustomProvider;
|
|
||||||
import eu.eudat.logic.security.customproviders.ConfigurableProvider.ConfigurableProviderUser;
|
|
||||||
import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProvider;
|
|
||||||
import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.oauth2.Oauth2ConfigurableProvider;
|
|
||||||
import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.saml2.Saml2ConfigurableProvider;
|
|
||||||
import eu.eudat.logic.security.validators.TokenValidator;
|
|
||||||
import eu.eudat.logic.security.validators.configurableProvider.helpers.ConfigurableProviderRequest;
|
|
||||||
import eu.eudat.logic.security.validators.configurableProvider.helpers.ConfigurableProviderResponseToken;
|
|
||||||
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
|
|
||||||
import eu.eudat.models.data.login.LoginInfo;
|
|
||||||
import eu.eudat.models.data.loginprovider.LoginProviderUser;
|
|
||||||
import eu.eudat.models.data.security.Principal;
|
|
||||||
|
|
||||||
import org.opensaml.saml.saml2.core.*;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Component("configurableProviderTokenValidator")
|
|
||||||
public class ConfigurableProviderTokenValidator implements TokenValidator {
|
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(ConfigurableProviderTokenValidator.class);
|
|
||||||
|
|
||||||
private ConfigurableProviderCustomProvider configurableProvider;
|
|
||||||
private AuthenticationService nonVerifiedUserAuthenticationService;
|
|
||||||
private ConfigLoader configLoader;
|
|
||||||
|
|
||||||
public ConfigurableProviderTokenValidator(ConfigurableProviderCustomProvider configurableProvider, AuthenticationService nonVerifiedUserAuthenticationService, ConfigLoader configLoader) {
|
|
||||||
this.configurableProvider = configurableProvider;
|
|
||||||
this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService;
|
|
||||||
this.configLoader = configLoader;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConfigurableProviderResponseToken getAccessToken(ConfigurableProviderRequest configurableProviderRequest) {
|
|
||||||
Oauth2ConfigurableProvider provider = (Oauth2ConfigurableProvider)getConfigurableProviderFromId(configurableProviderRequest.getConfigurableLoginId());
|
|
||||||
return this.configurableProvider.getAccessToken(configurableProviderRequest.getCode(),
|
|
||||||
provider.getRedirect_uri(), provider.getClientId(), provider.getClientSecret(),
|
|
||||||
provider.getAccess_token_url(), provider.getGrant_type(), provider.getToken().getAccess_token(), provider.getToken().getExpires_in());
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public Principal validateToken(LoginInfo credentials) throws NullEmailException {
|
|
||||||
String configurableLoginId = ((Map) credentials.getData()).get("configurableLoginId").toString();
|
|
||||||
ConfigurableProvider configurableProvider = getConfigurableProviderFromId(configurableLoginId);
|
|
||||||
|
|
||||||
LoginProviderUser user = new LoginProviderUser();
|
|
||||||
if (configurableProvider.getType().equals("oauth2")) {
|
|
||||||
ConfigurableProviderUser configurableUser = this.configurableProvider.getUser(credentials.getTicket(), ((Oauth2ConfigurableProvider)configurableProvider).getUser());
|
|
||||||
user.setId(configurableUser.getId());
|
|
||||||
user.setEmail(configurableUser.getEmail());
|
|
||||||
user.setName(configurableUser.getName());
|
|
||||||
user.setProvider(credentials.getProvider());
|
|
||||||
user.setSecret(credentials.getTicket());
|
|
||||||
return this.nonVerifiedUserAuthenticationService.Touch(user);
|
|
||||||
}
|
|
||||||
else if (configurableProvider.getType().equals("saml2")) {
|
|
||||||
|
|
||||||
Assertion saml2Assertion = null;
|
|
||||||
try {
|
|
||||||
Saml2ConfigurableProvider saml2Provider = (Saml2ConfigurableProvider)configurableProvider;
|
|
||||||
if(saml2Provider.getBinding().equals("Redirect") || saml2Provider.getBinding().equals("Post"))
|
|
||||||
saml2Assertion = Saml2SSOUtils.processResponse(credentials.getTicket(), saml2Provider);
|
|
||||||
else if(saml2Provider.getBinding().equals("Artifact"))
|
|
||||||
saml2Assertion = Saml2SSOUtils.processArtifactResponse(credentials.getTicket(), saml2Provider);
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(saml2Assertion == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
List<AttributeStatement> attributeStatements = saml2Assertion.getAttributeStatements();
|
|
||||||
if(attributeStatements != null && !attributeStatements.isEmpty()){
|
|
||||||
|
|
||||||
List<Attribute> attributes = attributeStatements.get(0).getAttributes();
|
|
||||||
if(attributes != null && !attributes.isEmpty()){
|
|
||||||
|
|
||||||
Saml2ConfigurableProvider.SAML2UsingFormat usingFormat = ((Saml2ConfigurableProvider)configurableProvider).getUsingFormat();
|
|
||||||
Map<String, String> attributeMapping = ((Saml2ConfigurableProvider)configurableProvider).getConfigurableUserFromAttributes();
|
|
||||||
Map<String, Saml2ConfigurableProvider.SAML2AttributeType> attributeType = ((Saml2ConfigurableProvider)configurableProvider).getAttributeTypes();
|
|
||||||
Map<String, Object> saml2User = new HashMap<>();
|
|
||||||
for(Attribute attribute: attributes){
|
|
||||||
|
|
||||||
String attributeName = Saml2SSOUtils.getAttributeName(attribute, usingFormat);
|
|
||||||
if(attributeName != null && attributeMapping.containsValue(attributeName)){
|
|
||||||
|
|
||||||
Saml2ConfigurableProvider.SAML2AttributeType attrType = attributeType.get(attributeName);
|
|
||||||
if(attribute.getAttributeValues() != null && !attribute.getAttributeValues().isEmpty() && attrType != null){
|
|
||||||
Object attributeValue = Saml2SSOUtils.getAttributeType(attribute.getAttributeValues().get(0), attrType);
|
|
||||||
if(attributeValue != null) {
|
|
||||||
saml2User.put(attributeName, attributeValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
try{
|
|
||||||
String subjectNameId = saml2Assertion.getSubject().getNameID().getValue();
|
|
||||||
String userId = configurableLoginId + ": " + subjectNameId;
|
|
||||||
user.setId(userId);
|
|
||||||
} catch(NullPointerException e){
|
|
||||||
logger.error("Could not get Subject NameID value of assertion");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
user.setEmail((String)saml2User.get(attributeMapping.get("email")));
|
|
||||||
user.setName((String)saml2User.get(attributeMapping.get("name")));
|
|
||||||
user.setProvider(credentials.getProvider());
|
|
||||||
user.setSecret(credentials.getTicket());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return this.nonVerifiedUserAuthenticationService.Touch(user);
|
|
||||||
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ConfigurableProvider getConfigurableProviderFromId(String configurableId) {
|
|
||||||
return this.configLoader.getConfigurableProviders().getProviders().stream()
|
|
||||||
.filter(prov -> prov.getConfigurableLoginId().equals(configurableId))
|
|
||||||
.collect(Collectors.toList())
|
|
||||||
.get(0);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
package eu.eudat.logic.security.validators.configurableProvider.helpers;
|
|
||||||
|
|
||||||
public class ConfigurableProviderRequest {
|
|
||||||
private String code;
|
|
||||||
private String configurableLoginId;
|
|
||||||
|
|
||||||
public String getCode() {
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
public void setCode(String code) {
|
|
||||||
this.code = code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getConfigurableLoginId() {
|
|
||||||
return configurableLoginId;
|
|
||||||
}
|
|
||||||
public void setConfigurableLoginId(String configurableLoginId) {
|
|
||||||
this.configurableLoginId = configurableLoginId;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
package eu.eudat.logic.security.validators.configurableProvider.helpers;
|
|
||||||
|
|
||||||
public class ConfigurableProviderResponseToken {
|
|
||||||
private String accessToken;
|
|
||||||
private Integer expiresIn;
|
|
||||||
|
|
||||||
public String getAccessToken() {
|
|
||||||
return accessToken;
|
|
||||||
}
|
|
||||||
public void setAccessToken(String accessToken) {
|
|
||||||
this.accessToken = accessToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getExpiresIn() {
|
|
||||||
return expiresIn;
|
|
||||||
}
|
|
||||||
public void setExpiresIn(Integer expiresIn) {
|
|
||||||
this.expiresIn = expiresIn;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
package eu.eudat.logic.security.validators.facebook;
|
|
||||||
|
|
||||||
import eu.eudat.exceptions.security.UnauthorisedException;
|
|
||||||
import eu.eudat.logic.security.validators.TokenValidator;
|
|
||||||
import eu.eudat.logic.security.validators.TokenValidatorFactoryImpl;
|
|
||||||
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
|
|
||||||
import eu.eudat.models.data.login.LoginInfo;
|
|
||||||
import eu.eudat.models.data.loginprovider.LoginProviderUser;
|
|
||||||
import eu.eudat.models.data.security.Principal;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
import org.springframework.social.facebook.api.User;
|
|
||||||
import org.springframework.social.facebook.connect.FacebookServiceProvider;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
|
|
||||||
@Component("facebookTokenValidator")
|
|
||||||
public class FacebookTokenValidator implements TokenValidator {
|
|
||||||
|
|
||||||
private AuthenticationService nonVerifiedUserAuthenticationService;
|
|
||||||
private FacebookServiceProvider facebookServiceProvider;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public FacebookTokenValidator(Environment environment, AuthenticationService nonVerifiedUserAuthenticationService) {
|
|
||||||
this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService;
|
|
||||||
this.facebookServiceProvider = new FacebookServiceProvider(environment.getProperty("facebook.login.clientId"), environment.getProperty("facebook.login.clientSecret"), environment.getProperty("facebook.login.namespace"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Principal validateToken(LoginInfo credentials) {
|
|
||||||
User profile = getFacebookUser(credentials.getTicket());
|
|
||||||
LoginProviderUser user = new LoginProviderUser();
|
|
||||||
if (profile.getEmail() == null)
|
|
||||||
throw new UnauthorisedException("Cannot login user.Facebook account did not provide email");
|
|
||||||
|
|
||||||
user.setEmail(profile.getEmail());
|
|
||||||
user.setId(profile.getId());
|
|
||||||
//user.setIsVerified(profile.isVerified());
|
|
||||||
user.setName(profile.getName());
|
|
||||||
user.setProvider(TokenValidatorFactoryImpl.LoginProvider.FACEBOOK);
|
|
||||||
String url = (String) ((Map<String, Object>) ((Map<String, Object>) profile.getExtraData().get("picture")).get("data")).get("url");
|
|
||||||
user.setAvatarUrl(url);
|
|
||||||
user.setSecret(credentials.getTicket());
|
|
||||||
return this.nonVerifiedUserAuthenticationService.Touch(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private User getFacebookUser(String accessToken) {
|
|
||||||
String[] fields = {"id", "email", "first_name", "last_name", "name", "verified", "picture"};
|
|
||||||
return this.facebookServiceProvider.getApi(accessToken).fetchObject("me", User.class, fields);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,55 +0,0 @@
|
||||||
package eu.eudat.logic.security.validators.google;
|
|
||||||
|
|
||||||
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
|
|
||||||
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload;
|
|
||||||
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
|
|
||||||
import com.google.api.client.http.HttpTransport;
|
|
||||||
import com.google.api.client.http.javanet.NetHttpTransport;
|
|
||||||
import com.google.api.client.json.gson.GsonFactory;
|
|
||||||
import eu.eudat.logic.security.validators.TokenValidator;
|
|
||||||
import eu.eudat.logic.security.validators.TokenValidatorFactoryImpl;
|
|
||||||
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
|
|
||||||
import eu.eudat.models.data.login.LoginInfo;
|
|
||||||
import eu.eudat.models.data.loginprovider.LoginProviderUser;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.security.GeneralSecurityException;
|
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
@Component("googleTokenValidator")
|
|
||||||
public class GoogleTokenValidator implements TokenValidator {
|
|
||||||
|
|
||||||
private static final HttpTransport transport = new NetHttpTransport();
|
|
||||||
private AuthenticationService nonVerifiedUserAuthenticationService;
|
|
||||||
private GoogleIdTokenVerifier verifier;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public GoogleTokenValidator(Environment environment, AuthenticationService nonVerifiedUserAuthenticationService) {
|
|
||||||
this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService;
|
|
||||||
verifier = new GoogleIdTokenVerifier.Builder(transport, GsonFactory.getDefaultInstance())
|
|
||||||
.setAudience(Collections.singletonList(environment.getProperty("google.login.clientId")))
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
private GoogleIdToken verifyUserAndGetUser(String idTokenString) throws IOException, GeneralSecurityException {
|
|
||||||
return verifier.verify(idTokenString);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public eu.eudat.models.data.security.Principal validateToken(LoginInfo credentials) throws IOException, GeneralSecurityException {
|
|
||||||
GoogleIdToken idToken = this.verifyUserAndGetUser(credentials.getTicket());
|
|
||||||
Payload payload = idToken.getPayload();
|
|
||||||
LoginProviderUser user = new LoginProviderUser();
|
|
||||||
user.setAvatarUrl((String) payload.get("picture"));
|
|
||||||
user.setSecret(credentials.getTicket());
|
|
||||||
user.setId(payload.getSubject());
|
|
||||||
user.setProvider(TokenValidatorFactoryImpl.LoginProvider.GOOGLE);
|
|
||||||
user.setName((String) payload.get("name"));
|
|
||||||
user.setEmail(payload.getEmail());
|
|
||||||
user.setIsVerified(payload.getEmailVerified());
|
|
||||||
return this.nonVerifiedUserAuthenticationService.Touch(user);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,67 +0,0 @@
|
||||||
package eu.eudat.logic.security.validators.linkedin;
|
|
||||||
|
|
||||||
import eu.eudat.exceptions.security.UnauthorisedException;
|
|
||||||
import eu.eudat.logic.security.customproviders.LinkedIn.LinkedInCustomProvider;
|
|
||||||
import eu.eudat.logic.security.customproviders.LinkedIn.LinkedInUser;
|
|
||||||
import eu.eudat.logic.security.validators.TokenValidator;
|
|
||||||
import eu.eudat.logic.security.validators.linkedin.helpers.LinkedInRequest;
|
|
||||||
import eu.eudat.logic.security.validators.linkedin.helpers.LinkedInResponseToken;
|
|
||||||
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
|
|
||||||
import eu.eudat.models.data.login.LoginInfo;
|
|
||||||
import eu.eudat.models.data.loginprovider.LoginProviderUser;
|
|
||||||
import eu.eudat.models.data.security.Principal;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
|
|
||||||
@Component("linkedInTokenValidator")
|
|
||||||
public class LinkedInTokenValidator implements TokenValidator {
|
|
||||||
|
|
||||||
private Environment environment;
|
|
||||||
private AuthenticationService nonVerifiedUserAuthenticationService;
|
|
||||||
private LinkedInCustomProvider linkedInCustomProvider;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public LinkedInTokenValidator(Environment environment, AuthenticationService nonVerifiedUserAuthenticationService, LinkedInCustomProvider linkedInCustomProvider) {
|
|
||||||
this.environment = environment;
|
|
||||||
this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService;
|
|
||||||
this.linkedInCustomProvider = linkedInCustomProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Principal validateToken(LoginInfo credentials) {
|
|
||||||
/*AccessGrant accessGrant = this.linkedInServiceProvider.getOAuthOperations().exchangeForAccess(credentials.getTicket(), this.environment.getProperty("linkedin.login.redirect_uri"), null);
|
|
||||||
LinkedIn linkedInService = this.linkedInServiceProvider.getApi(accessGrant.getAccessToken());
|
|
||||||
LinkedInProfile linkedInProfile = linkedInService.profileOperations().getUserProfile();
|
|
||||||
LoginProviderUser user = new LoginProviderUser();
|
|
||||||
|
|
||||||
if (linkedInProfile.getEmailAddress() == null)
|
|
||||||
throw new UnauthorisedException("Cannot login user.LinkedIn account did not provide email");
|
|
||||||
user.setEmail(linkedInProfile.getEmailAddress());
|
|
||||||
user.setId(linkedInProfile.getId());
|
|
||||||
user.setIsVerified(true); //TODO
|
|
||||||
user.setAvatarUrl(linkedInProfile.getProfilePictureUrl());
|
|
||||||
user.setName(linkedInProfile.getFirstName() + " " + linkedInProfile.getLastName());
|
|
||||||
user.setProvider(TokenValidatorFactoryImpl.LoginProvider.LINKEDIN);
|
|
||||||
user.setSecret(accessGrant.getAccessToken());*/
|
|
||||||
|
|
||||||
LinkedInUser linkedInUser = this.linkedInCustomProvider.getUser(credentials.getTicket());
|
|
||||||
if (linkedInUser.getEmail() == null)
|
|
||||||
throw new UnauthorisedException("Cannot login user.LinkedIn account did not provide email");
|
|
||||||
LoginProviderUser user = new LoginProviderUser();
|
|
||||||
user.setId(linkedInUser.getId());
|
|
||||||
user.setName(linkedInUser.getName());
|
|
||||||
user.setEmail(linkedInUser.getEmail());
|
|
||||||
user.setProvider(credentials.getProvider());
|
|
||||||
user.setSecret(credentials.getTicket());
|
|
||||||
|
|
||||||
return this.nonVerifiedUserAuthenticationService.Touch(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LinkedInResponseToken getAccessToken(LinkedInRequest linkedInRequest) {
|
|
||||||
return this.linkedInCustomProvider.getAccessToken(
|
|
||||||
linkedInRequest.getCode(), this.environment.getProperty("linkedin.login.redirect_uri"),
|
|
||||||
this.environment.getProperty("linkedin.login.clientId"), this.environment.getProperty("linkedin.login.clientSecret"));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package eu.eudat.logic.security.validators.linkedin.helpers;
|
|
||||||
|
|
||||||
public class LinkedInRequest {
|
|
||||||
private String code;
|
|
||||||
|
|
||||||
public String getCode() {
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
public void setCode(String code) {
|
|
||||||
this.code = code;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package eu.eudat.logic.security.validators.linkedin.helpers;
|
|
||||||
|
|
||||||
public class LinkedInResponseToken {
|
|
||||||
|
|
||||||
private String accessToken;
|
|
||||||
private Integer expiresIn;
|
|
||||||
|
|
||||||
public String getAccessToken() {
|
|
||||||
return accessToken;
|
|
||||||
}
|
|
||||||
public void setAccessToken(String accessToken) {
|
|
||||||
this.accessToken = accessToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getExpiresIn() {
|
|
||||||
return expiresIn;
|
|
||||||
}
|
|
||||||
public void setExpiresIn(Integer expiresIn) {
|
|
||||||
this.expiresIn = expiresIn;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
package eu.eudat.logic.security.validators.openaire;
|
|
||||||
|
|
||||||
import eu.eudat.exceptions.security.NonValidTokenException;
|
|
||||||
import eu.eudat.exceptions.security.NullEmailException;
|
|
||||||
import eu.eudat.logic.security.customproviders.OpenAIRE.OpenAIRECustomProvider;
|
|
||||||
import eu.eudat.logic.security.customproviders.OpenAIRE.OpenAIREUser;
|
|
||||||
import eu.eudat.logic.security.validators.TokenValidator;
|
|
||||||
import eu.eudat.logic.security.validators.openaire.helpers.OpenAIRERequest;
|
|
||||||
import eu.eudat.logic.security.validators.openaire.helpers.OpenAIREResponseToken;
|
|
||||||
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
|
|
||||||
import eu.eudat.models.data.login.LoginInfo;
|
|
||||||
import eu.eudat.models.data.loginprovider.LoginProviderUser;
|
|
||||||
import eu.eudat.models.data.security.Principal;
|
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.security.GeneralSecurityException;
|
|
||||||
|
|
||||||
@Component("openAIRETokenValidator")
|
|
||||||
public class OpenAIRETokenValidator implements TokenValidator {
|
|
||||||
|
|
||||||
private Environment environment;
|
|
||||||
private AuthenticationService nonVerifiedUserAuthenticationService;
|
|
||||||
private OpenAIRECustomProvider openAIRECustomProvider;
|
|
||||||
|
|
||||||
public OpenAIRETokenValidator(Environment environment, AuthenticationService nonVerifiedUserAuthenticationService, OpenAIRECustomProvider openAIRECustomProvider) {
|
|
||||||
this.environment = environment;
|
|
||||||
this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService;
|
|
||||||
this.openAIRECustomProvider = openAIRECustomProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OpenAIREResponseToken getAccessToken(OpenAIRERequest openAIRERequest) {
|
|
||||||
return this.openAIRECustomProvider.getAccessToken(
|
|
||||||
openAIRERequest.getCode(), this.environment.getProperty("openaire.login.redirect_uri"),
|
|
||||||
this.environment.getProperty("openaire.login.client_id"), this.environment.getProperty("openaire.login.client_secret")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Principal validateToken(LoginInfo credentials) throws NonValidTokenException, IOException, GeneralSecurityException, NullEmailException {
|
|
||||||
OpenAIREUser openAIREUser = this.openAIRECustomProvider.getUser(credentials.getTicket());
|
|
||||||
LoginProviderUser user = new LoginProviderUser();
|
|
||||||
user.setId(openAIREUser.getId());
|
|
||||||
user.setEmail(openAIREUser.getEmail());
|
|
||||||
user.setName(openAIREUser.getName());
|
|
||||||
user.setProvider(credentials.getProvider());
|
|
||||||
user.setSecret(credentials.getTicket());
|
|
||||||
|
|
||||||
return this.nonVerifiedUserAuthenticationService.Touch(user);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package eu.eudat.logic.security.validators.openaire.helpers;
|
|
||||||
|
|
||||||
public class OpenAIRERequest {
|
|
||||||
private String code;
|
|
||||||
|
|
||||||
public String getCode() {
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
public void setCode(String code) {
|
|
||||||
this.code = code;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
package eu.eudat.logic.security.validators.openaire.helpers;
|
|
||||||
|
|
||||||
public class OpenAIREResponseToken {
|
|
||||||
private String accessToken;
|
|
||||||
private Integer expiresIn;
|
|
||||||
|
|
||||||
public String getAccessToken() {
|
|
||||||
return accessToken;
|
|
||||||
}
|
|
||||||
public void setAccessToken(String accessToken) {
|
|
||||||
this.accessToken = accessToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getExpiresIn() {
|
|
||||||
return expiresIn;
|
|
||||||
}
|
|
||||||
public void setExpiresIn(Integer expiresIn) {
|
|
||||||
this.expiresIn = expiresIn;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
package eu.eudat.logic.security.validators.orcid;
|
|
||||||
|
|
||||||
import eu.eudat.exceptions.security.NonValidTokenException;
|
|
||||||
import eu.eudat.exceptions.security.NullEmailException;
|
|
||||||
import eu.eudat.logic.security.customproviders.ORCID.ORCIDCustomProvider;
|
|
||||||
import eu.eudat.logic.security.customproviders.ORCID.ORCIDUser;
|
|
||||||
import eu.eudat.logic.security.validators.TokenValidator;
|
|
||||||
import eu.eudat.logic.security.validators.orcid.helpers.ORCIDRequest;
|
|
||||||
import eu.eudat.logic.security.validators.orcid.helpers.ORCIDResponseToken;
|
|
||||||
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
|
|
||||||
import eu.eudat.models.data.login.LoginInfo;
|
|
||||||
import eu.eudat.models.data.loginprovider.LoginProviderUser;
|
|
||||||
import eu.eudat.models.data.security.Principal;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.security.GeneralSecurityException;
|
|
||||||
|
|
||||||
@Component("orcidTokenValidator")
|
|
||||||
public class ORCIDTokenValidator implements TokenValidator {
|
|
||||||
|
|
||||||
private ORCIDCustomProvider orcidCustomProvider;
|
|
||||||
private Environment environment;
|
|
||||||
private AuthenticationService nonVerifiedUserAuthenticationService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public ORCIDTokenValidator(Environment environment, AuthenticationService nonVerifiedUserAuthenticationService, ORCIDCustomProvider orcidCustomProvider) {
|
|
||||||
this.environment = environment;
|
|
||||||
this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService;
|
|
||||||
this.orcidCustomProvider = orcidCustomProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Principal validateToken(LoginInfo credentials) throws NonValidTokenException, IOException, GeneralSecurityException, NullEmailException {
|
|
||||||
ORCIDUser orcidUser = new ORCIDUser().getOrcidUser(credentials.getData());
|
|
||||||
LoginProviderUser user = new LoginProviderUser();
|
|
||||||
user.setId(orcidUser.getOrcidId());
|
|
||||||
user.setName(orcidUser.getName());
|
|
||||||
user.setProvider(credentials.getProvider());
|
|
||||||
user.setSecret(credentials.getTicket());
|
|
||||||
return this.nonVerifiedUserAuthenticationService.Touch(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ORCIDResponseToken getAccessToken(ORCIDRequest orcidRequest) {
|
|
||||||
return this.orcidCustomProvider.getAccessToken(orcidRequest.getCode(), this.environment.getProperty("orcid.login.redirect_uri")
|
|
||||||
, this.environment.getProperty("orcid.login.client_id")
|
|
||||||
, this.environment.getProperty("orcid.login.client_secret"));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package eu.eudat.logic.security.validators.orcid.helpers;
|
|
||||||
|
|
||||||
public class ORCIDRequest {
|
|
||||||
private String code;
|
|
||||||
|
|
||||||
public String getCode() {
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
public void setCode(String code) {
|
|
||||||
this.code = code;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
package eu.eudat.logic.security.validators.orcid.helpers;
|
|
||||||
|
|
||||||
public class ORCIDResponseToken {
|
|
||||||
private String orcidId;
|
|
||||||
private String name;
|
|
||||||
private String accessToken;
|
|
||||||
|
|
||||||
public String getOrcidId() {
|
|
||||||
return orcidId;
|
|
||||||
}
|
|
||||||
public void setOrcidId(String orcidId) {
|
|
||||||
this.orcidId = orcidId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAccessToken() {
|
|
||||||
return accessToken;
|
|
||||||
}
|
|
||||||
public void setAccessToken(String accessToken) {
|
|
||||||
this.accessToken = accessToken;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,74 +0,0 @@
|
||||||
package eu.eudat.logic.security.validators.twitter;
|
|
||||||
|
|
||||||
import eu.eudat.exceptions.security.NonValidTokenException;
|
|
||||||
import eu.eudat.exceptions.security.NullEmailException;
|
|
||||||
import eu.eudat.exceptions.security.UnauthorisedException;
|
|
||||||
import eu.eudat.logic.security.validators.TokenValidator;
|
|
||||||
import eu.eudat.logic.security.validators.TokenValidatorFactoryImpl;
|
|
||||||
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
|
|
||||||
import eu.eudat.models.data.login.LoginInfo;
|
|
||||||
import eu.eudat.models.data.loginprovider.LoginProviderUser;
|
|
||||||
import eu.eudat.models.data.security.Principal;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
import org.springframework.social.oauth1.AuthorizedRequestToken;
|
|
||||||
import org.springframework.social.oauth1.OAuthToken;
|
|
||||||
import org.springframework.social.twitter.api.TwitterProfile;
|
|
||||||
import org.springframework.social.twitter.api.impl.TwitterTemplate;
|
|
||||||
import org.springframework.social.twitter.connect.TwitterServiceProvider;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.security.GeneralSecurityException;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
|
|
||||||
@Component("twitterTokenValidator")
|
|
||||||
public class TwitterTokenValidator implements TokenValidator {
|
|
||||||
|
|
||||||
private Environment environment;
|
|
||||||
private AuthenticationService nonVerifiedUserAuthenticationService;
|
|
||||||
private TwitterServiceProvider twitterServiceProvider;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public TwitterTokenValidator(Environment environment, AuthenticationService nonVerifiedUserAuthenticationService) {
|
|
||||||
this.environment = environment;
|
|
||||||
this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService;
|
|
||||||
this.twitterServiceProvider = new TwitterServiceProvider(this.environment.getProperty("twitter.login.clientId"), this.environment.getProperty("twitter.login.clientSecret"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Principal validateToken(LoginInfo credentials) throws NonValidTokenException, IOException, GeneralSecurityException, NullEmailException {
|
|
||||||
String verifier = (String) ((Map)credentials.getData()).get("verifier");
|
|
||||||
String email = (String) ((Map) credentials.getData()).get("email");
|
|
||||||
OAuthToken oAuthToken = new OAuthToken(credentials.getTicket(), verifier);
|
|
||||||
AuthorizedRequestToken authorizedRequestToken = new AuthorizedRequestToken(oAuthToken, verifier);
|
|
||||||
OAuthToken finalOauthToken = this.twitterServiceProvider.getOAuthOperations().exchangeForAccessToken(authorizedRequestToken, null);
|
|
||||||
TwitterTemplate twitterTemplate = new TwitterTemplate(this.environment.getProperty("twitter.login.clientId"), this.environment.getProperty("twitter.login.clientSecret"), finalOauthToken.getValue(), finalOauthToken.getSecret());
|
|
||||||
TwitterProfile profile = this.twitterServiceProvider.getApi(finalOauthToken.getValue(), finalOauthToken.getSecret()).userOperations().getUserProfile();
|
|
||||||
LoginProviderUser user = new LoginProviderUser();
|
|
||||||
|
|
||||||
Map values = twitterTemplate.getRestTemplate().getForObject("https://api.twitter.com/1.1/account/verify_credentials.json?include_email=true", Map.class);
|
|
||||||
if (values.get("email") == null) {
|
|
||||||
// throw new UnauthorisedException("Cannot login user.Twitter account did not provide email");
|
|
||||||
user.setIsVerified(false); //TODO
|
|
||||||
if (email != null && !email.isEmpty()) {
|
|
||||||
user.setEmail(email);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
user.setEmail((String) values.get("email"));
|
|
||||||
user.setIsVerified(true); //TODO
|
|
||||||
}
|
|
||||||
user.setAvatarUrl(profile.getProfileImageUrl());
|
|
||||||
user.setId("" + profile.getId());
|
|
||||||
user.setName(profile.getName());
|
|
||||||
user.setProvider(TokenValidatorFactoryImpl.LoginProvider.TWITTER);
|
|
||||||
user.setSecret(finalOauthToken.getValue());
|
|
||||||
return this.nonVerifiedUserAuthenticationService.Touch(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
public OAuthToken getRequestToken() {
|
|
||||||
return this.twitterServiceProvider.getOAuthOperations().fetchRequestToken(this.environment.getProperty("twitter.login.redirect_uri"), null);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
package eu.eudat.logic.security.validators.zenodo;
|
|
||||||
|
|
||||||
import eu.eudat.exceptions.security.NonValidTokenException;
|
|
||||||
import eu.eudat.exceptions.security.NullEmailException;
|
|
||||||
import eu.eudat.logic.security.customproviders.ORCID.ORCIDCustomProvider;
|
|
||||||
import eu.eudat.logic.security.customproviders.ORCID.ORCIDUser;
|
|
||||||
import eu.eudat.logic.security.customproviders.Zenodo.ZenodoAccessType;
|
|
||||||
import eu.eudat.logic.security.customproviders.Zenodo.ZenodoCustomProvider;
|
|
||||||
import eu.eudat.logic.security.customproviders.Zenodo.ZenodoUser;
|
|
||||||
import eu.eudat.logic.security.validators.TokenValidator;
|
|
||||||
import eu.eudat.logic.security.validators.zenodo.helpers.ZenodoRequest;
|
|
||||||
import eu.eudat.logic.security.validators.zenodo.helpers.ZenodoResponseToken;
|
|
||||||
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
|
|
||||||
import eu.eudat.models.data.login.LoginInfo;
|
|
||||||
import eu.eudat.models.data.loginprovider.LoginProviderUser;
|
|
||||||
import eu.eudat.models.data.security.Principal;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.security.GeneralSecurityException;
|
|
||||||
|
|
||||||
@Component("zenodoTokenValidator")
|
|
||||||
public class ZenodoTokenValidator implements TokenValidator {
|
|
||||||
|
|
||||||
private ZenodoCustomProvider zenodoCustomProvider;
|
|
||||||
private Environment environment;
|
|
||||||
private AuthenticationService nonVerifiedUserAuthenticationService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public ZenodoTokenValidator(Environment environment, AuthenticationService nonVerifiedUserAuthenticationService, ZenodoCustomProvider zenodoCustomProvider) {
|
|
||||||
this.environment = environment;
|
|
||||||
this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService;
|
|
||||||
this.zenodoCustomProvider = zenodoCustomProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Principal validateToken(LoginInfo credentials) throws NonValidTokenException, IOException, GeneralSecurityException, NullEmailException {
|
|
||||||
ZenodoUser zenodoUser = new ZenodoUser().getZenodoUser(credentials.getData());
|
|
||||||
LoginProviderUser user = new LoginProviderUser();
|
|
||||||
user.setId(zenodoUser.getUserId());
|
|
||||||
user.setName(zenodoUser.getEmail());
|
|
||||||
user.setEmail(zenodoUser.getEmail());
|
|
||||||
user.setZenodoId(zenodoUser.getAccessToken());
|
|
||||||
user.setZenodoExpire(zenodoUser.getExpiresIn());
|
|
||||||
user.setZenodoRefresh(zenodoUser.getRefreshToken());
|
|
||||||
user.setProvider(credentials.getProvider());
|
|
||||||
user.setSecret(credentials.getTicket());
|
|
||||||
return this.nonVerifiedUserAuthenticationService.Touch(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ZenodoResponseToken getAccessToken(ZenodoRequest zenodoRequest) {
|
|
||||||
return this.zenodoCustomProvider.getAccessToken(ZenodoAccessType.AUTHORIZATION_CODE, zenodoRequest.getCode()
|
|
||||||
, this.environment.getProperty("zenodo.login.client_id")
|
|
||||||
, this.environment.getProperty("zenodo.login.client_secret")
|
|
||||||
, this.environment.getProperty("zenodo.login.redirect_uri"));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,7 +2,6 @@ package eu.eudat.logic.services.operations;
|
||||||
|
|
||||||
import eu.eudat.data.dao.entities.*;
|
import eu.eudat.data.dao.entities.*;
|
||||||
import eu.eudat.data.dao.entities.security.CredentialDao;
|
import eu.eudat.data.dao.entities.security.CredentialDao;
|
||||||
import eu.eudat.data.dao.entities.security.UserTokenDao;
|
|
||||||
|
|
||||||
|
|
||||||
public interface DatabaseRepository {
|
public interface DatabaseRepository {
|
||||||
|
@ -34,8 +33,6 @@ public interface DatabaseRepository {
|
||||||
|
|
||||||
CredentialDao getCredentialDao();
|
CredentialDao getCredentialDao();
|
||||||
|
|
||||||
UserTokenDao getUserTokenDao();
|
|
||||||
|
|
||||||
ExternalDatasetDao getExternalDatasetDao();
|
ExternalDatasetDao getExternalDatasetDao();
|
||||||
|
|
||||||
UserDatasetProfileDao getUserDatasetProfileDao();
|
UserDatasetProfileDao getUserDatasetProfileDao();
|
||||||
|
|
|
@ -2,7 +2,6 @@ package eu.eudat.logic.services.operations;
|
||||||
|
|
||||||
import eu.eudat.data.dao.entities.*;
|
import eu.eudat.data.dao.entities.*;
|
||||||
import eu.eudat.data.dao.entities.security.CredentialDao;
|
import eu.eudat.data.dao.entities.security.CredentialDao;
|
||||||
import eu.eudat.data.dao.entities.security.UserTokenDao;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@ -25,7 +24,6 @@ public class DatabaseRepositoryImpl implements DatabaseRepository {
|
||||||
private UserInfoDao userInfoDao;
|
private UserInfoDao userInfoDao;
|
||||||
private InvitationDao invitationDao;
|
private InvitationDao invitationDao;
|
||||||
private CredentialDao credentialDao;
|
private CredentialDao credentialDao;
|
||||||
private UserTokenDao userTokenDao;
|
|
||||||
private ExternalDatasetDao externalDatasetDao;
|
private ExternalDatasetDao externalDatasetDao;
|
||||||
private UserRoleDao userRoleDao;
|
private UserRoleDao userRoleDao;
|
||||||
private UserDatasetProfileDao userDatasetProfileDao;
|
private UserDatasetProfileDao userDatasetProfileDao;
|
||||||
|
@ -174,16 +172,6 @@ public class DatabaseRepositoryImpl implements DatabaseRepository {
|
||||||
this.credentialDao = credentialDao;
|
this.credentialDao = credentialDao;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserTokenDao getUserTokenDao() {
|
|
||||||
return userTokenDao;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public void setUserTokenDao(UserTokenDao userTokenDao) {
|
|
||||||
this.userTokenDao = userTokenDao;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExternalDatasetDao getExternalDatasetDao() {
|
public ExternalDatasetDao getExternalDatasetDao() {
|
||||||
return externalDatasetDao;
|
return externalDatasetDao;
|
||||||
|
|
|
@ -1,31 +1,16 @@
|
||||||
package eu.eudat.logic.services.operations.authentication;
|
package eu.eudat.logic.services.operations.authentication;
|
||||||
|
|
||||||
import eu.eudat.data.entities.Credential;
|
|
||||||
import eu.eudat.data.entities.UserInfo;
|
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.managers.MetricsManager;
|
import eu.eudat.logic.managers.MetricsManager;
|
||||||
import eu.eudat.logic.security.validators.TokenValidatorFactoryImpl;
|
|
||||||
import eu.eudat.logic.services.ApiContext;
|
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.models.data.security.Principal;
|
||||||
import eu.eudat.types.Authorities;
|
|
||||||
import eu.eudat.types.MetricNames;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
import java.sql.Timestamp;
|
import java.util.Calendar;
|
||||||
import java.time.Instant;
|
import java.util.Date;
|
||||||
import java.time.LocalDateTime;
|
import java.util.UUID;
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
public abstract class AbstractAuthenticationService implements AuthenticationService {
|
public abstract class AbstractAuthenticationService implements AuthenticationService {
|
||||||
private static final Logger logger = LoggerFactory.getLogger(AbstractAuthenticationService.class);
|
private static final Logger logger = LoggerFactory.getLogger(AbstractAuthenticationService.class);
|
||||||
|
@ -49,166 +34,13 @@ public abstract class AbstractAuthenticationService implements AuthenticationSer
|
||||||
return dt;
|
return dt;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract Principal Touch(UserToken token);
|
abstract Principal Touch(UserInfo 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;
|
|
||||||
|
|
||||||
|
|
||||||
|
public Principal Touch(UUID userId) { //TODO: Authn
|
||||||
|
UserInfo tokenEntry = this.apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(userId);
|
||||||
|
if (tokenEntry == null) return null;
|
||||||
|
|
||||||
return this.Touch(tokenEntry);
|
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());
|
|
||||||
metricsManager.increaseValue(MetricNames.USERS, 1, MetricNames.TOTAL);
|
|
||||||
} 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<Credential> 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);
|
|
||||||
metricsManager.increaseValue(MetricNames.USERS, 1, MetricNames.TOTAL);
|
|
||||||
} else {
|
|
||||||
Map<String, Object> additionalInfo = userInfo.getAdditionalinfo() != null ?
|
|
||||||
new JSONObject(userInfo.getAdditionalinfo()).toMap() : 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(new JSONObject(additionalInfo).toString());
|
|
||||||
Set<Credential> 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());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import eu.eudat.exceptions.security.NullEmailException;
|
||||||
import eu.eudat.models.data.login.Credentials;
|
import eu.eudat.models.data.login.Credentials;
|
||||||
import eu.eudat.models.data.loginprovider.LoginProviderUser;
|
import eu.eudat.models.data.loginprovider.LoginProviderUser;
|
||||||
import eu.eudat.models.data.security.Principal;
|
import eu.eudat.models.data.security.Principal;
|
||||||
|
import gr.cite.commons.web.oidc.principal.MyPrincipal;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@ -12,11 +13,7 @@ import java.util.UUID;
|
||||||
*/
|
*/
|
||||||
public interface AuthenticationService {
|
public interface AuthenticationService {
|
||||||
|
|
||||||
Principal Touch(LoginProviderUser profile) throws NullEmailException;
|
Principal Touch(MyPrincipal principal) throws NullEmailException;
|
||||||
|
|
||||||
Principal Touch(Credentials credentials) throws NullEmailException;
|
|
||||||
|
|
||||||
void Logout(UUID token);
|
|
||||||
|
|
||||||
Principal Touch(UUID token) throws NullEmailException;
|
Principal Touch(UUID token) throws NullEmailException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,100 +3,65 @@ package eu.eudat.logic.services.operations.authentication;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import eu.eudat.data.entities.UserInfo;
|
import eu.eudat.data.entities.UserInfo;
|
||||||
import eu.eudat.data.entities.UserRole;
|
import eu.eudat.data.entities.UserRole;
|
||||||
import eu.eudat.data.entities.UserToken;
|
import eu.eudat.exceptions.security.NullEmailException;
|
||||||
import eu.eudat.logic.builders.model.models.PrincipalBuilder;
|
import eu.eudat.logic.builders.model.models.PrincipalBuilder;
|
||||||
import eu.eudat.logic.managers.MetricsManager;
|
import eu.eudat.logic.managers.MetricsManager;
|
||||||
import eu.eudat.logic.services.ApiContext;
|
import eu.eudat.logic.services.ApiContext;
|
||||||
import eu.eudat.models.data.security.Principal;
|
import eu.eudat.models.data.security.Principal;
|
||||||
import eu.eudat.types.Authorities;
|
import eu.eudat.types.Authorities;
|
||||||
|
import gr.cite.commons.web.oidc.principal.MyPrincipal;
|
||||||
|
import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractor;
|
||||||
|
import org.apache.commons.lang3.NotImplementedException;
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
@Service("nonVerifiedUserAuthenticationService")
|
@Service("nonVerifiedUserAuthenticationService")
|
||||||
public class NonVerifiedUserEmailAuthenticationService extends AbstractAuthenticationService {
|
public class NonVerifiedUserEmailAuthenticationService extends AbstractAuthenticationService {
|
||||||
|
|
||||||
public NonVerifiedUserEmailAuthenticationService(ApiContext apiContext, Environment environment, MetricsManager metricsManager) {
|
private final ClaimExtractor claimExtractor;
|
||||||
|
public NonVerifiedUserEmailAuthenticationService(ApiContext apiContext, Environment environment, MetricsManager metricsManager, ClaimExtractor claimExtractor) {
|
||||||
super(apiContext, environment, metricsManager);
|
super(apiContext, environment, metricsManager);
|
||||||
|
this.claimExtractor = claimExtractor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Principal Touch(UserToken token) {
|
@Override
|
||||||
if (token == null || token.getExpiresAt().before(new Date())) return null;
|
Principal Touch(UserInfo token) {
|
||||||
|
throw new NotImplementedException("");
|
||||||
|
}
|
||||||
|
|
||||||
UserInfo user = this.apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(token.getUser().getId());
|
@Override
|
||||||
if (user == null) return null;
|
public Principal Touch(MyPrincipal principal) throws NullEmailException { //TODO: Authn
|
||||||
String avatarUrl;
|
if (principal == null /*|| this.claimExtractor.expiresAt(principal).isBefore(Instant.now())*/) return null;
|
||||||
try {
|
|
||||||
avatarUrl = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("avatarUrl").asText() : "";
|
Principal principalItem = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(PrincipalBuilder.class)
|
||||||
} catch (Exception e) {
|
.id(UUID.randomUUID()).token(UUID.randomUUID())//TODO: Authn
|
||||||
avatarUrl = "";
|
.expiresAt(Date.from(Instant.now().plus(5, ChronoUnit.DAYS)))
|
||||||
}
|
.name(this.claimExtractor.name(principal))
|
||||||
String zenodoToken;
|
.email(this.claimExtractor.email(principal))
|
||||||
try {
|
.avatarUrl("")
|
||||||
zenodoToken = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("zenodoToken").asText() : "";
|
.culture("")
|
||||||
} catch (Exception e) {
|
.language("")
|
||||||
zenodoToken = "";
|
.timezone("")
|
||||||
}
|
.zenodoToken("")
|
||||||
Instant zenodoDuration;
|
.zenodoDuration(Instant.now())
|
||||||
try {
|
.zenodoEmail("")
|
||||||
zenodoDuration = user.getAdditionalinfo() != null ? Instant.ofEpochMilli(new ObjectMapper().readTree(user.getAdditionalinfo()).get("expirationDate").asLong()) : Instant.now();
|
.zenodoRefresh("")
|
||||||
} catch (Exception e) {
|
|
||||||
zenodoDuration = Instant.now();
|
|
||||||
}
|
|
||||||
String zenodoEmail;
|
|
||||||
try {
|
|
||||||
zenodoEmail = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("zenodoEmail").asText() : "";
|
|
||||||
} catch (Exception e) {
|
|
||||||
zenodoEmail = "";
|
|
||||||
}
|
|
||||||
String zenodoRefresh;
|
|
||||||
try {
|
|
||||||
zenodoRefresh = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("zenodoRefresh").asText() : "";
|
|
||||||
} catch (Exception e) {
|
|
||||||
zenodoRefresh = "";
|
|
||||||
}
|
|
||||||
String culture;
|
|
||||||
try {
|
|
||||||
culture = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("culture").get("name").asText() : "";
|
|
||||||
} catch (Exception e) {
|
|
||||||
culture = "";
|
|
||||||
}
|
|
||||||
String language;
|
|
||||||
try {
|
|
||||||
language = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("language").get("value").asText() : "";
|
|
||||||
} catch (Exception e) {
|
|
||||||
language = "";
|
|
||||||
}
|
|
||||||
String timezone;
|
|
||||||
try {
|
|
||||||
timezone = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("timezone").asText() : "";
|
|
||||||
} catch (Exception e) {
|
|
||||||
timezone = "";
|
|
||||||
}
|
|
||||||
Principal principal = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(PrincipalBuilder.class)
|
|
||||||
.id(user.getId()).token(token.getToken())
|
|
||||||
.expiresAt(token.getExpiresAt())
|
|
||||||
.name(user.getName())
|
|
||||||
.email(user.getEmail())
|
|
||||||
.avatarUrl(avatarUrl)
|
|
||||||
.culture(culture)
|
|
||||||
.language(language)
|
|
||||||
.timezone(timezone)
|
|
||||||
.zenodoToken(zenodoToken)
|
|
||||||
.zenodoDuration(zenodoDuration)
|
|
||||||
.zenodoEmail(zenodoEmail)
|
|
||||||
.zenodoRefresh(zenodoRefresh)
|
|
||||||
.build();
|
.build();
|
||||||
|
principalItem.setAuthorities(new HashSet<>());
|
||||||
|
principalItem.getAuthz().add(Authorities.USER);
|
||||||
|
// List<UserRole> 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 principalItem;
|
||||||
|
|
||||||
List<UserRole> 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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,28 +1,25 @@
|
||||||
package eu.eudat.logic.services.operations.authentication;
|
package eu.eudat.logic.services.operations.authentication;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import eu.eudat.data.entities.Credential;
|
|
||||||
import eu.eudat.data.entities.UserInfo;
|
import eu.eudat.data.entities.UserInfo;
|
||||||
import eu.eudat.data.entities.UserRole;
|
import eu.eudat.data.entities.UserRole;
|
||||||
import eu.eudat.data.entities.UserToken;
|
|
||||||
import eu.eudat.exceptions.security.NullEmailException;
|
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.builders.model.models.PrincipalBuilder;
|
import eu.eudat.logic.builders.model.models.PrincipalBuilder;
|
||||||
import eu.eudat.logic.managers.MetricsManager;
|
import eu.eudat.logic.managers.MetricsManager;
|
||||||
import eu.eudat.logic.security.validators.TokenValidatorFactoryImpl;
|
|
||||||
import eu.eudat.logic.services.ApiContext;
|
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.models.data.security.Principal;
|
||||||
import eu.eudat.types.Authorities;
|
import eu.eudat.types.Authorities;
|
||||||
import org.json.JSONObject;
|
import gr.cite.commons.web.oidc.principal.MyPrincipal;
|
||||||
|
import org.apache.commons.lang3.NotImplementedException;
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.*;
|
import java.time.temporal.ChronoUnit;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
|
||||||
@Service("verifiedUserAuthenticationService")
|
@Service("verifiedUserAuthenticationService")
|
||||||
|
@ -32,10 +29,7 @@ public class VerifiedUserAuthenticationService extends AbstractAuthenticationSer
|
||||||
super(apiContext, environment, metricsManager);
|
super(apiContext, environment, metricsManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Principal Touch(UserToken token) {
|
public Principal Touch(UserInfo user) {
|
||||||
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;
|
if (user == null) return null;
|
||||||
if (user.getEmail() == null) throw new NullEmailException();
|
if (user.getEmail() == null) throw new NullEmailException();
|
||||||
String avatarUrl;
|
String avatarUrl;
|
||||||
|
@ -87,8 +81,8 @@ public class VerifiedUserAuthenticationService extends AbstractAuthenticationSer
|
||||||
timezone = "";
|
timezone = "";
|
||||||
}
|
}
|
||||||
Principal principal = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(PrincipalBuilder.class)
|
Principal principal = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(PrincipalBuilder.class)
|
||||||
.id(user.getId()).token(token.getToken())
|
.id(user.getId()).token(UUID.randomUUID()) //TODO: Authn
|
||||||
.expiresAt(token.getExpiresAt())
|
.expiresAt(Date.from(Instant.now().plus(5, ChronoUnit.DAYS)))//TODO: Authn
|
||||||
.name(user.getName())
|
.name(user.getName())
|
||||||
.email(user.getEmail())
|
.email(user.getEmail())
|
||||||
.avatarUrl(avatarUrl)
|
.avatarUrl(avatarUrl)
|
||||||
|
@ -108,4 +102,10 @@ public class VerifiedUserAuthenticationService extends AbstractAuthenticationSer
|
||||||
}
|
}
|
||||||
return principal;
|
return principal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Principal Touch(MyPrincipal principal) throws NullEmailException {
|
||||||
|
throw new NotImplementedException("");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
package eu.eudat.models.data.login;
|
package eu.eudat.models.data.login;
|
||||||
|
|
||||||
import eu.eudat.logic.security.validators.TokenValidatorFactoryImpl;
|
|
||||||
|
|
||||||
|
|
||||||
public class LoginInfo {
|
public class LoginInfo {
|
||||||
private String ticket;
|
private String ticket;
|
||||||
private TokenValidatorFactoryImpl.LoginProvider provider;
|
|
||||||
private Object data;
|
private Object data;
|
||||||
|
|
||||||
public String getTicket() {
|
public String getTicket() {
|
||||||
|
@ -16,13 +13,6 @@ public class LoginInfo {
|
||||||
this.ticket = ticket;
|
this.ticket = ticket;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TokenValidatorFactoryImpl.LoginProvider getProvider() {
|
|
||||||
return provider;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProvider(Integer provider) {
|
|
||||||
this.provider = TokenValidatorFactoryImpl.LoginProvider.fromInteger(provider);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object getData() {
|
public Object getData() {
|
||||||
return data;
|
return data;
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package eu.eudat.models.data.loginprovider;
|
package eu.eudat.models.data.loginprovider;
|
||||||
|
|
||||||
import eu.eudat.logic.security.validators.TokenValidatorFactoryImpl;
|
|
||||||
|
|
||||||
|
|
||||||
public class LoginProviderUser {
|
public class LoginProviderUser {
|
||||||
private String name;
|
private String name;
|
||||||
|
@ -10,7 +8,6 @@ public class LoginProviderUser {
|
||||||
private String secret;
|
private String secret;
|
||||||
private String avatarUrl;
|
private String avatarUrl;
|
||||||
private boolean isVerified;
|
private boolean isVerified;
|
||||||
private TokenValidatorFactoryImpl.LoginProvider provider;
|
|
||||||
private String zenodoId;
|
private String zenodoId;
|
||||||
private Integer zenodoExpire;
|
private Integer zenodoExpire;
|
||||||
private String zenodoRefresh;
|
private String zenodoRefresh;
|
||||||
|
@ -47,14 +44,6 @@ public class LoginProviderUser {
|
||||||
isVerified = verified;
|
isVerified = verified;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TokenValidatorFactoryImpl.LoginProvider getProvider() {
|
|
||||||
return provider;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProvider(TokenValidatorFactoryImpl.LoginProvider provider) {
|
|
||||||
this.provider = provider;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSecret() {
|
public String getSecret() {
|
||||||
return secret;
|
return secret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,165 @@
|
||||||
|
package eu.eudat.models.v2;
|
||||||
|
|
||||||
|
import gr.cite.tools.logging.annotation.LogSensitive;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class Account {
|
||||||
|
|
||||||
|
public static class PrincipalInfo {
|
||||||
|
|
||||||
|
public final static String _userId = "userId";
|
||||||
|
public UUID userId;
|
||||||
|
|
||||||
|
public UUID getUserId() {
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserId(UUID userId) {
|
||||||
|
this.userId = userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static String _subject = "subject";
|
||||||
|
public UUID subject;
|
||||||
|
|
||||||
|
public UUID getSubject() {
|
||||||
|
return subject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSubject(UUID subject) {
|
||||||
|
this.subject = subject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static String _name = "name";
|
||||||
|
@LogSensitive
|
||||||
|
public String name;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static String _scope = "scope";
|
||||||
|
public List<String> scope;
|
||||||
|
|
||||||
|
public List<String> getScope() {
|
||||||
|
return scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScope(List<String> scope) {
|
||||||
|
this.scope = scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static String _client = "client";
|
||||||
|
public String client;
|
||||||
|
|
||||||
|
public String getClient() {
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClient(String client) {
|
||||||
|
this.client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static String _notBefore = "notBefore";
|
||||||
|
public Instant notBefore;
|
||||||
|
|
||||||
|
public Instant getNotBefore() {
|
||||||
|
return notBefore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNotBefore(Instant notBefore) {
|
||||||
|
this.notBefore = notBefore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static String _issuedAt = "issuedAt";
|
||||||
|
public Instant issuedAt;
|
||||||
|
|
||||||
|
public Instant getIssuedAt() {
|
||||||
|
return issuedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIssuedAt(Instant issuedAt) {
|
||||||
|
this.issuedAt = issuedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static String _authenticatedAt = "authenticatedAt";
|
||||||
|
public Instant authenticatedAt;
|
||||||
|
|
||||||
|
public Instant getAuthenticatedAt() {
|
||||||
|
return authenticatedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuthenticatedAt(Instant authenticatedAt) {
|
||||||
|
this.authenticatedAt = authenticatedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static String _expiresAt = "expiresAt";
|
||||||
|
public Instant expiresAt;
|
||||||
|
|
||||||
|
public Instant getExpiresAt() {
|
||||||
|
return expiresAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExpiresAt(Instant expiresAt) {
|
||||||
|
this.expiresAt = expiresAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static String _more = "more";
|
||||||
|
@LogSensitive
|
||||||
|
public Map<String, List<String>> more;
|
||||||
|
|
||||||
|
public Map<String, List<String>> getMore() {
|
||||||
|
return more;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMore(Map<String, List<String>> more) {
|
||||||
|
this.more = more;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public final static String _isAuthenticated = "isAuthenticated";
|
||||||
|
private Boolean isAuthenticated;
|
||||||
|
|
||||||
|
public Boolean getIsAuthenticated() {
|
||||||
|
return isAuthenticated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsAuthenticated(Boolean authenticated) {
|
||||||
|
isAuthenticated = authenticated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static String _principal = "principal";
|
||||||
|
private PrincipalInfo principal;
|
||||||
|
|
||||||
|
public PrincipalInfo getPrincipal() {
|
||||||
|
return principal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrincipal(PrincipalInfo principal) {
|
||||||
|
this.principal = principal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static String _roles = "roles";
|
||||||
|
private List<Integer> roles;
|
||||||
|
|
||||||
|
public Boolean getAuthenticated() {
|
||||||
|
return isAuthenticated;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List<Integer> getRoles() {
|
||||||
|
return roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRoles(List<Integer> roles) {
|
||||||
|
this.roles = roles;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
package eu.eudat.models.v2;
|
||||||
|
|
||||||
|
import eu.eudat.commons.scope.UserScope;
|
||||||
|
import eu.eudat.data.entities.UserInfo;
|
||||||
|
import eu.eudat.data.entities.UserRole;
|
||||||
|
import eu.eudat.logic.services.ApiContext;
|
||||||
|
import eu.eudat.types.Authorities;
|
||||||
|
import gr.cite.commons.web.oidc.principal.CurrentPrincipalResolver;
|
||||||
|
import gr.cite.commons.web.oidc.principal.MyPrincipal;
|
||||||
|
import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractor;
|
||||||
|
import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractorKeys;
|
||||||
|
import gr.cite.tools.fieldset.BaseFieldSet;
|
||||||
|
import gr.cite.tools.fieldset.FieldSet;
|
||||||
|
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||||
|
public class AccountBuilder {
|
||||||
|
|
||||||
|
private final ClaimExtractor claimExtractor;
|
||||||
|
private final Set<String> excludeMoreClaim;
|
||||||
|
private final CurrentPrincipalResolver currentPrincipalResolver;
|
||||||
|
private final ApiContext apiContext;
|
||||||
|
private final UserScope userScope;
|
||||||
|
public AccountBuilder(ClaimExtractor claimExtractor, CurrentPrincipalResolver currentPrincipalResolver, ApiContext apiContext, UserScope userScope) {
|
||||||
|
this.claimExtractor = claimExtractor;
|
||||||
|
this.currentPrincipalResolver = currentPrincipalResolver;
|
||||||
|
this.apiContext = apiContext;
|
||||||
|
this.userScope = userScope;
|
||||||
|
this.excludeMoreClaim = Set.of(
|
||||||
|
ClaimExtractorKeys.Subject,
|
||||||
|
ClaimExtractorKeys.Name,
|
||||||
|
ClaimExtractorKeys.Scope,
|
||||||
|
ClaimExtractorKeys.Client,
|
||||||
|
ClaimExtractorKeys.IssuedAt,
|
||||||
|
ClaimExtractorKeys.NotBefore,
|
||||||
|
ClaimExtractorKeys.AuthenticatedAt,
|
||||||
|
ClaimExtractorKeys.ExpiresAt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Account build(FieldSet fields, MyPrincipal principal) {
|
||||||
|
Account model = new Account();
|
||||||
|
if (principal == null || !principal.isAuthenticated()) {
|
||||||
|
model.setIsAuthenticated(Boolean.FALSE);
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
model.setIsAuthenticated(Boolean.TRUE);
|
||||||
|
|
||||||
|
FieldSet principalFields = fields.extractPrefixed(BaseFieldSet.asIndexerPrefix(Account._principal));
|
||||||
|
if (!principalFields.isEmpty()) model.setPrincipal(new Account.PrincipalInfo());
|
||||||
|
if (principalFields.hasField(Account.PrincipalInfo._subject))
|
||||||
|
model.getPrincipal().setSubject(this.claimExtractor.subjectUUID(principal));
|
||||||
|
if (principalFields.hasField(Account.PrincipalInfo._userId))
|
||||||
|
model.getPrincipal().setUserId(this.userScope.getUserIdSafe());
|
||||||
|
if (principalFields.hasField(Account.PrincipalInfo._name))
|
||||||
|
model.getPrincipal().setName(this.claimExtractor.name(principal));
|
||||||
|
if (principalFields.hasField(Account.PrincipalInfo._scope))
|
||||||
|
model.getPrincipal().setScope(this.claimExtractor.scope(principal));
|
||||||
|
if (principalFields.hasField(Account.PrincipalInfo._client))
|
||||||
|
model.getPrincipal().setClient(this.claimExtractor.client(principal));
|
||||||
|
if (principalFields.hasField(Account.PrincipalInfo._issuedAt))
|
||||||
|
model.getPrincipal().setIssuedAt(this.claimExtractor.issuedAt(principal));
|
||||||
|
if (principalFields.hasField(Account.PrincipalInfo._notBefore))
|
||||||
|
model.getPrincipal().setNotBefore(this.claimExtractor.notBefore(principal));
|
||||||
|
if (principalFields.hasField(Account.PrincipalInfo._authenticatedAt))
|
||||||
|
model.getPrincipal().setAuthenticatedAt(this.claimExtractor.authenticatedAt(principal));
|
||||||
|
if (principalFields.hasField(Account.PrincipalInfo._expiresAt))
|
||||||
|
model.getPrincipal().setExpiresAt(this.claimExtractor.expiresAt(principal));
|
||||||
|
if (principalFields.hasField(Account.PrincipalInfo._more)) {
|
||||||
|
model.getPrincipal().setMore(new HashMap<>());
|
||||||
|
for (String key : this.claimExtractor.knownPublicKeys()) {
|
||||||
|
if (this.excludeMoreClaim.contains(key))
|
||||||
|
continue;
|
||||||
|
List<String> values = this.claimExtractor.asStrings(principal, key);
|
||||||
|
if (values == null || values.isEmpty())
|
||||||
|
continue;
|
||||||
|
if (!model.getPrincipal().getMore().containsKey(key))
|
||||||
|
model.getPrincipal().getMore().put(key, new ArrayList<>());
|
||||||
|
model.getPrincipal().getMore().get(key).addAll(values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UserInfo user = this.userScope.isSet() ? this.apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(this.userScope.getUserIdSafe()) : null; //TODO: Authn
|
||||||
|
List<UserRole> userRoles = this.userScope.isSet() ?apiContext.getOperationsContext().getDatabaseRepository().getUserRoleDao().getUserRoles(user) : new ArrayList<>();
|
||||||
|
if (fields.hasField(Account._roles)) {
|
||||||
|
//List<String> roles = claimExtractor.roles(currentPrincipalResolver.currentPrincipal());
|
||||||
|
//model.setRoles(roles);
|
||||||
|
model.setRoles(new ArrayList<>());
|
||||||
|
for (UserRole item : userRoles) {
|
||||||
|
model.getRoles().add(item.getRole());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,4 +12,5 @@ spring:
|
||||||
optional:classpath:config/email.yml[.yml], optional:classpath:config/email-${spring.profiles.active}.yml[.yml], optional:file:../config/email-${spring.profiles.active}.yml[.yml],
|
optional:classpath:config/email.yml[.yml], optional:classpath:config/email-${spring.profiles.active}.yml[.yml], optional:file:../config/email-${spring.profiles.active}.yml[.yml],
|
||||||
optional:classpath:config/elasticsearch.yml[.yml], optional:classpath:config/elasticsearch-${spring.profiles.active}.yml[.yml], optional:file:../config/elasticsearch-${spring.profiles.active}.yml[.yml],
|
optional:classpath:config/elasticsearch.yml[.yml], optional:classpath:config/elasticsearch-${spring.profiles.active}.yml[.yml], optional:file:../config/elasticsearch-${spring.profiles.active}.yml[.yml],
|
||||||
optional:classpath:config/file-path.yml[.yml], optional:classpath:config/file-path-${spring.profiles.active}.yml[.yml], optional:file:../config/file-path-${spring.profiles.active}.yml[.yml],
|
optional:classpath:config/file-path.yml[.yml], optional:classpath:config/file-path-${spring.profiles.active}.yml[.yml], optional:file:../config/file-path-${spring.profiles.active}.yml[.yml],
|
||||||
|
optional:classpath:config/idpclaims.yml[.yml], optional:classpath:config/idpclaims-${spring.profiles.active}.yml[.yml], optional:file:../config/idpclaims-${spring.profiles.active}.yml[.yml],
|
||||||
optional:classpath:config/external.yml[.yml], optional:classpath:config/external-${spring.profiles.active}.yml[.yml], optional:file:../config/external-${spring.profiles.active}.yml[.yml]
|
optional:classpath:config/external.yml[.yml], optional:classpath:config/external-${spring.profiles.active}.yml[.yml], optional:file:../config/external-${spring.profiles.active}.yml[.yml]
|
|
@ -15,9 +15,9 @@ cache:
|
||||||
initialCapacity: 100
|
initialCapacity: 100
|
||||||
maximumSize: 500
|
maximumSize: 500
|
||||||
enableRecordStats: false
|
enableRecordStats: false
|
||||||
expireAfterWriteMinutes: 1
|
expireAfterWriteMinutes: 10
|
||||||
expireAfterAccessMinutes: 1
|
expireAfterAccessMinutes: 10
|
||||||
refreshAfterWriteMinutes: 1
|
refreshAfterWriteMinutes: 10
|
||||||
- names: [ "supportiveMaterial" ]
|
- names: [ "supportiveMaterial" ]
|
||||||
allowNullValues: true
|
allowNullValues: true
|
||||||
initialCapacity: 100
|
initialCapacity: 100
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
idpclient:
|
||||||
|
claims:
|
||||||
|
mapping:
|
||||||
|
Subject:
|
||||||
|
- type: sub
|
||||||
|
Name:
|
||||||
|
- type: name
|
||||||
|
Client:
|
||||||
|
- type: client_id
|
||||||
|
AuthenticationMethod:
|
||||||
|
- type: amr
|
||||||
|
NotBefore:
|
||||||
|
- type: nbf
|
||||||
|
AuthenticatedAt:
|
||||||
|
- type: auth_time
|
||||||
|
ExpiresAt:
|
||||||
|
- type: exp
|
||||||
|
Email:
|
||||||
|
- type: email
|
||||||
|
Roles:
|
||||||
|
- type: resource_access
|
||||||
|
path: dmp_web.roles
|
||||||
|
Scope:
|
||||||
|
- type: scope
|
||||||
|
AccessToken:
|
||||||
|
- type: x-access-token
|
||||||
|
visibility: SENSITIVE
|
||||||
|
IssuedAt:
|
||||||
|
- type: iat
|
||||||
|
Issuer:
|
||||||
|
- type: iss
|
||||||
|
Audience:
|
||||||
|
- type: aud
|
||||||
|
TokenType:
|
||||||
|
- type: typ
|
||||||
|
AuthorizedParty:
|
||||||
|
- type: azp
|
||||||
|
Authorities:
|
||||||
|
- type: authorities
|
|
@ -1,3 +1,22 @@
|
||||||
|
web:
|
||||||
|
security:
|
||||||
|
enabled: true
|
||||||
|
authorized-endpoints: [ api ]
|
||||||
|
allowed-endpoints: [ api/public ]
|
||||||
|
idp:
|
||||||
|
api-key:
|
||||||
|
enabled: true
|
||||||
|
authorization-header: Authorization
|
||||||
|
client-id: ${IDP_APIKEY_CLIENT_ID:}
|
||||||
|
client-secret: ${IDP_APIKEY_CLIENT_SECRET:}
|
||||||
|
scope: ${IDP_APIKEY_SCOPE:}
|
||||||
|
resource:
|
||||||
|
opaque:
|
||||||
|
client-id: ${IDP_OPAQUE_CLIENT_ID:}
|
||||||
|
client-secret: ${IDP_OPAQUE_CLIENT_SECRET:}
|
||||||
|
jwt:
|
||||||
|
claims: [ role, x-role ]
|
||||||
|
|
||||||
autouser:
|
autouser:
|
||||||
root:
|
root:
|
||||||
email: ${AUTOUSER_EMAIL:}
|
email: ${AUTOUSER_EMAIL:}
|
||||||
|
|
|
@ -149,5 +149,8 @@
|
||||||
"@schematics/angular:directive": {
|
"@schematics/angular:directive": {
|
||||||
"prefix": "app"
|
"prefix": "app"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"cli": {
|
||||||
|
"analytics": false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
"dragula": "^3.7.3",
|
"dragula": "^3.7.3",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"moment": "^2.29.4",
|
"moment": "^2.29.4",
|
||||||
|
"keycloak-angular": "^14.0.0",
|
||||||
|
"keycloak-js": "^20.0.5",
|
||||||
"moment-timezone": "^0.5.43",
|
"moment-timezone": "^0.5.43",
|
||||||
"ng-dialog-animation": "^9.0.4",
|
"ng-dialog-animation": "^9.0.4",
|
||||||
"ng2-dragula": "^5.0.1",
|
"ng2-dragula": "^5.0.1",
|
||||||
|
|
|
@ -254,6 +254,7 @@ const appRoutes: Routes = [
|
||||||
title: 'GENERAL.TITLES.LOGIN'
|
title: 'GENERAL.TITLES.LOGIN'
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{ path: 'logout', loadChildren: () => import('./ui/auth/logout/logout.module').then(m => m.LogoutModule) },
|
||||||
{
|
{
|
||||||
path: 'api/oauth/authorized/b2access',
|
path: 'api/oauth/authorized/b2access',
|
||||||
component: B2AccessLoginComponent,
|
component: B2AccessLoginComponent,
|
||||||
|
|
|
@ -70,7 +70,7 @@ export class AppComponent implements OnInit, AfterViewInit {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const hamburger = document.getElementById('hamburger');
|
const hamburger = document.getElementById('hamburger');
|
||||||
if(hamburger){
|
if(hamburger){
|
||||||
hamburger.classList.add('change');
|
hamburger.classList.add('change');
|
||||||
}
|
}
|
||||||
}, 300);
|
}, 300);
|
||||||
}else{
|
}else{
|
||||||
|
@ -89,7 +89,7 @@ export class AppComponent implements OnInit, AfterViewInit {
|
||||||
hamburger.classList.remove('change');
|
hamburger.classList.remove('change');
|
||||||
}
|
}
|
||||||
this.sidenav.close();
|
this.sidenav.close();
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -120,7 +120,7 @@ export class AppComponent implements OnInit, AfterViewInit {
|
||||||
if (!this.cookieService.check("cookiesConsent")) {
|
if (!this.cookieService.check("cookiesConsent")) {
|
||||||
// this.cookieService.set("cookiesConsent", "false", 356);
|
// this.cookieService.set("cookiesConsent", "false", 356);
|
||||||
this.cookieService.set("cookiesConsent", "false", 356,null,null,false, 'Lax');
|
this.cookieService.set("cookiesConsent", "false", 356,null,null,false, 'Lax');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.hasBreadCrumb = this.router.events.pipe(
|
this.hasBreadCrumb = this.router.events.pipe(
|
||||||
|
@ -210,7 +210,7 @@ export class AppComponent implements OnInit, AfterViewInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
public isAuthenticated(): boolean {
|
public isAuthenticated(): boolean {
|
||||||
return !(!this.authentication.current());
|
return this.authentication.currentAccountIsAuthenticated();
|
||||||
}
|
}
|
||||||
|
|
||||||
goToDMPs() {
|
goToDMPs() {
|
||||||
|
@ -224,8 +224,8 @@ export class AppComponent implements OnInit, AfterViewInit {
|
||||||
|
|
||||||
initializeServices() {
|
initializeServices() {
|
||||||
this.translate.setDefaultLang(this.configurationService.defaultLanguage || 'en');
|
this.translate.setDefaultLang(this.configurationService.defaultLanguage || 'en');
|
||||||
this.authentication.current() && this.authentication.current().culture ? this.cultureService.cultureSelected(this.authentication.current().culture) : this.cultureService.cultureSelected(this.configurationService.defaultCulture);
|
this.authentication.currentAccountIsAuthenticated() && this.authentication.getUserProfileCulture() ? this.cultureService.cultureSelected(this.authentication.getUserProfileCulture()) : this.cultureService.cultureSelected(this.configurationService.defaultCulture);
|
||||||
this.authentication.current() && this.authentication.current().language ? this.language.changeLanguage(this.authentication.current().language) : (this.configurationService.defaultLanguage || 'en');
|
this.authentication.currentAccountIsAuthenticated() && this.authentication.getUserProfileLanguage() ? this.language.changeLanguage(this.authentication.getUserProfileLanguage()) : (this.configurationService.defaultLanguage || 'en');
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleNavbar(event) {
|
toggleNavbar(event) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { OverlayModule } from '@angular/cdk/overlay';
|
import { OverlayModule } from '@angular/cdk/overlay';
|
||||||
import { HttpClient, HttpClientModule } from '@angular/common/http';
|
import { HttpClient, HttpClientModule } from '@angular/common/http';
|
||||||
import { LOCALE_ID, NgModule } from '@angular/core';
|
import { APP_INITIALIZER, LOCALE_ID, NgModule } from '@angular/core';
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { MAT_MOMENT_DATE_FORMATS, MatMomentDateModule } from '@angular/material-moment-adapter';
|
import { MAT_MOMENT_DATE_FORMATS, MatMomentDateModule } from '@angular/material-moment-adapter';
|
||||||
import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE } from '@angular/material/core';
|
import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE } from '@angular/material/core';
|
||||||
|
@ -34,6 +34,11 @@ import { MatomoService } from './core/services/matomo/matomo-service';
|
||||||
import { GuidedTourModule } from './library/guided-tour/guided-tour.module';
|
import { GuidedTourModule } from './library/guided-tour/guided-tour.module';
|
||||||
import { Oauth2DialogModule } from './ui/misc/oauth2-dialog/oauth2-dialog.module';
|
import { Oauth2DialogModule } from './ui/misc/oauth2-dialog/oauth2-dialog.module';
|
||||||
import { OpenDMPCustomTranslationCompiler } from './utilities/translate/opendmp-custom-translation-compiler';
|
import { OpenDMPCustomTranslationCompiler } from './utilities/translate/opendmp-custom-translation-compiler';
|
||||||
|
import { KeycloakAngularModule, KeycloakService } from 'keycloak-angular';
|
||||||
|
import { BaseHttpParams } from '@common/http/base-http-params';
|
||||||
|
import { InterceptorType } from '@common/http/interceptors/interceptor-type';
|
||||||
|
import { from } from 'rxjs';
|
||||||
|
import { AuthService } from './core/services/auth/auth.service';
|
||||||
|
|
||||||
// AoT requires an exported function for factories
|
// AoT requires an exported function for factories
|
||||||
export function HttpLoaderFactory(http: HttpClient, appConfig: ConfigurationService) {
|
export function HttpLoaderFactory(http: HttpClient, appConfig: ConfigurationService) {
|
||||||
|
@ -77,10 +82,42 @@ const appearance: MatFormFieldDefaultOptions = {
|
||||||
// appearance: 'standard'
|
// appearance: 'standard'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function InstallationConfigurationFactory(appConfig: ConfigurationService, keycloak: KeycloakService, authService: AuthService) {
|
||||||
|
return () => appConfig.loadConfiguration().then(x => keycloak.init({
|
||||||
|
config: {
|
||||||
|
url: appConfig.keycloak.address,
|
||||||
|
realm: appConfig.keycloak.realm,
|
||||||
|
clientId: appConfig.keycloak.clientId,
|
||||||
|
},
|
||||||
|
initOptions: {
|
||||||
|
onLoad: 'check-sso',
|
||||||
|
flow: appConfig.keycloak.flow,
|
||||||
|
checkLoginIframe: false,
|
||||||
|
scope: appConfig.keycloak.scope,
|
||||||
|
pkceMethod: 'S256'
|
||||||
|
},
|
||||||
|
shouldAddToken: () => false
|
||||||
|
}).then(() => {
|
||||||
|
const params = new BaseHttpParams();
|
||||||
|
params.interceptorContext = {
|
||||||
|
excludedInterceptors: [
|
||||||
|
InterceptorType.Locale,
|
||||||
|
InterceptorType.ProgressIndication,
|
||||||
|
InterceptorType.RequestTiming,
|
||||||
|
InterceptorType.UnauthorizedResponse,
|
||||||
|
]
|
||||||
|
};
|
||||||
|
const tokenPromise = keycloak.getToken();
|
||||||
|
return authService.prepareAuthRequest(from(tokenPromise), {params}).toPromise().catch(error => authService.onAuthenticateError(error));
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
BrowserAnimationsModule,
|
BrowserAnimationsModule,
|
||||||
|
KeycloakAngularModule,
|
||||||
CoreServiceModule.forRoot(),
|
CoreServiceModule.forRoot(),
|
||||||
AppRoutingModule,
|
AppRoutingModule,
|
||||||
CommonUiModule,
|
CommonUiModule,
|
||||||
|
@ -120,6 +157,13 @@ const appearance: MatFormFieldDefaultOptions = {
|
||||||
ReloadHelperComponent
|
ReloadHelperComponent
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
|
ConfigurationService,
|
||||||
|
{
|
||||||
|
provide: APP_INITIALIZER,
|
||||||
|
useFactory: InstallationConfigurationFactory,
|
||||||
|
deps: [ConfigurationService, KeycloakService, AuthService],
|
||||||
|
multi: true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
provide: MAT_DATE_LOCALE,
|
provide: MAT_DATE_LOCALE,
|
||||||
deps: [CultureService],
|
deps: [CultureService],
|
||||||
|
|
|
@ -9,14 +9,8 @@ export class AdminAuthGuard implements CanActivate, CanLoad {
|
||||||
}
|
}
|
||||||
|
|
||||||
isAdmin(): boolean {
|
isAdmin(): boolean {
|
||||||
if (!this.auth.current()) { return false; }
|
if (!this.auth.currentAccountIsAuthenticated()) { return false; }
|
||||||
const principalRoles = this.auth.current().authorities;
|
return this.auth.hasRole(AppRole.Admin);
|
||||||
for (let i = 0; i < principalRoles.length; i++) {
|
|
||||||
if (principalRoles[i] === AppRole.Admin) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
|
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
|
||||||
|
|
|
@ -1,27 +1,40 @@
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { ActivatedRouteSnapshot, CanActivate, CanLoad, Route, Router, RouterStateSnapshot } from '@angular/router';
|
import { ActivatedRouteSnapshot, CanActivate, CanLoad, Route, Router, RouterStateSnapshot } from '@angular/router';
|
||||||
import { AuthService } from './services/auth/auth.service';
|
import { AuthService } from './services/auth/auth.service';
|
||||||
|
import { from, Observable, of as observableOf } from 'rxjs';
|
||||||
|
import { catchError, map, tap } from 'rxjs/operators';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AuthGuard implements CanActivate, CanLoad {
|
export class AuthGuard implements CanActivate, CanLoad {
|
||||||
constructor(private auth: AuthService, private router: Router) {
|
constructor(private authService: AuthService, private router: Router) {
|
||||||
}
|
}
|
||||||
|
|
||||||
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
|
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
|
||||||
const url: string = state.url;
|
const url: string = state.url;
|
||||||
if (!this.auth.current()) {
|
return this.applyGuard(url);
|
||||||
this.router.navigate(['/unauthorized'], { queryParams: { returnUrl: url } });
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
canLoad(route: Route): boolean {
|
canLoad(route: Route): Observable<boolean> {
|
||||||
const url = `/${route.path}`;
|
const url = `/${route.path}`;
|
||||||
if (!this.auth.current()) {
|
return this.applyGuard(url);
|
||||||
this.router.navigate(['/unauthorized'], { queryParams: { returnUrl: url } });
|
}
|
||||||
return false;
|
|
||||||
}
|
private applyGuard(url: string) {
|
||||||
return true;
|
return this.checkLogin(url).pipe(tap(loggedIn => {
|
||||||
|
if (!loggedIn) {
|
||||||
|
this.router.navigate(['/unauthorized'], { queryParams: { returnUrl: url } });
|
||||||
|
} else{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
private checkLogin(url: string): Observable<boolean> {
|
||||||
|
if (!this.authService.isLoggedIn()) { return observableOf(false); }
|
||||||
|
|
||||||
|
return this.authService.hasAccessToken()
|
||||||
|
? observableOf(true)
|
||||||
|
: from(this.authService.refreshToken()).pipe(
|
||||||
|
catchError(x => observableOf(false)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,16 +54,17 @@ import { TermsOfServiceService } from './services/terms-of-service/terms-of-serv
|
||||||
import { UnlinkAccountEmailConfirmationService } from './services/unlink-account-email-confirmation/unlink-account-email-confirmation.service';
|
import { UnlinkAccountEmailConfirmationService } from './services/unlink-account-email-confirmation/unlink-account-email-confirmation.service';
|
||||||
import { DescriptionTemplateTypeService } from './services/description-template-type/description-template-type.service';
|
import { DescriptionTemplateTypeService } from './services/description-template-type/description-template-type.service';
|
||||||
import { BaseHttpV2Service } from './services/http/base-http-v2.service';
|
import { BaseHttpV2Service } from './services/http/base-http-v2.service';
|
||||||
|
import { KeycloakService } from 'keycloak-angular';
|
||||||
|
import { PrincipalService } from './services/http/principal.service';
|
||||||
|
import { InterceptorType } from '@common/http/interceptors/interceptor-type';
|
||||||
|
import { BaseHttpParams } from '@common/http/base-http-params';
|
||||||
|
import { from } from 'rxjs';
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// This is shared module that provides all the services. Its imported only once on the AppModule.
|
// This is shared module that provides all the services. Its imported only once on the AppModule.
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
export function ConfigurationFactory(appConfig: ConfigurationService) {
|
|
||||||
return () => appConfig.loadConfiguration();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
})
|
})
|
||||||
export class CoreServiceModule {
|
export class CoreServiceModule {
|
||||||
|
@ -121,19 +122,13 @@ export class CoreServiceModule {
|
||||||
LockService,
|
LockService,
|
||||||
UserGuideService,
|
UserGuideService,
|
||||||
AboutService,
|
AboutService,
|
||||||
|
PrincipalService,
|
||||||
FaqService,
|
FaqService,
|
||||||
GlossaryService,
|
GlossaryService,
|
||||||
TermsOfServiceService,
|
TermsOfServiceService,
|
||||||
CurrencyService,
|
CurrencyService,
|
||||||
MergeEmailConfirmationService,
|
MergeEmailConfirmationService,
|
||||||
UnlinkAccountEmailConfirmationService,
|
UnlinkAccountEmailConfirmationService,
|
||||||
ConfigurationService,
|
|
||||||
{
|
|
||||||
provide: APP_INITIALIZER,
|
|
||||||
useFactory: ConfigurationFactory,
|
|
||||||
deps: [ConfigurationService, HttpClient],
|
|
||||||
multi: true
|
|
||||||
},
|
|
||||||
LanguageInfoService,
|
LanguageInfoService,
|
||||||
PrefillingService,
|
PrefillingService,
|
||||||
DescriptionTemplateTypeService
|
DescriptionTemplateTypeService
|
||||||
|
|
|
@ -1,15 +1,28 @@
|
||||||
import { AppRole } from "../../common/enum/app-role";
|
import { AppRole } from "@app/core/common/enum/app-role";
|
||||||
|
import { Guid } from "@common/types/guid";
|
||||||
|
|
||||||
export interface Principal {
|
export interface AppAccount {
|
||||||
id: string;
|
isAuthenticated: boolean;
|
||||||
token: string;
|
// permissions: AppPermission[];
|
||||||
name: string;
|
roles: AppRole[];
|
||||||
email: string;
|
principal: AppPrincipalInfo;
|
||||||
expiresAt: Date;
|
profile: UserProfileInfo;
|
||||||
authorities: AppRole[];
|
}
|
||||||
avatarUrl: string;
|
|
||||||
timezone: string;
|
export interface AppPrincipalInfo{
|
||||||
language: string;
|
subject: Guid;
|
||||||
culture: string;
|
name: string;
|
||||||
zenodoEmail: string;
|
scope: string[];
|
||||||
|
client: string;
|
||||||
|
notBefore: Date;
|
||||||
|
authenticatedAt: Date;
|
||||||
|
expiresAt: Date;
|
||||||
|
more: Record<string, string[]>
|
||||||
|
}
|
||||||
|
export interface UserProfileInfo {
|
||||||
|
culture: string;
|
||||||
|
language: string;
|
||||||
|
timezone: string;
|
||||||
|
avatarUrl: string;
|
||||||
|
email: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
import { KeycloakFlow } from 'keycloak-js';
|
||||||
|
import { LoginConfiguration } from './login-configuration.model';
|
||||||
|
|
||||||
|
export class KeycloakConfiguration {
|
||||||
|
|
||||||
|
private _enabled: boolean
|
||||||
|
get enabled(): boolean {
|
||||||
|
return this._enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _address: string
|
||||||
|
get address(): string {
|
||||||
|
return this._address;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _realm: string
|
||||||
|
get realm(): string {
|
||||||
|
return this._realm;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _flow: KeycloakFlow
|
||||||
|
get flow(): KeycloakFlow {
|
||||||
|
return this._flow;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _clientId: string
|
||||||
|
get clientId(): string {
|
||||||
|
return this._clientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _silentCheckSsoRedirectUri: string
|
||||||
|
get silentCheckSsoRedirectUri(): string {
|
||||||
|
return this._silentCheckSsoRedirectUri;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _scope: string
|
||||||
|
get scope(): string {
|
||||||
|
return this._scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static parseValue(value: any): KeycloakConfiguration {
|
||||||
|
const obj: KeycloakConfiguration = new KeycloakConfiguration();
|
||||||
|
obj._enabled = value.enabled;
|
||||||
|
obj._address = value.address;
|
||||||
|
obj._realm = value.realm;
|
||||||
|
obj._flow = value.flow;
|
||||||
|
obj._clientId = value.clientId;
|
||||||
|
obj._silentCheckSsoRedirectUri = value.silentCheckSsoRedirectUri;
|
||||||
|
obj._scope = value.scope;
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,203 +1,312 @@
|
||||||
|
|
||||||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
import { HttpClient, HttpErrorResponse, HttpHeaders } from '@angular/common/http';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { Credential } from '@app/core/model/auth/credential';
|
import { Credential } from '@app/core/model/auth/credential';
|
||||||
import { LoginInfo } from '@app/core/model/auth/login-info';
|
import { LoginInfo } from '@app/core/model/auth/login-info';
|
||||||
import { Principal } from '@app/core/model/auth/principal';
|
import { AppAccount } from '@app/core/model/auth/principal';
|
||||||
import { ConfigurableProvider } from '@app/core/model/configurable-provider/configurableProvider';
|
import { ConfigurableProvider } from '@app/core/model/configurable-provider/configurableProvider';
|
||||||
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
||||||
import { BaseService } from '@common/base/base.service';
|
import { BaseService } from '@common/base/base.service';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { environment } from 'environments/environment';
|
import { Observable, Subject, forkJoin, from, of as observableOf, throwError as observableThrowError } from 'rxjs';
|
||||||
import { Observable, of as observableOf, throwError as observableThrowError } from 'rxjs';
|
import { catchError, exhaustMap, map, takeUntil } from 'rxjs/operators';
|
||||||
import { catchError, map, takeUntil } from 'rxjs/operators';
|
|
||||||
import { ConfigurationService } from '../configuration/configuration.service';
|
import { ConfigurationService } from '../configuration/configuration.service';
|
||||||
import { CookieService } from 'ngx-cookie-service';
|
import { CookieService } from 'ngx-cookie-service';
|
||||||
|
import { Guid } from '@common/types/guid';
|
||||||
|
import { KeycloakEventType, KeycloakService } from 'keycloak-angular';
|
||||||
|
import { NgZone } from '@angular/core';
|
||||||
|
import { HttpError, HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service';
|
||||||
|
import { PrincipalService } from '../http/principal.service';
|
||||||
|
import { AppRole } from '@app/core/common/enum/app-role';
|
||||||
|
|
||||||
|
|
||||||
|
export interface AuthenticationState {
|
||||||
|
loginStatus: LoginStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum LoginStatus {
|
||||||
|
LoggedIn = 0,
|
||||||
|
LoggingOut = 1,
|
||||||
|
LoggedOut = 2
|
||||||
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AuthService extends BaseService {
|
export class AuthService extends BaseService {
|
||||||
private actionUrl: string;
|
|
||||||
private headers: HttpHeaders;
|
|
||||||
|
|
||||||
|
public authenticationStateSubject: Subject<AuthenticationState>;
|
||||||
|
private accessToken: string;
|
||||||
|
private appAccount: AppAccount;
|
||||||
|
|
||||||
|
private _authState: boolean;
|
||||||
constructor(
|
constructor(
|
||||||
private http: HttpClient,
|
private installationConfiguration: ConfigurationService,
|
||||||
private snackBar: MatSnackBar,
|
|
||||||
private language: TranslateService,
|
private language: TranslateService,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
|
private zone: NgZone,
|
||||||
|
private keycloakService: KeycloakService,
|
||||||
private uiNotificationService: UiNotificationService,
|
private uiNotificationService: UiNotificationService,
|
||||||
private configurationService: ConfigurationService,
|
private principalService: PrincipalService
|
||||||
private cookieService: CookieService
|
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
|
||||||
this.headers = new HttpHeaders();
|
this.authenticationStateSubject = new Subject<AuthenticationState>();
|
||||||
this.headers = this.headers.set('Content-Type', 'application/json');
|
|
||||||
this.headers = this.headers.set('Accept', 'application/json');
|
window.addEventListener('storage', (event: StorageEvent) => {
|
||||||
|
// Logout if we receive event that logout action occurred in a different tab.
|
||||||
|
if (
|
||||||
|
event.key &&
|
||||||
|
event.key === 'authState' &&
|
||||||
|
event.newValue === 'false' &&
|
||||||
|
this._authState
|
||||||
|
) {
|
||||||
|
this.clear();
|
||||||
|
this.router.navigate(['/unauthorized'], {
|
||||||
|
queryParams: { returnUrl: this.router.url },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public getAuthenticationStateObservable(): Observable<AuthenticationState> {
|
||||||
|
return this.authenticationStateSubject.asObservable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public beginLogOutProcess(): void {
|
||||||
|
this.authenticationStateSubject.next({
|
||||||
|
loginStatus: LoginStatus.LoggingOut,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public clear(): void {
|
public clear(): void {
|
||||||
localStorage.removeItem('principal');
|
this.authState(false);
|
||||||
|
this.accessToken = undefined;
|
||||||
|
this.appAccount = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
public current(principal?: Principal): Principal {
|
private authState(authState?: boolean): boolean {
|
||||||
if (principal) {
|
if (authState !== undefined) {
|
||||||
localStorage.setItem('principal', JSON.stringify(principal));
|
this._authState = authState;
|
||||||
return principal;
|
localStorage.setItem('authState', authState ? 'true' : 'false');
|
||||||
|
if (authState) {
|
||||||
|
this.authenticationStateSubject.next({
|
||||||
|
loginStatus: LoginStatus.LoggedIn,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.authenticationStateSubject.next({
|
||||||
|
loginStatus: LoginStatus.LoggedOut,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const principalJson = localStorage.getItem('principal');
|
if (this._authState === undefined) {
|
||||||
if (principalJson === null || principalJson === undefined) {
|
this._authState =
|
||||||
return null;
|
localStorage.getItem('authState') === 'true' ? true : false;
|
||||||
}
|
|
||||||
let principalObj = JSON.parse(principalJson) as Principal;
|
|
||||||
principalObj.expiresAt = new Date(principalObj.expiresAt);
|
|
||||||
if (principalObj.expiresAt < new Date()) {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
return principalObj;
|
return this._authState;
|
||||||
}
|
}
|
||||||
|
|
||||||
//public login(credential: Credential): Observable<Principal> {
|
public currentAccountIsAuthenticated(): boolean {
|
||||||
// const url = this.actionUrl + 'login';
|
return this.appAccount && this.appAccount.isAuthenticated;
|
||||||
|
|
||||||
// return this.http.post(url, credential, { headers: this.headers })
|
|
||||||
// .map((res: Response) => {
|
|
||||||
// let principal = this.current(new JsonSerializer<Principal>().fromJSONObject(res, Principal));
|
|
||||||
// //this.loginContextSubject.next(true);
|
|
||||||
// return principal;
|
|
||||||
// })
|
|
||||||
// .catch((error: any) => {
|
|
||||||
// //this.loginContextSubject.next(false);
|
|
||||||
// return Observable.throw(error);
|
|
||||||
// });
|
|
||||||
//}
|
|
||||||
|
|
||||||
public login(loginInfo: LoginInfo): Observable<Principal> {
|
|
||||||
this.actionUrl = this.configurationService.server + 'auth/';
|
|
||||||
const url = this.actionUrl + 'externallogin';
|
|
||||||
|
|
||||||
return this.http.post(url, loginInfo, { headers: this.headers }).pipe(
|
|
||||||
map((res: any) => {
|
|
||||||
const principal = this.current(res.payload);
|
|
||||||
// this.cookieService.set('cookiesConsent', 'true', 356);
|
|
||||||
this.cookieService.set("cookiesConsent", "true", 356,null,null,false, 'Lax');
|
|
||||||
//this.loginContextSubject.next(true);
|
|
||||||
return principal;
|
|
||||||
}),
|
|
||||||
catchError((error: any) => {
|
|
||||||
//this.loginContextSubject.next(false);
|
|
||||||
return observableThrowError(error);
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public mergeLogin(loginInfo: LoginInfo): Observable<any> {
|
//Should this be name @isAuthenticated@ instead?
|
||||||
this.actionUrl = this.configurationService.server + 'auth/';
|
public hasAccessToken(): boolean {
|
||||||
const url = this.actionUrl + 'externallogin';
|
return Boolean(this.currentAuthenticationToken());
|
||||||
|
|
||||||
return this.http.post(url, loginInfo, { headers: this.headers });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public nativeLogin(credentials: Credential): Observable<Principal> {
|
public currentAuthenticationToken(accessToken?: string): string {
|
||||||
this.actionUrl = this.configurationService.server + 'auth/';
|
if (accessToken) {
|
||||||
const url = this.actionUrl + 'nativelogin';
|
this.accessToken = accessToken;
|
||||||
|
|
||||||
return this.http.post(url, credentials, { headers: this.headers }).pipe(
|
|
||||||
map((res: any) => {
|
|
||||||
const principal = this.current(res.payload);
|
|
||||||
// this.cookieService.set('cookiesConsent', 'true', 356);
|
|
||||||
this.cookieService.set("cookiesConsent", "true", 356,null,null,false, 'Lax');
|
|
||||||
//this.loginContextSubject.next(true);
|
|
||||||
return principal;
|
|
||||||
}),
|
|
||||||
catchError((error: any) => {
|
|
||||||
//this.loginContextSubject.next(false);
|
|
||||||
return observableThrowError(error);
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public logout(): void {
|
|
||||||
this.actionUrl = this.configurationService.server + 'auth/';
|
|
||||||
const url = this.actionUrl + 'logout';
|
|
||||||
const principal = this.current();
|
|
||||||
this.clear();
|
|
||||||
|
|
||||||
if (!principal) { return; }
|
|
||||||
let headers = this.headers;
|
|
||||||
headers = headers.set('AuthToken', principal.token);
|
|
||||||
this.http.post(url, null, { headers: headers })
|
|
||||||
.pipe(takeUntil(this._destroyed))
|
|
||||||
.subscribe(
|
|
||||||
res => this.onLogOutSuccess(res),
|
|
||||||
error => this.onLogOutError(error)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public me(): Observable<Principal> {
|
|
||||||
this.actionUrl = this.configurationService.server + 'auth/';
|
|
||||||
const url = this.actionUrl + 'me';
|
|
||||||
const principal = this.current();
|
|
||||||
if (!principal) {
|
|
||||||
this.clear();
|
|
||||||
return observableOf<Principal>();
|
|
||||||
}
|
}
|
||||||
let headers = this.headers;
|
return this.accessToken;
|
||||||
headers = headers.set('AuthToken', principal.token);
|
|
||||||
return this.http.post(url, null, { headers: headers }).pipe(
|
|
||||||
map((res: any) => {
|
|
||||||
const princ = this.current(res.payload);
|
|
||||||
princ.expiresAt = new Date(princ.expiresAt);
|
|
||||||
console.log("Token Expires at: " + princ.expiresAt.toDateString() + ' ' + princ.expiresAt.toLocaleTimeString());
|
|
||||||
return princ;
|
|
||||||
}),
|
|
||||||
catchError((error: any) => {
|
|
||||||
//console.warn('could not retrieve me info:\n', error);
|
|
||||||
this.clear();
|
|
||||||
const princ = this.current();
|
|
||||||
this.router.navigate(['/login']);
|
|
||||||
return observableOf<Principal>(princ);
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public onLogOutSuccess(logoutMessage: any) {
|
public userId(): Guid {
|
||||||
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-LOGOUT'), SnackBarNotificationLevel.Success);
|
if (
|
||||||
this.router.navigate(['/login']);
|
this.appAccount &&
|
||||||
|
this.appAccount.principal &&
|
||||||
|
this.appAccount.principal.subject
|
||||||
|
) {
|
||||||
|
return this.appAccount.principal.subject;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public onLogOutError(errorMessage: string) {
|
public isLoggedIn(): boolean {
|
||||||
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-LOGOUT'), SnackBarNotificationLevel.Error);
|
return this.authState();
|
||||||
this.router.navigate(['/login']);
|
|
||||||
}
|
}
|
||||||
|
public prepareAuthRequest(observable: Observable<string>, httpParams?: Object): Observable<boolean> {
|
||||||
public getConfigurableProviders(): Observable<ConfigurableProvider[]> {
|
return observable.pipe(
|
||||||
this.actionUrl = this.configurationService.server + 'auth/';
|
map((x) => this.currentAuthenticationToken(x)),
|
||||||
const url = this.actionUrl + 'configurableLogin';
|
exhaustMap(() => forkJoin([
|
||||||
return this.http.get<ConfigurableProvider[]>(url, { headers: this.headers }).pipe(
|
this.principalService.me(httpParams)
|
||||||
map((res: any) => {
|
])),
|
||||||
const providers = res.payload.providers;
|
map((item) => {
|
||||||
return providers;
|
this.currentAccount(item[0]);
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
public refresh(): Observable<boolean> {
|
||||||
|
return this.principalService.me().pipe(
|
||||||
|
map((item) => {
|
||||||
|
this.currentAccount(item);
|
||||||
|
return true;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getUserFromToken(token: string): Observable<Principal> {
|
private currentAccount(
|
||||||
this.actionUrl = this.configurationService.server + 'auth/';
|
appAccount: AppAccount
|
||||||
const url = this.actionUrl + 'me';
|
): void {
|
||||||
let headers = this.headers;
|
this.appAccount = appAccount;
|
||||||
headers = headers.set('AuthToken', token);
|
this.authState(true);
|
||||||
return this.http.post(url, null, { headers: headers }).pipe(
|
|
||||||
map((res: any) => {
|
|
||||||
const princ = this.current(res.payload);
|
|
||||||
princ.expiresAt = new Date(princ.expiresAt);
|
|
||||||
return princ;
|
|
||||||
}),
|
|
||||||
catchError((error: any) => {
|
|
||||||
this.clear();
|
|
||||||
const princ = this.current();
|
|
||||||
this.router.navigate(['/login']);
|
|
||||||
return observableOf<Principal>(princ);
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getPrincipalName(): string {
|
||||||
|
if (this.appAccount && this.appAccount.principal) {
|
||||||
|
return this.appAccount.principal.name;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getRoles(): AppRole[] {
|
||||||
|
if (this.appAccount && this.appAccount.roles) {
|
||||||
|
return this.appAccount.roles;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public getUserProfileEmail(): string {
|
||||||
|
if (this.appAccount && this.appAccount.profile) {
|
||||||
|
return this.appAccount.profile.email;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getUserProfileLanguage(): string {
|
||||||
|
if (this.appAccount && this.appAccount.profile) {
|
||||||
|
return this.appAccount.profile.language;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public hasAnyRole(roles: AppRole[]): boolean {
|
||||||
|
if (!roles) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return roles.filter((r) => this.hasRole(r)).length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public hasRole(role: AppRole): boolean {
|
||||||
|
if (role === undefined) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
!this.appAccount ||
|
||||||
|
!this.appAccount.roles ||
|
||||||
|
this.appAccount.roles.length === 0
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return this.appAccount.roles
|
||||||
|
.includes(role);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getUserProfileCulture(): string {
|
||||||
|
if (this.appAccount && this.appAccount.profile) {
|
||||||
|
return this.appAccount.profile.culture;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getUserProfileAvatarUrl(): string {
|
||||||
|
if (this.appAccount && this.appAccount.profile) {
|
||||||
|
return this.appAccount.profile.avatarUrl;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getUserProfileTimezone(): string {
|
||||||
|
if (this.appAccount && this.appAccount.profile) {
|
||||||
|
return this.appAccount.profile.timezone;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public authenticate(returnUrl: string) {
|
||||||
|
this.keycloakService.isLoggedIn().then((isLoggedIn) => {
|
||||||
|
if (!isLoggedIn) {
|
||||||
|
this.keycloakService.login({
|
||||||
|
scope: this.installationConfiguration.keycloak.scope,
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
console.log('Keycloak Login');
|
||||||
|
this.keycloakService.keycloakEvents$.subscribe({
|
||||||
|
next: (e) => {
|
||||||
|
if (
|
||||||
|
e.type === KeycloakEventType.OnTokenExpired
|
||||||
|
) {
|
||||||
|
this.refreshToken({});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
this.onAuthenticateSuccess(returnUrl);
|
||||||
|
})
|
||||||
|
.catch((error) => this.onAuthenticateError(error));
|
||||||
|
} else {
|
||||||
|
this.zone.run(() => this.router.navigate([returnUrl]));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public refreshToken(httpParams?: Object): Promise<boolean> {
|
||||||
|
return this.keycloakService.updateToken(60).then((isRefreshed) => {
|
||||||
|
if (!isRefreshed) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.prepareAuthRequest(
|
||||||
|
from(this.keycloakService.getToken()),
|
||||||
|
httpParams
|
||||||
|
)
|
||||||
|
.pipe(takeUntil(this._destroyed))
|
||||||
|
.pipe(
|
||||||
|
map(
|
||||||
|
() => {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
this.onAuthenticateError(error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.toPromise();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onAuthenticateError(errorResponse: HttpErrorResponse) {
|
||||||
|
this.zone.run(() => {
|
||||||
|
// const error: HttpError =
|
||||||
|
// this.httpErrorHandlingService.getError(errorResponse);
|
||||||
|
this.uiNotificationService.snackBarNotification(
|
||||||
|
// error.getMessagesString(),
|
||||||
|
errorResponse.message,
|
||||||
|
SnackBarNotificationLevel.Warning
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onAuthenticateSuccess(returnUrl: string): void {
|
||||||
|
this.authState(true);
|
||||||
|
this.uiNotificationService.snackBarNotification(
|
||||||
|
this.language.instant('COMMONS.SNACK-BAR.SUCCESSFUL-LOGIN'),
|
||||||
|
SnackBarNotificationLevel.Success
|
||||||
|
);
|
||||||
|
this.zone.run(() => this.router.navigate([returnUrl]));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { HelpService } from '@app/core/model/configuration-models/help-service.m
|
||||||
import { LoginProviders } from '@app/core/model/configuration-models/login-providers.model';
|
import { LoginProviders } from '@app/core/model/configuration-models/login-providers.model';
|
||||||
import { Logging } from '@app/core/model/configuration-models/logging.model';
|
import { Logging } from '@app/core/model/configuration-models/logging.model';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
|
import { KeycloakConfiguration } from '@app/core/model/configuration-models/keycloak-configuration.model';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
|
@ -101,31 +102,47 @@ export class ConfigurationService extends BaseComponent {
|
||||||
return this._maxFileSizeInMB;
|
return this._maxFileSizeInMB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private _keycloak: KeycloakConfiguration;
|
||||||
|
get keycloak(): KeycloakConfiguration {
|
||||||
|
return this._keycloak;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public loadConfiguration(): Promise<any> {
|
public loadConfiguration(): Promise<any> {
|
||||||
return new Promise((r, e) => {
|
return new Promise((r, e) => {
|
||||||
|
|
||||||
// We need to exclude all interceptors here, for the initial configuration request.
|
// We need to exclude all interceptors here, for the initial configuration request.
|
||||||
const params = new BaseHttpParams();
|
const params = new BaseHttpParams();
|
||||||
params.interceptorContext = {
|
params.interceptorContext = {
|
||||||
excludedInterceptors: [InterceptorType.AuthToken,
|
excludedInterceptors: [
|
||||||
InterceptorType.JSONContentType,
|
InterceptorType.AuthToken,
|
||||||
InterceptorType.Locale,
|
InterceptorType.JSONContentType,
|
||||||
InterceptorType.ProgressIndication,
|
InterceptorType.Locale,
|
||||||
InterceptorType.RequestTiming,
|
InterceptorType.ProgressIndication,
|
||||||
InterceptorType.UnauthorizedResponse]
|
InterceptorType.RequestTiming,
|
||||||
|
InterceptorType.UnauthorizedResponse,
|
||||||
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
this.http.get('./assets/config/config.json', { params: params }).pipe(catchError((err: any, caught: Observable<any>) => throwError(err)))
|
this.http
|
||||||
|
.get("./assets/config/config.json", { params: params })
|
||||||
|
.pipe(
|
||||||
|
catchError((err: any, caught: Observable<any>) =>
|
||||||
|
throwError(err)
|
||||||
|
)
|
||||||
|
)
|
||||||
.pipe(takeUntil(this._destroyed))
|
.pipe(takeUntil(this._destroyed))
|
||||||
.subscribe(
|
.subscribe(
|
||||||
(content: ConfigurationService) => {
|
(content: ConfigurationService) => {
|
||||||
this.parseResponse(content);
|
this.parseResponse(content);
|
||||||
r(this);
|
r(this);
|
||||||
},
|
},
|
||||||
reason => e(reason));
|
(reason) => e(reason)
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private parseResponse(config: any) {
|
private parseResponse(config: any) {
|
||||||
this._server = config.Server;
|
this._server = config.Server;
|
||||||
this._app = config.App;
|
this._app = config.App;
|
||||||
|
@ -134,6 +151,7 @@ export class ConfigurationService extends BaseComponent {
|
||||||
this._defaultLanguage = config.defaultLanguage;
|
this._defaultLanguage = config.defaultLanguage;
|
||||||
this._availableLanguages = config.availableLanguages;
|
this._availableLanguages = config.availableLanguages;
|
||||||
this._loginProviders = LoginProviders.parseValue(config.loginProviders);
|
this._loginProviders = LoginProviders.parseValue(config.loginProviders);
|
||||||
|
this._keycloak = KeycloakConfiguration.parseValue(config.keycloak);
|
||||||
this._logging = Logging.parseValue(config.logging);
|
this._logging = Logging.parseValue(config.logging);
|
||||||
this._lockInterval = config.lockInterval;
|
this._lockInterval = config.lockInterval;
|
||||||
this._guideAssets = config.guideAssets;
|
this._guideAssets = config.guideAssets;
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { ConfigurationService } from '../configuration/configuration.service';
|
||||||
|
import { BaseHttpService } from './base-http.service';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { AppAccount } from '@app/core/model/auth/principal';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class PrincipalService {
|
||||||
|
|
||||||
|
private get apiBase(): string { return `${this.installationConfiguration.server}principal`; }
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private installationConfiguration: ConfigurationService,
|
||||||
|
private http: BaseHttpService
|
||||||
|
) { }
|
||||||
|
|
||||||
|
public me(options?: Object): Observable<AppAccount> {
|
||||||
|
const url = `${this.apiBase}/me`;
|
||||||
|
return this.http.get<AppAccount>(url, options);
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,24 +23,24 @@ export class MatomoService {
|
||||||
|
|
||||||
trackPageView(customTitle?: string): void {
|
trackPageView(customTitle?: string): void {
|
||||||
if (this.configurationService.matomoEnabled) {
|
if (this.configurationService.matomoEnabled) {
|
||||||
var principal = this.authService.current();
|
var principalid = this.authService.userId();
|
||||||
if (principal != null) { this.matomoTracker.setUserId(principal.id); }
|
if (principalid != null) { this.matomoTracker.setUserId(principalid.toString()); }
|
||||||
this.matomoTracker.trackPageView(customTitle);
|
this.matomoTracker.trackPageView(customTitle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trackSiteSearch(keyword: string, category?: string, resultsCount?: number): void {
|
trackSiteSearch(keyword: string, category?: string, resultsCount?: number): void {
|
||||||
if (this.configurationService.matomoEnabled) {
|
if (this.configurationService.matomoEnabled) {
|
||||||
var principal = this.authService.current();
|
var principalid = this.authService.userId();
|
||||||
if (principal != null) { this.matomoTracker.setUserId(principal.id); }
|
if (principalid != null) { this.matomoTracker.setUserId(principalid.toString()); }
|
||||||
this.matomoTracker.trackSiteSearch(keyword, category, resultsCount);
|
this.matomoTracker.trackSiteSearch(keyword, category, resultsCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trackDownload(category: "dmps" | "datasets", type: "docx" | "pdf" | "xml" | "json", id: string): void {
|
trackDownload(category: "dmps" | "datasets", type: "docx" | "pdf" | "xml" | "json", id: string): void {
|
||||||
if (this.configurationService.matomoEnabled) {
|
if (this.configurationService.matomoEnabled) {
|
||||||
var principal = this.authService.current();
|
var principalid = this.authService.userId();
|
||||||
if (principal != null) { this.matomoTracker.setUserId(principal.id); }
|
if (principalid != null) { this.matomoTracker.setUserId(principalid.toString()); }
|
||||||
this.matomoTracker.trackLink(this.configurationService.server + category + "/" + type + "/" + id, "download");
|
this.matomoTracker.trackLink(this.configurationService.server + category + "/" + type + "/" + id, "download");
|
||||||
|
|
||||||
// this.matomoTracker.trackLink(url, "download");
|
// this.matomoTracker.trackLink(url, "download");
|
||||||
|
|
|
@ -9,14 +9,8 @@ export class SpecialAuthGuard implements CanActivate, CanLoad {
|
||||||
}
|
}
|
||||||
|
|
||||||
hasPermission(permission: AppRole): boolean {
|
hasPermission(permission: AppRole): boolean {
|
||||||
if (!this.auth.current()) { return false; }
|
if (!this.auth.currentAccountIsAuthenticated()) { return false; }
|
||||||
const principalRoles = this.auth.current().authorities;
|
return this.auth.hasRole(permission);
|
||||||
for (let i = 0; i < principalRoles.length; i++) {
|
|
||||||
if (principalRoles[i] === permission) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
|
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
|
||||||
|
|
|
@ -177,12 +177,4 @@ export class UserListingComponent extends BaseComponent implements OnInit, After
|
||||||
public setDefaultAvatar(ev: Event) {
|
public setDefaultAvatar(ev: Event) {
|
||||||
(ev.target as HTMLImageElement).src = 'assets/images/profile-placeholder.png';
|
(ev.target as HTMLImageElement).src = 'assets/images/profile-placeholder.png';
|
||||||
}
|
}
|
||||||
|
|
||||||
// public principalHasAvatar(): boolean {
|
|
||||||
// return this.authentication.current().avatarUrl != null && this.authentication.current().avatarUrl.length > 0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// public getPrincipalAvatar(): string {
|
|
||||||
// return this.authentication.current().avatarUrl;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,18 +42,18 @@ export class AdminLoginComponent extends BaseComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
public nativeLogin() {
|
public nativeLogin() {
|
||||||
this.authService.nativeLogin(this.credential)
|
// this.authService.nativeLogin(this.credential)
|
||||||
.pipe(takeUntil(this._destroyed))
|
// .pipe(takeUntil(this._destroyed))
|
||||||
.subscribe(
|
// .subscribe(
|
||||||
res => this.onLogInSuccess(res),
|
// res => this.onLogInSuccess(res),
|
||||||
error => this.onLogInError(error)
|
// error => this.onLogInError(error)
|
||||||
);
|
// );
|
||||||
}
|
}
|
||||||
|
|
||||||
public onLogInSuccess(loginResponse: any) {
|
public onLogInSuccess(loginResponse: any) {
|
||||||
this.uiNotificationService.snackBarNotification(this.translate.instant('GENERAL.SNACK-BAR.SUCCESSFUL-LOGIN'), SnackBarNotificationLevel.Success);
|
this.uiNotificationService.snackBarNotification(this.translate.instant('GENERAL.SNACK-BAR.SUCCESSFUL-LOGIN'), SnackBarNotificationLevel.Success);
|
||||||
if (this.authService.current().culture) { this.cultureService.cultureSelected(this.authService.current().culture); }
|
if (this.authService.currentAccountIsAuthenticated() && this.authService.getUserProfileCulture()) { this.cultureService.cultureSelected(this.authService.getUserProfileCulture()); }
|
||||||
if (this.authService.current().language) { this.language.changeLanguage(this.authService.current().language); }
|
if (this.authService.currentAccountIsAuthenticated() && this.authService.getUserProfileLanguage()) { this.language.changeLanguage(this.authService.getUserProfileLanguage()); }
|
||||||
this.router.navigate(['/']);
|
this.router.navigate(['/']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,18 +48,18 @@ export class B2AccessLoginComponent extends BaseComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
public b2AccessLogin(code: String) {
|
public b2AccessLogin(code: String) {
|
||||||
let headers = new HttpHeaders();
|
// let headers = new HttpHeaders();
|
||||||
headers = headers.set('Content-Type', 'application/json');
|
// headers = headers.set('Content-Type', 'application/json');
|
||||||
headers = headers.set('Accept', 'application/json');
|
// headers = headers.set('Accept', 'application/json');
|
||||||
this.httpClient.post(this.configurationService.server + 'auth/b2AccessRequestToken', { code: code }, { headers: headers })
|
// this.httpClient.post(this.configurationService.server + 'auth/b2AccessRequestToken', { code: code }, { headers: headers })
|
||||||
.pipe(takeUntil(this._destroyed))
|
// .pipe(takeUntil(this._destroyed))
|
||||||
.subscribe((data: any) => {
|
// .subscribe((data: any) => {
|
||||||
this.authService.login({ ticket: data.payload.accessToken, provider: AuthProvider.B2Access, data: null })
|
// this.authService.login({ ticket: data.payload.accessToken, provider: AuthProvider.B2Access, data: null })
|
||||||
.pipe(takeUntil(this._destroyed))
|
// .pipe(takeUntil(this._destroyed))
|
||||||
.subscribe(
|
// .subscribe(
|
||||||
res => this.loginService.onLogInSuccess(res, this.returnUrl),
|
// res => this.loginService.onLogInSuccess(res, this.returnUrl),
|
||||||
error => this.loginService.onLogInError(error)
|
// error => this.loginService.onLogInError(error)
|
||||||
);
|
// );
|
||||||
});
|
// });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue