package org.gcube.data.access.storagehub.services.admin; import static org.gcube.data.access.storagehub.Roles.INFRASTRUCTURE_MANAGER_ROLE; import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.inject.Inject; import javax.jcr.Node; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.security.AccessControlEntry; import javax.jcr.security.Privilege; import javax.jcr.version.Version; import javax.servlet.ServletContext; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; 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; import org.apache.jackrabbit.api.JackrabbitSession; import org.apache.jackrabbit.api.security.JackrabbitAccessControlList; import org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils; import org.gcube.common.authorization.control.annotations.AuthorizationControl; import org.gcube.common.gxrest.response.outbound.GXOutboundErrorResponse; import org.gcube.common.storagehub.model.Excludes; import org.gcube.common.storagehub.model.acls.ACL; import org.gcube.common.storagehub.model.acls.AccessType; import org.gcube.common.storagehub.model.exceptions.BackendGenericError; import org.gcube.common.storagehub.model.exceptions.StorageHubException; import org.gcube.common.storagehub.model.items.Item; import org.gcube.common.storagehub.model.service.ItemList; import org.gcube.common.storagehub.model.service.ItemWrapper; import org.gcube.common.storagehub.model.types.ACLList; import org.gcube.data.access.storagehub.StorageHubAppllicationManager; 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.TrashHandler; import org.gcube.data.access.storagehub.handlers.VersionHandler; import org.gcube.data.access.storagehub.handlers.items.Item2NodeConverter; import org.gcube.data.access.storagehub.handlers.items.Item2NodeConverter.Values; import org.gcube.data.access.storagehub.handlers.items.Node2ItemConverter; import org.gcube.data.access.storagehub.services.RepositoryInitializer; import org.gcube.smartgears.utils.InnerMethodName; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Path("admin") public class ItemManagerAdmin { private static final Logger log = LoggerFactory.getLogger(ItemManagerAdmin.class); RepositoryInitializer repository = StorageHubAppllicationManager.repository; @Inject Node2ItemConverter node2Item; @Inject TrashHandler trashHandler; @Inject VersionHandler versionHandler; @Context ServletContext context; @POST @Consumes(MediaType.APPLICATION_JSON) @Path("items/{id}") @AuthorizationControl(allowedRoles = {INFRASTRUCTURE_MANAGER_ROLE},exception=MyAuthException.class) public String createItem(@PathParam("id") String id, Item item) { InnerMethodName.instance.set("creteItemAdmin)"); //TODO: implement this method return null; } @GET @Produces(MediaType.APPLICATION_JSON) @Path("byPath/children") @AuthorizationControl(allowedRoles = {INFRASTRUCTURE_MANAGER_ROLE},exception=MyAuthException.class) public ItemList getbyPath(@QueryParam("path") String path) { InnerMethodName.instance.set("getByPathChildrenAdmin"); List items =null; Session session = null; try{ session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); Node node = session.getNode(path); items = Utils.getItemList(node, Excludes.EXCLUDE_ACCOUNTING , null, true, null); }catch(RepositoryException re ){ log.error("jcr error getting children by path", re); GXOutboundErrorResponse.throwException(new BackendGenericError(re)); }catch(StorageHubException she ){ log.error(she.getErrorMessage(), she); GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus())); } finally{ if (session!=null) { session.logout(); } } return new ItemList(items); } @GET @Produces(MediaType.APPLICATION_JSON) @Path("{user}") @AuthorizationControl(allowedRoles = {INFRASTRUCTURE_MANAGER_ROLE},exception=MyAuthException.class) public ItemWrapper getWorkspace(@PathParam("user") String user) { InnerMethodName.instance.set("getWorkspaceAdmin"); Item item =null; Session session = null; try{ session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); String workspacePath = Utils.getWorkspacePath(user).toPath(); Node node = session.getNode(workspacePath); item = node2Item.getItem(node, Collections.emptyList()); }catch(RepositoryException re ){ log.error("jcr error getting WS admin", re); GXOutboundErrorResponse.throwException(new BackendGenericError(re)); }catch(StorageHubException she ){ log.error(she.getErrorMessage(), she); GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus())); } finally{ if (session!=null) { session.logout(); } } return new ItemWrapper(item); } @GET @Produces(MediaType.APPLICATION_JSON) @Path("items/{id}") @AuthorizationControl(allowedRoles = {INFRASTRUCTURE_MANAGER_ROLE},exception=MyAuthException.class) public ItemWrapper getItem(@PathParam("id") String id) { InnerMethodName.instance.set("getItemAdmin"); Item item =null; Session session = null; try{ session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); Node node = session.getNodeByIdentifier(id); item = node2Item.getItem(node, Collections.emptyList()); }catch(RepositoryException re ){ log.error("jcr error getting item admin", re); GXOutboundErrorResponse.throwException(new BackendGenericError(re)); }catch(StorageHubException she ){ log.error(she.getErrorMessage(), she); GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus())); } finally{ if (session!=null) { session.logout(); } } return new ItemWrapper(item); } @DELETE @Produces(MediaType.APPLICATION_JSON) @Path("items/{id}") @AuthorizationControl(allowedRoles = {INFRASTRUCTURE_MANAGER_ROLE},exception=MyAuthException.class) public void deleteItem(@PathParam("id") String id) { InnerMethodName.instance.set("deleteAdmin"); Session session = null; try{ session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); Node node = session.getNodeByIdentifier(id); Item item = node2Item.getItem(node, Excludes.GET_ONLY_CONTENT); trashHandler.removeNodes(session, Collections.singletonList(item)); }catch(RepositoryException re ){ log.error("jcr error deleting item admin", re); GXOutboundErrorResponse.throwException(new BackendGenericError(re)); }catch(StorageHubException she ){ log.error(she.getErrorMessage(), she); GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus())); } finally{ if (session!=null) { session.logout(); } } } @GET @Produces(MediaType.APPLICATION_JSON) @Path("items/{id}/children") @AuthorizationControl(allowedRoles = {INFRASTRUCTURE_MANAGER_ROLE},exception=MyAuthException.class) public ItemList getChildren(@PathParam("id") String id) { InnerMethodName.instance.set("getChildrenAdmin"); List items =null; Session session = null; try{ session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); Node node = session.getNodeByIdentifier(id); items = Utils.getItemList(node, Collections.emptyList(), null, true, null); }catch(RepositoryException re ){ log.error("jcr error getting children admin", re); GXOutboundErrorResponse.throwException(new BackendGenericError(re)); }catch(StorageHubException she ){ log.error(she.getErrorMessage(), she); GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus())); } finally{ if (session!=null) { session.logout(); } } return new ItemList(items); } @PUT @Consumes(MediaType.APPLICATION_OCTET_STREAM) @Path("items/{id}/{propertyName}") @AuthorizationControl(allowedRoles = {INFRASTRUCTURE_MANAGER_ROLE},exception=MyAuthException.class) public void setProperty(@PathParam("id") String id, @QueryParam("path") String subPath, @PathParam("propertyName") String propertyName, String value) { InnerMethodName.instance.set("setPropertyAdmin"); Session session = null; try{ session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); Node node = session.getNodeByIdentifier(id); if (subPath!=null) node = node.getNode(subPath); boolean checkedIn = false; if (!node.isCheckedOut()) { checkedIn=true; versionHandler.checkoutContentNode(node, session); } Values internalValue = Item2NodeConverter.getObjectValue(value.getClass(), value); node.setProperty(propertyName, internalValue.getValue()); session.save(); if (checkedIn) { versionHandler.checkinContentNode(node, session); List versions = versionHandler.getContentVersionHistory(node, session); if (versions.size()>1) { log.info("removing version {} ",versions.get(versions.size()-2).getName()); session.removeItem(versions.get(versions.size()-2).getPath()); } } }catch(Exception re ){ log.error("jcr error setting prop admin", re); GXOutboundErrorResponse.throwException(new BackendGenericError(re)); } finally{ if (session!=null) { session.logout(); } } } @GET @Path("items/{id}/acls") @Produces(MediaType.APPLICATION_JSON) public ACLList getACL(@PathParam("id") String id) { InnerMethodName.instance.set("getACLByIdAdmin"); Session ses = null; List acls = new ArrayList<>(); try{ ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); String path = ses.getNodeByIdentifier(id).getPath(); log.info("checking acces for path {}",path); JackrabbitAccessControlList accessControlList = AccessControlUtils.getAccessControlList(ses, path ); for (AccessControlEntry aclEntry : accessControlList.getAccessControlEntries()) { ACL acl = new ACL(); acl.setPricipal(aclEntry.getPrincipal().getName()); List types = new ArrayList<>(); for (Privilege priv : aclEntry.getPrivileges()) try { types.add(AccessType.fromValue(priv.getName())); }catch (Exception e) { log.warn(priv.getName()+" cannot be mapped to AccessTypes",e); } acl.setAccessTypes(types); acls.add(acl); } }catch(RepositoryException re){ log.error("jcr error getting acl", re); GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error getting acl", re)); }finally{ if (ses!=null) ses.logout(); } return new ACLList(acls); } }