Skip to content
Snippets Groups Projects
Commit 844e9e5e authored by Sonia Zorba's avatar Sonia Zorba
Browse files

Started groups persistence and retrieval implementation

parent fe1de660
No related branches found
No related tags found
No related merge requests found
Showing
with 603 additions and 0 deletions
# IA2 GMS
## MySQL setup
```
create database gms;
create user gms@localhost identified by 'gms';
grant all privileges on gms.* to gms@localhost;
```
......@@ -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>
......
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;
}
}
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;
}
}
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;
}
}
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;
}
}
package it.inaf.ia2.gms.controller.model;
public class GroupsModelResponse extends BaseModelResponse {
}
package it.inaf.ia2.gms.exception;
public class BadRequestException extends RuntimeException {
public BadRequestException(String message) {
super(message);
}
}
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);
}
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);
}
package it.inaf.ia2.gms.persistence;
public class UserGroupsFromParentSpecification {
}
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> {
}
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;
}
}
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;
}
}
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;
}
}
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;
}
}
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"));
}
}
package it.inaf.ia2.gms.service;
public class MainModelService {
}
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;
}
}
package it.inaf.ia2.gms.service.model;
public enum Permission {
ADMIN,
MANAGE_MEMBERS,
READ
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment