From 391a88a23640755553177f44aef32f34f25e413b Mon Sep 17 00:00:00 2001 From: George Kalampokis Date: Mon, 4 May 2020 15:47:30 +0300 Subject: [PATCH] The invite pop up will show only user collaborating with DMP that the current user also is collaborating (ref #258) --- .../data/dao/entities/UserAssociationDao.java | 15 ++++ .../dao/entities/UserAssociationDaoImpl.java | 73 +++++++++++++++++++ .../eudat/data/entities/UserAssociation.java | 66 +++++++++++++++++ .../controllers/UserInvitationController.java | 4 +- .../logic/managers/InvitationsManager.java | 25 ++++++- .../operations/DatabaseRepository.java | 2 + .../operations/DatabaseRepositoryImpl.java | 11 +++ .../updates/09/01_create_user_association.sql | 21 ++++++ 8 files changed, 212 insertions(+), 5 deletions(-) create mode 100644 dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/UserAssociationDao.java create mode 100644 dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/UserAssociationDaoImpl.java create mode 100644 dmp-backend/data/src/main/java/eu/eudat/data/entities/UserAssociation.java create mode 100644 dmp-db-scema/updates/09/01_create_user_association.sql diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/UserAssociationDao.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/UserAssociationDao.java new file mode 100644 index 000000000..bd80fa49b --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/UserAssociationDao.java @@ -0,0 +1,15 @@ +package eu.eudat.data.dao.entities; + +import eu.eudat.data.dao.DatabaseAccessLayer; +import eu.eudat.data.entities.UserAssociation; +import eu.eudat.data.entities.UserInfo; + +import java.util.List; +import java.util.UUID; + +public interface UserAssociationDao extends DatabaseAccessLayer { + + public List getAssociated(UserInfo userId); + + public Boolean areAssociated(UserInfo firstUser, UserInfo secondUser); +} diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/UserAssociationDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/UserAssociationDaoImpl.java new file mode 100644 index 000000000..b8ecc0668 --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/UserAssociationDaoImpl.java @@ -0,0 +1,73 @@ +package eu.eudat.data.dao.entities; + +import eu.eudat.data.dao.DatabaseAccess; +import eu.eudat.data.dao.databaselayer.service.DatabaseService; +import eu.eudat.data.entities.UserAssociation; +import eu.eudat.data.entities.UserInfo; +import eu.eudat.queryable.QueryableList; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; + +@Component("UserAssociationDao") +public class UserAssociationDaoImpl extends DatabaseAccess implements UserAssociationDao { + + @Autowired + public UserAssociationDaoImpl(DatabaseService databaseService) { + super(databaseService); + } + + @Override + public UserAssociation createOrUpdate(UserAssociation item) { + return this.getDatabaseService().createOrUpdate(item, UserAssociation.class); + } + + @Override + public CompletableFuture createOrUpdateAsync(UserAssociation item) { + return CompletableFuture.supplyAsync(() -> this.createOrUpdate(item)); + } + + @Override + public UserAssociation find(UUID id) { + return this.getDatabaseService().getQueryable(UserAssociation.class).where(((builder, root) -> builder.equal(root.get("id"), id))).getSingle(); + } + + @Override + public UserAssociation find(UUID id, String hint) { + throw new UnsupportedOperationException(); + } + + @Override + public void delete(UserAssociation item) { + this.getDatabaseService().delete(item); + } + + @Override + public QueryableList asQueryable() { + return this.getDatabaseService().getQueryable(UserAssociation.class); + } + + @Override + public List getAssociated(UserInfo userId) { + return this.getDatabaseService().getQueryable(UserAssociation.class).where(((builder, root) -> + builder.or(builder.equal(root.get("firstUser"), userId), builder.equal(root.get("secondUser"), userId)))).toList(); + } + + @Override + public Boolean areAssociated(UserInfo firstUser, UserInfo secondUser) { + return this.getDatabaseService().getQueryable(UserAssociation.class).where(((builder, root) -> + builder.or( + builder.and( + builder.equal(root.get("firstUser"), firstUser), + builder.equal(root.get("secondUser"), secondUser) + ), + builder.and( + builder.equal(root.get("secondUser"), firstUser), + builder.equal(root.get("firstUser"), secondUser) + ) + ))).count() > 0; + } +} diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/UserAssociation.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/UserAssociation.java new file mode 100644 index 000000000..898bbd8a6 --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/UserAssociation.java @@ -0,0 +1,66 @@ +package eu.eudat.data.entities; + +import eu.eudat.queryable.queryableentity.DataEntity; +import org.hibernate.annotations.GenericGenerator; + +import javax.persistence.*; +import java.util.List; +import java.util.UUID; + +@Entity +@Table(name = "\"UserAssociation\"") +public class UserAssociation implements DataEntity { + + @Id + @GeneratedValue + @GenericGenerator(name = "uuid2", strategy = "uuid2") + @Column(name = "id", updatable = false, nullable = false, columnDefinition = "BINARY(16)") + private UUID id; + + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "\"firstUser\"") + private UserInfo firstUser; + + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "\"secondUser\"") + private UserInfo secondUser; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public UserInfo getFirstUser() { + return firstUser; + } + + public void setFirstUser(UserInfo firstUser) { + this.firstUser = firstUser; + } + + public UserInfo getSecondUser() { + return secondUser; + } + + public void setSecondUser(UserInfo secondUser) { + this.secondUser = secondUser; + } + + @Override + public void update(UserAssociation entity) { + + } + + @Override + public UUID getKeys() { + return null; + } + + @Override + public UserAssociation buildFromTuple(List tuple, List fields, String base) { + return null; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/UserInvitationController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/UserInvitationController.java index 3e09dd43b..b6d045a67 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/UserInvitationController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/UserInvitationController.java @@ -48,8 +48,8 @@ public class UserInvitationController extends BaseController { @RequestMapping(method = RequestMethod.POST, value = {"/getUsers"}, consumes = "application/json", produces = "application/json") public @ResponseBody - ResponseEntity>> getUsers(@RequestBody UserInfoRequestItem userInfoRequestItem) throws IllegalAccessException, InstantiationException { - List users = invitationsManager.getUsers(userInfoRequestItem); + ResponseEntity>> getUsers(Principal principal) throws IllegalAccessException, InstantiationException { + List users = invitationsManager.getUsers(principal); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.SUCCESS_MESSAGE).payload(users)); } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/InvitationsManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/InvitationsManager.java index eea0d1c41..2625fdfd3 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/InvitationsManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/InvitationsManager.java @@ -1,6 +1,7 @@ package eu.eudat.logic.managers; import eu.eudat.data.entities.DMP; +import eu.eudat.data.entities.UserAssociation; import eu.eudat.data.entities.UserDMP; import eu.eudat.data.entities.UserInfo; import eu.eudat.exceptions.security.UnauthorisedException; @@ -38,15 +39,27 @@ public class InvitationsManager { UserDMP userDMP = new UserDMP(); userDMP.setUser(userInfo); userInfoToUserDmp.add(userDMP); + if (!apiContext.getOperationsContext().getDatabaseRepository().getUserAssociationDao().areAssociated(principalUser, userInfo)) { + UserAssociation userAssociation = new UserAssociation(); + userAssociation.setFirstUser(principalUser); + userAssociation.setSecondUser(userInfo); + } } DMP dataManagementPlan = apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().find(invitation.getDataManagementPlan()); apiContext.getUtilitiesService().getInvitationService().createInvitations(apiContext.getOperationsContext().getDatabaseRepository().getInvitationDao(), apiContext.getUtilitiesService().getMailService(), invitation.getUsers().stream().map(item -> item.toDataModel()).collect(Collectors.toList()), dataManagementPlan, principalUser); apiContext.getUtilitiesService().getInvitationService().assignToDmp(apiContext.getOperationsContext().getDatabaseRepository().getDmpDao(), userInfoToUserDmp, dataManagementPlan); } - public List getUsers(UserInfoRequestItem userInfoRequestItem) throws InstantiationException, IllegalAccessException { - QueryableList users = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().getWithCriteria(userInfoRequestItem.getCriteria()); - List userModels = users.select(item -> new UserInfoInvitationModel().fromDataModel(item)); + public List getUsers(Principal principal) throws InstantiationException, IllegalAccessException { + UserInfo principalUser = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(principal.getId()); + List users = apiContext.getOperationsContext().getDatabaseRepository().getUserAssociationDao().getAssociated(principalUser).stream().map(userAssociation -> { + if (userAssociation.getFirstUser().getId().equals(principal.getId())) { + return userAssociation.getSecondUser(); + } else { + return userAssociation.getFirstUser(); + } + }).collect(Collectors.toList()); + List userModels = users.stream().map(userInfo -> new UserInfoInvitationModel().fromDataModel(userInfo)).collect(Collectors.toList()); return userModels; } @@ -60,6 +73,12 @@ public class InvitationsManager { userDMP.setUser(invitedUser); userDMP.setDmp(invitation.getDmp()); userDMP.setRole(UserDMP.UserDMPRoles.USER.getValue()); + if (!apiContext.getOperationsContext().getDatabaseRepository().getUserAssociationDao().areAssociated(invitedUser, invitation.getUser())) { + UserAssociation userAssociation = new UserAssociation(); + userAssociation.setFirstUser(invitedUser); + userAssociation.setSecondUser(invitation.getUser()); + apiContext.getOperationsContext().getDatabaseRepository().getUserAssociationDao().createOrUpdate(userAssociation); + } DMP datamanagementPlan = invitation.getDmp(); apiContext.getOperationsContext().getDatabaseRepository().getUserDmpDao().createOrUpdate(userDMP); apiContext.getUtilitiesService().getInvitationService().assignToDmp(apiContext.getOperationsContext().getDatabaseRepository().getDmpDao(), userDMP, datamanagementPlan); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepository.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepository.java index 539e417a6..516f7e949 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepository.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepository.java @@ -56,5 +56,7 @@ public interface DatabaseRepository { NotificationDao getNotificationDao(); + UserAssociationDao getUserAssociationDao(); + void detachEntity(T entity); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepositoryImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepositoryImpl.java index a87ba7734..ff5f6506e 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepositoryImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepositoryImpl.java @@ -37,6 +37,7 @@ public class DatabaseRepositoryImpl implements DatabaseRepository { private FunderDao funderDao; private LockDao lockDao; private NotificationDao notificationDao; + private UserAssociationDao userAssociationDao; private EntityManager entityManager; @@ -290,6 +291,16 @@ public class DatabaseRepositoryImpl implements DatabaseRepository { return notificationDao; } + @Override + public UserAssociationDao getUserAssociationDao() { + return userAssociationDao; + } + + @Autowired + public void setUserAssociationDao(UserAssociationDao userAssociationDao) { + this.userAssociationDao = userAssociationDao; + } + @Autowired public void setNotificationDao(NotificationDao notificationDao) { this.notificationDao = notificationDao; diff --git a/dmp-db-scema/updates/09/01_create_user_association.sql b/dmp-db-scema/updates/09/01_create_user_association.sql new file mode 100644 index 000000000..c569ca2fe --- /dev/null +++ b/dmp-db-scema/updates/09/01_create_user_association.sql @@ -0,0 +1,21 @@ +CREATE TABLE public."UserAssociation" ( + id uuid NOT NULL, + "firstUser" uuid NOT NULL, + "secondUser" uuid NOT NULL +); + + +ALTER TABLE public."UserAssociation" OWNER TO dmptool; + +ALTER TABLE ONLY public."UserAssociation" + ADD CONSTRAINT pk_user_association PRIMARY KEY (id); + +ALTER TABLE ONLY public."UserAssociation" + ADD CONSTRAINT fk_userinfo_user_association_1 FOREIGN KEY ("firstUser") REFERENCES public."UserInfo"(id); + +ALTER TABLE ONLY public."UserAssociation" + ADD CONSTRAINT fk_userinfo_user_association_2 FOREIGN KEY ("secondUser") REFERENCES public."UserInfo"(id); + +INSERT INTO public."DBVersion" VALUES ('DMPDB', '00.00.002', '2020-05-04 13:42:00.000000+03', now(), 'Add User Association'); + +