diff --git a/dmp-backend/src/main/java/eu/eudat/EuDatApplication.java b/dmp-backend/src/main/java/eu/eudat/EuDatApplication.java index 39f2c2410..fe4b30503 100644 --- a/dmp-backend/src/main/java/eu/eudat/EuDatApplication.java +++ b/dmp-backend/src/main/java/eu/eudat/EuDatApplication.java @@ -1,13 +1,19 @@ package eu.eudat; +import eu.eudat.handlers.PrincipalArgumentResolver; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; + +import java.util.List; /** * Created by ikalyvas on 12/15/2017. */ @SpringBootApplication public class EuDatApplication { + + public static void main(String[] args) { System.setProperty("spring.devtools.restart.enabled", "true"); SpringApplication.run(EuDatApplication.class, args); diff --git a/dmp-backend/src/main/java/eu/eudat/configurations/WebMVCConfiguration.java b/dmp-backend/src/main/java/eu/eudat/configurations/WebMVCConfiguration.java new file mode 100644 index 000000000..449ca039f --- /dev/null +++ b/dmp-backend/src/main/java/eu/eudat/configurations/WebMVCConfiguration.java @@ -0,0 +1,21 @@ +package eu.eudat.configurations; + +import eu.eudat.handlers.PrincipalArgumentResolver; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; + +import java.util.List; + +/** + * Created by ikalyvas on 12/15/2017. + */ +@Configuration +public class WebMVCConfiguration extends WebMvcConfigurerAdapter { + + + @Override + public void addArgumentResolvers(List argumentResolvers) { + argumentResolvers.add(new PrincipalArgumentResolver()); + } +} diff --git a/dmp-backend/src/main/java/eu/eudat/controllers/DMPs.java b/dmp-backend/src/main/java/eu/eudat/controllers/DMPs.java index 1b0665b31..92e805fde 100644 --- a/dmp-backend/src/main/java/eu/eudat/controllers/DMPs.java +++ b/dmp-backend/src/main/java/eu/eudat/controllers/DMPs.java @@ -15,6 +15,7 @@ import eu.eudat.models.dmp.DataManagementPlan; import eu.eudat.models.dmp.DataManagementPlanTableRequest; import eu.eudat.models.helpers.DataTableData; +import eu.eudat.models.responses.ResponseItem; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -68,27 +69,27 @@ public class DMPs { @RequestMapping(method = RequestMethod.POST, value = { "/dmps/getPaged" }, consumes = "application/json", produces="application/json") - public @ResponseBody ResponseEntity> getPaged(@RequestBody DataManagementPlanTableRequest dataManagementPlanTableRequest) { + public @ResponseBody ResponseItem> getPaged(@RequestBody DataManagementPlanTableRequest dataManagementPlanTableRequest) { try { DataTableData dataTable = new DataManagementPlanManager().getPaged(dMPDao, dataManagementPlanTableRequest); - return ResponseEntity.status(HttpStatus.OK).body(dataTable); + return new ResponseItem>().status(HttpStatus.OK).payload(dataTable); } catch (Exception ex) { ex.printStackTrace(); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null); + return new ResponseItem>().status(HttpStatus.BAD_REQUEST).message(ex.getMessage()); } } @RequestMapping(method = RequestMethod.GET, value = { "/dmps/getSingle/{id}" }, produces="application/json") - public @ResponseBody ResponseEntity getPaged(@PathVariable String id) { + public @ResponseBody ResponseItem getPaged(@PathVariable String id) { try { eu.eudat.models.dmp.DataManagementPlan project = new DataManagementPlanManager().getSingle(dMPDao, id); - return ResponseEntity.status(HttpStatus.OK).body(project); + return new ResponseItem().status(HttpStatus.OK).payload(project); } catch (Exception ex) { ex.printStackTrace(); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null); + return new ResponseItem().status(HttpStatus.BAD_REQUEST).message(ex.getMessage()); } } diff --git a/dmp-backend/src/main/java/eu/eudat/controllers/DashBoardController.java b/dmp-backend/src/main/java/eu/eudat/controllers/DashBoardController.java index 9df9d3842..ea52b4541 100644 --- a/dmp-backend/src/main/java/eu/eudat/controllers/DashBoardController.java +++ b/dmp-backend/src/main/java/eu/eudat/controllers/DashBoardController.java @@ -3,6 +3,8 @@ package eu.eudat.controllers; import java.util.Map; import java.util.UUID; +import eu.eudat.models.responses.ResponseItem; +import eu.eudat.models.security.Principal; import org.json.JSONObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -38,14 +40,14 @@ public class DashBoardController { @Autowired private ProjectDao projectDao; @RequestMapping(method = RequestMethod.GET, value = { "/dashboard/getStatistics" }, produces="application/json") - public ResponseEntity getStatistics(){ + public ResponseItem getStatistics(Principal principal){ try { DashBoardStatistics statistics = new DashBoardManager().getStatistics(datasetDao, dMPDao, projectDao); - return ResponseEntity.status(HttpStatus.OK).body(statistics); + return new ResponseItem().status(HttpStatus.OK).payload(statistics); } catch(Exception ex) { ex.printStackTrace(); - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); + return new ResponseItem().status(HttpStatus.INTERNAL_SERVER_ERROR).message(ex.getMessage()); } } } diff --git a/dmp-backend/src/main/java/eu/eudat/controllers/Datasets.java b/dmp-backend/src/main/java/eu/eudat/controllers/Datasets.java index 7fedf775a..235e0f4f6 100644 --- a/dmp-backend/src/main/java/eu/eudat/controllers/Datasets.java +++ b/dmp-backend/src/main/java/eu/eudat/controllers/Datasets.java @@ -14,6 +14,7 @@ import eu.eudat.models.dataset.DatasetTableRequest; import eu.eudat.models.helpers.DataTableData; import eu.eudat.models.project.Project; import eu.eudat.models.project.ProjectTableRequest; +import eu.eudat.models.responses.ResponseItem; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -68,25 +69,25 @@ public class Datasets { @RequestMapping(method = RequestMethod.POST, value = { "/datasets/getPaged" }, consumes = "application/json", produces="application/json") - public @ResponseBody ResponseEntity> getPaged(@RequestBody DatasetTableRequest datasetTableRequest) { + public @ResponseBody ResponseItem> getPaged(@RequestBody DatasetTableRequest datasetTableRequest) { try { DataTableData dataTable = new DatasetManager().getPaged(datasetDao, datasetTableRequest); - return ResponseEntity.status(HttpStatus.OK).body(dataTable); + return new ResponseItem>().status(HttpStatus.OK).payload(dataTable); } catch (Exception ex) { ex.printStackTrace(); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null); + return new ResponseItem>().status(HttpStatus.OK).message(ex.getMessage()); } } @RequestMapping(method = RequestMethod.GET, value = { "/datasets/getSingle/{id}" }, produces="application/json") - public @ResponseBody ResponseEntity getPaged(@PathVariable String id) { + public @ResponseBody ResponseItem getPaged(@PathVariable String id) { try { eu.eudat.models.dataset.Dataset dataset = new DatasetManager().getSingle(datasetDao, id); - return ResponseEntity.status(HttpStatus.OK).body(dataset); + return new ResponseItem().status(HttpStatus.OK).payload(dataset); } catch (Exception ex) { ex.printStackTrace(); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null); + return new ResponseItem().status(HttpStatus.OK).message(ex.getMessage()); } } diff --git a/dmp-backend/src/main/java/eu/eudat/controllers/Login.java b/dmp-backend/src/main/java/eu/eudat/controllers/Login.java new file mode 100644 index 000000000..99a3d70d0 --- /dev/null +++ b/dmp-backend/src/main/java/eu/eudat/controllers/Login.java @@ -0,0 +1,36 @@ +package eu.eudat.controllers; + +import eu.eudat.managers.DataManagementPlanManager; +import eu.eudat.models.dmp.DataManagementPlan; +import eu.eudat.models.dmp.DataManagementPlanTableRequest; +import eu.eudat.models.helpers.DataTableData; +import eu.eudat.models.login.Credentials; +import eu.eudat.models.responses.ResponseItem; +import eu.eudat.models.security.Principal; +import eu.eudat.security.CustomAuthenticationProvider; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.*; + +/** + * Created by ikalyvas on 12/15/2017. + */ +@RestController +@CrossOrigin +@RequestMapping(value = "/login") +public class Login { + + @Autowired + private CustomAuthenticationProvider customAuthenticationProvider; + + @RequestMapping(method = RequestMethod.POST, value = { "/googlelogin" }, consumes = "application/json", produces="application/json") + public @ResponseBody ResponseItem googleLogin(@RequestBody Credentials credentials) { + try { + return new ResponseItem().payload(customAuthenticationProvider.authenticate(credentials)).status(HttpStatus.OK); + + } catch (Exception ex) { + ex.printStackTrace(); + return new ResponseItem().status(HttpStatus.BAD_REQUEST).message(ex.getMessage()); + } + } +} diff --git a/dmp-backend/src/main/java/eu/eudat/controllers/Projects.java b/dmp-backend/src/main/java/eu/eudat/controllers/Projects.java index 1fd32d3d4..c6f71ec23 100644 --- a/dmp-backend/src/main/java/eu/eudat/controllers/Projects.java +++ b/dmp-backend/src/main/java/eu/eudat/controllers/Projects.java @@ -11,6 +11,7 @@ import java.util.stream.Collectors; import javax.transaction.Transactional; +import eu.eudat.models.responses.ResponseItem; import org.apache.commons.lang3.SerializationUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -94,34 +95,34 @@ public class Projects { @RequestMapping(method = RequestMethod.POST, value = { "/projects/getPaged" }, consumes = "application/json", produces="application/json") - public @ResponseBody ResponseEntity> getPaged(@RequestBody ProjectTableRequest projectTableRequest) { + public @ResponseBody ResponseItem> getPaged(@RequestBody ProjectTableRequest projectTableRequest) { try { DataTableData dataTable = new ProjectManager().getPaged(projectDao, projectTableRequest); - return ResponseEntity.status(HttpStatus.OK).body(dataTable); + return new ResponseItem>().payload(dataTable).status(HttpStatus.OK); } catch (Exception ex) { ex.printStackTrace(); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null); + return new ResponseItem>().status(HttpStatus.BAD_REQUEST).message(ex.getMessage()); } } @RequestMapping(method = RequestMethod.GET, value = { "/projects/getSingle/{id}" }, produces="application/json") - public @ResponseBody ResponseEntity getPaged(@PathVariable String id) { + public @ResponseBody ResponseItem getPaged(@PathVariable String id) { try { eu.eudat.models.project.Project project = new ProjectManager().getSingle(projectDao, id); - return ResponseEntity.status(HttpStatus.OK).body(project); + return new ResponseItem().payload(project).status(HttpStatus.OK); } catch (Exception ex) { ex.printStackTrace(); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null); + return new ResponseItem().status(HttpStatus.BAD_REQUEST).message(ex.getMessage()); } } @Transactional @RequestMapping(method = RequestMethod.POST, value = { "/projects/add" }, consumes = "application/json", produces="application/json") - public @ResponseBody ResponseEntity addProject(@RequestBody eu.eudat.models.project.Project project) { + public @ResponseBody ResponseItem addProject(@RequestBody eu.eudat.models.project.Project project) { Project createdProject = projectDao.update(project.toDataModel()); - return ResponseEntity.status(HttpStatus.CREATED).body(createdProject); + return new ResponseItem().payload(createdProject).status(HttpStatus.OK); } diff --git a/dmp-backend/src/main/java/eu/eudat/dao/entities/UserInfoDao.java b/dmp-backend/src/main/java/eu/eudat/dao/entities/UserInfoDao.java index 2f6db17cf..28a9fb1f4 100644 --- a/dmp-backend/src/main/java/eu/eudat/dao/entities/UserInfoDao.java +++ b/dmp-backend/src/main/java/eu/eudat/dao/entities/UserInfoDao.java @@ -15,9 +15,7 @@ public interface UserInfoDao extends Dao { public UserInfo getByIdAndMail(String id, String email); public UserInfo getByMail(String email); - - public UserInfo getByAuthenticationId(String authentication); - + public UserInfo getByUsername(String username); public List getDmpsOfUser(String userID); diff --git a/dmp-backend/src/main/java/eu/eudat/dao/entities/UserInfoDaoImpl.java b/dmp-backend/src/main/java/eu/eudat/dao/entities/UserInfoDaoImpl.java index 00153e50c..7a265be81 100644 --- a/dmp-backend/src/main/java/eu/eudat/dao/entities/UserInfoDaoImpl.java +++ b/dmp-backend/src/main/java/eu/eudat/dao/entities/UserInfoDaoImpl.java @@ -1,7 +1,6 @@ package eu.eudat.dao.entities; import java.util.List; -import java.util.Set; import java.util.UUID; import javax.persistence.NoResultException; @@ -10,7 +9,6 @@ import javax.persistence.TypedQuery; import eu.eudat.dao.JpaDao; import eu.eudat.entities.DMP; import eu.eudat.entities.UserInfo; -import eu.eudat.entities.security.UserAuth; import org.springframework.stereotype.Component; @Component("userInfoDao") @@ -51,22 +49,6 @@ public class UserInfoDaoImpl extends JpaDao implements UserInfoD return null; } } - - @Override - public UserInfo getByAuthenticationId(String authenticationID) { - UserAuth userauth = new UserAuth(); - userauth.setId(UUID.fromString(authenticationID)); - String queryString = "FROM UserInfo userInfo where userInfo.authentication = :auth"; - TypedQuery typedQuery = entityManager.createQuery(queryString, UserInfo.class); - typedQuery.setParameter("auth", userauth); - try { - return typedQuery.getSingleResult(); - } - catch(NoResultException ex) { - return null; - } - } - @Override diff --git a/dmp-backend/src/main/java/eu/eudat/dao/entities/security/CredentialDao.java b/dmp-backend/src/main/java/eu/eudat/dao/entities/security/CredentialDao.java new file mode 100644 index 000000000..4c258d96e --- /dev/null +++ b/dmp-backend/src/main/java/eu/eudat/dao/entities/security/CredentialDao.java @@ -0,0 +1,13 @@ +package eu.eudat.dao.entities.security; + +import eu.eudat.dao.Dao; +import eu.eudat.entities.Credential; +import eu.eudat.entities.UserToken; + +import java.util.UUID; + +/** + * Created by ikalyvas on 12/15/2017. + */ +public interface CredentialDao extends Dao { +} diff --git a/dmp-backend/src/main/java/eu/eudat/dao/entities/security/CredentialDaoImpl.java b/dmp-backend/src/main/java/eu/eudat/dao/entities/security/CredentialDaoImpl.java new file mode 100644 index 000000000..1326c3d49 --- /dev/null +++ b/dmp-backend/src/main/java/eu/eudat/dao/entities/security/CredentialDaoImpl.java @@ -0,0 +1,19 @@ +package eu.eudat.dao.entities.security; + +import eu.eudat.dao.JpaDao; +import eu.eudat.entities.Credential; +import eu.eudat.entities.UserToken; +import org.springframework.stereotype.Component; + +import java.util.UUID; + +/** + * Created by ikalyvas on 12/15/2017. + */ +@Component("credentialDao") +public class CredentialDaoImpl extends JpaDao implements CredentialDao { + @Override + public Credential loadDetails(Credential credential) { + return null; + } +} diff --git a/dmp-backend/src/main/java/eu/eudat/dao/entities/security/UserAuthDao.java b/dmp-backend/src/main/java/eu/eudat/dao/entities/security/UserAuthDao.java deleted file mode 100644 index e1e3c1669..000000000 --- a/dmp-backend/src/main/java/eu/eudat/dao/entities/security/UserAuthDao.java +++ /dev/null @@ -1,15 +0,0 @@ -package eu.eudat.dao.entities.security; - -import java.util.UUID; - -import eu.eudat.dao.Dao; -import eu.eudat.entities.security.UserAuth; - -public interface UserAuthDao extends Dao { - - - public String getPasswordHashOfUser(String username); - - public UserAuth getUserAuthBy(String username); - -} diff --git a/dmp-backend/src/main/java/eu/eudat/dao/entities/security/UserAuthDaoImpl.java b/dmp-backend/src/main/java/eu/eudat/dao/entities/security/UserAuthDaoImpl.java deleted file mode 100644 index 0c1abb399..000000000 --- a/dmp-backend/src/main/java/eu/eudat/dao/entities/security/UserAuthDaoImpl.java +++ /dev/null @@ -1,51 +0,0 @@ -package eu.eudat.dao.entities.security; - -import java.util.UUID; - -import javax.persistence.TypedQuery; - -import eu.eudat.dao.JpaDao; -import eu.eudat.entities.security.UserAuth; -import org.springframework.stereotype.Component; - -@Component("userAuthDaoImpl") -public class UserAuthDaoImpl extends JpaDao implements UserAuthDao { - - @Override - public UserAuth loadDetails(UserAuth t) { - // TODO Auto-generated method stub - return null; - } - - - @Override - public String getPasswordHashOfUser(String username) { - - String queryString = "SELECT userAuth.password FROM UserAuth userAuth where userAuth.username = :username"; - TypedQuery typedQuery = entityManager.createQuery(queryString, String.class); - typedQuery.setParameter("username", username); - try { - return typedQuery.getSingleResult(); - } - catch(Exception ex) { - return null; - } - } - - @Override - public UserAuth getUserAuthBy(String username) { - - String queryString = "FROM UserAuth userAuth where userAuth.username = :username"; - TypedQuery typedQuery = entityManager.createQuery(queryString, UserAuth.class); - typedQuery.setParameter("username", username); - try { - return typedQuery.getSingleResult(); - } - catch(Exception ex) { - return null; - } - } - - - -} diff --git a/dmp-backend/src/main/java/eu/eudat/dao/entities/security/UserTokenDao.java b/dmp-backend/src/main/java/eu/eudat/dao/entities/security/UserTokenDao.java new file mode 100644 index 000000000..2250bfd68 --- /dev/null +++ b/dmp-backend/src/main/java/eu/eudat/dao/entities/security/UserTokenDao.java @@ -0,0 +1,13 @@ +package eu.eudat.dao.entities.security; + +import eu.eudat.dao.Dao; +import eu.eudat.entities.UserToken; + +import java.util.UUID; + +/** + * Created by ikalyvas on 12/15/2017. + */ +public interface UserTokenDao extends Dao { + +} diff --git a/dmp-backend/src/main/java/eu/eudat/dao/entities/security/UserTokenDaoImpl.java b/dmp-backend/src/main/java/eu/eudat/dao/entities/security/UserTokenDaoImpl.java new file mode 100644 index 000000000..0ce6b797d --- /dev/null +++ b/dmp-backend/src/main/java/eu/eudat/dao/entities/security/UserTokenDaoImpl.java @@ -0,0 +1,18 @@ +package eu.eudat.dao.entities.security; + +import eu.eudat.dao.JpaDao; +import eu.eudat.entities.UserToken; +import org.springframework.stereotype.Component; + +import java.util.UUID; + +/** + * Created by ikalyvas on 12/15/2017. + */ +@Component("userTokenDao") +public class UserTokenDaoImpl extends JpaDao implements UserTokenDao { + @Override + public UserToken loadDetails(UserToken userToken) { + return null; + } +} diff --git a/dmp-backend/src/main/java/eu/eudat/entities/Credential.java b/dmp-backend/src/main/java/eu/eudat/entities/Credential.java new file mode 100644 index 000000000..c2543108e --- /dev/null +++ b/dmp-backend/src/main/java/eu/eudat/entities/Credential.java @@ -0,0 +1,116 @@ +package eu.eudat.entities; + +import org.hibernate.annotations.GenericGenerator; + +import javax.persistence.*; +import java.util.Date; +import java.util.UUID; + +/** + * Created by ikalyvas on 12/15/2017. + */ +@Entity +@Table(name="\"Credential\"") +public class Credential { + + @Id + @Column(name = "\"ID\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)") + private UUID id; + + @ManyToOne + @JoinColumn(name="userid", nullable=false) + private UserInfo userInfo; + + @Column(name = "status", nullable = false) + private Integer status; + + @Column(name = "provider", nullable = false) + private Integer provider; + @Column(name = "publicValue", nullable = false) + private String publicValue; + @Column(name = "secret", nullable = false) + private String secret; + @Column(name = "creationtime", nullable = false) + private Date creationTime; + @Column(name = "lastupdatetime", nullable = false) + private Date lastUpdateTime; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public UserInfo getUserInfo() { + return userInfo; + } + + public void setUserInfo(UserInfo userInfo) { + this.userInfo = userInfo; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public Integer getProvider() { + return provider; + } + + public void setProvider(Integer provider) { + this.provider = provider; + } + + public String getPublicValue() { + return publicValue; + } + + public void setPublicValue(String publicValue) { + this.publicValue = publicValue; + } + + public String getSecret() { + return secret; + } + + public void setSecret(String secret) { + this.secret = secret; + } + + public Date getCreationTime() { + return creationTime; + } + + public void setCreationTime(Date creationTime) { + this.creationTime = creationTime; + } + + public Date getLastUpdateTime() { + return lastUpdateTime; + } + + public void setLastUpdateTime(Date lastUpdateTime) { + this.lastUpdateTime = lastUpdateTime; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Credential that = (Credential) o; + + return provider.intValue() == that.provider.intValue(); + } + + @Override + public int hashCode() { + return provider.intValue(); + } +} diff --git a/dmp-backend/src/main/java/eu/eudat/entities/UserInfo.java b/dmp-backend/src/main/java/eu/eudat/entities/UserInfo.java index 471e50253..4c534f4db 100644 --- a/dmp-backend/src/main/java/eu/eudat/entities/UserInfo.java +++ b/dmp-backend/src/main/java/eu/eudat/entities/UserInfo.java @@ -2,20 +2,11 @@ package eu.eudat.entities; import java.io.Serializable; import java.util.Date; +import java.util.HashSet; import java.util.Set; import java.util.UUID; -import java.util.stream.Collectors; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.OneToMany; -import javax.persistence.OneToOne; -import javax.persistence.Table; +import javax.persistence.*; import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.Type; @@ -23,8 +14,6 @@ import org.hibernate.annotations.Type; import com.fasterxml.jackson.annotation.JsonIdentityInfo; import com.fasterxml.jackson.annotation.ObjectIdGenerators; -import eu.eudat.entities.security.UserAuth; - @Entity @Table(name="\"UserInfo\"") @@ -49,10 +38,6 @@ public class UserInfo implements Serializable,DataEntity{ @Column(name = "usertype", nullable = false) private Short usertype; // 0 internal, 1 external - @OneToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "authentication", nullable = true) - private UserAuth authentication; - @Column(name = "verified_email", nullable = true) private Boolean verified_email = null; @@ -78,13 +63,9 @@ public class UserInfo implements Serializable,DataEntity{ inverseJoinColumns={@JoinColumn(name="dmp", referencedColumnName="\"ID\"")} ) private Set dmps; - - - /* - public Set getDmpsNonDeleted(){ - return getDmps().parallelStream().filter(dmp -> dmp.getStatus()>=0).collect(Collectors.toSet()); - } - */ + + @OneToMany(mappedBy="userInfo",fetch = FetchType.LAZY) + Set credentials = new HashSet<>(); public Set getDmps() { return dmps; @@ -142,14 +123,6 @@ public class UserInfo implements Serializable,DataEntity{ this.usertype = usertype; } - public UserAuth getAuthentication() { - return authentication; - } - - public void setAuthentication(UserAuth authentication) { - this.authentication = authentication; - } - public Boolean getVerified_email() { return verified_email; } @@ -173,7 +146,12 @@ public class UserInfo implements Serializable,DataEntity{ public void setAdditionalinfo(String additionalinfo) { this.additionalinfo = additionalinfo; } - - - + + public Set getCredentials() { + return credentials; + } + + public void setCredentials(Set credentials) { + this.credentials = credentials; + } } diff --git a/dmp-backend/src/main/java/eu/eudat/entities/UserToken.java b/dmp-backend/src/main/java/eu/eudat/entities/UserToken.java new file mode 100644 index 000000000..d38595483 --- /dev/null +++ b/dmp-backend/src/main/java/eu/eudat/entities/UserToken.java @@ -0,0 +1,62 @@ +package eu.eudat.entities; + +import javax.persistence.*; +import java.util.Date; +import java.util.UUID; + +/** + * Created by ikalyvas on 12/15/2017. + */ +@Entity +@Table(name="\"UserToken\"") +public class UserToken implements DataEntity{ + + private static final long serialVersionUID = 1225151430484658395L; + + @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) + private Date issuedAt = null; + + + @Column(name = "expiresat", nullable = false) + 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; + } +} diff --git a/dmp-backend/src/main/java/eu/eudat/entities/security/UserAuth.java b/dmp-backend/src/main/java/eu/eudat/entities/security/UserAuth.java deleted file mode 100644 index 8aa51577c..000000000 --- a/dmp-backend/src/main/java/eu/eudat/entities/security/UserAuth.java +++ /dev/null @@ -1,61 +0,0 @@ -package eu.eudat.entities.security; - -import java.util.UUID; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.Table; - -import org.hibernate.annotations.GenericGenerator; - -import com.fasterxml.jackson.annotation.JsonIdentityInfo; -import com.fasterxml.jackson.annotation.ObjectIdGenerators; - -@Entity -@Table(name="\"UserAuth\"") -@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id") -public class UserAuth { - - @Id - @GeneratedValue - @GenericGenerator(name = "uuid2", strategy = "uuid2") - @Column(name = "id", updatable = false, nullable = false, columnDefinition = "BINARY(16)") - private UUID id; - - @Column(name = "username", nullable = false) - private String username; - - @Column(name = "password", nullable = false) - private String password; //hash-encoded password - - - - public UUID getId() { - return id; - } - - public void setId(UUID id) { - this.id = id; - } - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - - -} diff --git a/dmp-backend/src/main/java/eu/eudat/handlers/PrincipalArgumentResolver.java b/dmp-backend/src/main/java/eu/eudat/handlers/PrincipalArgumentResolver.java new file mode 100644 index 000000000..96862f1c0 --- /dev/null +++ b/dmp-backend/src/main/java/eu/eudat/handlers/PrincipalArgumentResolver.java @@ -0,0 +1,33 @@ +package eu.eudat.handlers; + +import eu.eudat.models.security.Principal; +import org.springframework.core.MethodParameter; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; + +import java.util.Date; +import java.util.UUID; + +/** + * Created by ikalyvas on 12/15/2017. + */ +public final class PrincipalArgumentResolver implements HandlerMethodArgumentResolver { + + @Override + public boolean supportsParameter(MethodParameter methodParameter) { + return methodParameter.getParameterType().equals(Principal.class); + } + + @Override + public Object resolveArgument(MethodParameter methodParameter,ModelAndViewContainer modelAndViewContainer,NativeWebRequest nativeWebRequest,WebDataBinderFactory webDataBinderFactory) throws Exception { + Principal principal = new Principal(); + principal.setName("Giannis"); + principal.setId(UUID.randomUUID()); + principal.setExpiresAt(new Date()); + principal.setToken(UUID.randomUUID()); + return principal; + } + +} \ No newline at end of file diff --git a/dmp-backend/src/main/java/eu/eudat/login/Login.java b/dmp-backend/src/main/java/eu/eudat/login/Login.java deleted file mode 100644 index 574a63f11..000000000 --- a/dmp-backend/src/main/java/eu/eudat/login/Login.java +++ /dev/null @@ -1,170 +0,0 @@ -package eu.eudat.login; - -import java.io.Serializable; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.util.concurrent.TimeUnit; - -import javax.annotation.PostConstruct; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.bind.annotation.RestController; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; - -import eu.eudat.dao.entities.UserInfoDao; -import eu.eudat.dao.entities.security.UserAuthDao; -import eu.eudat.entities.UserInfo; -import eu.eudat.entities.security.UserAuth; -import eu.eudat.security.TokenSessionManager; - - -@RestController -@CrossOrigin -public class Login { - - - @Autowired private UserInfoDao userInfoDao; - @Autowired private UserAuthDao userAuthDao; - - @Autowired private TokenSessionManager tokenSessionManager; - - - - @RequestMapping(method = RequestMethod.POST, value = { "/nativeLogin" }, consumes = "application/json", produces = "application/json") - public @ResponseBody ResponseEntity nativeLogin(@RequestBody Credentials credentials) { - - String token = null; - - if(credentials == null || credentials.getPassword() == null || credentials.getUsername() ==null || - credentials.getPassword().isEmpty() || credentials.getUsername().isEmpty()) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Username and/or password cannot be empty."); - } - - UserAuth userAuth = userAuthDao.getUserAuthBy(credentials.getUsername()); - - if(userAuth == null) userAuth = new UserAuth(); - - String userHash = userAuth.getPassword(); - - String providedHash = ""; - try { - providedHash = tokenSessionManager.hashPassword(credentials.getPassword()); - } - catch(NoSuchAlgorithmException ex) { - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Internal error. Cannot authenticate."); - } - - if(userHash == null || "".equals(userHash) || !userHash.equals(providedHash)) { - return ResponseEntity.status(HttpStatus.NOT_ACCEPTABLE).body("Wrong username or password"); - } - else if(userHash.equals(providedHash)) { - // create a token - token = tokenSessionManager.generateRandomAlphanumeric(512); - // add it to the eu.eudat.cache - tokenSessionManager.set(token, credentials.getUsername()); - } - - //get also the additional info of the user (if he has) - UserInfo userInfo = userInfoDao.getByAuthenticationId((userAuth.getId() == null) ? "" : userAuth.getId().toString()); - if(userInfo == null) userInfo = new UserInfo(); - - Response response = new Response(); - response.setToken(token); - response.setEmail(userInfo.getEmail()); - response.setName(userInfo.getName()); - response.setUsername(credentials.getUsername()); - - return new ResponseEntity(response.toJson(), HttpStatus.OK); - - } - - -} - -class Credentials implements Serializable{ - - private static final long serialVersionUID = 3519634756673886633L; - - private String username; - private String password; - - public String getUsername() { - return username; - } - public void setUsername(String username) { - this.username = username; - } - public String getPassword() { - return password; - } - public void setPassword(String password) { - this.password = password; - } - -} - -class Response implements Serializable { - - private static final long serialVersionUID = -3855159530298902864L; - - private String token; - private String username; - private String email; - private String name; - - - public String getToken() { - return token; - } - - public void setToken(String token) { - this.token = token; - } - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - - public String toJson() { - ObjectMapper objMapper = new ObjectMapper(); - try { - return objMapper.writeValueAsString(this); - } - catch(JsonProcessingException ex) { - return "{}"; - } - } - -} - diff --git a/dmp-backend/src/main/java/eu/eudat/models/login/Credentials.java b/dmp-backend/src/main/java/eu/eudat/models/login/Credentials.java new file mode 100644 index 000000000..72786d291 --- /dev/null +++ b/dmp-backend/src/main/java/eu/eudat/models/login/Credentials.java @@ -0,0 +1,25 @@ +package eu.eudat.models.login; + +/** + * Created by ikalyvas on 12/15/2017. + */ +public class Credentials { + private String username; + private String secret; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getSecret() { + return secret; + } + + public void setSecret(String secret) { + this.secret = secret; + } +} diff --git a/dmp-backend/src/main/java/eu/eudat/models/responses/ResponseItem.java b/dmp-backend/src/main/java/eu/eudat/models/responses/ResponseItem.java new file mode 100644 index 000000000..1ea0e57b1 --- /dev/null +++ b/dmp-backend/src/main/java/eu/eudat/models/responses/ResponseItem.java @@ -0,0 +1,52 @@ +package eu.eudat.models.responses; + +import org.springframework.http.HttpStatus; + +/** + * Created by ikalyvas on 12/15/2017. + */ +public class ResponseItem { + private HttpStatus statusCode; + private String message; + private T payload; + + public HttpStatus getStatusCode() { + return statusCode; + } + + public void setStatusCode(HttpStatus statusCode) { + this.statusCode = statusCode; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public T getPayload() { + return payload; + } + + public void setpayload(T payload) { + this.payload = payload; + } + + public ResponseItem status(HttpStatus statusCode){ + this.statusCode = statusCode; + return this; + } + + public ResponseItem message(String message){ + this.message = message; + return this; + } + + public ResponseItem payload(T payload){ + this.payload = payload; + return this; + } + +} diff --git a/dmp-backend/src/main/java/eu/eudat/models/security/Principal.java b/dmp-backend/src/main/java/eu/eudat/models/security/Principal.java new file mode 100644 index 000000000..f1d6509ed --- /dev/null +++ b/dmp-backend/src/main/java/eu/eudat/models/security/Principal.java @@ -0,0 +1,56 @@ +package eu.eudat.models.security; + +import java.util.Date; +import java.util.Set; +import java.util.UUID; + +/** + * Created by ikalyvas on 12/15/2017. + */ +public class Principal { + private UUID id; + private UUID token; + private String name; + private Date expiresAt; + private Set roles; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public UUID getToken() { + return token; + } + + public void setToken(UUID token) { + this.token = token; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Date getExpiresAt() { + return expiresAt; + } + + public void setExpiresAt(Date expiresAt) { + this.expiresAt = expiresAt; + } + + public Set getRoles() { + return roles; + } + + public void setRoles(Set roles) { + this.roles = roles; + } +} diff --git a/dmp-backend/src/main/java/eu/eudat/security/CustomAuthenticationProvider.java b/dmp-backend/src/main/java/eu/eudat/security/CustomAuthenticationProvider.java index 3e5934b7e..3a2920dbe 100644 --- a/dmp-backend/src/main/java/eu/eudat/security/CustomAuthenticationProvider.java +++ b/dmp-backend/src/main/java/eu/eudat/security/CustomAuthenticationProvider.java @@ -4,6 +4,8 @@ import java.util.ArrayList; import javax.naming.NameAlreadyBoundException; +import eu.eudat.models.login.Credentials; +import eu.eudat.models.security.Principal; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.AuthenticationServiceException; @@ -20,7 +22,7 @@ import eu.eudat.security.validators.NativeTokenValidator; import eu.eudat.security.validators.TokenValidator; @Component -public class CustomAuthenticationProvider implements AuthenticationProvider { +public class CustomAuthenticationProvider { @Autowired private UserInfoDao userInfoDao; @@ -28,43 +30,14 @@ public class CustomAuthenticationProvider implements AuthenticationProvider { @Autowired private GoogleTokenValidator googleTokenValidator; @Autowired private NativeTokenValidator nativeTokenValidator; - - @Override - public Authentication authenticate(Authentication authentication) throws AuthenticationException { - - if (authentication != null) { - - String token = (String)authentication.getCredentials(); - TokenValidator tokenValidator = null; - - if(TokenAuthenticationFilter.HEADER_GOOGLE_TOKEN_FIELD.equals(authentication.getPrincipal())) - tokenValidator = googleTokenValidator; - else if(TokenAuthenticationFilter.HEADER_NATIVE_TOKEN_FIELD.equals(authentication.getPrincipal())) - tokenValidator = nativeTokenValidator; - else - throw new AuthenticationServiceException("The appropriate http headers have not been set. Please check!"); - - UserInfo userInfo; + public Principal authenticate(Credentials credentials) throws AuthenticationException { + String token = credentials.getSecret(); try { - userInfo = tokenValidator.validateToken(token); + Principal principal = googleTokenValidator.validateToken(token); + return principal; } catch (NonValidTokenException e) { - System.out.println("Could not validate a user by his token! Reason: "+e.getMessage()); + System.out.println("Could not validate a user by his token! Reason: " + e.getMessage()); throw new AuthenticationServiceException("Token validation failed - Not a valid token"); } - - // if reached this point, authentication is ok, so return just an instance where the principal is the UserInfo ID - //(to have it at the webservices calls - it's ESSENTIAL) while the password can be whatever... - return new UsernamePasswordAuthenticationToken(userInfo.getId(), authentication.getCredentials(), new ArrayList<>()); - - } - else - throw new AuthenticationServiceException("Authentication failed"); - } - - @Override - public boolean supports(Class authentication) { - return authentication.equals(UsernamePasswordAuthenticationToken.class); - } - } \ No newline at end of file diff --git a/dmp-backend/src/main/java/eu/eudat/security/validators/GoogleTokenValidator.java b/dmp-backend/src/main/java/eu/eudat/security/validators/GoogleTokenValidator.java index 5cab1485c..9188a606d 100644 --- a/dmp-backend/src/main/java/eu/eudat/security/validators/GoogleTokenValidator.java +++ b/dmp-backend/src/main/java/eu/eudat/security/validators/GoogleTokenValidator.java @@ -2,10 +2,13 @@ package eu.eudat.security.validators; import java.io.IOException; import java.security.GeneralSecurityException; -import java.util.Arrays; -import java.util.Date; -import java.util.List; +import java.security.Principal; +import java.util.*; +import eu.eudat.dao.entities.security.CredentialDao; +import eu.eudat.entities.Credential; +import eu.eudat.entities.UserToken; +import eu.eudat.services.AuthenticationService; import org.springframework.beans.factory.annotation.Autowired; import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken; @@ -28,8 +31,8 @@ public class GoogleTokenValidator implements TokenValidator { private static final HttpTransport transport = new NetHttpTransport(); @Autowired private UserInfoDao userInfoDao; - - + @Autowired private CredentialDao credentialDao; + @Autowired private AuthenticationService authenticationService; private static final List clientIDs = Arrays.asList( "1010962018903-glegmqudqtl1lub0150vacopbu06lgsg.apps.googleusercontent.com", "1010962018903-glegmqudqtl1lub0150vacopbu06lgsg.apps.googleusercontent.com" @@ -48,7 +51,7 @@ public class GoogleTokenValidator implements TokenValidator { @Override - public UserInfo validateToken(String token) throws NonValidTokenException { + public eu.eudat.models.security.Principal validateToken(String token) throws NonValidTokenException { GoogleIdToken idToken = null; try { @@ -72,6 +75,15 @@ public class GoogleTokenValidator implements TokenValidator { UserInfo userInfo = userInfoDao.getByMail(payload.getEmail()); + Credential credential = new Credential(); + credential.setCreationTime(new Date()); + credential.setId(UUID.randomUUID()); + credential.setLastUpdateTime(new Date()); + credential.setProvider(1); + credential.setSecret(token); + credential.setPublicValue(userInfo.getName()); + credential.setUserInfo(userInfo); + if(userInfo == null) { //means not existing in db, so create one userInfo = new UserInfo(); userInfo.setName((String)payload.get("name")); @@ -82,13 +94,22 @@ public class GoogleTokenValidator implements TokenValidator { userInfo.setAuthorization_level(new Short("1")); userInfo.setUsertype(new Short("1")); userInfo = userInfoDao.create(userInfo); + credential = credentialDao.create(credential); } else { userInfo.setLastloggedin(new Date()); + Set credentials = userInfo.getCredentials(); + credentials.add(credential); userInfo = userInfoDao.update(userInfo); } + + UserToken userToken = new UserToken(); + userToken.setUser(userInfo); + userToken.setIssuedAt(new Date()); + userToken.setToken(UUID.randomUUID()); + userToken.setExpiresAt(new Date()); - return userInfo; + return authenticationService.Touch(userToken.getToken()); } diff --git a/dmp-backend/src/main/java/eu/eudat/security/validators/NativeTokenValidator.java b/dmp-backend/src/main/java/eu/eudat/security/validators/NativeTokenValidator.java index 9609b7c99..89c9a2e13 100644 --- a/dmp-backend/src/main/java/eu/eudat/security/validators/NativeTokenValidator.java +++ b/dmp-backend/src/main/java/eu/eudat/security/validators/NativeTokenValidator.java @@ -1,5 +1,6 @@ package eu.eudat.security.validators; +import eu.eudat.models.security.Principal; import org.springframework.beans.factory.annotation.Autowired; import eu.eudat.dao.entities.UserInfoDao; @@ -15,11 +16,11 @@ public class NativeTokenValidator implements TokenValidator { @Autowired private UserInfoDao userInfoDao; @Override - public UserInfo validateToken(String token) throws NonValidTokenException { + public Principal validateToken(String token) throws NonValidTokenException { String tokenUser = tokenSessionManager.getUser(token); if(tokenUser==null || tokenUser.isEmpty()) throw new NonValidTokenException("Login session has expired! Need to eu.eudat.login again!"); - return userInfoDao.getByUsername(tokenUser); + return new Principal(); } diff --git a/dmp-backend/src/main/java/eu/eudat/security/validators/TokenValidator.java b/dmp-backend/src/main/java/eu/eudat/security/validators/TokenValidator.java index 0a0cdb6fa..e7f0ce7de 100644 --- a/dmp-backend/src/main/java/eu/eudat/security/validators/TokenValidator.java +++ b/dmp-backend/src/main/java/eu/eudat/security/validators/TokenValidator.java @@ -2,9 +2,10 @@ package eu.eudat.security.validators; import eu.eudat.entities.UserInfo; import eu.eudat.exceptions.NonValidTokenException; +import eu.eudat.models.security.Principal; public interface TokenValidator { - public UserInfo validateToken(String token) throws NonValidTokenException; + public Principal validateToken(String token) throws NonValidTokenException; } diff --git a/dmp-backend/src/main/java/eu/eudat/services/AuthenticationService.java b/dmp-backend/src/main/java/eu/eudat/services/AuthenticationService.java new file mode 100644 index 000000000..86d377c51 --- /dev/null +++ b/dmp-backend/src/main/java/eu/eudat/services/AuthenticationService.java @@ -0,0 +1,67 @@ +package eu.eudat.services; + +import eu.eudat.dao.entities.UserInfoDao; +import eu.eudat.dao.entities.security.UserTokenDao; +import eu.eudat.entities.UserInfo; +import eu.eudat.entities.UserToken; +import eu.eudat.models.security.Principal; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.xml.ws.ServiceMode; +import java.util.Date; +import java.util.List; +import java.util.UUID; + +/** + * Created by ikalyvas on 12/15/2017. + */ +@Service +public class AuthenticationService { + @Autowired + UserTokenDao userTokenDao; + @Autowired + UserInfoDao userInfoDao; + + public Principal Touch(UUID token) + { + UserToken tokenEntry = userTokenDao.read(token); + if (tokenEntry == null || tokenEntry.getExpiresAt().before(new Date())) return null; + + Principal principal = this.Touch(tokenEntry); + + return principal; + } + + public void Logout(UUID token) + { + UserToken tokenEntry = userTokenDao.read(token); + userTokenDao.delete(tokenEntry); + } + + private Principal Touch(UserToken token) + { + if (token == null || token.getExpiresAt().before(new Date())) return null; + + UserInfo user = this.userInfoDao.read(token.getUser().getId()); + if (user == null /*|| user.Status != ActivityStatus.Active*/) return null; + + //List appRoles = this._unitOfWork.UserRoles.GetAll().Where(x => x.UserId == token.UserId /*&& x.Status == ActivityStatus.Active*/).ToList(); + + Principal principal = new Principal(); + principal.setId(user.getId()); + principal.setToken(token.getToken()); + principal.setExpiresAt(token.getExpiresAt()); + principal.setName(user.getName()); + + /*foreach (UserRole item in appRoles) + { + if (principal.AppRoles == null) principal.AppRoles = new HashSet(); + principal.AppRoles.Add(item.Role); + } + + if (this._config.Refresh) token.ExpiresAt = DateTime.UtcNow.AddMinutes(this._config.Lifetime); + */ + return principal; + } +}