1
0
mirror of https://github.com/sismics/docs.git synced 2025-12-13 09:46:17 +00:00

#18: Group resource, groups handling in ACL, groups returned in users

This commit is contained in:
jendib
2016-03-19 19:41:28 +01:00
parent 43a1575187
commit a5ce5bf9ec
27 changed files with 725 additions and 133 deletions

View File

@@ -68,10 +68,11 @@ public class AclDao {
@SuppressWarnings("unchecked")
public List<AclDto> getBySourceId(String sourceId) {
EntityManager em = ThreadLocalContext.get().getEntityManager();
StringBuilder sb = new StringBuilder("select a.ACL_ID_C, a.ACL_PERM_C, a.ACL_TARGETID_C, u.USE_USERNAME_C, s.SHA_NAME_C");
StringBuilder sb = new StringBuilder("select a.ACL_ID_C, a.ACL_PERM_C, a.ACL_TARGETID_C, u.USE_USERNAME_C, s.SHA_NAME_C, g.GRP_NAME_C ");
sb.append(" from T_ACL a ");
sb.append(" left join T_USER u on u.USE_ID_C = a.ACL_TARGETID_C ");
sb.append(" left join T_SHARE s on s.SHA_ID_C = a.ACL_TARGETID_C ");
sb.append(" left join T_GROUP g on g.GRP_ID_C = a.ACL_TARGETID_C ");
sb.append(" where a.ACL_DELETEDATE_D is null and a.ACL_SOURCEID_C = :sourceId ");
// Perform the query
@@ -89,9 +90,19 @@ public class AclDao {
aclDto.setTargetId((String) o[i++]);
String userName = (String) o[i++];
String shareName = (String) o[i++];
aclDto.setTargetName(userName == null ? shareName : userName);
aclDto.setTargetType(userName == null ?
AclTargetType.SHARE.name() : AclTargetType.USER.name());
String groupName = (String) o[i++];
if (userName != null) {
aclDto.setTargetName(userName);
aclDto.setTargetType(AclTargetType.USER.name());
}
if (shareName != null) {
aclDto.setTargetName(shareName);
aclDto.setTargetType(AclTargetType.SHARE.name());
}
if (groupName != null) {
aclDto.setTargetName(groupName);
aclDto.setTargetType(AclTargetType.GROUP.name());
}
aclDtoList.add(aclDto);
}
return aclDtoList;

View File

@@ -92,13 +92,14 @@ public class DocumentDao {
*/
public DocumentDto getDocument(String id, PermType perm, List<String> targetIdList) {
EntityManager em = ThreadLocalContext.get().getEntityManager();
StringBuilder sb = new StringBuilder("select d.DOC_ID_C, d.DOC_TITLE_C, d.DOC_DESCRIPTION_C, d.DOC_SUBJECT_C, d.DOC_IDENTIFIER_C, d.DOC_PUBLISHER_C, d.DOC_FORMAT_C, d.DOC_SOURCE_C, d.DOC_TYPE_C, d.DOC_COVERAGE_C, d.DOC_RIGHTS_C, d.DOC_CREATEDATE_D, d.DOC_LANGUAGE_C, ");
StringBuilder sb = new StringBuilder("select distinct d.DOC_ID_C, d.DOC_TITLE_C, d.DOC_DESCRIPTION_C, d.DOC_SUBJECT_C, d.DOC_IDENTIFIER_C, d.DOC_PUBLISHER_C, d.DOC_FORMAT_C, d.DOC_SOURCE_C, d.DOC_TYPE_C, d.DOC_COVERAGE_C, d.DOC_RIGHTS_C, d.DOC_CREATEDATE_D, d.DOC_LANGUAGE_C, ");
sb.append(" (select count(s.SHA_ID_C) from T_SHARE s, T_ACL ac where ac.ACL_SOURCEID_C = d.DOC_ID_C and ac.ACL_TARGETID_C = s.SHA_ID_C and ac.ACL_DELETEDATE_D is null and s.SHA_DELETEDATE_D is null), ");
sb.append(" (select count(f.FIL_ID_C) from T_FILE f where f.FIL_DELETEDATE_D is null and f.FIL_IDDOC_C = d.DOC_ID_C), ");
sb.append(" u.USE_USERNAME_C ");
sb.append(" from T_DOCUMENT d, T_USER u ");
sb.append(" join T_ACL a on a.ACL_SOURCEID_C = d.DOC_ID_C and a.ACL_TARGETID_C in (:targetIdList) and a.ACL_PERM_C = :perm and a.ACL_DELETEDATE_D is null ");
sb.append(" where d.DOC_IDUSER_C = u.USE_ID_C and d.DOC_ID_C = :id and d.DOC_DELETEDATE_D is null ");
sb.append(" from T_DOCUMENT d ");
sb.append(" join T_USER u on d.DOC_IDUSER_C = u.USE_ID_C ");
sb.append(" left join T_ACL a on a.ACL_SOURCEID_C = d.DOC_ID_C and a.ACL_TARGETID_C in (:targetIdList) and a.ACL_PERM_C = :perm and a.ACL_DELETEDATE_D is null ");
sb.append(" where d.DOC_ID_C = :id and a.ACL_ID_C is not null and d.DOC_DELETEDATE_D is null ");
Query q = em.createNativeQuery(sb.toString());
q.setParameter("id", id);

View File

@@ -1,16 +1,28 @@
package com.sismics.docs.core.dao.jpa;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import com.google.common.base.Joiner;
import com.sismics.docs.core.constant.AuditLogType;
import com.sismics.docs.core.dao.jpa.criteria.GroupCriteria;
import com.sismics.docs.core.dao.jpa.dto.GroupDto;
import com.sismics.docs.core.model.jpa.Group;
import com.sismics.docs.core.model.jpa.UserGroup;
import com.sismics.docs.core.util.AuditLogUtil;
import com.sismics.docs.core.util.jpa.QueryParam;
import com.sismics.docs.core.util.jpa.QueryUtil;
import com.sismics.docs.core.util.jpa.SortCriteria;
import com.sismics.util.context.ThreadLocalContext;
/**
@@ -25,7 +37,7 @@ public class GroupDao {
* @param name Name
* @return Tag
*/
public Group getByName(String name) {
public Group getActiveByName(String name) {
EntityManager em = ThreadLocalContext.get().getEntityManager();
Query q = em.createQuery("select g from Group g where g.name = :name and g.deleteDate is null");
q.setParameter("name", name);
@@ -81,6 +93,11 @@ public class GroupDao {
q.setParameter("dateNow", dateNow);
q.setParameter("groupId", groupId);
q.executeUpdate();
q = em.createQuery("update Acl a set a.deleteDate = :dateNow where a.targetId = :groupId and a.deleteDate is null");
q.setParameter("groupId", groupDb.getId());
q.setParameter("dateNow", dateNow);
q.executeUpdate();
// Create audit log
AuditLogUtil.create(groupDb, AuditLogType.DELETE, userId);
@@ -108,18 +125,107 @@ public class GroupDao {
* Remove an user from a group.
*
* @param groupId Group ID
* @param userId User ID
*/
public void removeMember(String userGroupId) {
public void removeMember(String groupId, String userId) {
EntityManager em = ThreadLocalContext.get().getEntityManager();
// Get the user group
Query q = em.createQuery("select ug from UserGroup ug where ug.id = :id and ug.deleteDate is null");
q.setParameter("id", userGroupId);
Query q = em.createQuery("select ug from UserGroup ug where ug.groupId = :groupId and ug.userId = :userId and ug.deleteDate is null");
q.setParameter("groupId", groupId);
q.setParameter("userId", userId);
UserGroup userGroupDb = (UserGroup) q.getSingleResult();
// Delete the user group
Date dateNow = new Date();
userGroupDb.setDeleteDate(dateNow);
}
/**
* Returns the list of all groups.
*
* @param criteria Search criteria
* @param sortCriteria Sort criteria
* @return List of groups
*/
public List<GroupDto> findByCriteria(GroupCriteria criteria, SortCriteria sortCriteria) {
Map<String, Object> parameterMap = new HashMap<String, Object>();
List<String> criteriaList = new ArrayList<String>();
StringBuilder sb = new StringBuilder("select g.GRP_ID_C as c0, g.GRP_NAME_C as c1, g.GRP_IDPARENT_C as c2, ug.UGP_ID_C ");
sb.append(" from T_GROUP g ");
// Add search criterias
if (criteria.getSearch() != null) {
criteriaList.add("lower(g.GRP_NAME_C) like lower(:search)");
parameterMap.put("search", "%" + criteria.getSearch() + "%");
}
if (criteria.getUserId() != null) {
// Left join and post-filtering for recursive groups
sb.append((criteria.isRecursive() ? " left " : "")
+ " join T_USER_GROUP ug on ug.UGP_IDGROUP_C = g.GRP_ID_C and ug.UGP_IDUSER_C = :userId and ug.UGP_DELETEDATE_D is null ");
parameterMap.put("userId", criteria.getUserId());
}
criteriaList.add("g.GRP_DELETEDATE_D is null");
if (!criteriaList.isEmpty()) {
sb.append(" where ");
sb.append(Joiner.on(" and ").join(criteriaList));
}
// Perform the search
QueryParam queryParam = QueryUtil.getSortedQueryParam(new QueryParam(sb.toString(), parameterMap), sortCriteria);
@SuppressWarnings("unchecked")
List<Object[]> l = QueryUtil.getNativeQuery(queryParam).getResultList();
// Assemble results
List<GroupDto> groupDtoList = new ArrayList<>();
List<GroupDto> userGroupDtoList = new ArrayList<>();
for (Object[] o : l) {
int i = 0;
GroupDto groupDto = new GroupDto()
.setId((String) o[i++])
.setName((String) o[i++])
.setParentId((String) o[i++]);
groupDtoList.add(groupDto);
if (o[i++] != null) {
userGroupDtoList.add(groupDto);
}
}
// Post-query filtering for recursive groups
if (criteria.getUserId() != null && criteria.isRecursive()) {
Set<GroupDto> filteredGroupDtoSet = new HashSet<>();
for (GroupDto userGroupDto : userGroupDtoList) {
filteredGroupDtoSet.add(userGroupDto); // Direct group
findGroupParentHierarchy(filteredGroupDtoSet, groupDtoList, userGroupDto, 0); // Indirect groups
}
groupDtoList = new ArrayList<>(filteredGroupDtoSet);
}
return groupDtoList;
}
/**
* Recursively search group's parents.
*
* @param parentGroupDtoSet Resulting parents
* @param groupDtoList All groups
* @param userGroupDto Reference group to search from
* @param depth Depth
*/
private void findGroupParentHierarchy(Set<GroupDto> parentGroupDtoSet, List<GroupDto> groupDtoList, GroupDto userGroupDto, int depth) {
if (userGroupDto.getParentId() == null || depth == 10) { // Max depth 10 to avoid infinite loop
return;
}
for (GroupDto groupDto : groupDtoList) {
if (groupDto.getId().equals(userGroupDto.getParentId())) {
parentGroupDtoSet.add(groupDto); // Add parent
findGroupParentHierarchy(parentGroupDtoSet, groupDtoList, groupDto, depth + 1); // Find parent's parents
}
}
}
}

View File

@@ -20,9 +20,8 @@ import com.sismics.docs.core.dao.jpa.criteria.UserCriteria;
import com.sismics.docs.core.dao.jpa.dto.UserDto;
import com.sismics.docs.core.model.jpa.User;
import com.sismics.docs.core.util.AuditLogUtil;
import com.sismics.docs.core.util.jpa.PaginatedList;
import com.sismics.docs.core.util.jpa.PaginatedLists;
import com.sismics.docs.core.util.jpa.QueryParam;
import com.sismics.docs.core.util.jpa.QueryUtil;
import com.sismics.docs.core.util.jpa.SortCriteria;
import com.sismics.util.context.ThreadLocalContext;
@@ -265,10 +264,11 @@ public class UserDao {
/**
* Returns the list of all users.
*
* @param paginatedList List of users (updated by side effects)
* @param criteria Search criteria
* @param sortCriteria Sort criteria
* @return List of users
*/
public void findByCriteria(PaginatedList<UserDto> paginatedList, UserCriteria criteria, SortCriteria sortCriteria) {
public List<UserDto> findByCriteria(UserCriteria criteria, SortCriteria sortCriteria) {
Map<String, Object> parameterMap = new HashMap<String, Object>();
List<String> criteriaList = new ArrayList<String>();
@@ -289,8 +289,9 @@ public class UserDao {
}
// Perform the search
QueryParam queryParam = new QueryParam(sb.toString(), parameterMap);
List<Object[]> l = PaginatedLists.executePaginatedQuery(paginatedList, queryParam, sortCriteria);
QueryParam queryParam = QueryUtil.getSortedQueryParam(new QueryParam(sb.toString(), parameterMap), sortCriteria);
@SuppressWarnings("unchecked")
List<Object[]> l = QueryUtil.getNativeQuery(queryParam).getResultList();
// Assemble results
List<UserDto> userDtoList = new ArrayList<UserDto>();
@@ -305,6 +306,6 @@ public class UserDao {
userDto.setStorageQuota(((Number) o[i++]).longValue());
userDtoList.add(userDto);
}
paginatedList.setResultList(userDtoList);
return userDtoList;
}
}

View File

@@ -0,0 +1,50 @@
package com.sismics.docs.core.dao.jpa.criteria;
/**
* Group criteria.
*
* @author bgamard
*/
public class GroupCriteria {
/**
* Search query.
*/
private String search;
/**
* User ID.
*/
private String userId;
/**
* Retrieve user groups recursively.
*/
private boolean recursive = false;
public String getSearch() {
return search;
}
public GroupCriteria setSearch(String search) {
this.search = search;
return this;
}
public String getUserId() {
return userId;
}
public GroupCriteria setUserId(String userId) {
this.userId = userId;
return this;
}
public boolean isRecursive() {
return recursive;
}
public GroupCriteria setRecursive(boolean recursive) {
this.recursive = recursive;
return this;
}
}

View File

@@ -1,7 +1,5 @@
package com.sismics.docs.core.dao.jpa.criteria;
/**
* User criteria.
*

View File

@@ -0,0 +1,60 @@
package com.sismics.docs.core.dao.jpa.dto;
/**
* Group DTO.
*
* @author bgamard
*/
public class GroupDto {
/**
* Group ID.
*/
private String id;
/**
* Name.
*/
private String name;
/**
* Parent ID.
*/
private String parentId;
public String getId() {
return id;
}
public GroupDto setId(String id) {
this.id = id;
return this;
}
public String getName() {
return name;
}
public GroupDto setName(String name) {
this.name = name;
return this;
}
public String getParentId() {
return parentId;
}
public GroupDto setParentId(String parentId) {
this.parentId = parentId;
return this;
}
@Override
public boolean equals(Object obj) {
return id.equals(((GroupDto) obj).getId());
}
@Override
public int hashCode() {
return id.hashCode();
}
}

View File

@@ -1,6 +1,5 @@
package com.sismics.docs.core.dao.jpa.dto;
/**
* User DTO.
*

View File

@@ -105,13 +105,7 @@ public class PaginatedLists {
* @return List of results
*/
public static <E> List<Object[]> executePaginatedQuery(PaginatedList<E> paginatedList, QueryParam queryParam, SortCriteria sortCriteria) {
StringBuilder sb = new StringBuilder(queryParam.getQueryString());
sb.append(" order by c");
sb.append(sortCriteria.getColumn());
sb.append(sortCriteria.isAsc() ? " asc" : " desc");
QueryParam sortedQueryParam = new QueryParam(sb.toString(), queryParam.getParameterMap());
QueryParam sortedQueryParam = QueryUtil.getSortedQueryParam(queryParam, sortCriteria);
executeCountQuery(paginatedList, sortedQueryParam);
return executeResultQuery(paginatedList, sortedQueryParam);
}

View File

@@ -1,10 +1,11 @@
package com.sismics.docs.core.util.jpa;
import com.sismics.util.context.ThreadLocalContext;
import java.util.Map.Entry;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.util.Map.Entry;
import com.sismics.util.context.ThreadLocalContext;
/**
* Query utilities.
@@ -27,4 +28,22 @@ public class QueryUtil {
}
return query;
}
/**
* Returns sorted query parameters.
*
* @param queryParam Query parameters
* @param sortCriteria Sort criteria
* @return Sorted query parameters
*/
public static QueryParam getSortedQueryParam(QueryParam queryParam, SortCriteria sortCriteria) {
StringBuilder sb = new StringBuilder(queryParam.getQueryString());
if (sortCriteria != null) {
sb.append(" order by c");
sb.append(sortCriteria.getColumn());
sb.append(sortCriteria.isAsc() ? " asc" : " desc");
}
return new QueryParam(sb.toString(), queryParam.getParameterMap());
}
}