diff --git a/README.md b/README.md new file mode 100644 index 0000000000000000000000000000000000000000..8513c3f178dbf66ced6224536a3f1036ae0142fb --- /dev/null +++ b/README.md @@ -0,0 +1,10 @@ +# IA2 GMS + +## MySQL setup + +``` +create database gms; +create user gms@localhost identified by 'gms'; +grant all privileges on gms.* to gms@localhost; + +``` diff --git a/gms/pom.xml b/gms/pom.xml index 6ab11e6f5f79ce17a038a8086bb3bd6ee3bf7ba8..3042e6941fcfacddc3e329665964f2d0f679b177 100644 --- a/gms/pom.xml +++ b/gms/pom.xml @@ -32,6 +32,15 @@ <groupId>org.springframework.security</groupId> <artifactId>spring-security-oauth2-client</artifactId> </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-data-jpa</artifactId> + </dependency> + <dependency> + <groupId>mysql</groupId> + <artifactId>mysql-connector-java</artifactId> + <scope>runtime</scope> + </dependency> <dependency> <groupId>org.springframework.boot</groupId> @@ -49,6 +58,11 @@ <artifactId>spring-security-test</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + <scope>test</scope> + </dependency> </dependencies> <build> diff --git a/gms/src/main/java/it/inaf/ia2/gms/controller/GroupsModelController.java b/gms/src/main/java/it/inaf/ia2/gms/controller/GroupsModelController.java new file mode 100644 index 0000000000000000000000000000000000000000..56a344ea4c8f7cf51e246f29478701c96aa73999 --- /dev/null +++ b/gms/src/main/java/it/inaf/ia2/gms/controller/GroupsModelController.java @@ -0,0 +1,17 @@ +package it.inaf.ia2.gms.controller; + +import it.inaf.ia2.gms.controller.model.GroupsModelRequest; +import it.inaf.ia2.gms.controller.model.GroupsModelResponse; +import javax.validation.Valid; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class GroupsModelController { + + @GetMapping + public GroupsModelResponse getGroupsModelResponse(@Valid @RequestBody GroupsModelRequest groupsModelRequest) { + return null; + } +} diff --git a/gms/src/main/java/it/inaf/ia2/gms/controller/model/BaseModelRequest.java b/gms/src/main/java/it/inaf/ia2/gms/controller/model/BaseModelRequest.java new file mode 100644 index 0000000000000000000000000000000000000000..3e93b83aed42181fe0e2c9a659221fbb04dc7209 --- /dev/null +++ b/gms/src/main/java/it/inaf/ia2/gms/controller/model/BaseModelRequest.java @@ -0,0 +1,14 @@ +package it.inaf.ia2.gms.controller.model; + +public abstract class BaseModelRequest { + + private String page; + + public String getPage() { + return page; + } + + public void setPage(String page) { + this.page = page; + } +} diff --git a/gms/src/main/java/it/inaf/ia2/gms/controller/model/BaseModelResponse.java b/gms/src/main/java/it/inaf/ia2/gms/controller/model/BaseModelResponse.java new file mode 100644 index 0000000000000000000000000000000000000000..98c6b2a09062713a16b46a2b69fb5a9c003f6e32 --- /dev/null +++ b/gms/src/main/java/it/inaf/ia2/gms/controller/model/BaseModelResponse.java @@ -0,0 +1,23 @@ +package it.inaf.ia2.gms.controller.model; + +public abstract class BaseModelResponse { + + private String user; + private String page; + + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + + public String getPage() { + return page; + } + + public void setPage(String page) { + this.page = page; + } +} diff --git a/gms/src/main/java/it/inaf/ia2/gms/controller/model/GroupsModelRequest.java b/gms/src/main/java/it/inaf/ia2/gms/controller/model/GroupsModelRequest.java new file mode 100644 index 0000000000000000000000000000000000000000..8a5c00a1ab1ea02b3c45367c9da177dd33aa0977 --- /dev/null +++ b/gms/src/main/java/it/inaf/ia2/gms/controller/model/GroupsModelRequest.java @@ -0,0 +1,14 @@ +package it.inaf.ia2.gms.controller.model; + +public class GroupsModelRequest extends BaseModelRequest { + + private String groupId; + + public String getGroupId() { + return groupId; + } + + public void setGroupId(String groupId) { + this.groupId = groupId; + } +} diff --git a/gms/src/main/java/it/inaf/ia2/gms/controller/model/GroupsModelResponse.java b/gms/src/main/java/it/inaf/ia2/gms/controller/model/GroupsModelResponse.java new file mode 100644 index 0000000000000000000000000000000000000000..8bc0046cd5a6bd04988a614a481aca27fb1dc982 --- /dev/null +++ b/gms/src/main/java/it/inaf/ia2/gms/controller/model/GroupsModelResponse.java @@ -0,0 +1,6 @@ +package it.inaf.ia2.gms.controller.model; + +public class GroupsModelResponse extends BaseModelResponse { + + +} diff --git a/gms/src/main/java/it/inaf/ia2/gms/exception/BadRequestException.java b/gms/src/main/java/it/inaf/ia2/gms/exception/BadRequestException.java new file mode 100644 index 0000000000000000000000000000000000000000..039ecfe5de87742c49e5da4b04dbeb51342788ba --- /dev/null +++ b/gms/src/main/java/it/inaf/ia2/gms/exception/BadRequestException.java @@ -0,0 +1,8 @@ +package it.inaf.ia2.gms.exception; + +public class BadRequestException extends RuntimeException { + + public BadRequestException(String message) { + super(message); + } +} diff --git a/gms/src/main/java/it/inaf/ia2/gms/persistence/GroupsRepository.java b/gms/src/main/java/it/inaf/ia2/gms/persistence/GroupsRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..c7ad1eb1a6f4c06df8e121ab4e462fd76fe12548 --- /dev/null +++ b/gms/src/main/java/it/inaf/ia2/gms/persistence/GroupsRepository.java @@ -0,0 +1,14 @@ +package it.inaf.ia2.gms.persistence; + +import it.inaf.ia2.gms.persistence.model.Group; +import java.util.List; +import javax.transaction.Transactional; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +@Transactional +public interface GroupsRepository extends JpaRepository<Group, String> { + + List<Group> findByParentGroup(Group parent); +} diff --git a/gms/src/main/java/it/inaf/ia2/gms/persistence/PermissionsRepository.java b/gms/src/main/java/it/inaf/ia2/gms/persistence/PermissionsRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..9b8b50a13afb474e9697aeca3a5fdd1a9d0056b7 --- /dev/null +++ b/gms/src/main/java/it/inaf/ia2/gms/persistence/PermissionsRepository.java @@ -0,0 +1,16 @@ +package it.inaf.ia2.gms.persistence; + +import it.inaf.ia2.gms.persistence.model.User; +import it.inaf.ia2.gms.persistence.model.UserGroup; +import it.inaf.ia2.gms.persistence.model.UserGroupId; +import java.util.List; +import javax.transaction.Transactional; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +@Transactional +public interface PermissionsRepository extends JpaRepository<UserGroup, UserGroupId> { + + List<UserGroup> findBy_user(User user); +} diff --git a/gms/src/main/java/it/inaf/ia2/gms/persistence/UserGroupsFromParentSpecification.java b/gms/src/main/java/it/inaf/ia2/gms/persistence/UserGroupsFromParentSpecification.java new file mode 100644 index 0000000000000000000000000000000000000000..6a991061ce8fc81bfb96f8eb815ddb1277582a1f --- /dev/null +++ b/gms/src/main/java/it/inaf/ia2/gms/persistence/UserGroupsFromParentSpecification.java @@ -0,0 +1,5 @@ +package it.inaf.ia2.gms.persistence; + +public class UserGroupsFromParentSpecification { + +} diff --git a/gms/src/main/java/it/inaf/ia2/gms/persistence/UsersRepository.java b/gms/src/main/java/it/inaf/ia2/gms/persistence/UsersRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..bf60c63ff38fe12288a75407874bbf70757a0533 --- /dev/null +++ b/gms/src/main/java/it/inaf/ia2/gms/persistence/UsersRepository.java @@ -0,0 +1,11 @@ +package it.inaf.ia2.gms.persistence; + +import it.inaf.ia2.gms.persistence.model.User; +import javax.transaction.Transactional; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +@Transactional +public interface UsersRepository extends JpaRepository<User, String> { +} diff --git a/gms/src/main/java/it/inaf/ia2/gms/persistence/model/Group.java b/gms/src/main/java/it/inaf/ia2/gms/persistence/model/Group.java new file mode 100644 index 0000000000000000000000000000000000000000..92cb5d0c1ab8326b0bc2c4b9c146c050c8f1aced --- /dev/null +++ b/gms/src/main/java/it/inaf/ia2/gms/persistence/model/Group.java @@ -0,0 +1,94 @@ +package it.inaf.ia2.gms.persistence.model; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.OrderBy; +import javax.persistence.Table; + +@Entity +@Table(name = "gms_group") +public class Group { + + @Id + private String id; + + @Column(nullable = false) + private String name; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "parent_group") + private Group parentGroup; + + @OneToMany(mappedBy = "parentGroup", fetch = FetchType.LAZY) + @OrderBy("name ASC") + private List<Group> groupsMembers; + + public Group() { + groupsMembers = new ArrayList<>(); + } + + 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 Group getParentGroup() { + return parentGroup; + } + + public void setParentGroup(Group parentGroup) { + this.parentGroup = parentGroup; + } + + public List<Group> getGroupsMembers() { + return groupsMembers; + } + + public void setGroupsMembers(List<Group> groupsMembers) { + this.groupsMembers = groupsMembers; + } + + @Override + public int hashCode() { + int hash = 3; + hash = 89 * hash + Objects.hashCode(this.id); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final Group other = (Group) obj; + if (!Objects.equals(this.id, other.id)) { + return false; + } + return true; + } +} diff --git a/gms/src/main/java/it/inaf/ia2/gms/persistence/model/User.java b/gms/src/main/java/it/inaf/ia2/gms/persistence/model/User.java new file mode 100644 index 0000000000000000000000000000000000000000..82238da1765629ce7b38629fc563fef4a6626814 --- /dev/null +++ b/gms/src/main/java/it/inaf/ia2/gms/persistence/model/User.java @@ -0,0 +1,21 @@ +package it.inaf.ia2.gms.persistence.model; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "gms_user") +public class User { + + @Id + private String id; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } +} diff --git a/gms/src/main/java/it/inaf/ia2/gms/persistence/model/UserGroup.java b/gms/src/main/java/it/inaf/ia2/gms/persistence/model/UserGroup.java new file mode 100644 index 0000000000000000000000000000000000000000..8bfb1fad8cab5529559541db1a4a51aba54716ab --- /dev/null +++ b/gms/src/main/java/it/inaf/ia2/gms/persistence/model/UserGroup.java @@ -0,0 +1,95 @@ +package it.inaf.ia2.gms.persistence.model; + +import it.inaf.ia2.gms.service.model.Permission; +import java.util.Objects; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.Id; +import javax.persistence.IdClass; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +/** + * NOTE: underscores in variable names are used when a field is a reserved JPQL + * keyword. + */ +@Entity +@IdClass(UserGroupId.class) +@Table(name = "gms_user_group") +public class UserGroup { + + @Id + @ManyToOne + @JoinColumn(name = "user_id", referencedColumnName = "id") + private User _user; + + @Id + @ManyToOne + @JoinColumn(name = "group_id", referencedColumnName = "id") + private Group _group; + + @Id + @Enumerated(EnumType.STRING) + @Column(name = "permission") + private Permission permission; + + public User getUser() { + return _user; + } + + public void setUser(User user) { + this._user = user; + } + + public Group getGroup() { + return _group; + } + + public void setGroup(Group group) { + this._group = group; + } + + public Permission getPermission() { + return permission; + } + + public void setPermission(Permission permission) { + this.permission = permission; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 47 * hash + Objects.hashCode(this._user); + hash = 47 * hash + Objects.hashCode(this._group); + hash = 47 * hash + Objects.hashCode(this.permission); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final UserGroup other = (UserGroup) obj; + if (!Objects.equals(this._user, other._user)) { + return false; + } + if (!Objects.equals(this._group, other._group)) { + return false; + } + if (this.permission != other.permission) { + return false; + } + return true; + } +} diff --git a/gms/src/main/java/it/inaf/ia2/gms/persistence/model/UserGroupId.java b/gms/src/main/java/it/inaf/ia2/gms/persistence/model/UserGroupId.java new file mode 100644 index 0000000000000000000000000000000000000000..c546caedfa87edbc20f6d8250892233a946f02c2 --- /dev/null +++ b/gms/src/main/java/it/inaf/ia2/gms/persistence/model/UserGroupId.java @@ -0,0 +1,45 @@ +package it.inaf.ia2.gms.persistence.model; + +import it.inaf.ia2.gms.service.model.Permission; +import java.io.Serializable; +import java.util.Objects; + +public class UserGroupId implements Serializable { + + String _user; + String _group; + Permission permission; + + @Override + public int hashCode() { + int hash = 5; + hash = 71 * hash + Objects.hashCode(this._user); + hash = 71 * hash + Objects.hashCode(this._group); + hash = 71 * hash + Objects.hashCode(this.permission); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final UserGroupId other = (UserGroupId) obj; + if (!Objects.equals(this._user, other._user)) { + return false; + } + if (!Objects.equals(this._group, other._group)) { + return false; + } + if (this.permission != other.permission) { + return false; + } + return true; + } +} diff --git a/gms/src/main/java/it/inaf/ia2/gms/service/GroupsService.java b/gms/src/main/java/it/inaf/ia2/gms/service/GroupsService.java new file mode 100644 index 0000000000000000000000000000000000000000..f2affaf6be06d382bec45a9604ac9a11192006d2 --- /dev/null +++ b/gms/src/main/java/it/inaf/ia2/gms/service/GroupsService.java @@ -0,0 +1,135 @@ +package it.inaf.ia2.gms.service; + +import it.inaf.ia2.gms.exception.BadRequestException; +import it.inaf.ia2.gms.persistence.GroupsRepository; +import it.inaf.ia2.gms.persistence.UsersRepository; +import it.inaf.ia2.gms.persistence.model.Group; +import it.inaf.ia2.gms.persistence.model.User; +import it.inaf.ia2.gms.persistence.model.UserGroup; +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import it.inaf.ia2.gms.persistence.PermissionsRepository; +import it.inaf.ia2.gms.service.model.GroupNode; +import it.inaf.ia2.gms.service.model.Permission; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.UUID; + +@Service +public class GroupsService { + + public static final String ROOT = "ROOT"; + + private final GroupsRepository groupsRepository; + private final UsersRepository usersRepository; + private final PermissionsRepository permissionsRepository; + + @Autowired + public GroupsService(GroupsRepository groupsRepository, + UsersRepository usersRepository, PermissionsRepository permissionsRepository) { + this.groupsRepository = groupsRepository; + this.usersRepository = usersRepository; + this.permissionsRepository = permissionsRepository; + createRootIfNecessary(); + } + + private void createRootIfNecessary() { + if (groupsRepository.count() == 0) { + Group root = new Group(); + root.setId(ROOT); + root.setName(ROOT); + groupsRepository.save(root); + } + } + + public Group addGroup(String parentId, String groupName) { + Group parent = getGroupById(parentId); + Group group = new Group(); + group.setId(UUID.randomUUID().toString()); + group.setName(groupName); + group.setParentGroup(parent); + parent.getGroupsMembers().add(group); + group = groupsRepository.save(group); + groupsRepository.save(parent); + return group; + } + + public List<Group> getSubgroups(String parentId) { + Group parent = getGroupById(parentId); + return groupsRepository.findByParentGroup(parent); + } + + public List<GroupNode> getSubgroups(String parentGroupId, String userId) { + + User user = usersRepository.findById(userId) + .orElseThrow(() -> new BadRequestException("User " + userId + " not found")); + + Group parent = getGroupById(parentGroupId); + + List<UserGroup> permissions = permissionsRepository.findBy_user(user); + + Map<String, GroupNode> nodes = new LinkedHashMap<>(); + + for (Group childGroup : parent.getGroupsMembers()) { + + Iterator<UserGroup> ite = permissions.iterator(); + while (ite.hasNext()) { + + UserGroup permission = ite.next(); + + boolean isChild = false; + if (permission.getGroup().getId().equals(childGroup.getId()) + || (isChild = isChildOf(permission.getGroup(), parentGroupId))) { + + GroupNode node = nodes.get(childGroup.getId()); + if (node == null) { + node = getGroupNode(childGroup); + } + + if (isChild) { + // Traversal only + node.getPermissions().add(Permission.READ); + } else { + // Direct permission + node.getPermissions().add(permission.getPermission()); + } + + nodes.put(childGroup.getId(), node); + ite.remove(); + } + } + } + + // TODO: pagination + return new ArrayList<>(nodes.values()); + } + + private GroupNode getGroupNode(Group group) { + GroupNode node = new GroupNode(); + node.setGroupId(group.getId()); + node.setGroupName(group.getName()); + node.setHasChildren(!group.getGroupsMembers().isEmpty()); + return node; + } + + private boolean isChildOf(Group group, String parentGroupId) { + Group parent = group.getParentGroup(); + if (parent == null) { + // ROOT has no parent + return false; + } + if (parentGroupId.equals(parent.getId())) { + return true; + } + // recursive call to parent group + return isChildOf(parent, parentGroupId); + } + + private Group getGroupById(String groupId) { + return groupsRepository.findById(groupId) + .orElseThrow(() -> new BadRequestException("Group " + groupId + " not found")); + } +} diff --git a/gms/src/main/java/it/inaf/ia2/gms/service/MainModelService.java b/gms/src/main/java/it/inaf/ia2/gms/service/MainModelService.java new file mode 100644 index 0000000000000000000000000000000000000000..cf11a1aa52e7a97e06d047cc4fbc1b9470b62045 --- /dev/null +++ b/gms/src/main/java/it/inaf/ia2/gms/service/MainModelService.java @@ -0,0 +1,5 @@ +package it.inaf.ia2.gms.service; + +public class MainModelService { + +} diff --git a/gms/src/main/java/it/inaf/ia2/gms/service/model/GroupNode.java b/gms/src/main/java/it/inaf/ia2/gms/service/model/GroupNode.java new file mode 100644 index 0000000000000000000000000000000000000000..920ec3d6aa19c1509faa7e921eb3cc92ea9ad2ba --- /dev/null +++ b/gms/src/main/java/it/inaf/ia2/gms/service/model/GroupNode.java @@ -0,0 +1,48 @@ +package it.inaf.ia2.gms.service.model; + +import java.util.ArrayList; +import java.util.List; + +public class GroupNode { + + private String groupId; + private String groupName; + private List<Permission> permissions; + private boolean hasChildren; + + public GroupNode() { + permissions = new ArrayList<>(); + } + + public String getGroupId() { + return groupId; + } + + public void setGroupId(String groupId) { + this.groupId = groupId; + } + + public String getGroupName() { + return groupName; + } + + public void setGroupName(String groupName) { + this.groupName = groupName; + } + + public List<Permission> getPermissions() { + return permissions; + } + + public void setPermissions(List<Permission> permissions) { + this.permissions = permissions; + } + + public boolean isHasChildren() { + return hasChildren; + } + + public void setHasChildren(boolean hasChildren) { + this.hasChildren = hasChildren; + } +} diff --git a/gms/src/main/java/it/inaf/ia2/gms/service/model/Permission.java b/gms/src/main/java/it/inaf/ia2/gms/service/model/Permission.java new file mode 100644 index 0000000000000000000000000000000000000000..899a1b4fc1be254ab225a47d21285f9c15cecf8f --- /dev/null +++ b/gms/src/main/java/it/inaf/ia2/gms/service/model/Permission.java @@ -0,0 +1,8 @@ +package it.inaf.ia2.gms.service.model; + +public enum Permission { + + ADMIN, + MANAGE_MEMBERS, + READ +} diff --git a/gms/src/main/resources/application.properties b/gms/src/main/resources/application.properties index f256cf2f8f3dde5482e978eff9743de529d1e228..46854617fed06dfd5de53595b4435cfb3daee721 100644 --- a/gms/src/main/resources/application.properties +++ b/gms/src/main/resources/application.properties @@ -8,4 +8,10 @@ security.oauth2.resource.token-info-uri=http://localhost/rap-ia2/auth/oauth2/che security.oauth2.client.scope=openid,email,profile security.oauth2.resource.jwk.key-set-uri=http://localhost/rap-ia2/auth/oidc/jwks -logging.level.org.springframework.security=DEBUG \ No newline at end of file +logging.level.org.springframework.security=DEBUG + +spring.jpa.hibernate.ddl-auto=update +spring.jpa.database-platform=org.hibernate.dialect.MariaDBDialect +spring.datasource.url=jdbc:mysql://localhost:3306/gms?useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC +spring.datasource.username=gms +spring.datasource.password=gms diff --git a/gms/src/test/java/it/inaf/ia2/gms/persistence/GroupsRepositoryTest.java b/gms/src/test/java/it/inaf/ia2/gms/persistence/GroupsRepositoryTest.java new file mode 100644 index 0000000000000000000000000000000000000000..c5afa9b3558d1e31069aa64bf71e112be665955a --- /dev/null +++ b/gms/src/test/java/it/inaf/ia2/gms/persistence/GroupsRepositoryTest.java @@ -0,0 +1,63 @@ +package it.inaf.ia2.gms.persistence; + +import it.inaf.ia2.gms.persistence.model.Group; +import it.inaf.ia2.gms.persistence.model.User; +import java.util.Arrays; +import static org.junit.Assert.assertEquals; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.test.context.junit4.SpringRunner; + +@DataJpaTest +@AutoConfigureTestDatabase +@RunWith(SpringRunner.class) +public class GroupsRepositoryTest { + + @Autowired + private UsersRepository usersRepository; + + @Autowired + private GroupsRepository groupsRepository; + + @Test + public void testCreateGroup() { + + User user1 = new User(); + user1.setId("user1"); + user1 = usersRepository.save(user1); + User user2 = new User(); + user2.setId("user2"); + user2 = usersRepository.save(user2); + + Group group = new Group(); + group.setId("parent-group"); + group.setName("Parent"); + + // Test cascade persist + Group childGroup = new Group(); + childGroup.setId("child-group"); + childGroup.setName("Child 1"); + + group.setGroupsMembers(Arrays.asList(childGroup)); + + group = groupsRepository.save(group); + + // Test cascade merge + Group childGroup2 = new Group(); + childGroup2.setId("child-group-2"); + childGroup2.setName("Child 2"); + group.getGroupsMembers().add(childGroup2); + groupsRepository.save(group); + + // Reload + group = groupsRepository.findById("parent-group").get(); + + assertEquals("Parent", group.getName()); + assertEquals(2, group.getGroupsMembers().size()); + assertEquals("Child 1", group.getGroupsMembers().get(0).getName()); + assertEquals("Child 2", group.getGroupsMembers().get(1).getName()); + } +} diff --git a/gms/src/test/java/it/inaf/ia2/gms/persistence/NestedGroupsIntegrationTest.java b/gms/src/test/java/it/inaf/ia2/gms/persistence/NestedGroupsIntegrationTest.java new file mode 100644 index 0000000000000000000000000000000000000000..89f7f86186750a52228c33c5fef48f52d9d444d1 --- /dev/null +++ b/gms/src/test/java/it/inaf/ia2/gms/persistence/NestedGroupsIntegrationTest.java @@ -0,0 +1,58 @@ +package it.inaf.ia2.gms.persistence; + +import it.inaf.ia2.gms.persistence.model.Group; +import it.inaf.ia2.gms.persistence.model.User; +import it.inaf.ia2.gms.persistence.model.UserGroup; +import it.inaf.ia2.gms.service.GroupsService; +import it.inaf.ia2.gms.service.model.GroupNode; +import it.inaf.ia2.gms.service.model.Permission; +import java.util.List; +import static org.junit.Assert.assertEquals; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.test.context.junit4.SpringRunner; + +@DataJpaTest +@AutoConfigureTestDatabase +@RunWith(SpringRunner.class) +public class NestedGroupsIntegrationTest { + + @Autowired + private UsersRepository usersRepository; + + @Autowired + private GroupsRepository groupsRepository; + + @Autowired + private PermissionsRepository permissionsRepository; + + @Test + public void testNestedGroupRetrieval() { + + GroupsService groupsService = new GroupsService(groupsRepository, usersRepository, permissionsRepository); + + // Create user + User user = new User(); + user.setId("user"); + user = usersRepository.save(user); + + // Setup groups + Group lbt = groupsService.addGroup(GroupsService.ROOT, "LBT"); + Group lbtInaf = groupsService.addGroup(lbt.getId(), "INAF"); + Group lbtInafProgram = groupsService.addGroup(lbtInaf.getId(), "P1"); + + // Setup permissions + UserGroup permission = new UserGroup(); + permission.setUser(user); + permission.setGroup(lbtInafProgram); + permission.setPermission(Permission.MANAGE_MEMBERS); + permissionsRepository.save(permission); + + List<GroupNode> groupNodes = groupsService.getSubgroups(GroupsService.ROOT, user.getId()); + assertEquals(1, groupNodes.size()); + } + +}