diff --git a/model/src/main/java/lcsb/mapviewer/model/security/Privilege.java b/model/src/main/java/lcsb/mapviewer/model/security/Privilege.java index d973e473a65ce25d2b491ba57acc838adbffcca2..3c9e3607bc07753b46481698898e98326eb6bd17 100644 --- a/model/src/main/java/lcsb/mapviewer/model/security/Privilege.java +++ b/model/src/main/java/lcsb/mapviewer/model/security/Privilege.java @@ -6,30 +6,38 @@ import java.util.Objects; import javax.persistence.*; @Entity +@Table(uniqueConstraints = @UniqueConstraint(columnNames = { "type", "object_id" })) public class Privilege implements Serializable { private static final long serialVersionUID = 1L; - @EmbeddedId - private PrivilegePK privilegePK; + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + @Enumerated(EnumType.STRING) + private PrivilegeType type; + + private Integer objectId = -1; public Privilege() { } public Privilege(PrivilegeType type) { - this.privilegePK = new PrivilegePK(type, -1); + this.type = type; } public Privilege(PrivilegeType type, Integer objectId) { - this.privilegePK = new PrivilegePK(type, objectId); + this.type = type; + this.objectId = objectId; } @Override public String toString() { - if (privilegePK.objectId.equals(-1)) { - return privilegePK.type.name(); + if (isObjectPrivilege()) { + return type.name() + ":" + objectId; } else { - return privilegePK.type.name() + ":" + privilegePK.objectId; + return type.name(); } } @@ -38,27 +46,45 @@ public class Privilege implements Serializable { if (this == o) return true; if (!(o instanceof Privilege)) return false; Privilege that = (Privilege) o; - return Objects.equals(privilegePK, that.privilegePK); + return type == that.type + && Objects.equals(objectId, that.objectId); } @Override public int hashCode() { - if (privilegePK == null) return 0; - return privilegePK.hashCode(); + if (isObjectPrivilege()) { + return Objects.hash(type, objectId); + } else { + return type.hashCode(); + } + } + + public boolean isObjectPrivilege() { + return objectId != -1; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; } public PrivilegeType getType() { - return privilegePK.type; + return type; + } + + public void setType(PrivilegeType type) { + this.type = type; } public Integer getObjectId() { - return privilegePK.objectId; + return objectId; } - public boolean isObjectPrivilege() { - return privilegePK != null - && privilegePK.objectId != null - && !privilegePK.objectId.equals(-1); + public void setObjectId(Integer objectId) { + this.objectId = objectId; } } diff --git a/model/src/main/java/lcsb/mapviewer/model/security/PrivilegePK.java b/model/src/main/java/lcsb/mapviewer/model/security/PrivilegePK.java deleted file mode 100644 index f8a0f2e3594f6257d2d1db8177b32db80d67c019..0000000000000000000000000000000000000000 --- a/model/src/main/java/lcsb/mapviewer/model/security/PrivilegePK.java +++ /dev/null @@ -1,38 +0,0 @@ -package lcsb.mapviewer.model.security; - -import javax.persistence.Embeddable; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import java.io.Serializable; -import java.util.Objects; - -@Embeddable -class PrivilegePK implements Serializable { - - private static final long serialVersionUID = 1L; - - @Enumerated(EnumType.STRING) - PrivilegeType type; - - Integer objectId; - - PrivilegePK(PrivilegeType type, Integer objectId) { - this.type = type; - this.objectId = objectId; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof PrivilegePK)) return false; - PrivilegePK that = (PrivilegePK) o; - return type == that.type - && Objects.equals(objectId, that.objectId); - } - - @Override - public int hashCode() { - return Objects.hash(type, objectId); - } - -} diff --git a/model/src/main/java/lcsb/mapviewer/model/user/User.java b/model/src/main/java/lcsb/mapviewer/model/user/User.java index 2bd610423190c5746933c4db1374fc9c0541c712..b685515b9dde39a415d9fc9d34ff77e6c81b69cf 100644 --- a/model/src/main/java/lcsb/mapviewer/model/user/User.java +++ b/model/src/main/java/lcsb/mapviewer/model/user/User.java @@ -70,7 +70,7 @@ public class User implements Serializable { @JoinTable( name = "user_privilege_map_table", joinColumns = @JoinColumn(name = "user_id"), - inverseJoinColumns = { @JoinColumn(name = "type"), @JoinColumn(name = "object_id") } + inverseJoinColumns = @JoinColumn(name = "privilege_id") ) private Set<Privilege> privileges = new HashSet<>(); diff --git a/persist/src/main/resources/db/migration/14.0.0~alpha.0/V14.0.0.20190618__new_permission_model.sql b/persist/src/main/resources/db/migration/14.0.0~alpha.0/V14.0.0.20190618__new_permission_model.sql index afa47a99eb215a89f18d6c12fe33180720f46fb0..5534fd15be39be5d9dae0f0f81ee41d5eb0195ff 100644 --- a/persist/src/main/resources/db/migration/14.0.0~alpha.0/V14.0.0.20190618__new_permission_model.sql +++ b/persist/src/main/resources/db/migration/14.0.0~alpha.0/V14.0.0.20190618__new_permission_model.sql @@ -4,56 +4,46 @@ delete from user_table where login = 'anonymous'; alter table privilege_table rename column id_object to object_id; delete from privilege_table where level = 0; alter table privilege_table drop column level; +alter table privilege_table drop column privilege_class_type_db; +insert into privilege_table (type, object_id) +values ('IS_ADMIN', null); -insert into privilege_table (privilege_class_type_db, type, object_id) -values ('BASIC_PRIVILEGE', 'IS_ADMIN', -1); - -insert into privilege_table (privilege_class_type_db, type, object_id) -values ('BASIC_PRIVILEGE', 'IS_CURATOR', -1); +insert into privilege_table (type, object_id) +values ('IS_CURATOR', null); -insert into privilege_table (privilege_class_type_db, type, object_id) -values ('BASIC_PRIVILEGE', 'CAN_CREATE_OVERLAYS', -1); +insert into privilege_table (type, object_id) +values ('CAN_CREATE_OVERLAYS', null); -insert into privilege_table (privilege_class_type_db, type, object_id) -select 'OBJECT_PRIVILEGE', 'READ_PROJECT', object_id +insert into privilege_table (type, object_id) +select 'READ_PROJECT', object_id from privilege_table where type = 'VIEW_PROJECT'; -insert into privilege_table (privilege_class_type_db, type, object_id) -select 'OBJECT_PRIVILEGE', 'WRITE_PROJECT', object_id +insert into privilege_table (type, object_id) +select 'WRITE_PROJECT', object_id from privilege_table where type = 'VIEW_PROJECT'; - -alter table privilege_table drop column privilege_class_type_db; -alter table privilege_table drop column id; -update privilege_table set object_id = -1 where object_id is null; -alter table privilege_table add primary key (type, object_id); - - create table user_privilege_map_table ( user_id integer not null references user_table(id), - type varchar not null, - object_id integer not null, - foreign key (type, object_id) references privilege_table(type, object_id) + privilege_id integer not null references privilege_table(id) ); - -insert into user_privilege_map_table (user_id, type, object_id) -select s1.user_id, s2.type, s2.object_id +insert into user_privilege_map_table (user_id, privilege_id) +select s1.user_id, s2.id from (select user_id, object_id from privilege_table where type = 'VIEW_PROJECT') s1 inner join (select type, object_id from privilege_table where type = 'READ_PROJECT') s2 on s1.object_id = s2.object_id; -insert into user_privilege_map_table (user_id, type, object_id) -select user_id, (select type from privilege_table where type = 'IS_ADMIN'), -1 +insert into user_privilege_map_table (user_id, privilege_id) +select user_id, (select type from privilege_table where type = 'IS_ADMIN') from privilege_table where type = 'USER_MANAGEMENT'; -insert into user_privilege_map_table (user_id, type, object_id) -select user_id, (select type from privilege_table where type = 'IS_CURATOR'), -1 +insert into user_privilege_map_table (user_id, privilege_id) +select user_id, (select type from privilege_table where type = 'IS_CURATOR') from privilege_table where type = 'ADD_MAP'; -insert into user_privilege_map_table (user_id, type, object_id) -select user_id, (select type from privilege_table where type = 'CAN_CREATE_OVERLAYS'), -1 +insert into user_privilege_map_table (user_id, privilege_id) +select user_id, (select type from privilege_table where type = 'CAN_CREATE_OVERLAYS') from privilege_table where type = 'CUSTOM_LAYOUTS'; delete from privilege_table where type = 'VIEW_PROJECT' @@ -71,9 +61,10 @@ delete from privilege_table where type = 'VIEW_PROJECT' delete from user_privilege_map_table t1 using user_privilege_map_table t2 where t1.CTID != t2.CTID and t1.user_id = t2.user_id - and t1.type = t2.type - and t1.object_id = t2.object_id; + and t1.privilege_id = t2.privilege_id; -alter table user_privilege_map_table add primary key (user_id, type, object_id); +alter table user_privilege_map_table add primary key (user_id, privilege_id); alter table privilege_table drop column user_id; + +alter table privilege_table add constraint unique_rows unique (type, object_id); \ No newline at end of file diff --git a/service/src/main/java/lcsb/mapviewer/services/impl/UserService.java b/service/src/main/java/lcsb/mapviewer/services/impl/UserService.java index d4e5867c215a1e01675832aa06add3673108f473..94ccdee9966039962c9687a1d5b6f27d1d18f686 100644 --- a/service/src/main/java/lcsb/mapviewer/services/impl/UserService.java +++ b/service/src/main/java/lcsb/mapviewer/services/impl/UserService.java @@ -71,11 +71,13 @@ public class UserService implements IUserService { @Override public void grantUserPrivilege(User user, Privilege privilege) { user.addPrivilege(privilege); + userDao.update(user); } @Override public void revokeUserPrivilege(User user, Privilege privilege) { user.removePrivilege(privilege); + userDao.update(user); } @Override @@ -86,7 +88,7 @@ public class UserService implements IUserService { @Override public void revokeObjectDomainPrivilegesForAllUsers(PrivilegeType privilegeType, Integer objectId) { Privilege privilege = new Privilege(privilegeType, objectId); - userDao.getAll().forEach(user -> user.removePrivilege(privilege)); + userDao.getAll().forEach(user -> revokeUserPrivilege(user, privilege)); } @Override diff --git a/service/src/test/java/lcsb/mapviewer/services/impl/UserServiceTest.java b/service/src/test/java/lcsb/mapviewer/services/impl/UserServiceTest.java index da7aca529928fe09c456516d054c63ee65b4ba40..6de9d64814b09ea5a55f2b0b060e1da3101696da 100644 --- a/service/src/test/java/lcsb/mapviewer/services/impl/UserServiceTest.java +++ b/service/src/test/java/lcsb/mapviewer/services/impl/UserServiceTest.java @@ -1,17 +1,57 @@ package lcsb.mapviewer.services.impl; +import lcsb.mapviewer.model.security.Privilege; +import lcsb.mapviewer.model.security.PrivilegeType; +import lcsb.mapviewer.model.user.User; +import lcsb.mapviewer.persist.dao.security.PrivilegeDao; import lcsb.mapviewer.services.ServiceTestFunctions; import lcsb.mapviewer.services.interfaces.IUserService; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.Rollback; +import org.springframework.transaction.annotation.Transactional; +import static org.junit.Assert.*; + +@Transactional +@Rollback(false) public class UserServiceTest extends ServiceTestFunctions { @Autowired private IUserService userService; + @Autowired + private PrivilegeDao privilegeDao; + + @Test + public void grantExistingPrivilegeDoesNotProduceDuplicates() { + User user1 = new User(); + user1.setLogin("test_user_1"); + user1.setCryptedPassword("***"); + userService.addUser(user1); + + User user2 = new User(); + user2.setLogin("test_user_2"); + user2.setCryptedPassword("***"); + userService.addUser(user2); + + Privilege curatorPrivilege = new Privilege(PrivilegeType.IS_CURATOR); + if (!privilegeDao.getAll().contains(curatorPrivilege)) { + privilegeDao.add(curatorPrivilege); + } + + assertFalse(userService.userHasPrivilege(user1, new Privilege(PrivilegeType.IS_CURATOR))); + assertFalse(userService.userHasPrivilege(user2, new Privilege(PrivilegeType.IS_CURATOR))); + + userService.grantUserPrivilege(user1, new Privilege(PrivilegeType.IS_CURATOR)); + userService.grantUserPrivilege(user2, new Privilege(PrivilegeType.IS_CURATOR)); + + assertTrue(userService.userHasPrivilege(user1, new Privilege(PrivilegeType.IS_CURATOR))); + assertTrue(userService.userHasPrivilege(user2, new Privilege(PrivilegeType.IS_CURATOR))); + } + @Test - public void grantPrivilegeWorks() { + public void globalPrivilegeRemovalWorks() { }