From 18cba6c067a51166fb69505fcf483b53206889d0 Mon Sep 17 00:00:00 2001 From: lucio Date: Thu, 10 Oct 2019 18:15:38 +0200 Subject: [PATCH 01/10] added client method for User and Group management --- .settings/org.eclipse.wst.common.component | 2 +- .../storagehub/services/GroupManager.java | 40 +++++++++++++++---- .../storagehub/services/ItemsManager.java | 2 +- .../storagehub/services/UserManager.java | 7 ++-- src/main/webapp/WEB-INF/gcube-app.xml | 7 ++++ 5 files changed, 45 insertions(+), 13 deletions(-) diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component index 56c3566..2275b5a 100644 --- a/.settings/org.eclipse.wst.common.component +++ b/.settings/org.eclipse.wst.common.component @@ -4,7 +4,7 @@ - + uses diff --git a/src/main/java/org/gcube/data/access/storagehub/services/GroupManager.java b/src/main/java/org/gcube/data/access/storagehub/services/GroupManager.java index cbee116..04aaee4 100644 --- a/src/main/java/org/gcube/data/access/storagehub/services/GroupManager.java +++ b/src/main/java/org/gcube/data/access/storagehub/services/GroupManager.java @@ -34,9 +34,11 @@ import org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils import org.gcube.common.authorization.control.annotations.AuthorizationControl; import org.gcube.common.authorization.library.provider.AuthorizationProvider; import org.gcube.common.gxrest.response.outbound.GXOutboundErrorResponse; +import org.gcube.common.scope.api.ScopeProvider; import org.gcube.common.storagehub.model.acls.AccessType; import org.gcube.common.storagehub.model.exceptions.BackendGenericError; import org.gcube.common.storagehub.model.exceptions.InvalidItemException; +import org.gcube.common.storagehub.model.exceptions.UserNotAuthorizedException; import org.gcube.common.storagehub.model.types.NodeProperty; import org.gcube.common.storagehub.model.types.PrimaryNodeType; import org.gcube.data.access.storagehub.Constants; @@ -51,6 +53,8 @@ public class GroupManager { @Context ServletContext context; + private static final String VREMANAGER_ROLE = "VRE-Manager"; + private static final Logger log = LoggerFactory.getLogger(GroupManager.class); @Inject @@ -59,7 +63,6 @@ public class GroupManager { @GET @Path("") @Produces(MediaType.APPLICATION_JSON) - @AuthorizationControl(allowed={"lucio.lelii"}, exception=MyAuthException.class) public List getGroups(){ JackrabbitSession session = null; @@ -93,14 +96,18 @@ public class GroupManager { @POST @Path("") @Consumes(MediaType.APPLICATION_FORM_URLENCODED) - @AuthorizationControl(allowed={"lucio.lelii"}, exception=MyAuthException.class) + @AuthorizationControl(allowedRoles={VREMANAGER_ROLE}, exception=MyAuthException.class) public String createGroup(@FormParam("group") String group, @FormParam("accessType") AccessType accessType){ + JackrabbitSession session = null; String groupId = null; try { + + checkGroupValidity(group); + session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); - + org.apache.jackrabbit.api.security.user.UserManager usrManager = session.getUserManager(); Group createdGroup = usrManager.createGroup(group); @@ -122,11 +129,13 @@ public class GroupManager { @DELETE @Path("{group}") - @AuthorizationControl(allowed={"lucio.lelii"}, exception=MyAuthException.class) + @AuthorizationControl(allowedRoles={VREMANAGER_ROLE}, exception=MyAuthException.class) public String deleteGroup(@PathParam("group") String group){ JackrabbitSession session = null; try { + + checkGroupValidity(group); session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); org.apache.jackrabbit.api.security.user.UserManager usrManager = session.getUserManager(); @@ -154,12 +163,15 @@ public class GroupManager { @PUT @Path("{id}") @Consumes(MediaType.APPLICATION_FORM_URLENCODED) - @AuthorizationControl(allowed={"lucio.lelii"}, exception=MyAuthException.class) + @AuthorizationControl(allowedRoles={VREMANAGER_ROLE}, exception=MyAuthException.class) public boolean addUserToGroup(@PathParam("id") String groupId, @FormParam("userId") String userId){ JackrabbitSession session = null; boolean success = false; try { + + checkGroupValidity(groupId); + session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); org.apache.jackrabbit.api.security.user.UserManager usrManager = session.getUserManager(); @@ -190,12 +202,15 @@ public class GroupManager { @DELETE @Path("{groupId}/users/{userId}") - @AuthorizationControl(allowed={"lucio.lelii"}, exception=MyAuthException.class) + @AuthorizationControl(allowedRoles={VREMANAGER_ROLE}, exception=MyAuthException.class) public boolean removeUserFromGroup(@PathParam("groupId") String groupId, @PathParam("userId") String userId){ JackrabbitSession session = null; boolean success = false; try { + + checkGroupValidity(groupId); + session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); org.apache.jackrabbit.api.security.user.UserManager usrManager = session.getUserManager(); @@ -233,12 +248,15 @@ public class GroupManager { @GET @Path("{groupId}/users") @Produces(MediaType.APPLICATION_JSON) - @AuthorizationControl(allowed={"lucio.lelii"}, exception=MyAuthException.class) + @AuthorizationControl(allowedRoles={VREMANAGER_ROLE}, exception=MyAuthException.class) public List getUsersOfGroup(@PathParam("groupId") String groupId){ JackrabbitSession session = null; List users = new ArrayList<>(); try { + + checkGroupValidity(groupId); + session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); org.apache.jackrabbit.api.security.user.UserManager usrManager = session.getUserManager(); @@ -313,4 +331,12 @@ public class GroupManager { return vreFolder; } + private void checkGroupValidity(String group) throws UserNotAuthorizedException{ + String currentContext = ScopeProvider.instance.get(); + String expectedGroupId= currentContext.replace("/", "-").substring(1); + if (!group.equals(expectedGroupId)) + throw new UserNotAuthorizedException("only VREManager can execute this operation"); + + } + } diff --git a/src/main/java/org/gcube/data/access/storagehub/services/ItemsManager.java b/src/main/java/org/gcube/data/access/storagehub/services/ItemsManager.java index dce3abd..7444d7b 100644 --- a/src/main/java/org/gcube/data/access/storagehub/services/ItemsManager.java +++ b/src/main/java/org/gcube/data/access/storagehub/services/ItemsManager.java @@ -280,7 +280,7 @@ public class ItemsManager { @GET @Path("publiclink/{id}") - @AuthorizationControl(allowed={"URIResolver"}, exception=MyAuthException.class) + @AuthorizationControl(allowedUsers={"URIResolver"}, exception=MyAuthException.class) public Response resolvePublicLink() { InnerMethodName.instance.set("resolvePubliclink"); diff --git a/src/main/java/org/gcube/data/access/storagehub/services/UserManager.java b/src/main/java/org/gcube/data/access/storagehub/services/UserManager.java index 4b59a63..7a86c6c 100644 --- a/src/main/java/org/gcube/data/access/storagehub/services/UserManager.java +++ b/src/main/java/org/gcube/data/access/storagehub/services/UserManager.java @@ -43,7 +43,7 @@ import org.slf4j.LoggerFactory; public class UserManager { @Context ServletContext context; - + private static final Logger log = LoggerFactory.getLogger(UserManager.class); @Inject @@ -55,7 +55,6 @@ public class UserManager { @GET @Path("") @Produces(MediaType.APPLICATION_JSON) - @AuthorizationControl(allowed={"lucio.lelii"}, exception=MyAuthException.class) public List getUsers(){ JackrabbitSession session = null; @@ -89,7 +88,7 @@ public class UserManager { @POST @Path("") @Consumes(MediaType.APPLICATION_FORM_URLENCODED) - @AuthorizationControl(allowed={"lucio.lelii"}, exception=MyAuthException.class) + @AuthorizationControl(allowedUsers={"lucio.lelii"}, exception=MyAuthException.class) public String createUser(@FormParam("user") String user, @FormParam("password") String password){ JackrabbitSession session = null; @@ -127,7 +126,7 @@ public class UserManager { @DELETE @Path("{id}") - @AuthorizationControl(allowed={"lucio.lelii"}, exception=MyAuthException.class) + @AuthorizationControl(allowedUsers={"lucio.lelii"}, exception=MyAuthException.class) public String deleteUser(@PathParam("id") String id){ JackrabbitSession session = null; diff --git a/src/main/webapp/WEB-INF/gcube-app.xml b/src/main/webapp/WEB-INF/gcube-app.xml index e69de29..4f0d8e1 100644 --- a/src/main/webapp/WEB-INF/gcube-app.xml +++ b/src/main/webapp/WEB-INF/gcube-app.xml @@ -0,0 +1,7 @@ + + StorageHub + DataAccess + 1.0.0-SNAPSHOT + Storage Hub webapp + + \ No newline at end of file From 0508aa0e3ac13ca4da60ea1ccb708c2f01bcfd9f Mon Sep 17 00:00:00 2001 From: lucio Date: Thu, 10 Oct 2019 19:09:30 +0200 Subject: [PATCH 02/10] added inner method name to GroupManager --- .../storagehub/services/GroupManager.java | 35 ++++++++++++++----- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/gcube/data/access/storagehub/services/GroupManager.java b/src/main/java/org/gcube/data/access/storagehub/services/GroupManager.java index 04aaee4..037e2cf 100644 --- a/src/main/java/org/gcube/data/access/storagehub/services/GroupManager.java +++ b/src/main/java/org/gcube/data/access/storagehub/services/GroupManager.java @@ -37,6 +37,7 @@ import org.gcube.common.gxrest.response.outbound.GXOutboundErrorResponse; import org.gcube.common.scope.api.ScopeProvider; import org.gcube.common.storagehub.model.acls.AccessType; import org.gcube.common.storagehub.model.exceptions.BackendGenericError; +import org.gcube.common.storagehub.model.exceptions.InvalidCallParameters; import org.gcube.common.storagehub.model.exceptions.InvalidItemException; import org.gcube.common.storagehub.model.exceptions.UserNotAuthorizedException; import org.gcube.common.storagehub.model.types.NodeProperty; @@ -45,6 +46,7 @@ import org.gcube.data.access.storagehub.Constants; import org.gcube.data.access.storagehub.Utils; import org.gcube.data.access.storagehub.exception.MyAuthException; import org.gcube.data.access.storagehub.handlers.CredentialHandler; +import org.gcube.smartgears.utils.InnerMethodName; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -64,7 +66,9 @@ public class GroupManager { @Path("") @Produces(MediaType.APPLICATION_JSON) public List getGroups(){ - + + InnerMethodName.instance.set("getGroups"); + JackrabbitSession session = null; List groups= new ArrayList<>(); try { @@ -98,7 +102,8 @@ public class GroupManager { @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @AuthorizationControl(allowedRoles={VREMANAGER_ROLE}, exception=MyAuthException.class) public String createGroup(@FormParam("group") String group, @FormParam("accessType") AccessType accessType){ - + + InnerMethodName.instance.set("createGroup"); JackrabbitSession session = null; String groupId = null; @@ -131,7 +136,9 @@ public class GroupManager { @Path("{group}") @AuthorizationControl(allowedRoles={VREMANAGER_ROLE}, exception=MyAuthException.class) public String deleteGroup(@PathParam("group") String group){ - + + InnerMethodName.instance.set("deleteGroup"); + JackrabbitSession session = null; try { @@ -165,7 +172,9 @@ public class GroupManager { @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @AuthorizationControl(allowedRoles={VREMANAGER_ROLE}, exception=MyAuthException.class) public boolean addUserToGroup(@PathParam("id") String groupId, @FormParam("userId") String userId){ - + + InnerMethodName.instance.set("addUserToGroup"); + JackrabbitSession session = null; boolean success = false; try { @@ -178,7 +187,10 @@ public class GroupManager { Group group = (Group)usrManager.getAuthorizable(groupId); User user = (User)usrManager.getAuthorizable(userId); - + + if (group.isMember(user)) + throw new InvalidCallParameters("user "+userId+" is already member of group "+groupId); + success = group.addMember(user); String folderName = group.getPrincipal().getName(); @@ -204,7 +216,9 @@ public class GroupManager { @Path("{groupId}/users/{userId}") @AuthorizationControl(allowedRoles={VREMANAGER_ROLE}, exception=MyAuthException.class) public boolean removeUserFromGroup(@PathParam("groupId") String groupId, @PathParam("userId") String userId){ - + + InnerMethodName.instance.set("removeUserFromGroup"); + JackrabbitSession session = null; boolean success = false; try { @@ -217,7 +231,10 @@ public class GroupManager { Group group = (Group)usrManager.getAuthorizable(groupId); User user = (User)usrManager.getAuthorizable(userId); - + + if (!group.isMember(user)) + throw new InvalidCallParameters("user "+userId+" is not member of group "+groupId); + //delete folder on user String folderName = group.getPrincipal().getName(); Node folder = getVreFolderNode(session, folderName); @@ -250,7 +267,9 @@ public class GroupManager { @Produces(MediaType.APPLICATION_JSON) @AuthorizationControl(allowedRoles={VREMANAGER_ROLE}, exception=MyAuthException.class) public List getUsersOfGroup(@PathParam("groupId") String groupId){ - + + InnerMethodName.instance.set("getUsersOfGroup"); + JackrabbitSession session = null; List users = new ArrayList<>(); try { From 0f156c663709cbb8a61ca1ea357056de12eca801 Mon Sep 17 00:00:00 2001 From: lucio Date: Fri, 25 Oct 2019 14:58:09 +0200 Subject: [PATCH 03/10] gcube-app file updated --- .settings/org.eclipse.wst.common.component | 2 +- distro/gcube-app.xml | 2 +- pom.xml | 2 +- .../storagehub/services/ACLManager.java | 50 +++++++++---------- .../storagehub/services/GroupManager.java | 36 +++++++------ .../storagehub/services/UserManager.java | 26 ++++++---- src/main/webapp/WEB-INF/gcube-app.xml | 2 +- 7 files changed, 67 insertions(+), 53 deletions(-) diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component index 2275b5a..1314f66 100644 --- a/.settings/org.eclipse.wst.common.component +++ b/.settings/org.eclipse.wst.common.component @@ -7,7 +7,7 @@ uses - + uses diff --git a/distro/gcube-app.xml b/distro/gcube-app.xml index 4f0d8e1..aa6e541 100644 --- a/distro/gcube-app.xml +++ b/distro/gcube-app.xml @@ -1,7 +1,7 @@ StorageHub DataAccess - 1.0.0-SNAPSHOT + ${version} Storage Hub webapp \ No newline at end of file diff --git a/pom.xml b/pom.xml index 474122e..3aa3b2d 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ 4.0.0 org.gcube.data.access storagehub - 1.0.8 + 1.0.8-SNAPSHOT storagehub diff --git a/src/main/java/org/gcube/data/access/storagehub/services/ACLManager.java b/src/main/java/org/gcube/data/access/storagehub/services/ACLManager.java index 9227378..15224cf 100644 --- a/src/main/java/org/gcube/data/access/storagehub/services/ACLManager.java +++ b/src/main/java/org/gcube/data/access/storagehub/services/ACLManager.java @@ -143,19 +143,19 @@ public class ACLManager { InnerMethodName.instance.set("setACLById"); Session ses = null; try{ - + ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); - + Node node = ses.getNodeByIdentifier(id); Item item = node2Item.getItem(node, Excludes.ALL); - + if (!(item instanceof SharedFolder)) throw new InvalidItemException("the item is not a shared folder"); - + if (item.getOwner().equals(user)) throw new UserNotAuthorizedException("owner acl cannot be changed"); - + authChecker.checkAdministratorControl(ses, (SharedFolder) item); SharedFolder folder = ((SharedFolder)item); @@ -234,14 +234,14 @@ public class ACLManager { * * * @param String user - * @param accessType accessType + * * * @exception {@link RepositoryException} when a generic jcr error occurs * @exception {@link UserNotAuthorizedException} when the caller is not ADMINISTRATOR of the shared folder * @exception {@link InvalidCallParameters} when the folder is not shared with the specified user * @exception {@link InvalidItemException} when the folder is not share */ - /*@DELETE + @DELETE @Consumes(MediaType.TEXT_PLAIN) @Path("{id}/acls/{user}") public void removeACL(@PathParam("user") String user) { @@ -261,28 +261,26 @@ public class ACLManager { SharedFolder folder = ((SharedFolder)item); - if (folder.isVreFolder()) { - AccessControlManager acm = ses.getAccessControlManager(); - JackrabbitAccessControlList acls = AccessControlUtils.getAccessControlList(acm, folder.getPath()); + AccessControlManager acm = ses.getAccessControlManager(); + JackrabbitAccessControlList acls = AccessControlUtils.getAccessControlList(acm, folder.getPath()); - AccessControlEntry entryToDelete= null; - for (AccessControlEntry ace :acls.getAccessControlEntries()) { - if (ace.getPrincipal().getName().equals(user)) { - entryToDelete = ace; - break; - } - + AccessControlEntry entryToDelete= null; + for (AccessControlEntry ace :acls.getAccessControlEntries()) { + if (ace.getPrincipal().getName().equals(user)) { + entryToDelete = ace; + break; } - if (entryToDelete!=null) - acls.removeAccessControlEntry(entryToDelete); - else return; - - acm.setPolicy(folder.getPath(), acls); - ses.save(); - log.debug("removed Access control entry for user {}",user); - } else throw new InvalidCallParameters("remove acl can be called only on VRE folder"); + } + if (entryToDelete!=null) + acls.removeAccessControlEntry(entryToDelete); + else return; + + acm.setPolicy(folder.getPath(), acls); + ses.save(); + log.debug("removed Access control entry for user {}",user); + }catch(RepositoryException re){ log.error("jcr error extracting archive", re); @@ -294,7 +292,7 @@ public class ACLManager { if (ses!=null) ses.logout(); } - }*/ + } @GET @Path("{id}/acls/write") diff --git a/src/main/java/org/gcube/data/access/storagehub/services/GroupManager.java b/src/main/java/org/gcube/data/access/storagehub/services/GroupManager.java index 037e2cf..4abdae8 100644 --- a/src/main/java/org/gcube/data/access/storagehub/services/GroupManager.java +++ b/src/main/java/org/gcube/data/access/storagehub/services/GroupManager.java @@ -56,6 +56,7 @@ public class GroupManager { @Context ServletContext context; private static final String VREMANAGER_ROLE = "VRE-Manager"; + private static final String INFRASTRUCTURE_MANAGER_ROLE = "Infrastructure-Manager"; private static final Logger log = LoggerFactory.getLogger(GroupManager.class); @@ -100,7 +101,7 @@ public class GroupManager { @POST @Path("") @Consumes(MediaType.APPLICATION_FORM_URLENCODED) - @AuthorizationControl(allowedRoles={VREMANAGER_ROLE}, exception=MyAuthException.class) + @AuthorizationControl(allowedRoles={INFRASTRUCTURE_MANAGER_ROLE}, exception=MyAuthException.class) public String createGroup(@FormParam("group") String group, @FormParam("accessType") AccessType accessType){ InnerMethodName.instance.set("createGroup"); @@ -109,7 +110,8 @@ public class GroupManager { String groupId = null; try { - checkGroupValidity(group); + if (!isValidGroupForContext(groupId)) + throw new UserNotAuthorizedException("only VREManager can execute this operation"); session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); @@ -134,7 +136,7 @@ public class GroupManager { @DELETE @Path("{group}") - @AuthorizationControl(allowedRoles={VREMANAGER_ROLE}, exception=MyAuthException.class) + @AuthorizationControl(allowedRoles={INFRASTRUCTURE_MANAGER_ROLE}, exception=MyAuthException.class) public String deleteGroup(@PathParam("group") String group){ InnerMethodName.instance.set("deleteGroup"); @@ -142,7 +144,9 @@ public class GroupManager { JackrabbitSession session = null; try { - checkGroupValidity(group); + if (!isValidGroupForContext(group)) + throw new UserNotAuthorizedException("only VREManager of the selected VRE can execute this operation"); + session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); org.apache.jackrabbit.api.security.user.UserManager usrManager = session.getUserManager(); @@ -163,14 +167,17 @@ public class GroupManager { if (session!=null) session.logout(); } - return group; } + + public boolean isAdmin() { return AuthorizationProvider.instance.get().getClient().getRoles().contains(INFRASTRUCTURE_MANAGER_ROLE); } + + @PUT @Path("{id}") @Consumes(MediaType.APPLICATION_FORM_URLENCODED) - @AuthorizationControl(allowedRoles={VREMANAGER_ROLE}, exception=MyAuthException.class) + @AuthorizationControl(allowedRoles={VREMANAGER_ROLE, INFRASTRUCTURE_MANAGER_ROLE}, exception=MyAuthException.class) public boolean addUserToGroup(@PathParam("id") String groupId, @FormParam("userId") String userId){ InnerMethodName.instance.set("addUserToGroup"); @@ -179,7 +186,8 @@ public class GroupManager { boolean success = false; try { - checkGroupValidity(groupId); + if (!isValidGroupForContext(groupId) && !isAdmin()) + throw new UserNotAuthorizedException("only VREManager of the selected VRE can execute this operation"); session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); @@ -214,7 +222,7 @@ public class GroupManager { @DELETE @Path("{groupId}/users/{userId}") - @AuthorizationControl(allowedRoles={VREMANAGER_ROLE}, exception=MyAuthException.class) + @AuthorizationControl(allowedRoles={VREMANAGER_ROLE, INFRASTRUCTURE_MANAGER_ROLE}, exception=MyAuthException.class) public boolean removeUserFromGroup(@PathParam("groupId") String groupId, @PathParam("userId") String userId){ InnerMethodName.instance.set("removeUserFromGroup"); @@ -223,7 +231,8 @@ public class GroupManager { boolean success = false; try { - checkGroupValidity(groupId); + if (!isValidGroupForContext(groupId) && !isAdmin()) + throw new UserNotAuthorizedException("only VREManager of the selected VRE can execute this operation"); session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); @@ -274,7 +283,8 @@ public class GroupManager { List users = new ArrayList<>(); try { - checkGroupValidity(groupId); + if (!isValidGroupForContext(groupId)) + throw new UserNotAuthorizedException("only VREManager of the selected VRE can execute this operation"); session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); @@ -350,12 +360,10 @@ public class GroupManager { return vreFolder; } - private void checkGroupValidity(String group) throws UserNotAuthorizedException{ + private boolean isValidGroupForContext(String group){ String currentContext = ScopeProvider.instance.get(); String expectedGroupId= currentContext.replace("/", "-").substring(1); - if (!group.equals(expectedGroupId)) - throw new UserNotAuthorizedException("only VREManager can execute this operation"); - + return group.equals(expectedGroupId); } } diff --git a/src/main/java/org/gcube/data/access/storagehub/services/UserManager.java b/src/main/java/org/gcube/data/access/storagehub/services/UserManager.java index 7a86c6c..fcee912 100644 --- a/src/main/java/org/gcube/data/access/storagehub/services/UserManager.java +++ b/src/main/java/org/gcube/data/access/storagehub/services/UserManager.java @@ -28,8 +28,10 @@ import org.apache.jackrabbit.api.security.user.QueryBuilder; import org.apache.jackrabbit.api.security.user.User; import org.apache.jackrabbit.core.security.principal.PrincipalImpl; import org.gcube.common.authorization.control.annotations.AuthorizationControl; +import org.gcube.common.authorization.library.provider.AuthorizationProvider; import org.gcube.common.gxrest.response.outbound.GXOutboundErrorResponse; import org.gcube.common.storagehub.model.exceptions.BackendGenericError; +import org.gcube.common.storagehub.model.exceptions.UserNotAuthorizedException; import org.gcube.common.storagehub.model.types.NodeProperty; import org.gcube.data.access.storagehub.Constants; import org.gcube.data.access.storagehub.Utils; @@ -42,6 +44,8 @@ import org.slf4j.LoggerFactory; @Path("users") public class UserManager { + private static final String INFRASTRUCTURE_MANAGER_ROLE = "Infrastructure-Manager"; + @Context ServletContext context; private static final Logger log = LoggerFactory.getLogger(UserManager.class); @@ -88,14 +92,15 @@ public class UserManager { @POST @Path("") @Consumes(MediaType.APPLICATION_FORM_URLENCODED) - @AuthorizationControl(allowedUsers={"lucio.lelii"}, exception=MyAuthException.class) + @AuthorizationControl(allowedRoles={INFRASTRUCTURE_MANAGER_ROLE}, exception=MyAuthException.class) public String createUser(@FormParam("user") String user, @FormParam("password") String password){ JackrabbitSession session = null; String userId = null; try { session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); - + + org.apache.jackrabbit.api.security.user.UserManager usrManager = session.getUserManager(); User createdUser = usrManager.createUser(user, password); @@ -125,18 +130,21 @@ public class UserManager { @DELETE - @Path("{id}") - @AuthorizationControl(allowedUsers={"lucio.lelii"}, exception=MyAuthException.class) - public String deleteUser(@PathParam("id") String id){ + @Path("{user}") + @AuthorizationControl(allowedRoles={INFRASTRUCTURE_MANAGER_ROLE}, exception=MyAuthException.class) + public String deleteUser(@PathParam("user") String user){ + + JackrabbitSession session = null; String userId = null; try { + session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); org.apache.jackrabbit.api.security.user.UserManager usrManager = session.getUserManager(); - org.gcube.common.storagehub.model.Path path = Utils.getWorkspacePath(id); + org.gcube.common.storagehub.model.Path path = Utils.getWorkspacePath(user); String sql2Query = String.format("SELECT * FROM [nthl:workspaceSharedItem] AS node WHERE ISDESCENDANTNODE('%s')", path.toPath()); @@ -152,12 +160,12 @@ public class UserManager { Node rNode = nodeIt.nextNode(); String title = rNode.hasProperty(NodeProperty.TITLE.toString()) ? rNode.getProperty(NodeProperty.TITLE.toString()).getString():"unknown"; log.debug("removing sharing for folder name {} with title {} and path {} ",rNode.getName(), title, rNode.getPath()); - unshareHandler.unshare(session, Collections.singleton(id), rNode, id); + unshareHandler.unshare(session, Collections.singleton(user), rNode, user); } - Authorizable authorizable = usrManager.getAuthorizable(new PrincipalImpl(id)); + Authorizable authorizable = usrManager.getAuthorizable(new PrincipalImpl(user)); if (!authorizable.isGroup()) { - log.info("removing user {}", id); + log.info("removing user {}", user); authorizable.remove(); } session.save(); diff --git a/src/main/webapp/WEB-INF/gcube-app.xml b/src/main/webapp/WEB-INF/gcube-app.xml index 4f0d8e1..36e3d04 100644 --- a/src/main/webapp/WEB-INF/gcube-app.xml +++ b/src/main/webapp/WEB-INF/gcube-app.xml @@ -1,7 +1,7 @@ StorageHub DataAccess - 1.0.0-SNAPSHOT + 1.0.8-SNAPSHOT Storage Hub webapp \ No newline at end of file From 4802a0542e5685868ff75f67055c578d66697245 Mon Sep 17 00:00:00 2001 From: lucio Date: Tue, 7 Jan 2020 17:05:51 +0100 Subject: [PATCH 04/10] Corrected a Authorization message error --- pom.xml | 5 ----- .../access/storagehub/AuthorizationChecker.java | 14 +++++++------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/pom.xml b/pom.xml index 3aa3b2d..1c29013 100644 --- a/pom.xml +++ b/pom.xml @@ -97,11 +97,6 @@ common-scope - - org.gcube.core - common-encryption - - org.gcube.common storagehub-model diff --git a/src/main/java/org/gcube/data/access/storagehub/AuthorizationChecker.java b/src/main/java/org/gcube/data/access/storagehub/AuthorizationChecker.java index ad792be..a294964 100644 --- a/src/main/java/org/gcube/data/access/storagehub/AuthorizationChecker.java +++ b/src/main/java/org/gcube/data/access/storagehub/AuthorizationChecker.java @@ -44,7 +44,7 @@ public class AuthorizationChecker { Item item = node2Item.getItem(node, Excludes.ALL); - if (item==null) throw new UserNotAuthorizedException("Insufficent Provileges for user "+login+" to read node with id "+id+": it's not a valid StorageHub node"); + if (item==null) throw new UserNotAuthorizedException("Insufficent Privileges for user "+login+" to read node with id "+id+": it's not a valid StorageHub node"); @@ -64,10 +64,10 @@ public class AuthorizationChecker { if (!authorizable.isGroup() && entry.getPrincipal().getName().equals(login)) return; if (authorizable.isGroup() && ((Group) authorizable).isMember(userAuthorizable)) return; } - throw new UserNotAuthorizedException("Insufficent Provileges for user "+login+" to read node with id "+id); + throw new UserNotAuthorizedException("Insufficent Privileges for user "+login+" to read node with id "+id); } else if (item.getOwner()==null || !item.getOwner().equals(login)) - throw new UserNotAuthorizedException("Insufficent Provileges for user "+login+" to read node with id "+id); + throw new UserNotAuthorizedException("Insufficent Privileges for user "+login+" to read node with id "+id); } @@ -86,10 +86,10 @@ public class AuthorizationChecker { String login = AuthorizationProvider.instance.get().getClient().getId(); - if (item==null) throw new UserNotAuthorizedException("Insufficent Provileges for user "+login+" to write into node with id "+id+": it's not a valid StorageHub node"); + if (item==null) throw new UserNotAuthorizedException("Insufficent Privileges for user "+login+" to write into node with id "+id+": it's not a valid StorageHub node"); if (Constants.WRITE_PROTECTED_FOLDER.contains(item.getName()) || Constants.WRITE_PROTECTED_FOLDER.contains(item.getTitle())) - throw new UserNotAuthorizedException("Insufficent Provileges for user "+login+" to write into node with id "+id+": it's a protected folder"); + throw new UserNotAuthorizedException("Insufficent Privileges for user "+login+" to write into node with id "+id+": it's a protected folder"); if (item.isShared()) { Node parentSharedNode = retrieveSharedFolderParent(node, session); @@ -116,7 +116,7 @@ public class AuthorizationChecker { } else if(item.getOwner().equals(login)) return; - throw new UserNotAuthorizedException("Insufficent Provileges for user "+login+" to write into node with id "+id); + throw new UserNotAuthorizedException("Insufficent Privileges for user "+login+" to write into node with id "+id); } @@ -132,7 +132,7 @@ public class AuthorizationChecker { //TODO: riguardare questo pezzo di codice String login = AuthorizationProvider.instance.get().getClient().getId(); - if (item==null) throw new UserNotAuthorizedException("Insufficent Provileges for user "+login+": it's not a valid StorageHub node"); + if (item==null) throw new UserNotAuthorizedException("Insufficent Privileges for user "+login+": it's not a valid StorageHub node"); Node node = session.getNodeByIdentifier(item.getId()); From 2dc02aa194b3157f4be016709b6fab37954fc91f Mon Sep 17 00:00:00 2001 From: lucio Date: Tue, 7 Jan 2020 18:25:52 +0100 Subject: [PATCH 05/10] unshared accounting added --- .../accounting/AccountingHandler.java | 6 +++--- .../storagehub/handlers/UnshareHandler.java | 19 ++++++++++++++++--- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/gcube/data/access/storagehub/accounting/AccountingHandler.java b/src/main/java/org/gcube/data/access/storagehub/accounting/AccountingHandler.java index d2986c0..9232037 100644 --- a/src/main/java/org/gcube/data/access/storagehub/accounting/AccountingHandler.java +++ b/src/main/java/org/gcube/data/access/storagehub/accounting/AccountingHandler.java @@ -172,7 +172,7 @@ public class AccountingHandler { } } - public void createUnshareFolder(String title, Session ses, Node sharedNode, boolean saveHistory ) { + public void createUnshareFolder(String title, String user, Session ses, Node sharedNode, boolean saveHistory ) { try { if (!sharedNode.hasNode(NodeProperty.ACCOUNTING.toString())){ @@ -180,8 +180,8 @@ public class AccountingHandler { } Node accountingNodeParent = sharedNode.getNode(NodeProperty.ACCOUNTING.toString()); - Node accountingNode = accountingNodeParent.addNode(UUID.randomUUID().toString(),AccountingEntryType.SHARE.getNodeTypeDefinition()); - accountingNode.setProperty(USER, AuthorizationProvider.instance.get().getClient().getId()); + Node accountingNode = accountingNodeParent.addNode(UUID.randomUUID().toString(),AccountingEntryType.UNSHARE.getNodeTypeDefinition()); + accountingNode.setProperty(USER, user); accountingNode.setProperty(DATE, Calendar.getInstance()); accountingNode.setProperty(ITEM_NAME, title); diff --git a/src/main/java/org/gcube/data/access/storagehub/handlers/UnshareHandler.java b/src/main/java/org/gcube/data/access/storagehub/handlers/UnshareHandler.java index 1387eb4..73c6417 100644 --- a/src/main/java/org/gcube/data/access/storagehub/handlers/UnshareHandler.java +++ b/src/main/java/org/gcube/data/access/storagehub/handlers/UnshareHandler.java @@ -27,6 +27,7 @@ import org.gcube.common.storagehub.model.items.FolderItem; import org.gcube.common.storagehub.model.items.Item; import org.gcube.common.storagehub.model.items.SharedFolder; import org.gcube.common.storagehub.model.types.ItemAction; +import org.gcube.common.storagehub.model.types.NodeProperty; import org.gcube.data.access.storagehub.AuthorizationChecker; import org.gcube.data.access.storagehub.Utils; import org.gcube.data.access.storagehub.accounting.AccountingHandler; @@ -122,6 +123,11 @@ public class UnshareHandler { log.debug("copying {} to {}", itemToCopyNode.getPath(), unsharedNode.getPath()); ses.move(itemToCopyNode.getPath(), String.format("%s/%s",unsharedNode.getPath(), itemToCopyNode.getName())); } + + ses.move(sharedItemNode.getNode(NodeProperty.ACCOUNTING.toString()).getPath(), String.format("%s/%s",unsharedNode.getPath(), NodeProperty.ACCOUNTING.toString())); + + accountingHandler.createUnshareFolder(sharedItemNode.getProperty(NodeProperty.TITLE.toString()).getString(), "ALL", ses, unsharedNode, false); + ses.save(); }finally { ses.getWorkspace().getLockManager().unlock(sharedItemNode.getPath()); @@ -164,6 +170,9 @@ public class UnshareHandler { log.debug("removed Access control entry for user {}",login); Node sharedItemNode = ses.getNodeByIdentifier(item.getId()); + + accountingHandler.createUnshareFolder(sharedItemNode.getProperty(NodeProperty.TITLE.toString()).getString(), login, ses, sharedItemNode, false); + Node usersNode = sharedItemNode.getNode(NodeConstants.USERS_NAME); usersNode.remove(); Node newUsersNode = sharedItemNode.addNode(NodeConstants.USERS_NAME); @@ -175,7 +184,8 @@ public class UnshareHandler { }}); acm.setPolicy(sharedFolderNode.getPath(), acls); - + + ses.save(); return parentId; @@ -225,7 +235,11 @@ public class UnshareHandler { }}); acm.setPolicy(sharedFolderNode.getPath(), acls); - + + for (String user: usersToUnshare) { + accountingHandler.createUnshareFolder(sharedItemNode.getProperty(NodeProperty.TITLE.toString()).getString(), user, ses, sharedItemNode, false); + } + ses.save(); return item.getId(); @@ -242,7 +256,6 @@ public class UnshareHandler { Node parentNode = ses.getNodeByIdentifier(parentDirectoryId); Node userNode = ses.getNode(String.format("%s/%s",parentNode.getPath(), directoryName)); userNode.removeShare(); - accountingHandler.createUnshareFolder(directoryName, ses, parentNode, false); log.debug("directory removed for user {}",user); return parentDirectoryId; } From 67fe556a4ff46f8e3b645100ee4f60c9900b2492 Mon Sep 17 00:00:00 2001 From: lucio Date: Wed, 15 Jan 2020 19:11:07 +0100 Subject: [PATCH 06/10] methdo for administrator management added --- .../gcube/data/access/storagehub/Utils.java | 61 ++++- .../accounting/AccountingHandler.java | 29 ++- .../storagehub/handlers/UnshareHandler.java | 6 + .../storagehub/services/ACLManager.java | 30 +-- .../storagehub/services/GroupManager.java | 226 +++++++++++++++--- .../storagehub/services/ItemsCreator.java | 4 +- .../storagehub/services/WorkspaceManager.java | 8 +- 7 files changed, 284 insertions(+), 80 deletions(-) diff --git a/src/main/java/org/gcube/data/access/storagehub/Utils.java b/src/main/java/org/gcube/data/access/storagehub/Utils.java index 62f4ec8..b4d3b28 100644 --- a/src/main/java/org/gcube/data/access/storagehub/Utils.java +++ b/src/main/java/org/gcube/data/access/storagehub/Utils.java @@ -22,11 +22,15 @@ import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.lock.Lock; import javax.jcr.lock.LockException; +import javax.jcr.query.Query; import javax.jcr.version.Version; import org.apache.commons.io.FilenameUtils; import org.apache.jackrabbit.util.Text; import org.gcube.common.authorization.library.provider.AuthorizationProvider; +import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.common.scope.impl.ScopeBean; +import org.gcube.common.scope.impl.ScopeBean.Type; import org.gcube.common.storagehub.model.Excludes; import org.gcube.common.storagehub.model.Paths; import org.gcube.common.storagehub.model.exceptions.BackendGenericError; @@ -39,15 +43,13 @@ import org.gcube.common.storagehub.model.items.Item; import org.gcube.common.storagehub.model.items.SharedFolder; import org.gcube.common.storagehub.model.types.ItemAction; import org.gcube.common.storagehub.model.types.NodeProperty; -import org.gcube.contentmanager.storageclient.wrapper.AccessType; -import org.gcube.contentmanager.storageclient.wrapper.MemoryType; -import org.gcube.contentmanager.storageclient.wrapper.StorageClient; import org.gcube.data.access.storagehub.accounting.AccountingHandler; import org.gcube.data.access.storagehub.handlers.Item2NodeConverter; import org.gcube.data.access.storagehub.handlers.Node2ItemConverter; import org.gcube.data.access.storagehub.handlers.StorageBackendHandler; +import org.gcube.data.access.storagehub.handlers.VRE; +import org.gcube.data.access.storagehub.handlers.VREManager; import org.gcube.data.access.storagehub.handlers.VersionHandler; -import org.gcube.data.access.storagehub.storage.backend.impl.GCubeStorageBackend; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -323,8 +325,10 @@ public class Utils { //item.setHidden(destinationItem.isHidden()); Node newNode = new Item2NodeConverter().getNode(destinationNode, item); - if (accountingHandler!=null) - accountingHandler.createFolderAddObj(name, item.getClass().getSimpleName(), null, ses, newNode, false); + if (accountingHandler!=null) { + accountingHandler.createFolderAddObj(name, item.getClass().getSimpleName(), null, ses, destinationNode, false); + accountingHandler.createEntryCreate(item.getTitle(), ses, newNode, false); + } return newNode; } @@ -349,8 +353,10 @@ public class Utils { //item.setHidden(destinationItem.isHidden()); Node newNode = new Item2NodeConverter().getNode(destinationNode, item); - if (accountingHandler!=null) - accountingHandler.createFolderAddObj(name, item.getClass().getSimpleName(), null, ses, newNode, false); + if (accountingHandler!=null) { + accountingHandler.createFolderAddObj(name, item.getClass().getSimpleName(), null, ses, destinationNode, false); + accountingHandler.createEntryCreate(item.getTitle(), ses, newNode, false); + } return newNode; } @@ -380,4 +386,43 @@ public class Utils { node.setProperty(NodeProperty.LAST_MODIFIED_BY.toString(), login); node.setProperty(NodeProperty.LAST_ACTION.toString(), action.name()); } + + public static synchronized VRE getVreFolderItem(Session ses, Node2ItemConverter node2Item, VREManager vreManager, List excludes ) throws RepositoryException, BackendGenericError{ + org.gcube.common.storagehub.model.Path vrePath = Paths.append(Utils.getWorkspacePath(), Constants.VRE_FOLDER_PARENT_NAME); + ScopeBean bean = new ScopeBean(ScopeProvider.instance.get()); + if (!bean.is(Type.VRE)) throw new BackendGenericError("the current scope is not a VRE"); + String entireScopeName= bean.toString().replaceAll("^/(.*)/?$", "$1").replaceAll("/", "-"); + VRE vre = vreManager.getVRE(entireScopeName); + if (vre!=null) return vre; + else { + String query = String.format("SELECT * FROM [nthl:workspaceItem] As node WHERE node.[jcr:title] like '%s' AND ISDESCENDANTNODE('%s')",entireScopeName, vrePath.toPath()); + Query jcrQuery = ses.getWorkspace().getQueryManager().createQuery(query, Constants.QUERY_LANGUAGE); + NodeIterator it = jcrQuery.execute().getNodes(); + + if (!it.hasNext()) throw new BackendGenericError("vre folder not found for context "+entireScopeName); + + Node folder = it.nextNode(); + Item vreFolder = node2Item.getItem(folder, excludes); + return vreManager.putVRE(vreFolder); + } + + } + + public static synchronized VRE getVreFolderItemByGroupNameAndUser(Session ses, String goupName, String userId, Node2ItemConverter node2Item, VREManager vreManager, List excludes ) throws RepositoryException, BackendGenericError{ + org.gcube.common.storagehub.model.Path vrePath = Paths.append(Utils.getWorkspacePath(userId), Constants.VRE_FOLDER_PARENT_NAME); + VRE vre = vreManager.getVRE(goupName); + if (vre!=null) return vre; + else { + String query = String.format("SELECT * FROM [nthl:workspaceItem] As node WHERE node.[jcr:title] like '%s' AND ISDESCENDANTNODE('%s')",goupName, vrePath.toPath()); + Query jcrQuery = ses.getWorkspace().getQueryManager().createQuery(query, Constants.QUERY_LANGUAGE); + NodeIterator it = jcrQuery.execute().getNodes(); + + if (!it.hasNext()) throw new BackendGenericError("vre folder not found for context "+goupName); + + Node folder = it.nextNode(); + Item vreFolder = node2Item.getItem(folder, excludes); + return vreManager.putVRE(vreFolder); + } + } + } diff --git a/src/main/java/org/gcube/data/access/storagehub/accounting/AccountingHandler.java b/src/main/java/org/gcube/data/access/storagehub/accounting/AccountingHandler.java index 9232037..d321019 100644 --- a/src/main/java/org/gcube/data/access/storagehub/accounting/AccountingHandler.java +++ b/src/main/java/org/gcube/data/access/storagehub/accounting/AccountingHandler.java @@ -70,6 +70,25 @@ public class AccountingHandler { } } + public void createEntryCreate(String title, Session ses, Node node, boolean saveHistory ) { + try { + + if (!node.hasNode(NodeProperty.ACCOUNTING.toString())){ + node.addNode(NodeProperty.ACCOUNTING.toString(), NodeProperty.NT_ACCOUNTING.toString()); + } + + Node accountingNodeParent = node.getNode(NodeProperty.ACCOUNTING.toString()); + Node accountingNode = accountingNodeParent.addNode(UUID.randomUUID().toString(),AccountingEntryType.CREATE.getNodeTypeDefinition()); + accountingNode.setProperty(USER, AuthorizationProvider.instance.get().getClient().getId()); + accountingNode.setProperty(DATE, Calendar.getInstance()); + accountingNode.setProperty(ITEM_NAME, title); + + if (saveHistory) ses.save(); + } catch (RepositoryException e) { + logger.warn("error trying to retrieve accountign node",e); + } + } + public void createFileUpdated(String title, Session ses, Node node, boolean saveHistory ) { try { @@ -107,15 +126,15 @@ public class AccountingHandler { } - public void createFolderAddObj(String title, String itemType, String mimeType, Session ses, Node node, boolean saveHistory ) { + public void createFolderAddObj(String title, String itemType, String mimeType, Session ses, Node parentNode, boolean saveHistory ) { try { - Node directoryNode = node.getParent(); - if (!directoryNode.hasNode(NodeProperty.ACCOUNTING.toString())){ - directoryNode.addNode(NodeProperty.ACCOUNTING.toString(), NodeProperty.NT_ACCOUNTING.toString()); + + if (!parentNode.hasNode(NodeProperty.ACCOUNTING.toString())){ + parentNode.addNode(NodeProperty.ACCOUNTING.toString(), NodeProperty.NT_ACCOUNTING.toString()); } - Node accountingNodeParent = directoryNode.getNode(NodeProperty.ACCOUNTING.toString()); + Node accountingNodeParent = parentNode.getNode(NodeProperty.ACCOUNTING.toString()); Node accountingNode = accountingNodeParent.addNode(UUID.randomUUID().toString(),AccountingEntryType.ADD.getNodeTypeDefinition()); accountingNode.setProperty(USER, AuthorizationProvider.instance.get().getClient().getId()); accountingNode.setProperty(DATE, Calendar.getInstance()); diff --git a/src/main/java/org/gcube/data/access/storagehub/handlers/UnshareHandler.java b/src/main/java/org/gcube/data/access/storagehub/handlers/UnshareHandler.java index 73c6417..35646c6 100644 --- a/src/main/java/org/gcube/data/access/storagehub/handlers/UnshareHandler.java +++ b/src/main/java/org/gcube/data/access/storagehub/handlers/UnshareHandler.java @@ -116,6 +116,8 @@ public class UnshareHandler { unsharedNode = createUnsharedFolder(ses, parentNode, directoryName, item.getDescription(), login); + + List itemsToCopy = Utils.getItemList(sharedItemNode, Excludes.ALL, null, true, null); for (Item itemCopy: itemsToCopy) { @@ -124,11 +126,15 @@ public class UnshareHandler { ses.move(itemToCopyNode.getPath(), String.format("%s/%s",unsharedNode.getPath(), itemToCopyNode.getName())); } + unsharedNode.getNode(NodeProperty.ACCOUNTING.toString()).remove(); ses.move(sharedItemNode.getNode(NodeProperty.ACCOUNTING.toString()).getPath(), String.format("%s/%s",unsharedNode.getPath(), NodeProperty.ACCOUNTING.toString())); accountingHandler.createUnshareFolder(sharedItemNode.getProperty(NodeProperty.TITLE.toString()).getString(), "ALL", ses, unsharedNode, false); ses.save(); + }catch(Throwable t) { + log.error("erro unsharing all",t); + throw t; }finally { ses.getWorkspace().getLockManager().unlock(sharedItemNode.getPath()); } diff --git a/src/main/java/org/gcube/data/access/storagehub/services/ACLManager.java b/src/main/java/org/gcube/data/access/storagehub/services/ACLManager.java index 15224cf..3436006 100644 --- a/src/main/java/org/gcube/data/access/storagehub/services/ACLManager.java +++ b/src/main/java/org/gcube/data/access/storagehub/services/ACLManager.java @@ -2,7 +2,6 @@ package org.gcube.data.access.storagehub.services; import java.security.Principal; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; import javax.enterprise.context.RequestScoped; @@ -22,7 +21,6 @@ import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; @@ -161,27 +159,7 @@ public class ACLManager { SharedFolder folder = ((SharedFolder)item); if (folder.isVreFolder()) { - if (accessType!=AccessType.ADMINISTRATOR) - throw new InvalidCallParameters("acls in vreFolder cannot be changed, only new admin can be set"); - - org.apache.jackrabbit.api.security.user.UserManager usrManager = ((JackrabbitSession)ses).getUserManager(); - - String groupId = folder.getTitle(); - - Group group = (Group)usrManager.getAuthorizable(groupId); - User authUser = (User)usrManager.getAuthorizable(user); - - if (!group.isMember(authUser)) - throw new InvalidCallParameters("user "+user+" is not in the group "+groupId); - - String path = node.getPath(); - AccessControlManager acm = ses.getAccessControlManager(); - JackrabbitAccessControlList acls = AccessControlUtils.getAccessControlList(acm, path); - Privilege[] userPrivileges = new Privilege[] { acm.privilegeFromName(AccessType.ADMINISTRATOR.getValue()) }; - Principal principal = AccessControlUtils.getPrincipal(ses, user); - acls.addAccessControlEntry(principal, userPrivileges); - acm.setPolicy(path, acls); - ses.save(); + throw new InvalidCallParameters("acls in vreFolder cannot be changed with this method"); } else { @@ -254,9 +232,13 @@ public class ACLManager { Item item = node2Item.getItem(node, Excludes.ALL); + if (!(item instanceof SharedFolder)) throw new InvalidItemException("the item is not a shared folder"); - + + if (item instanceof VreFolder) + throw new InvalidCallParameters("acls in vreFolder cannot be changed with this method"); + authChecker.checkAdministratorControl(ses, (SharedFolder) item); SharedFolder folder = ((SharedFolder)item); diff --git a/src/main/java/org/gcube/data/access/storagehub/services/GroupManager.java b/src/main/java/org/gcube/data/access/storagehub/services/GroupManager.java index 4abdae8..4f5b28e 100644 --- a/src/main/java/org/gcube/data/access/storagehub/services/GroupManager.java +++ b/src/main/java/org/gcube/data/access/storagehub/services/GroupManager.java @@ -1,5 +1,6 @@ package org.gcube.data.access.storagehub.services; +import java.security.Principal; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -8,6 +9,8 @@ import javax.inject.Inject; import javax.jcr.Node; import javax.jcr.NodeIterator; import javax.jcr.PathNotFoundException; +import javax.jcr.RepositoryException; +import javax.jcr.security.AccessControlEntry; import javax.jcr.security.AccessControlManager; import javax.jcr.security.Privilege; import javax.servlet.ServletContext; @@ -22,6 +25,7 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; import org.apache.jackrabbit.api.JackrabbitSession; import org.apache.jackrabbit.api.security.JackrabbitAccessControlList; @@ -35,17 +39,23 @@ import org.gcube.common.authorization.control.annotations.AuthorizationControl; import org.gcube.common.authorization.library.provider.AuthorizationProvider; import org.gcube.common.gxrest.response.outbound.GXOutboundErrorResponse; import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.common.storagehub.model.Excludes; import org.gcube.common.storagehub.model.acls.AccessType; import org.gcube.common.storagehub.model.exceptions.BackendGenericError; import org.gcube.common.storagehub.model.exceptions.InvalidCallParameters; import org.gcube.common.storagehub.model.exceptions.InvalidItemException; +import org.gcube.common.storagehub.model.exceptions.StorageHubException; import org.gcube.common.storagehub.model.exceptions.UserNotAuthorizedException; import org.gcube.common.storagehub.model.types.NodeProperty; import org.gcube.common.storagehub.model.types.PrimaryNodeType; +import org.gcube.data.access.storagehub.AuthorizationChecker; import org.gcube.data.access.storagehub.Constants; import org.gcube.data.access.storagehub.Utils; import org.gcube.data.access.storagehub.exception.MyAuthException; import org.gcube.data.access.storagehub.handlers.CredentialHandler; +import org.gcube.data.access.storagehub.handlers.Node2ItemConverter; +import org.gcube.data.access.storagehub.handlers.VRE; +import org.gcube.data.access.storagehub.handlers.VREManager; import org.gcube.smartgears.utils.InnerMethodName; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -57,19 +67,28 @@ public class GroupManager { private static final String VREMANAGER_ROLE = "VRE-Manager"; private static final String INFRASTRUCTURE_MANAGER_ROLE = "Infrastructure-Manager"; - + private static final Logger log = LoggerFactory.getLogger(GroupManager.class); @Inject RepositoryInitializer repository; + @Inject + VREManager vreManager; + + @Inject + Node2ItemConverter node2Item; + + @Inject + AuthorizationChecker authChecker; + @GET @Path("") @Produces(MediaType.APPLICATION_JSON) public List getGroups(){ - + InnerMethodName.instance.set("getGroups"); - + JackrabbitSession session = null; List groups= new ArrayList<>(); try { @@ -103,18 +122,18 @@ public class GroupManager { @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @AuthorizationControl(allowedRoles={INFRASTRUCTURE_MANAGER_ROLE}, exception=MyAuthException.class) public String createGroup(@FormParam("group") String group, @FormParam("accessType") AccessType accessType){ - + InnerMethodName.instance.set("createGroup"); - + JackrabbitSession session = null; String groupId = null; try { - + if (!isValidGroupForContext(groupId)) throw new UserNotAuthorizedException("only VREManager can execute this operation"); - + session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); - + org.apache.jackrabbit.api.security.user.UserManager usrManager = session.getUserManager(); Group createdGroup = usrManager.createGroup(group); @@ -138,15 +157,15 @@ public class GroupManager { @Path("{group}") @AuthorizationControl(allowedRoles={INFRASTRUCTURE_MANAGER_ROLE}, exception=MyAuthException.class) public String deleteGroup(@PathParam("group") String group){ - + InnerMethodName.instance.set("deleteGroup"); - + JackrabbitSession session = null; try { - + if (!isValidGroupForContext(group)) throw new UserNotAuthorizedException("only VREManager of the selected VRE can execute this operation"); - + session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); org.apache.jackrabbit.api.security.user.UserManager usrManager = session.getUserManager(); @@ -170,35 +189,166 @@ public class GroupManager { return group; } - - public boolean isAdmin() { return AuthorizationProvider.instance.get().getClient().getRoles().contains(INFRASTRUCTURE_MANAGER_ROLE); } - + public boolean isInfraManager() { return AuthorizationProvider.instance.get().getClient().getRoles().contains(INFRASTRUCTURE_MANAGER_ROLE); } + @PUT - @Path("{id}") + @Path("{id}/admins") + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @AuthorizationControl(allowedRoles={VREMANAGER_ROLE, INFRASTRUCTURE_MANAGER_ROLE}, exception=MyAuthException.class) + public void addAdmin(@PathParam("id") String groupId, @FormParam("userId") String userId){ + + InnerMethodName.instance.set("addAddmin"); + + JackrabbitSession session = null; + try { + + if (!isInfraManager() && !isValidGroupForContext(groupId) ) + throw new UserNotAuthorizedException("only VREManager of the selected VRE can execute this operation"); + + session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); + VRE vreFolder = Utils.getVreFolderItemByGroupNameAndUser(session, groupId, userId, node2Item, vreManager, Excludes.ALL); + + org.apache.jackrabbit.api.security.user.UserManager usrManager = ((JackrabbitSession)session).getUserManager(); + + + Group group = (Group)usrManager.getAuthorizable(groupId); + User authUser = (User)usrManager.getAuthorizable(userId); + + if (!group.isMember(authUser)) + throw new InvalidCallParameters("user "+userId+" is not in the group "+groupId); + + Node node = session.getNodeByIdentifier(vreFolder.getVreFolder().getId()); + AccessControlManager acm = session.getAccessControlManager(); + JackrabbitAccessControlList acls = AccessControlUtils.getAccessControlList(acm, node.getPath()); + Privilege[] userPrivileges = new Privilege[] { acm.privilegeFromName(AccessType.ADMINISTRATOR.getValue()) }; + Principal principal = AccessControlUtils.getPrincipal(session, userId); + acls.addAccessControlEntry(principal, userPrivileges); + acm.setPolicy(node.getPath(), acls); + + session.save(); + }catch(StorageHubException she ){ + log.error(she.getErrorMessage(), she); + GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus())); + }catch(RepositoryException re ){ + log.error("adding admin to VREFolder", re); + GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error adding admin to VREFolder", re)); + } finally { + if (session!=null) + session.logout(); + } + } + + @DELETE + @Path("{id}/admins/{userId}") + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @AuthorizationControl(allowedRoles={VREMANAGER_ROLE, INFRASTRUCTURE_MANAGER_ROLE}, exception=MyAuthException.class) + public void removeAdmin(@PathParam("id") String groupId, @PathParam("userId") String userId){ + + InnerMethodName.instance.set("removeAdmin"); + + JackrabbitSession session = null; + + try { + + if (!isValidGroupForContext(groupId) && !isInfraManager()) + throw new UserNotAuthorizedException("only VREManager of the selected VRE can execute this operation"); + + session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); + VRE vreFolder = Utils.getVreFolderItemByGroupNameAndUser(session, groupId, userId, node2Item, vreManager, Excludes.ALL); + + Node node = session.getNodeByIdentifier(vreFolder.getVreFolder().getId()); + AccessControlManager acm = session.getAccessControlManager(); + JackrabbitAccessControlList acls = AccessControlUtils.getAccessControlList(acm, node.getPath()); + + AccessControlEntry toRemove = null; + for (AccessControlEntry acl: acls.getAccessControlEntries()) + if (acl.getPrincipal().getName().equals(userId)) { + toRemove = acl; + break; + } + + acls.removeAccessControlEntry(toRemove); + acm.setPolicy(node.getPath(), acls); + session.save(); + }catch(StorageHubException she ){ + log.error(she.getErrorMessage(), she); + GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus())); + }catch(RepositoryException re ){ + log.error("removing admin to VREFolder", re); + GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error removing admin to VREFolder", re)); + } finally { + if (session!=null) + session.logout(); + } + } + + @GET + @Path("{groupId}/admins") + @Produces(MediaType.APPLICATION_JSON) + public List getAdmins(@PathParam("groupId") String groupId){ + + InnerMethodName.instance.set("getAdmins"); + + JackrabbitSession session = null; + List users = new ArrayList<>(); + try { + + session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); + + session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); + VRE vreFolder = Utils.getVreFolderItemByGroupNameAndUser(session, groupId, AuthorizationProvider.instance.get().getClient().getId(), node2Item, vreManager, Excludes.ALL); + AccessControlManager acm = session.getAccessControlManager(); + //authChecker.checkAdministratorControl(session, (VreFolder)vreFolder.getVreFolder()); + Node node = session.getNodeByIdentifier(vreFolder.getVreFolder().getId()); + + JackrabbitAccessControlList acls = AccessControlUtils.getAccessControlList(acm, node.getPath()); + + for (AccessControlEntry acl: acls.getAccessControlEntries()) + for (Privilege pr: acl.getPrivileges()) { + if (pr.getName().equals(AccessType.ADMINISTRATOR.getValue())){ + users.add(acl.getPrincipal().getName()); + } + + } + + }catch(Exception e) { + log.error("jcr error getting admins of group {}", groupId, e); + GXOutboundErrorResponse.throwException(new BackendGenericError(e)); + } finally { + if (session!=null) + session.logout(); + } + + return users; + } + + + @PUT + @Path("{id}/users") @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @AuthorizationControl(allowedRoles={VREMANAGER_ROLE, INFRASTRUCTURE_MANAGER_ROLE}, exception=MyAuthException.class) public boolean addUserToGroup(@PathParam("id") String groupId, @FormParam("userId") String userId){ - + InnerMethodName.instance.set("addUserToGroup"); - + JackrabbitSession session = null; boolean success = false; try { - - if (!isValidGroupForContext(groupId) && !isAdmin()) + + if (!isValidGroupForContext(groupId) && !isInfraManager()) throw new UserNotAuthorizedException("only VREManager of the selected VRE can execute this operation"); - + session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); org.apache.jackrabbit.api.security.user.UserManager usrManager = session.getUserManager(); Group group = (Group)usrManager.getAuthorizable(groupId); User user = (User)usrManager.getAuthorizable(userId); - + if (group.isMember(user)) throw new InvalidCallParameters("user "+userId+" is already member of group "+groupId); - + success = group.addMember(user); String folderName = group.getPrincipal().getName(); @@ -224,26 +374,26 @@ public class GroupManager { @Path("{groupId}/users/{userId}") @AuthorizationControl(allowedRoles={VREMANAGER_ROLE, INFRASTRUCTURE_MANAGER_ROLE}, exception=MyAuthException.class) public boolean removeUserFromGroup(@PathParam("groupId") String groupId, @PathParam("userId") String userId){ - + InnerMethodName.instance.set("removeUserFromGroup"); - + JackrabbitSession session = null; boolean success = false; try { - - if (!isValidGroupForContext(groupId) && !isAdmin()) + + if (!isValidGroupForContext(groupId) && !isInfraManager()) throw new UserNotAuthorizedException("only VREManager of the selected VRE can execute this operation"); - + session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); org.apache.jackrabbit.api.security.user.UserManager usrManager = session.getUserManager(); Group group = (Group)usrManager.getAuthorizable(groupId); User user = (User)usrManager.getAuthorizable(userId); - + if (!group.isMember(user)) throw new InvalidCallParameters("user "+userId+" is not member of group "+groupId); - + //delete folder on user String folderName = group.getPrincipal().getName(); Node folder = getVreFolderNode(session, folderName); @@ -276,16 +426,16 @@ public class GroupManager { @Produces(MediaType.APPLICATION_JSON) @AuthorizationControl(allowedRoles={VREMANAGER_ROLE}, exception=MyAuthException.class) public List getUsersOfGroup(@PathParam("groupId") String groupId){ - + InnerMethodName.instance.set("getUsersOfGroup"); - + JackrabbitSession session = null; List users = new ArrayList<>(); try { - + if (!isValidGroupForContext(groupId)) throw new UserNotAuthorizedException("only VREManager of the selected VRE can execute this operation"); - + session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); org.apache.jackrabbit.api.security.user.UserManager usrManager = session.getUserManager(); @@ -336,17 +486,17 @@ public class GroupManager { acm.setPolicy(folder.getPath(), acls); } - + private Node getVreFolderNode(JackrabbitSession session, String name) throws InvalidItemException, Exception { Node sharedRootNode = session.getNode(Constants.SHARED_FOLDER_PATH); - + Node vreFolder = null; try { vreFolder = sharedRootNode.getNode(name); }catch (PathNotFoundException e) { log.debug("is an old HL VRE"); } - + NodeIterator nodes = sharedRootNode.getNodes(); while (nodes.hasNext()) { Node node = nodes.nextNode(); @@ -365,5 +515,5 @@ public class GroupManager { String expectedGroupId= currentContext.replace("/", "-").substring(1); return group.equals(expectedGroupId); } - + } diff --git a/src/main/java/org/gcube/data/access/storagehub/services/ItemsCreator.java b/src/main/java/org/gcube/data/access/storagehub/services/ItemsCreator.java index e669bdd..4e00d42 100644 --- a/src/main/java/org/gcube/data/access/storagehub/services/ItemsCreator.java +++ b/src/main/java/org/gcube/data/access/storagehub/services/ItemsCreator.java @@ -192,6 +192,7 @@ public class ItemsCreator { ses.getWorkspace().getLockManager().unlock(destination.getPath()); } + log.info("item with id {} correctly created",newNode.getIdentifier()); toReturn = newNode.getIdentifier(); }catch(StorageHubException she ){ @@ -354,12 +355,13 @@ public class ItemsCreator { } try { newNode = item2Node.getNode(destinationNode, item); + accountingHandler.createEntryCreate(item.getTitle(), ses, newNode, false); ses.save(); }finally { if (withLock) ses.getWorkspace().getLockManager().unlock(destinationNode.getPath()); } versionHandler.makeVersionableContent(newNode, ses); - accountingHandler.createFolderAddObj(name, item.getClass().getSimpleName(), item.getContent().getMimeType(), ses, newNode, false); + accountingHandler.createFolderAddObj(name, item.getClass().getSimpleName(), item.getContent().getMimeType(), ses, destinationNode, false); } return newNode; diff --git a/src/main/java/org/gcube/data/access/storagehub/services/WorkspaceManager.java b/src/main/java/org/gcube/data/access/storagehub/services/WorkspaceManager.java index 6168e7e..2f9fa10 100644 --- a/src/main/java/org/gcube/data/access/storagehub/services/WorkspaceManager.java +++ b/src/main/java/org/gcube/data/access/storagehub/services/WorkspaceManager.java @@ -136,7 +136,7 @@ public class WorkspaceManager { return new ItemWrapper(toReturn); } - private synchronized VRE getVreFolderItem(Session ses) throws RepositoryException, BackendGenericError{ + /*private synchronized VRE getVreFolderItem(Session ses) throws RepositoryException, BackendGenericError{ org.gcube.common.storagehub.model.Path vrePath = Paths.append(Utils.getWorkspacePath(), Constants.VRE_FOLDER_PARENT_NAME); ScopeBean bean = new ScopeBean(ScopeProvider.instance.get()); if (!bean.is(Type.VRE)) throw new BackendGenericError("the current scope is not a VRE"); @@ -155,7 +155,7 @@ public class WorkspaceManager { return vreManager.putVRE(vreFolder); } - } + }*/ @Path("vrefolder") @@ -167,7 +167,7 @@ public class WorkspaceManager { Item vreItem = null; try { ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); - vreItem = getVreFolderItem(ses).getVreFolder(); + vreItem = Utils.getVreFolderItem(ses, node2Item, vreManager, excludes).getVreFolder(); }catch(RepositoryException re ){ log.error("jcr error getting vrefolder", re); GXOutboundErrorResponse.throwException(new BackendGenericError(re)); @@ -192,7 +192,7 @@ public class WorkspaceManager { String login = AuthorizationProvider.instance.get().getClient().getId(); ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); - VRE vre = getVreFolderItem(ses); + VRE vre = Utils.getVreFolderItem(ses, node2Item, vreManager, excludes); log.trace("VRE retrieved {}",vre.getVreFolder().getTitle()); recentItems = vre.getRecents(); log.trace("recents retrieved {}",vre.getVreFolder().getTitle()); From c1ab8333b8a0061f44a26d01722cc41552a9d8e3 Mon Sep 17 00:00:00 2001 From: lucio Date: Thu, 16 Jan 2020 18:11:23 +0100 Subject: [PATCH 07/10] solved error on group creation --- .../storagehub/services/GroupManager.java | 43 +++++++++---------- .../storagehub/services/UserManager.java | 11 +++-- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/main/java/org/gcube/data/access/storagehub/services/GroupManager.java b/src/main/java/org/gcube/data/access/storagehub/services/GroupManager.java index 4f5b28e..c73995a 100644 --- a/src/main/java/org/gcube/data/access/storagehub/services/GroupManager.java +++ b/src/main/java/org/gcube/data/access/storagehub/services/GroupManager.java @@ -57,6 +57,7 @@ import org.gcube.data.access.storagehub.handlers.Node2ItemConverter; import org.gcube.data.access.storagehub.handlers.VRE; import org.gcube.data.access.storagehub.handlers.VREManager; import org.gcube.smartgears.utils.InnerMethodName; +import org.glassfish.jersey.media.multipart.FormDataParam; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -119,9 +120,9 @@ public class GroupManager { @POST @Path("") - @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @Consumes(MediaType.MULTIPART_FORM_DATA) @AuthorizationControl(allowedRoles={INFRASTRUCTURE_MANAGER_ROLE}, exception=MyAuthException.class) - public String createGroup(@FormParam("group") String group, @FormParam("accessType") AccessType accessType){ + public String createGroup(@FormDataParam("group") String group, @FormDataParam("accessType") AccessType accessType, @FormDataParam("folderOwner") String folderOwner){ InnerMethodName.instance.set("createGroup"); @@ -129,9 +130,6 @@ public class GroupManager { String groupId = null; try { - if (!isValidGroupForContext(groupId)) - throw new UserNotAuthorizedException("only VREManager can execute this operation"); - session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); org.apache.jackrabbit.api.security.user.UserManager usrManager = session.getUserManager(); @@ -139,7 +137,7 @@ public class GroupManager { Group createdGroup = usrManager.createGroup(group); groupId = createdGroup.getID(); - createVreFolder(groupId, session, accessType!=null?accessType:AccessType.WRITE_OWNER); + createVreFolder(groupId, session, accessType!=null?accessType:AccessType.WRITE_OWNER, folderOwner); session.save(); }catch(Exception e) { @@ -162,10 +160,7 @@ public class GroupManager { JackrabbitSession session = null; try { - - if (!isValidGroupForContext(group)) - throw new UserNotAuthorizedException("only VREManager of the selected VRE can execute this operation"); - + session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); org.apache.jackrabbit.api.security.user.UserManager usrManager = session.getUserManager(); @@ -207,7 +202,7 @@ public class GroupManager { throw new UserNotAuthorizedException("only VREManager of the selected VRE can execute this operation"); session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); - VRE vreFolder = Utils.getVreFolderItemByGroupNameAndUser(session, groupId, userId, node2Item, vreManager, Excludes.ALL); + org.apache.jackrabbit.api.security.user.UserManager usrManager = ((JackrabbitSession)session).getUserManager(); @@ -218,13 +213,13 @@ public class GroupManager { if (!group.isMember(authUser)) throw new InvalidCallParameters("user "+userId+" is not in the group "+groupId); - Node node = session.getNodeByIdentifier(vreFolder.getVreFolder().getId()); + Node vreFolder = getVreFolderNode(session, groupId); AccessControlManager acm = session.getAccessControlManager(); - JackrabbitAccessControlList acls = AccessControlUtils.getAccessControlList(acm, node.getPath()); + JackrabbitAccessControlList acls = AccessControlUtils.getAccessControlList(acm, vreFolder.getPath()); Privilege[] userPrivileges = new Privilege[] { acm.privilegeFromName(AccessType.ADMINISTRATOR.getValue()) }; Principal principal = AccessControlUtils.getPrincipal(session, userId); acls.addAccessControlEntry(principal, userPrivileges); - acm.setPolicy(node.getPath(), acls); + acm.setPolicy(vreFolder.getPath(), acls); session.save(); }catch(StorageHubException she ){ @@ -255,11 +250,11 @@ public class GroupManager { throw new UserNotAuthorizedException("only VREManager of the selected VRE can execute this operation"); session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); - VRE vreFolder = Utils.getVreFolderItemByGroupNameAndUser(session, groupId, userId, node2Item, vreManager, Excludes.ALL); - Node node = session.getNodeByIdentifier(vreFolder.getVreFolder().getId()); + + Node vreFolder = getVreFolderNode(session, groupId); AccessControlManager acm = session.getAccessControlManager(); - JackrabbitAccessControlList acls = AccessControlUtils.getAccessControlList(acm, node.getPath()); + JackrabbitAccessControlList acls = AccessControlUtils.getAccessControlList(acm, vreFolder.getPath()); AccessControlEntry toRemove = null; for (AccessControlEntry acl: acls.getAccessControlEntries()) @@ -269,7 +264,7 @@ public class GroupManager { } acls.removeAccessControlEntry(toRemove); - acm.setPolicy(node.getPath(), acls); + acm.setPolicy(vreFolder.getPath(), acls); session.save(); }catch(StorageHubException she ){ log.error(she.getErrorMessage(), she); @@ -461,7 +456,7 @@ public class GroupManager { return users; } - private void createVreFolder(String groupId, JackrabbitSession session, AccessType defaultAccessType) throws Exception{ + private void createVreFolder(String groupId, JackrabbitSession session, AccessType defaultAccessType, String owner ) throws Exception{ Node sharedRootNode = session.getNode(Constants.SHARED_FOLDER_PATH); @@ -469,7 +464,7 @@ public class GroupManager { String title = groupId.substring(groupId.lastIndexOf("-")+1); - Node folder= Utils.createFolderInternally(session, sharedRootNode, name, "VREFolder for "+groupId, false, AuthorizationProvider.instance.get().getClient().getId(), null); + Node folder= Utils.createFolderInternally(session, sharedRootNode, name, "VREFolder for "+groupId, false, owner, null); folder.setPrimaryType(PrimaryNodeType.NT_WORKSPACE_SHARED_FOLDER); folder.setProperty(NodeProperty.IS_VRE_FOLDER.toString(), true); folder.setProperty(NodeProperty.TITLE.toString(), name); @@ -478,8 +473,12 @@ public class GroupManager { AccessControlManager acm = session.getAccessControlManager(); JackrabbitAccessControlList acls = AccessControlUtils.getAccessControlList(acm, folder.getPath()); - Privilege[] adminPrivileges = new Privilege[] { acm.privilegeFromName(AccessType.ADMINISTRATOR.getValue()) }; + + + /*Privilege[] adminPrivileges = new Privilege[] { acm.privilegeFromName(AccessType.ADMINISTRATOR.getValue()) }; acls.addAccessControlEntry(AccessControlUtils.getPrincipal(session, AuthorizationProvider.instance.get().getClient().getId()), adminPrivileges ); + */ + Privilege[] usersPrivileges = new Privilege[] { acm.privilegeFromName(defaultAccessType.getValue()) }; acls.addAccessControlEntry(AccessControlUtils.getPrincipal(session,groupId), usersPrivileges ); @@ -487,7 +486,7 @@ public class GroupManager { } - private Node getVreFolderNode(JackrabbitSession session, String name) throws InvalidItemException, Exception { + private Node getVreFolderNode(JackrabbitSession session, String name) throws InvalidItemException, RepositoryException { Node sharedRootNode = session.getNode(Constants.SHARED_FOLDER_PATH); Node vreFolder = null; diff --git a/src/main/java/org/gcube/data/access/storagehub/services/UserManager.java b/src/main/java/org/gcube/data/access/storagehub/services/UserManager.java index fcee912..3756b22 100644 --- a/src/main/java/org/gcube/data/access/storagehub/services/UserManager.java +++ b/src/main/java/org/gcube/data/access/storagehub/services/UserManager.java @@ -38,6 +38,7 @@ import org.gcube.data.access.storagehub.Utils; import org.gcube.data.access.storagehub.exception.MyAuthException; import org.gcube.data.access.storagehub.handlers.CredentialHandler; import org.gcube.data.access.storagehub.handlers.UnshareHandler; +import org.gcube.smartgears.utils.InnerMethodName; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -60,7 +61,9 @@ public class UserManager { @Path("") @Produces(MediaType.APPLICATION_JSON) public List getUsers(){ - + + InnerMethodName.instance.set("getUsers"); + JackrabbitSession session = null; List users= new ArrayList<>(); try { @@ -94,7 +97,9 @@ public class UserManager { @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @AuthorizationControl(allowedRoles={INFRASTRUCTURE_MANAGER_ROLE}, exception=MyAuthException.class) public String createUser(@FormParam("user") String user, @FormParam("password") String password){ - + + InnerMethodName.instance.set("createUser"); + JackrabbitSession session = null; String userId = null; try { @@ -133,8 +138,8 @@ public class UserManager { @Path("{user}") @AuthorizationControl(allowedRoles={INFRASTRUCTURE_MANAGER_ROLE}, exception=MyAuthException.class) public String deleteUser(@PathParam("user") String user){ - + InnerMethodName.instance.set("deleteUser"); JackrabbitSession session = null; String userId = null; From 188d11ff709f0a744bbcedf49e030925b633aee6 Mon Sep 17 00:00:00 2001 From: lucio Date: Wed, 22 Jan 2020 12:32:49 +0100 Subject: [PATCH 08/10] Application Listener add to correctly shutdown the jackrabbit repository --- .settings/org.eclipse.wst.common.component | 2 +- .../data/access/storagehub/StorageHub.java | 1 + .../gcube/data/access/storagehub/Utils.java | 40 +++++++---- .../handlers/Item2NodeConverter.java | 6 +- .../handlers/Node2ItemConverter.java | 4 +- .../handlers/VREQueryRetriever.java | 67 ++++++++++++++----- .../storagehub/services/GroupManager.java | 60 ++++++++++------- .../storagehub/services/ItemsManager.java | 28 ++++++++ .../storagehub/services/UserManager.java | 31 +++++++-- 9 files changed, 174 insertions(+), 65 deletions(-) diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component index 1314f66..666f8ff 100644 --- a/.settings/org.eclipse.wst.common.component +++ b/.settings/org.eclipse.wst.common.component @@ -7,7 +7,7 @@ uses - + uses diff --git a/src/main/java/org/gcube/data/access/storagehub/StorageHub.java b/src/main/java/org/gcube/data/access/storagehub/StorageHub.java index da500a3..53ba0be 100644 --- a/src/main/java/org/gcube/data/access/storagehub/StorageHub.java +++ b/src/main/java/org/gcube/data/access/storagehub/StorageHub.java @@ -32,6 +32,7 @@ public class StorageHub extends Application { classes.add(UserManager.class); classes.add(GroupManager.class); classes.add(SerializableErrorEntityTextWriter.class); + classes.add(MyApplicationListener.class); return classes; } diff --git a/src/main/java/org/gcube/data/access/storagehub/Utils.java b/src/main/java/org/gcube/data/access/storagehub/Utils.java index b4d3b28..ed7448a 100644 --- a/src/main/java/org/gcube/data/access/storagehub/Utils.java +++ b/src/main/java/org/gcube/data/access/storagehub/Utils.java @@ -26,6 +26,7 @@ import javax.jcr.query.Query; import javax.jcr.version.Version; import org.apache.commons.io.FilenameUtils; +import org.apache.jackrabbit.util.ISO9075; import org.apache.jackrabbit.util.Text; import org.gcube.common.authorization.library.provider.AuthorizationProvider; import org.gcube.common.scope.api.ScopeProvider; @@ -109,15 +110,30 @@ public class Utils { } + public static List serachByNameOnFolder(Session ses, Node parent, List excludes, Range range, boolean showHidden, Class nodeTypeToInclude, String nameParam) throws RepositoryException, BackendGenericError{ + String xpath = String.format("/jcr:root%s//element(*,nthl:workspaceItem)[jcr:like(@jcr:title, '%s')]",ISO9075.encodePath(parent.getPath()), nameParam); + + //String query = String.format("SELECT * FROM [nthl:workspaceLeafItem] AS node WHERE ISDESCENDANTNODE('%s') ORDER BY node.[jcr:lastModified] DESC ",vreFolder.getPath()); + logger.trace("query for search is {}",xpath); + + Query jcrQuery = ses.getWorkspace().getQueryManager().createQuery(xpath, Query.XPATH); + + NodeIterator it = jcrQuery.execute().getNodes(); + return getItemListFromNodeIterator(it, excludes, range, showHidden, nodeTypeToInclude); + } + public static List getItemList(Node parent, List excludes, Range range, boolean showHidden, Class nodeTypeToInclude) throws RepositoryException, BackendGenericError{ - - logger.debug("getting children of node {}", parent.getIdentifier()); - - List returnList = new ArrayList(); + logger.trace("getting children of node {}", parent.getIdentifier()); long start = System.currentTimeMillis(); NodeIterator iterator = parent.getNodes(); logger.trace("time to get iterator {}",(System.currentTimeMillis()-start)); + return getItemListFromNodeIterator(iterator, excludes, range, showHidden, nodeTypeToInclude); + } + + private static List getItemListFromNodeIterator(NodeIterator iterator, List excludes, Range range, boolean showHidden, Class nodeTypeToInclude) throws RepositoryException, BackendGenericError{ + List returnList = new ArrayList(); + logger.trace("nodeType is {}",nodeTypeToInclude); int count =0; logger.trace("selected range is {}", range); @@ -125,12 +141,12 @@ public class Utils { while (iterator.hasNext()){ Node current = iterator.nextNode(); - logger.debug("current node "+current.getName()); + logger.trace("current node "+current.getName()); if (isToExclude(current, showHidden)) continue; - logger.debug("current node not excluded "+current.getName()); + logger.trace("current node not excluded "+current.getName()); if (range==null || (count>=range.getStart() && returnList.size() tempQueue = new LinkedList(); - logger.debug("adding directory {}",currentNode.getPath()); + logger.trace("adding directory {}",currentNode.getPath()); for (Item item : Utils.getItemList(currentNode,Excludes.GET_ONLY_CONTENT, null, false, null)){ if (excludes.contains(item.getId())) continue; if (item instanceof FolderItem) tempQueue.addAll(getAllNodesForZip((FolderItem) item, session, accountingHandler, excludes)); else if (item instanceof AbstractFileItem){ - logger.debug("adding file {}",item.getPath()); + logger.trace("adding file {}",item.getPath()); AbstractFileItem fileItem = (AbstractFileItem) item; accountingHandler.createReadObj(fileItem.getTitle(), session, session.getNodeByIdentifier(item.getId()), false); queue.addLast(item); @@ -190,9 +206,9 @@ public class Utils { Item item = queue.pop(); if (item instanceof FolderItem) { actualPath = Paths.getPath(item.getPath()); - logger.debug("actualPath is {}",actualPath.toPath()); + logger.trace("actualPath is {}",actualPath.toPath()); String name = Paths.remove(actualPath, originalPath).toPath().replaceFirst("/", ""); - logger.debug("writing dir {}",name); + logger.trace("writing dir {}",name); if (name.isEmpty()) continue; try { zos.putNextEntry(new ZipEntry(name)); @@ -208,7 +224,7 @@ public class Utils { } try(BufferedInputStream is = new BufferedInputStream(streamToWrite)){ String name = (Paths.remove(actualPath, originalPath).toPath()+item.getName()).replaceFirst("/", ""); - logger.debug("writing file {}",name); + logger.trace("writing file {}",name); zos.putNextEntry(new ZipEntry(name)); copyStream(is, zos); }catch (Exception e) { @@ -285,7 +301,7 @@ public class Utils { String nameTocheck = ext.isEmpty()? String.format("%s(*)",filename): String.format("%s(*).%s",filename, ext); - logger.debug("filename is {}, extension is {} , and name to check is {}", filename, ext, nameTocheck); + logger.trace("filename is {}, extension is {} , and name to check is {}", filename, ext, nameTocheck); NodeIterator ni = destination.getNodes(nameTocheck); int maxval = 0; diff --git a/src/main/java/org/gcube/data/access/storagehub/handlers/Item2NodeConverter.java b/src/main/java/org/gcube/data/access/storagehub/handlers/Item2NodeConverter.java index 1b72bd0..68e4e09 100644 --- a/src/main/java/org/gcube/data/access/storagehub/handlers/Item2NodeConverter.java +++ b/src/main/java/org/gcube/data/access/storagehub/handlers/Item2NodeConverter.java @@ -56,7 +56,7 @@ public class Item2NodeConverter { field.setAccessible(true); try{ //Class returnType = field.getType(); - logger.debug("creating node - added field {}",field.getName()); + logger.trace("creating node - added field {}",field.getName()); Values values = getObjectValue(field.getType(), field.get(item)); if (values.isMulti()) newNode.setProperty(attribute.value(), values.getValues()); else newNode.setProperty(attribute.value(), values.getValue()); @@ -67,7 +67,7 @@ public class Item2NodeConverter { NodeAttribute nodeAttribute = field.getAnnotation(NodeAttribute.class); if (nodeAttribute.isReadOnly()) continue; String nodeName = nodeAttribute.value(); - logger.debug("retrieving field node "+field.getName()); + logger.trace("retrieving field node "+field.getName()); field.setAccessible(true); try{ Object obj = field.get(item); @@ -129,7 +129,7 @@ public class Item2NodeConverter { } } else if (field.isAnnotationPresent(ListNodes.class)){ - logger.debug("found field {} of type annotated as ListNodes in class {} on node {}", field.getName(), object.getClass().getName(), newNode.getName()); + logger.trace("found field {} of type annotated as ListNodes in class {} on node {}", field.getName(), object.getClass().getName(), newNode.getName()); field.setAccessible(true); List toSetList = (List) field.get(object); diff --git a/src/main/java/org/gcube/data/access/storagehub/handlers/Node2ItemConverter.java b/src/main/java/org/gcube/data/access/storagehub/handlers/Node2ItemConverter.java index f139d93..bddef6b 100644 --- a/src/main/java/org/gcube/data/access/storagehub/handlers/Node2ItemConverter.java +++ b/src/main/java/org/gcube/data/access/storagehub/handlers/Node2ItemConverter.java @@ -127,7 +127,7 @@ public class Node2ItemConverter { try{ Class returnType = field.getType(); field.set(item, getPropertyValue(returnType, node.getProperty(attribute.value()))); - logger.debug("retrieve item - added field {}",field.getName()); + logger.trace("retrieve item - added field {}",field.getName()); }catch(PathNotFoundException e){ logger.trace("the current node dosn't contain {} property",attribute.value()); } catch (Exception e ) { @@ -320,7 +320,7 @@ public class Node2ItemConverter { public boolean checkNodeType(Node node, Class classToCompare) throws BackendGenericError{ try { - logger.info("class from nodetype is {} and class to compare is {}",ClassHandler.instance().get(node.getPrimaryNodeType().getName()), classToCompare); + logger.trace("class from nodetype is {} and class to compare is {}",ClassHandler.instance().get(node.getPrimaryNodeType().getName()), classToCompare); return classToCompare.isAssignableFrom(ClassHandler.instance().get(node.getPrimaryNodeType().getName())); diff --git a/src/main/java/org/gcube/data/access/storagehub/handlers/VREQueryRetriever.java b/src/main/java/org/gcube/data/access/storagehub/handlers/VREQueryRetriever.java index 955f486..fa4b726 100644 --- a/src/main/java/org/gcube/data/access/storagehub/handlers/VREQueryRetriever.java +++ b/src/main/java/org/gcube/data/access/storagehub/handlers/VREQueryRetriever.java @@ -1,9 +1,13 @@ package org.gcube.data.access.storagehub.handlers; +import java.text.SimpleDateFormat; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Arrays; +import java.util.Calendar; import java.util.Iterator; import java.util.List; +import java.util.Locale; import java.util.concurrent.Callable; import javax.jcr.Credentials; @@ -17,10 +21,11 @@ import javax.jcr.observation.Event; import javax.jcr.observation.EventJournal; import javax.jcr.query.Query; +import org.apache.jackrabbit.util.ISO9075; import org.gcube.common.storagehub.model.Excludes; import org.gcube.common.storagehub.model.NodeConstants; import org.gcube.common.storagehub.model.items.Item; -import org.gcube.data.access.storagehub.Constants; +import org.gcube.common.storagehub.model.types.NodeProperty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,7 +34,7 @@ public class VREQueryRetriever implements Callable> { private static final Logger logger = LoggerFactory.getLogger(VREQueryRetriever.class); private static final int CACHE_DIMENSION = 50; - + private Repository repository; private Credentials credentials; private Item vreFolder; @@ -37,7 +42,7 @@ public class VREQueryRetriever implements Callable> { long lastTimestamp =0; private Node2ItemConverter node2Item = new Node2ItemConverter(); - + public VREQueryRetriever(Repository repository, Credentials credentials, Item vreFolder) { super(); @@ -53,20 +58,50 @@ public class VREQueryRetriever implements Callable> { try { long start = System.currentTimeMillis(); ses = repository.login(credentials); - String query = String.format("SELECT * FROM [nthl:workspaceLeafItem] AS node WHERE ISDESCENDANTNODE('%s') ORDER BY node.[jcr:lastModified] DESC ",vreFolder.getPath()); - logger.trace("query for recents is {}",query); - Query jcrQuery = ses.getWorkspace().getQueryManager().createQuery(query, Constants.QUERY_LANGUAGE); + + Calendar now = Calendar.getInstance(); + now.add(Calendar.YEAR, -1); + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.ENGLISH); + String formattedDate = formatter.format(now.getTime()); + + + String xpath = String.format("/jcr:root%s//element(*,nthl:workspaceLeafItem)[@jcr:lastModified>xs:dateTime('%s')] order by @jcr:lastModified descending",ISO9075.encodePath(vreFolder.getPath()),formattedDate); + + //String query = String.format("SELECT * FROM [nthl:workspaceLeafItem] AS node WHERE ISDESCENDANTNODE('%s') ORDER BY node.[jcr:lastModified] DESC ",vreFolder.getPath()); + logger.debug("query for recents is {}",xpath); + + Query jcrQuery = ses.getWorkspace().getQueryManager().createQuery(xpath, Query.XPATH); + jcrQuery.setLimit(CACHE_DIMENSION); lastTimestamp = System.currentTimeMillis(); NodeIterator it = jcrQuery.execute().getNodes(); - logger.trace("query for recents took {}",System.currentTimeMillis()-start); + logger.debug("query for recents took {}",System.currentTimeMillis()-start); while (it.hasNext()) { Node node = it.nextNode(); - Item item =node2Item.getItem(node, Excludes.EXCLUDE_ACCOUNTING); + + //long lastModifiedTimeItem = node.getProperty(NodeProperty.LAST_MODIFIED.toString()).getLong(); + + //logger.debug("RECENTS - node {} has timestamp {} ", node.getProperty(NodeProperty.TITLE.toString()).getString(), lastModifiedTimeItem); + /* + if(cachedList.size()<=CACHE_DIMENSION || lastModifiedTimeItem>cachedList.get(CACHE_DIMENSION-1).getLastModificationTime().getTimeInMillis()) { + logger.debug("cachedList contains {}",cachedList.size()); + if(cachedList.size()>=CACHE_DIMENSION) cachedList.remove(CACHE_DIMENSION-1); + Item item =node2Item.getItem(node, Excludes.EXCLUDE_ACCOUNTING); + int insertposition =0; + for(Item cachedItem: cachedList) { + if (cachedItem.getLastModificationTime().before(item.getLastModificationTime())) + break; + insertposition++; + } + cachedList.add(insertposition, item); + logger.debug("RECENTS - adding item {} with node {} in position {}",item.getTitle(), node.getName(), insertposition); + }*/ + Item item = node2Item.getItem(node, Excludes.EXCLUDE_ACCOUNTING); + logger.debug("RECENTS - adding item {} with timestamp {}",item.getTitle(), item.getLastModificationTime().getTimeInMillis()); cachedList.add(item); - logger.trace("adding item {} with node {}",item.getTitle(), node.getName()); + } - logger.trace("creating objects took {}",System.currentTimeMillis()-start); + logger.debug("creating objects took {}",System.currentTimeMillis()-start); if (cachedList.size()<=10) return cachedList; else return cachedList.subList(0, 10); } catch (Exception e) { @@ -79,7 +114,7 @@ public class VREQueryRetriever implements Callable> { } } else { try { - + long timestampToUse = lastTimestamp; lastTimestamp = System.currentTimeMillis(); @@ -89,16 +124,16 @@ public class VREQueryRetriever implements Callable> { EventJournal journalChanged = ses.getWorkspace().getObservationManager().getEventJournal(Event.PROPERTY_CHANGED^Event.NODE_REMOVED^Event.NODE_MOVED^Event.NODE_ADDED, vreFolder.getPath(), true, null, types); journalChanged.skipTo(timestampToUse); - + logger.trace("getting the journal took {}",System.currentTimeMillis()-start); - + int events = 0; - + while (journalChanged.hasNext()) { events++; Event event = journalChanged.nextEvent(); switch(event.getType()) { - + case Event.NODE_ADDED: if (ses.nodeExists(event.getPath())) { Node nodeAdded = ses.getNode(event.getPath()); @@ -109,7 +144,7 @@ public class VREQueryRetriever implements Callable> { } } break; - + case Event.PROPERTY_CHANGED: if (ses.propertyExists(event.getPath())) { Property property = ses.getProperty(event.getPath()); diff --git a/src/main/java/org/gcube/data/access/storagehub/services/GroupManager.java b/src/main/java/org/gcube/data/access/storagehub/services/GroupManager.java index c73995a..25e4279 100644 --- a/src/main/java/org/gcube/data/access/storagehub/services/GroupManager.java +++ b/src/main/java/org/gcube/data/access/storagehub/services/GroupManager.java @@ -108,9 +108,9 @@ public class GroupManager { log.info("group {} found",group.getPrincipal().getName()); groups.add(group.getPrincipal().getName()); } - }catch(Exception e) { - log.error("jcr error getting groups", e); - GXOutboundErrorResponse.throwException(new BackendGenericError(e)); + }catch(RepositoryException re ){ + log.error("jcr error creating item", re); + GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error creating item", re)); } finally { if (session!=null) session.logout(); @@ -174,9 +174,9 @@ public class GroupManager { if (authorizable.isGroup()) authorizable.remove(); session.save(); - }catch(Exception e) { - log.error("jcr error getting users", e); - GXOutboundErrorResponse.throwException(new BackendGenericError(e)); + }catch(RepositoryException re ){ + log.error("jcr error creating item", re); + GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error creating item", re)); } finally { if (session!=null) session.logout(); @@ -270,9 +270,9 @@ public class GroupManager { log.error(she.getErrorMessage(), she); GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus())); }catch(RepositoryException re ){ - log.error("removing admin to VREFolder", re); - GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error removing admin to VREFolder", re)); - } finally { + log.error("jcr error creating item", re); + GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error creating item", re)); + }finally { if (session!=null) session.logout(); } @@ -307,10 +307,13 @@ public class GroupManager { } - }catch(Exception e) { - log.error("jcr error getting admins of group {}", groupId, e); - GXOutboundErrorResponse.throwException(new BackendGenericError(e)); - } finally { + }catch(StorageHubException she ){ + log.error(she.getErrorMessage(), she); + GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus())); + }catch(RepositoryException re ){ + log.error("jcr error creating item", re); + GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error creating item", re)); + }finally { if (session!=null) session.logout(); } @@ -354,10 +357,13 @@ public class GroupManager { session.getWorkspace().clone(session.getWorkspace().getName(), folder.getPath(),userPath , false); session.save(); - }catch(Exception e) { - log.error("jcr error adding user {} to group {}", userId, groupId, e); - GXOutboundErrorResponse.throwException(new BackendGenericError(e)); - } finally { + }catch(StorageHubException she ){ + log.error(she.getErrorMessage(), she); + GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus())); + }catch(RepositoryException re ){ + log.error("jcr error creating item", re); + GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error creating item", re)); + }finally { if (session!=null) session.logout(); } @@ -405,9 +411,12 @@ public class GroupManager { success = group.removeMember(user); session.save(); - }catch(Exception e) { - log.error("jcr error adding user {} to group {}", userId, groupId, e); - GXOutboundErrorResponse.throwException(new BackendGenericError(e)); + }catch(StorageHubException she ){ + log.error(she.getErrorMessage(), she); + GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus())); + }catch(RepositoryException re ){ + log.error("jcr error creating item", re); + GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error creating item", re)); } finally { if (session!=null) session.logout(); @@ -445,10 +454,13 @@ public class GroupManager { } - }catch(Exception e) { - log.error("jcr error getting users of group {}", groupId, e); - GXOutboundErrorResponse.throwException(new BackendGenericError(e)); - } finally { + }catch(StorageHubException she ){ + log.error(she.getErrorMessage(), she); + GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus())); + }catch(RepositoryException re ){ + log.error("jcr error creating item", re); + GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error creating item", re)); + }finally { if (session!=null) session.logout(); } diff --git a/src/main/java/org/gcube/data/access/storagehub/services/ItemsManager.java b/src/main/java/org/gcube/data/access/storagehub/services/ItemsManager.java index 7444d7b..9d8470b 100644 --- a/src/main/java/org/gcube/data/access/storagehub/services/ItemsManager.java +++ b/src/main/java/org/gcube/data/access/storagehub/services/ItemsManager.java @@ -250,6 +250,34 @@ public class ItemsManager { return new ItemList(toReturn); } + @GET + @Path("{id}/search") + @Produces(MediaType.APPLICATION_JSON) + public ItemList searchItems(@QueryParam("showHidden") Boolean showHidden, @QueryParam("exclude") List excludes, @QueryParam("onlyType") String nodeType,@QueryParam("name") String name ){ + InnerMethodName.instance.set("listById"); + Session ses = null; + List toReturn = null; + try{ + ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); + authChecker.checkReadAuthorizationControl(ses, id); + toReturn = Utils.serachByNameOnFolder(ses, ses.getNodeByIdentifier(id), excludes, null, showHidden==null?false:showHidden, nodeType!=null ? ClassHandler.instance().get(nodeType) : null, name); + }catch (ItemNotFoundException e) { + log.error("id {} not found",id,e); + GXOutboundErrorResponse.throwException(new IdNotFoundException(id, e), Status.NOT_FOUND); + }catch(RepositoryException re){ + log.error("jcr error getting children", re); + GXOutboundErrorResponse.throwException(new BackendGenericError(re)); + }catch(StorageHubException she ){ + log.error(she.getErrorMessage(), she); + GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus())); + }finally{ + if (ses!=null) + ses.logout(); + } + + return new ItemList(toReturn); + } + @GET @Path("{id}/children/paged") @Produces(MediaType.APPLICATION_JSON) diff --git a/src/main/java/org/gcube/data/access/storagehub/services/UserManager.java b/src/main/java/org/gcube/data/access/storagehub/services/UserManager.java index 3756b22..c250505 100644 --- a/src/main/java/org/gcube/data/access/storagehub/services/UserManager.java +++ b/src/main/java/org/gcube/data/access/storagehub/services/UserManager.java @@ -8,6 +8,8 @@ import java.util.List; import javax.inject.Inject; import javax.jcr.Node; import javax.jcr.NodeIterator; +import javax.jcr.PathNotFoundException; +import javax.jcr.RepositoryException; import javax.jcr.query.QueryResult; import javax.servlet.ServletContext; import javax.ws.rs.Consumes; @@ -20,6 +22,7 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; import org.apache.jackrabbit.api.JackrabbitSession; import org.apache.jackrabbit.api.security.user.Authorizable; @@ -31,6 +34,7 @@ import org.gcube.common.authorization.control.annotations.AuthorizationControl; import org.gcube.common.authorization.library.provider.AuthorizationProvider; import org.gcube.common.gxrest.response.outbound.GXOutboundErrorResponse; import org.gcube.common.storagehub.model.exceptions.BackendGenericError; +import org.gcube.common.storagehub.model.exceptions.StorageHubException; import org.gcube.common.storagehub.model.exceptions.UserNotAuthorizedException; import org.gcube.common.storagehub.model.types.NodeProperty; import org.gcube.data.access.storagehub.Constants; @@ -122,9 +126,12 @@ public class UserManager { Utils.createFolderInternally(session, workspaceFolder, Constants.VRE_FOLDER_PARENT_NAME, "special folder container of "+user, false, user, null); session.save(); - }catch(Exception e) { - log.error("jcr error creating user {}", user, e); - GXOutboundErrorResponse.throwException(new BackendGenericError(e)); + }catch(StorageHubException she ){ + log.error(she.getErrorMessage(), she); + GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus())); + }catch(RepositoryException re ){ + log.error("jcr error creating item", re); + GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error creating item", re)); } finally { if (session!=null) session.logout(); @@ -169,14 +176,24 @@ public class UserManager { } Authorizable authorizable = usrManager.getAuthorizable(new PrincipalImpl(user)); - if (!authorizable.isGroup()) { + if (authorizable!=null && !authorizable.isGroup()) { log.info("removing user {}", user); authorizable.remove(); + } else log.warn("the user {} was already deleted", user); + + org.gcube.common.storagehub.model.Path homePath = Utils.getHome(user); + try { + session.getNode(homePath.toPath()).remove(); + } catch (PathNotFoundException e) { + log.warn("{} home dir was already deleted", user); } session.save(); - }catch(Exception e) { - log.error("jcr error getting users", e); - GXOutboundErrorResponse.throwException(new BackendGenericError(e)); + }catch(StorageHubException she ){ + log.error(she.getErrorMessage(), she); + GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus())); + }catch(RepositoryException re ){ + log.error("jcr error creating item", re); + GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error creating item", re)); } finally { if (session!=null) session.logout(); From de91f86daf6004e1f54797208e5a4649bb5d0a43 Mon Sep 17 00:00:00 2001 From: lucio Date: Wed, 22 Jan 2020 12:40:01 +0100 Subject: [PATCH 09/10] version changed for release --- pom.xml | 2 +- src/main/webapp/WEB-INF/LICENSE | 402 ++++++++++++++++---------------- src/main/webapp/WEB-INF/README | 30 +-- 3 files changed, 217 insertions(+), 217 deletions(-) diff --git a/pom.xml b/pom.xml index 1c29013..ab8da1a 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ 4.0.0 org.gcube.data.access storagehub - 1.0.8-SNAPSHOT + 1.0.9 storagehub diff --git a/src/main/webapp/WEB-INF/LICENSE b/src/main/webapp/WEB-INF/LICENSE index 573db28..ddd1eb9 100644 --- a/src/main/webapp/WEB-INF/LICENSE +++ b/src/main/webapp/WEB-INF/LICENSE @@ -1,313 +1,313 @@ European Union Public Licence V. 1.1 -EUPL © the European Community 2007 + EUPL © the European Community 2007 -This European Union Public Licence (the “EUPL”) applies to the Work or Software -(as defined below) which is provided under the terms of this Licence. Any use of -the Work, other than as authorised under this Licence is prohibited (to the -extent such use is covered by a right of the copyright holder of the Work). + This European Union Public Licence (the “EUPL”) applies to the Work or Software + (as defined below) which is provided under the terms of this Licence. Any use of + the Work, other than as authorised under this Licence is prohibited (to the + extent such use is covered by a right of the copyright holder of the Work). -The Original Work is provided under the terms of this Licence when the Licensor -(as defined below) has placed the following notice immediately following the -copyright notice for the Original Work: + The Original Work is provided under the terms of this Licence when the Licensor + (as defined below) has placed the following notice immediately following the + copyright notice for the Original Work: -Licensed under the EUPL V.1.1 + Licensed under the EUPL V.1.1 -or has expressed by any other mean his willingness to license under the EUPL. + or has expressed by any other mean his willingness to license under the EUPL. -1. Definitions + 1. Definitions -In this Licence, the following terms have the following meaning: + In this Licence, the following terms have the following meaning: -- The Licence: this Licence. + - The Licence: this Licence. -- The Original Work or the Software: the software distributed and/or - communicated by the Licensor under this Licence, available as Source Code and - also as Executable Code as the case may be. + - The Original Work or the Software: the software distributed and/or + communicated by the Licensor under this Licence, available as Source Code and + also as Executable Code as the case may be. -- Derivative Works: the works or software that could be created by the Licensee, - based upon the Original Work or modifications thereof. This Licence does not - define the extent of modification or dependence on the Original Work required - in order to classify a work as a Derivative Work; this extent is determined by - copyright law applicable in the country mentioned in Article 15. + - Derivative Works: the works or software that could be created by the Licensee, + based upon the Original Work or modifications thereof. This Licence does not + define the extent of modification or dependence on the Original Work required + in order to classify a work as a Derivative Work; this extent is determined by + copyright law applicable in the country mentioned in Article 15. -- The Work: the Original Work and/or its Derivative Works. + - The Work: the Original Work and/or its Derivative Works. -- The Source Code: the human-readable form of the Work which is the most - convenient for people to study and modify. + - The Source Code: the human-readable form of the Work which is the most + convenient for people to study and modify. -- The Executable Code: any code which has generally been compiled and which is - meant to be interpreted by a computer as a program. + - The Executable Code: any code which has generally been compiled and which is + meant to be interpreted by a computer as a program. -- The Licensor: the natural or legal person that distributes and/or communicates - the Work under the Licence. + - The Licensor: the natural or legal person that distributes and/or communicates + the Work under the Licence. -- Contributor(s): any natural or legal person who modifies the Work under the - Licence, or otherwise contributes to the creation of a Derivative Work. + - Contributor(s): any natural or legal person who modifies the Work under the + Licence, or otherwise contributes to the creation of a Derivative Work. -- The Licensee or “You”: any natural or legal person who makes any usage of the - Software under the terms of the Licence. + - The Licensee or “You”: any natural or legal person who makes any usage of the + Software under the terms of the Licence. -- Distribution and/or Communication: any act of selling, giving, lending, - renting, distributing, communicating, transmitting, or otherwise making - available, on-line or off-line, copies of the Work or providing access to its - essential functionalities at the disposal of any other natural or legal - person. + - Distribution and/or Communication: any act of selling, giving, lending, + renting, distributing, communicating, transmitting, or otherwise making + available, on-line or off-line, copies of the Work or providing access to its + essential functionalities at the disposal of any other natural or legal + person. -2. Scope of the rights granted by the Licence + 2. Scope of the rights granted by the Licence -The Licensor hereby grants You a world-wide, royalty-free, non-exclusive, -sub-licensable licence to do the following, for the duration of copyright vested -in the Original Work: + The Licensor hereby grants You a world-wide, royalty-free, non-exclusive, + sub-licensable licence to do the following, for the duration of copyright vested + in the Original Work: -- use the Work in any circumstance and for all usage, reproduce the Work, modify -- the Original Work, and make Derivative Works based upon the Work, communicate -- to the public, including the right to make available or display the Work or -- copies thereof to the public and perform publicly, as the case may be, the -- Work, distribute the Work or copies thereof, lend and rent the Work or copies -- thereof, sub-license rights in the Work or copies thereof. + - use the Work in any circumstance and for all usage, reproduce the Work, modify + - the Original Work, and make Derivative Works based upon the Work, communicate + - to the public, including the right to make available or display the Work or + - copies thereof to the public and perform publicly, as the case may be, the + - Work, distribute the Work or copies thereof, lend and rent the Work or copies + - thereof, sub-license rights in the Work or copies thereof. -Those rights can be exercised on any media, supports and formats, whether now -known or later invented, as far as the applicable law permits so. + Those rights can be exercised on any media, supports and formats, whether now + known or later invented, as far as the applicable law permits so. -In the countries where moral rights apply, the Licensor waives his right to -exercise his moral right to the extent allowed by law in order to make effective -the licence of the economic rights here above listed. + In the countries where moral rights apply, the Licensor waives his right to + exercise his moral right to the extent allowed by law in order to make effective + the licence of the economic rights here above listed. -The Licensor grants to the Licensee royalty-free, non exclusive usage rights to -any patents held by the Licensor, to the extent necessary to make use of the -rights granted on the Work under this Licence. + The Licensor grants to the Licensee royalty-free, non exclusive usage rights to + any patents held by the Licensor, to the extent necessary to make use of the + rights granted on the Work under this Licence. -3. Communication of the Source Code + 3. Communication of the Source Code -The Licensor may provide the Work either in its Source Code form, or as -Executable Code. If the Work is provided as Executable Code, the Licensor -provides in addition a machine-readable copy of the Source Code of the Work -along with each copy of the Work that the Licensor distributes or indicates, in -a notice following the copyright notice attached to the Work, a repository where -the Source Code is easily and freely accessible for as long as the Licensor -continues to distribute and/or communicate the Work. + The Licensor may provide the Work either in its Source Code form, or as + Executable Code. If the Work is provided as Executable Code, the Licensor + provides in addition a machine-readable copy of the Source Code of the Work + along with each copy of the Work that the Licensor distributes or indicates, in + a notice following the copyright notice attached to the Work, a repository where + the Source Code is easily and freely accessible for as long as the Licensor + continues to distribute and/or communicate the Work. -4. Limitations on copyright + 4. Limitations on copyright -Nothing in this Licence is intended to deprive the Licensee of the benefits from -any exception or limitation to the exclusive rights of the rights owners in the -Original Work or Software, of the exhaustion of those rights or of other -applicable limitations thereto. + Nothing in this Licence is intended to deprive the Licensee of the benefits from + any exception or limitation to the exclusive rights of the rights owners in the + Original Work or Software, of the exhaustion of those rights or of other + applicable limitations thereto. -5. Obligations of the Licensee + 5. Obligations of the Licensee -The grant of the rights mentioned above is subject to some restrictions and -obligations imposed on the Licensee. Those obligations are the following: + The grant of the rights mentioned above is subject to some restrictions and + obligations imposed on the Licensee. Those obligations are the following: -Attribution right: the Licensee shall keep intact all copyright, patent or -trademarks notices and all notices that refer to the Licence and to the -disclaimer of warranties. The Licensee must include a copy of such notices and a -copy of the Licence with every copy of the Work he/she distributes and/or -communicates. The Licensee must cause any Derivative Work to carry prominent -notices stating that the Work has been modified and the date of modification. + Attribution right: the Licensee shall keep intact all copyright, patent or + trademarks notices and all notices that refer to the Licence and to the + disclaimer of warranties. The Licensee must include a copy of such notices and a + copy of the Licence with every copy of the Work he/she distributes and/or + communicates. The Licensee must cause any Derivative Work to carry prominent + notices stating that the Work has been modified and the date of modification. -Copyleft clause: If the Licensee distributes and/or communicates copies of the -Original Works or Derivative Works based upon the Original Work, this -Distribution and/or Communication will be done under the terms of this Licence -or of a later version of this Licence unless the Original Work is expressly -distributed only under this version of the Licence. The Licensee (becoming -Licensor) cannot offer or impose any additional terms or conditions on the Work -or Derivative Work that alter or restrict the terms of the Licence. + Copyleft clause: If the Licensee distributes and/or communicates copies of the + Original Works or Derivative Works based upon the Original Work, this + Distribution and/or Communication will be done under the terms of this Licence + or of a later version of this Licence unless the Original Work is expressly + distributed only under this version of the Licence. The Licensee (becoming + Licensor) cannot offer or impose any additional terms or conditions on the Work + or Derivative Work that alter or restrict the terms of the Licence. -Compatibility clause: If the Licensee Distributes and/or Communicates Derivative -Works or copies thereof based upon both the Original Work and another work -licensed under a Compatible Licence, this Distribution and/or Communication can -be done under the terms of this Compatible Licence. For the sake of this clause, -“Compatible Licence” refers to the licences listed in the appendix attached to -this Licence. Should the Licensee’s obligations under the Compatible Licence -conflict with his/her obligations under this Licence, the obligations of the -Compatible Licence shall prevail. + Compatibility clause: If the Licensee Distributes and/or Communicates Derivative + Works or copies thereof based upon both the Original Work and another work + licensed under a Compatible Licence, this Distribution and/or Communication can + be done under the terms of this Compatible Licence. For the sake of this clause, + “Compatible Licence” refers to the licences listed in the appendix attached to + this Licence. Should the Licensee’s obligations under the Compatible Licence + conflict with his/her obligations under this Licence, the obligations of the + Compatible Licence shall prevail. -Provision of Source Code: When distributing and/or communicating copies of the -Work, the Licensee will provide a machine-readable copy of the Source Code or -indicate a repository where this Source will be easily and freely available for -as long as the Licensee continues to distribute and/or communicate the Work. + Provision of Source Code: When distributing and/or communicating copies of the + Work, the Licensee will provide a machine-readable copy of the Source Code or + indicate a repository where this Source will be easily and freely available for + as long as the Licensee continues to distribute and/or communicate the Work. -Legal Protection: This Licence does not grant permission to use the trade names, -trademarks, service marks, or names of the Licensor, except as required for -reasonable and customary use in describing the origin of the Work and -reproducing the content of the copyright notice. + Legal Protection: This Licence does not grant permission to use the trade names, + trademarks, service marks, or names of the Licensor, except as required for + reasonable and customary use in describing the origin of the Work and + reproducing the content of the copyright notice. -6. Chain of Authorship + 6. Chain of Authorship -The original Licensor warrants that the copyright in the Original Work granted -hereunder is owned by him/her or licensed to him/her and that he/she has the -power and authority to grant the Licence. + The original Licensor warrants that the copyright in the Original Work granted + hereunder is owned by him/her or licensed to him/her and that he/she has the + power and authority to grant the Licence. -Each Contributor warrants that the copyright in the modifications he/she brings -to the Work are owned by him/her or licensed to him/her and that he/she has the -power and authority to grant the Licence. + Each Contributor warrants that the copyright in the modifications he/she brings + to the Work are owned by him/her or licensed to him/her and that he/she has the + power and authority to grant the Licence. -Each time You accept the Licence, the original Licensor and subsequent -Contributors grant You a licence to their contributions to the Work, under the -terms of this Licence. + Each time You accept the Licence, the original Licensor and subsequent + Contributors grant You a licence to their contributions to the Work, under the + terms of this Licence. -7. Disclaimer of Warranty + 7. Disclaimer of Warranty -The Work is a work in progress, which is continuously improved by numerous -contributors. It is not a finished work and may therefore contain defects or -“bugs” inherent to this type of software development. + The Work is a work in progress, which is continuously improved by numerous + contributors. It is not a finished work and may therefore contain defects or + “bugs” inherent to this type of software development. -For the above reason, the Work is provided under the Licence on an “as is” basis -and without warranties of any kind concerning the Work, including without -limitation merchantability, fitness for a particular purpose, absence of defects -or errors, accuracy, non-infringement of intellectual property rights other than -copyright as stated in Article 6 of this Licence. + For the above reason, the Work is provided under the Licence on an “as is” basis + and without warranties of any kind concerning the Work, including without + limitation merchantability, fitness for a particular purpose, absence of defects + or errors, accuracy, non-infringement of intellectual property rights other than + copyright as stated in Article 6 of this Licence. -This disclaimer of warranty is an essential part of the Licence and a condition -for the grant of any rights to the Work. + This disclaimer of warranty is an essential part of the Licence and a condition + for the grant of any rights to the Work. -8. Disclaimer of Liability + 8. Disclaimer of Liability -Except in the cases of wilful misconduct or damages directly caused to natural -persons, the Licensor will in no event be liable for any direct or indirect, -material or moral, damages of any kind, arising out of the Licence or of the use -of the Work, including without limitation, damages for loss of goodwill, work -stoppage, computer failure or malfunction, loss of data or any commercial -damage, even if the Licensor has been advised of the possibility of such -damage. However, the Licensor will be liable under statutory product liability -laws as far such laws apply to the Work. + Except in the cases of wilful misconduct or damages directly caused to natural + persons, the Licensor will in no event be liable for any direct or indirect, + material or moral, damages of any kind, arising out of the Licence or of the use + of the Work, including without limitation, damages for loss of goodwill, work + stoppage, computer failure or malfunction, loss of data or any commercial + damage, even if the Licensor has been advised of the possibility of such + damage. However, the Licensor will be liable under statutory product liability + laws as far such laws apply to the Work. -9. Additional agreements + 9. Additional agreements -While distributing the Original Work or Derivative Works, You may choose to -conclude an additional agreement to offer, and charge a fee for, acceptance of -support, warranty, indemnity, or other liability obligations and/or services -consistent with this Licence. However, in accepting such obligations, You may -act only on your own behalf and on your sole responsibility, not on behalf of -the original Licensor or any other Contributor, and only if You agree to -indemnify, defend, and hold each Contributor harmless for any liability incurred -by, or claims asserted against such Contributor by the fact You have accepted -any such warranty or additional liability. + While distributing the Original Work or Derivative Works, You may choose to + conclude an additional agreement to offer, and charge a fee for, acceptance of + support, warranty, indemnity, or other liability obligations and/or services + consistent with this Licence. However, in accepting such obligations, You may + act only on your own behalf and on your sole responsibility, not on behalf of + the original Licensor or any other Contributor, and only if You agree to + indemnify, defend, and hold each Contributor harmless for any liability incurred + by, or claims asserted against such Contributor by the fact You have accepted + any such warranty or additional liability. -10. Acceptance of the Licence + 10. Acceptance of the Licence -The provisions of this Licence can be accepted by clicking on an icon “I agree” -placed under the bottom of a window displaying the text of this Licence or by -affirming consent in any other similar way, in accordance with the rules of -applicable law. Clicking on that icon indicates your clear and irrevocable -acceptance of this Licence and all of its terms and conditions. + The provisions of this Licence can be accepted by clicking on an icon “I agree” + placed under the bottom of a window displaying the text of this Licence or by + affirming consent in any other similar way, in accordance with the rules of + applicable law. Clicking on that icon indicates your clear and irrevocable + acceptance of this Licence and all of its terms and conditions. -Similarly, you irrevocably accept this Licence and all of its terms and -conditions by exercising any rights granted to You by Article 2 of this Licence, -such as the use of the Work, the creation by You of a Derivative Work or the -Distribution and/or Communication by You of the Work or copies thereof. + Similarly, you irrevocably accept this Licence and all of its terms and + conditions by exercising any rights granted to You by Article 2 of this Licence, + such as the use of the Work, the creation by You of a Derivative Work or the + Distribution and/or Communication by You of the Work or copies thereof. -11. Information to the public + 11. Information to the public -In case of any Distribution and/or Communication of the Work by means of -electronic communication by You (for example, by offering to download the Work -from a remote location) the distribution channel or media (for example, a -website) must at least provide to the public the information requested by the -applicable law regarding the Licensor, the Licence and the way it may be -accessible, concluded, stored and reproduced by the Licensee. + In case of any Distribution and/or Communication of the Work by means of + electronic communication by You (for example, by offering to download the Work + from a remote location) the distribution channel or media (for example, a + website) must at least provide to the public the information requested by the + applicable law regarding the Licensor, the Licence and the way it may be + accessible, concluded, stored and reproduced by the Licensee. -12. Termination of the Licence + 12. Termination of the Licence -The Licence and the rights granted hereunder will terminate automatically upon -any breach by the Licensee of the terms of the Licence. + The Licence and the rights granted hereunder will terminate automatically upon + any breach by the Licensee of the terms of the Licence. -Such a termination will not terminate the licences of any person who has -received the Work from the Licensee under the Licence, provided such persons -remain in full compliance with the Licence. + Such a termination will not terminate the licences of any person who has + received the Work from the Licensee under the Licence, provided such persons + remain in full compliance with the Licence. -13. Miscellaneous + 13. Miscellaneous -Without prejudice of Article 9 above, the Licence represents the complete -agreement between the Parties as to the Work licensed hereunder. + Without prejudice of Article 9 above, the Licence represents the complete + agreement between the Parties as to the Work licensed hereunder. -If any provision of the Licence is invalid or unenforceable under applicable -law, this will not affect the validity or enforceability of the Licence as a -whole. Such provision will be construed and/or reformed so as necessary to make -it valid and enforceable. + If any provision of the Licence is invalid or unenforceable under applicable + law, this will not affect the validity or enforceability of the Licence as a + whole. Such provision will be construed and/or reformed so as necessary to make + it valid and enforceable. -The European Commission may publish other linguistic versions and/or new -versions of this Licence, so far this is required and reasonable, without -reducing the scope of the rights granted by the Licence. New versions of the -Licence will be published with a unique version number. + The European Commission may publish other linguistic versions and/or new + versions of this Licence, so far this is required and reasonable, without + reducing the scope of the rights granted by the Licence. New versions of the + Licence will be published with a unique version number. -All linguistic versions of this Licence, approved by the European Commission, -have identical value. Parties can take advantage of the linguistic version of -their choice. + All linguistic versions of this Licence, approved by the European Commission, + have identical value. Parties can take advantage of the linguistic version of + their choice. -14. Jurisdiction + 14. Jurisdiction -Any litigation resulting from the interpretation of this License, arising -between the European Commission, as a Licensor, and any Licensee, will be -subject to the jurisdiction of the Court of Justice of the European Communities, -as laid down in article 238 of the Treaty establishing the European Community. + Any litigation resulting from the interpretation of this License, arising + between the European Commission, as a Licensor, and any Licensee, will be + subject to the jurisdiction of the Court of Justice of the European Communities, + as laid down in article 238 of the Treaty establishing the European Community. -Any litigation arising between Parties, other than the European Commission, and -resulting from the interpretation of this License, will be subject to the -exclusive jurisdiction of the competent court where the Licensor resides or -conducts its primary business. + Any litigation arising between Parties, other than the European Commission, and + resulting from the interpretation of this License, will be subject to the + exclusive jurisdiction of the competent court where the Licensor resides or + conducts its primary business. -15. Applicable Law + 15. Applicable Law -This Licence shall be governed by the law of the European Union country where -the Licensor resides or has his registered office. + This Licence shall be governed by the law of the European Union country where + the Licensor resides or has his registered office. -This licence shall be governed by the Belgian law if: + This licence shall be governed by the Belgian law if: -- a litigation arises between the European Commission, as a Licensor, and any -- Licensee; the Licensor, other than the European Commission, has no residence -- or registered office inside a European Union country. + - a litigation arises between the European Commission, as a Licensor, and any + - Licensee; the Licensor, other than the European Commission, has no residence + - or registered office inside a European Union country. -=== + === -Appendix + Appendix -“Compatible Licences” according to article 5 EUPL are: + “Compatible Licences” according to article 5 EUPL are: -- GNU General Public License (GNU GPL) v. 2 + - GNU General Public License (GNU GPL) v. 2 -- Open Software License (OSL) v. 2.1, v. 3.0 + - Open Software License (OSL) v. 2.1, v. 3.0 -- Common Public License v. 1.0 + - Common Public License v. 1.0 -- Eclipse Public License v. 1.0 + - Eclipse Public License v. 1.0 -- Cecill v. 2.0 + - Cecill v. 2.0 diff --git a/src/main/webapp/WEB-INF/README b/src/main/webapp/WEB-INF/README index 6476e3b..54089d3 100644 --- a/src/main/webapp/WEB-INF/README +++ b/src/main/webapp/WEB-INF/README @@ -5,27 +5,27 @@ REST web service for Jackrabbit This software is part of the gCube Framework (https://www.gcube-system.org/): an -open-source software toolkit used for building and operating Hybrid Data -Infrastructures enabling the dynamic deployment of Virtual Research Environments -by favouring the realisation of reuse oriented policies. + open-source software toolkit used for building and operating Hybrid Data + Infrastructures enabling the dynamic deployment of Virtual Research Environments + by favouring the realisation of reuse oriented policies. The projects leading to this software have received funding from a series of -European Union programmes including: -* the Sixth Framework Programme for Research and Technological Development - -DILIGENT (grant no. 004260); -* the Seventh Framework Programme for research, technological development and -demonstration - D4Science (grant no. 212488), D4Science-II (grant no. -239019),ENVRI (grant no. 283465), EUBrazilOpenBio (grant no. 288754), iMarine -(grant no. 283644); -* the H2020 research and innovation programme - BlueBRIDGE (grant no. 675680), -EGIEngage (grant no. 654142), ENVRIplus (grant no. 654182), Parthenos (grant -no. 654119), SoBigData (grant no. 654024), AGINFRA PLUS (grant no. 731001). + European Union programmes including: + * the Sixth Framework Programme for Research and Technological Development - + DILIGENT (grant no. 004260); + * the Seventh Framework Programme for research, technological development and + demonstration - D4Science (grant no. 212488), D4Science-II (grant no. + 239019),ENVRI (grant no. 283465), EUBrazilOpenBio (grant no. 288754), iMarine + (grant no. 283644); + * the H2020 research and innovation programme - BlueBRIDGE (grant no. 675680), + EGIEngage (grant no. 654142), ENVRIplus (grant no. 654182), Parthenos (grant + no. 654119), SoBigData (grant no. 654024), AGINFRA PLUS (grant no. 731001). Version -------------------------------------------------- -1.0.7-SNAPSHOT (2019-09-16) +1.0.8-SNAPSHOT (2020-01-22) Please see the file named "changelog.xml" in this directory for the release notes. @@ -48,7 +48,7 @@ Download information -------------------------------------------------- Source code is available from SVN: - ${scm.url} + https://code-repo.d4science.org/gCubeSystem/storagehub Binaries can be downloaded from the gCube website: https://www.gcube-system.org/ From a4dc3cff54751d506be4400b72e7a0f8986d41dd Mon Sep 17 00:00:00 2001 From: lucio Date: Wed, 22 Jan 2020 12:40:35 +0100 Subject: [PATCH 10/10] My ApplicationListener added --- .../storagehub/MyApplicationListener.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/main/java/org/gcube/data/access/storagehub/MyApplicationListener.java diff --git a/src/main/java/org/gcube/data/access/storagehub/MyApplicationListener.java b/src/main/java/org/gcube/data/access/storagehub/MyApplicationListener.java new file mode 100644 index 0000000..0600c8d --- /dev/null +++ b/src/main/java/org/gcube/data/access/storagehub/MyApplicationListener.java @@ -0,0 +1,40 @@ +package org.gcube.data.access.storagehub; + +import javax.inject.Inject; + +import org.apache.jackrabbit.api.JackrabbitRepository; +import org.gcube.data.access.storagehub.services.GroupManager; +import org.gcube.data.access.storagehub.services.RepositoryInitializer; +import org.glassfish.jersey.server.monitoring.ApplicationEvent; +import org.glassfish.jersey.server.monitoring.ApplicationEventListener; +import org.glassfish.jersey.server.monitoring.RequestEvent; +import org.glassfish.jersey.server.monitoring.RequestEventListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MyApplicationListener implements ApplicationEventListener { + + private static final Logger log = LoggerFactory.getLogger(MyApplicationListener.class); + + @Inject + RepositoryInitializer repository; + + @Override + public void onEvent(ApplicationEvent event) { + switch (event.getType()) { + case DESTROY_FINISHED: + log.info("Destroying application storageHub"); + ((JackrabbitRepository) repository.getRepository()).shutdown(); + log.info("Jackrabbit repository stopped"); + default: + break; + } + } + + @Override + public RequestEventListener onRequest(RequestEvent requestEvent) { + return null; + } + + +} \ No newline at end of file