diff --git a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/GroupDao.java b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/GroupDao.java index ed15c8ee..a4f6735b 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/GroupDao.java +++ b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/GroupDao.java @@ -173,7 +173,7 @@ public class GroupDao { Map parameterMap = new HashMap(); List criteriaList = new ArrayList(); - StringBuilder sb = new StringBuilder("select g.GRP_ID_C as c0, g.GRP_NAME_C as c1, g.GRP_IDPARENT_C as c2, gp.GRP_NAME_C as c3 "); + StringBuilder sb = new StringBuilder("select g.GRP_ID_C as c0, g.GRP_NAME_C as c1, g.GRP_IDPARENT_C as c2, gp.GRP_NAME_C as c3, g.GRP_IDROLE_C "); if (criteria.getUserId() != null) { sb.append(" , ug.UGP_ID_C "); } @@ -213,7 +213,8 @@ public class GroupDao { .setId((String) o[i++]) .setName((String) o[i++]) .setParentId((String) o[i++]) - .setParentName((String) o[i++]); + .setParentName((String) o[i++]) + .setRoleId((String) o[i++]); groupDtoList.add(groupDto); if (criteria.getUserId() != null && o[i++] != null) { userGroupDtoList.add(groupDto); diff --git a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/RoleBaseFunctionDao.java b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/RoleBaseFunctionDao.java index 25562032..dda2740c 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/RoleBaseFunctionDao.java +++ b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/RoleBaseFunctionDao.java @@ -16,17 +16,17 @@ public class RoleBaseFunctionDao { /** * Find the set of base functions of a role. * - * @param roleId Role ID + * @param roleIdSet Set of role ID * @return Set of base functions */ @SuppressWarnings("unchecked") - public Set findByRoleId(String roleId) { + public Set findByRoleId(Set roleIdSet) { EntityManager em = ThreadLocalContext.get().getEntityManager(); StringBuilder sb = new StringBuilder("select rbf.RBF_IDBASEFUNCTION_C from T_ROLE_BASE_FUNCTION rbf, T_ROLE r"); - sb.append(" where rbf.RBF_IDROLE_C = :roleId and rbf.RBF_DELETEDATE_D is null"); + sb.append(" where rbf.RBF_IDROLE_C in (:roleIdSet) and rbf.RBF_DELETEDATE_D is null"); sb.append(" and r.ROL_ID_C = rbf.RBF_IDROLE_C and r.ROL_DELETEDATE_D is null"); Query q = em.createNativeQuery(sb.toString()); - q.setParameter("roleId", roleId); + q.setParameter("roleIdSet", roleIdSet); return Sets.newHashSet(q.getResultList()); } } diff --git a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/dto/GroupDto.java b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/dto/GroupDto.java index 7c879222..44cac882 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/dto/GroupDto.java +++ b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/dto/GroupDto.java @@ -26,6 +26,11 @@ public class GroupDto { */ private String parentName; + /** + * Role ID. + */ + private String roleId; + public String getId() { return id; } @@ -62,6 +67,15 @@ public class GroupDto { return this; } + public String getRoleId() { + return roleId; + } + + public GroupDto setRoleId(String roleId) { + this.roleId = roleId; + return this; + } + @Override public boolean equals(Object obj) { return id.equals(((GroupDto) obj).getId()); diff --git a/docs-core/src/main/java/com/sismics/docs/core/model/jpa/Group.java b/docs-core/src/main/java/com/sismics/docs/core/model/jpa/Group.java index 800b599d..56c7fdea 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/model/jpa/Group.java +++ b/docs-core/src/main/java/com/sismics/docs/core/model/jpa/Group.java @@ -36,6 +36,12 @@ public class Group implements Loggable { @Column(name = "GRP_NAME_C", nullable = false, length = 50) private String name; + /** + * Role ID. + */ + @Column(name = "GRP_IDROLE_C", length = 36) + private String roleId; + /** * Deletion date. */ @@ -79,10 +85,20 @@ public class Group implements Loggable { return this; } + public String getRoleId() { + return roleId; + } + + public Group setRoleId(String roleId) { + this.roleId = roleId; + return this; + } + @Override public String toString() { return MoreObjects.toStringHelper(this) .add("id", id) + .add("roleId", roleId) .add("parentId", parentId) .add("name", name) .toString(); diff --git a/docs-core/src/main/resources/db/update/dbupdate-008-0.sql b/docs-core/src/main/resources/db/update/dbupdate-008-0.sql index 47738c2f..7b433108 100644 --- a/docs-core/src/main/resources/db/update/dbupdate-008-0.sql +++ b/docs-core/src/main/resources/db/update/dbupdate-008-0.sql @@ -1,7 +1,7 @@ -create memory table T_GROUP ( GRP_ID_C varchar(36) not null, GRP_IDPARENT_C varchar(36), GRP_NAME_C varchar(50) not null, GRP_DELETEDATE_D datetime, primary key (GRP_ID_C) ); +create memory table T_GROUP ( GRP_ID_C varchar(36) not null, GRP_IDPARENT_C varchar(36), GRP_NAME_C varchar(50) not null, GRP_IDROLE_C varchar(36), GRP_DELETEDATE_D datetime, primary key (GRP_ID_C) ); create memory table T_USER_GROUP ( UGP_ID_C varchar(36) not null, UGP_IDUSER_C varchar(36) not null, UGP_IDGROUP_C varchar(36) not null, UGP_DELETEDATE_D datetime, primary key (UGP_ID_C) ); -insert into T_GROUP(GRP_ID_C, GRP_NAME_C) values('administrators', 'administrators'); +insert into T_GROUP(GRP_ID_C, GRP_NAME_C, GRP_IDROLE_C) values('administrators', 'administrators', 'admin'); insert into T_USER_GROUP(UGP_ID_C, UGP_IDUSER_C, UGP_IDGROUP_C) values('admin-administrators', 'admin', 'administrators'); update T_CONFIG set CFG_VALUE_C = '8' where CFG_ID_C = 'DB_VERSION'; diff --git a/docs-web-common/src/main/java/com/sismics/util/filter/TokenBasedSecurityFilter.java b/docs-web-common/src/main/java/com/sismics/util/filter/TokenBasedSecurityFilter.java index 5be61d6c..f1ba671d 100644 --- a/docs-web-common/src/main/java/com/sismics/util/filter/TokenBasedSecurityFilter.java +++ b/docs-web-common/src/main/java/com/sismics/util/filter/TokenBasedSecurityFilter.java @@ -3,6 +3,7 @@ package com.sismics.util.filter; import java.io.IOException; import java.text.MessageFormat; import java.util.Date; +import java.util.HashSet; import java.util.List; import java.util.Set; @@ -36,7 +37,7 @@ import jersey.repackaged.com.google.common.collect.Sets; /** * This filter is used to authenticate the user having an active session via an authentication token stored in database. * The filter extracts the authentication token stored in a cookie. - * If the ocokie exists and the token is valid, the filter injects a UserPrincipal into a request attribute. + * If the cookie exists and the token is valid, the filter injects a UserPrincipal into a request attribute. * If not, the user is anonymous, and the filter injects a AnonymousPrincipal into the request attribute. * * @author jtremeaux @@ -154,22 +155,27 @@ public class TokenBasedSecurityFilter implements Filter { private void injectAuthenticatedUser(HttpServletRequest request, User user) { UserPrincipal userPrincipal = new UserPrincipal(user.getId(), user.getUsername()); - // Add base functions - RoleBaseFunctionDao userBaseFuction = new RoleBaseFunctionDao(); - Set baseFunctionSet = userBaseFuction.findByRoleId(user.getRoleId()); - userPrincipal.setBaseFunctionSet(baseFunctionSet); - // Add groups GroupDao groupDao = new GroupDao(); + Set groupRoleIdSet = new HashSet<>(); List groupDtoList = groupDao.findByCriteria(new GroupCriteria() .setUserId(user.getId()) .setRecursive(true), null); Set groupIdSet = Sets.newHashSet(); for (GroupDto groupDto : groupDtoList) { groupIdSet.add(groupDto.getId()); + if (groupDto.getRoleId() != null) { + groupRoleIdSet.add(groupDto.getRoleId()); + } } userPrincipal.setGroupIdSet(groupIdSet); + // Add base functions + groupRoleIdSet.add(user.getRoleId()); + RoleBaseFunctionDao userBaseFuction = new RoleBaseFunctionDao(); + Set baseFunctionSet = userBaseFuction.findByRoleId(groupRoleIdSet); + userPrincipal.setBaseFunctionSet(baseFunctionSet); + // Add email userPrincipal.setEmail(user.getEmail()); diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/GroupResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/GroupResource.java index e0cf17b1..8cf8c07c 100644 --- a/docs-web/src/main/java/com/sismics/docs/rest/resource/GroupResource.java +++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/GroupResource.java @@ -310,7 +310,6 @@ public class GroupResource extends BaseResource { if (!authenticate()) { throw new ForbiddenClientException(); } - checkBaseFunction(BaseFunction.ADMIN); // Get the group GroupDao groupDao = new GroupDao(); diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/UserResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/UserResource.java index 3d4beaed..d27ca7c6 100644 --- a/docs-web/src/main/java/com/sismics/docs/rest/resource/UserResource.java +++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/UserResource.java @@ -25,6 +25,7 @@ import javax.ws.rs.core.Response; import org.apache.commons.lang.StringUtils; import com.google.common.base.Strings; +import com.google.common.collect.Sets; import com.sismics.docs.core.constant.Constants; import com.sismics.docs.core.dao.jpa.AuthenticationTokenDao; import com.sismics.docs.core.dao.jpa.DocumentDao; @@ -398,7 +399,7 @@ public class UserResource extends BaseResource { // Ensure that the admin user is not deleted RoleBaseFunctionDao userBaseFuction = new RoleBaseFunctionDao(); - Set baseFunctionSet = userBaseFuction.findByRoleId(user.getRoleId()); + Set baseFunctionSet = userBaseFuction.findByRoleId(Sets.newHashSet(user.getRoleId())); if (baseFunctionSet.contains(BaseFunction.ADMIN.name())) { throw new ClientException("ForbiddenError", "The admin user cannot be deleted"); } diff --git a/docs-web/src/test/java/com/sismics/docs/rest/TestGroupResource.java b/docs-web/src/test/java/com/sismics/docs/rest/TestGroupResource.java index ae40300d..834c1261 100644 --- a/docs-web/src/test/java/com/sismics/docs/rest/TestGroupResource.java +++ b/docs-web/src/test/java/com/sismics/docs/rest/TestGroupResource.java @@ -41,6 +41,18 @@ public class TestGroupResource extends BaseJerseyTest { clientUtil.createUser("group1", "g112", "g12"); String group1Token = clientUtil.login("group1"); + // Login admin2 + clientUtil.createUser("admin2", "administrators"); + String admin2Token = clientUtil.login("admin2"); + + // Create trashme + clientUtil.createUser("trashme"); + + // Delete trashme with admin2 + target().path("/user/trashme").request() + .cookie(TokenBasedSecurityFilter.COOKIE_NAME, admin2Token) + .delete(JsonObject.class); + // Get all groups JsonObject json = target().path("/group") .queryParam("sort_column", "1")