diff --git a/dspace-api/src/main/java/org/dspace/app/util/AuthorizeUtil.java b/dspace-api/src/main/java/org/dspace/app/util/AuthorizeUtil.java new file mode 100644 index 0000000000..ed47032471 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/app/util/AuthorizeUtil.java @@ -0,0 +1,406 @@ +/* + * AuthorizeUtil.java + * + * Version: $Revision: 3980 $ + * + * Date: $Date: 2009-06-26 19:07:25 +0200 (ven, 26 giu 2009) $ + * + * Copyright (c) 2002-2009, The DSpace Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the DSpace Foundation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ +package org.dspace.app.util; + +import java.sql.SQLException; + +import org.dspace.authorize.AuthorizeConfiguration; +import org.dspace.authorize.AuthorizeException; +import org.dspace.authorize.AuthorizeManager; +import org.dspace.authorize.ResourcePolicy; +import org.dspace.content.Bitstream; +import org.dspace.content.Bundle; +import org.dspace.content.Collection; +import org.dspace.content.Community; +import org.dspace.content.Item; +import org.dspace.core.Constants; +import org.dspace.core.Context; + +public class AuthorizeUtil +{ + + public static void authorizeManageBitstreamPolicy(Context context, + Bitstream bitstream) throws AuthorizeException, SQLException + { + Bundle bundle = bitstream.getBundles()[0]; + authorizeManageBundlePolicy(context, bundle); + } + + public static void authorizeManageBundlePolicy(Context context, + Bundle bundle) throws AuthorizeException, SQLException + { + Item item = bundle.getItems()[0]; + authorizeManageItemPolicy(context, item); + } + + public static void authorizeManageItemPolicy(Context context, Item item) + throws AuthorizeException, SQLException + { + if (AuthorizeConfiguration.canItemAdminManagePolicies()) + { + AuthorizeManager.authorizeAction(context, item, Constants.ADMIN); + } + else if (AuthorizeConfiguration.canCollectionAdminManageItemPolicies()) + { + AuthorizeManager.authorizeAction(context, item + .getOwningCollection(), Constants.ADMIN); + } + else if (AuthorizeConfiguration.canCommunityAdminManageItemPolicies()) + { + AuthorizeManager + .authorizeAction(context, item.getOwningCollection() + .getCommunities()[0], Constants.ADMIN); + } + else if (!AuthorizeManager.isAdmin(context)) + { + throw new AuthorizeException( + "Only system admin are allowed to manage item policies"); + } + } + + public static void authorizeManageCollectionPolicy(Context context, + Collection collection) throws AuthorizeException, SQLException + { + if (AuthorizeConfiguration.canCollectionAdminManagePolicies()) + { + AuthorizeManager.authorizeAction(context, collection, + Constants.ADMIN); + } + else if (AuthorizeConfiguration + .canCommunityAdminManageCollectionPolicies()) + { + AuthorizeManager.authorizeAction(context, collection + .getCommunities()[0], Constants.ADMIN); + } + else if (!AuthorizeManager.isAdmin(context)) + { + throw new AuthorizeException( + "Only system admin are allowed to manage collection policies"); + } + } + + public static void authorizeManageCommunityPolicy(Context context, + Community community) throws AuthorizeException, SQLException + { + if (AuthorizeConfiguration.canCommunityAdminManagePolicies()) + { + AuthorizeManager.authorizeAction(context, community, + Constants.ADMIN); + } + else if (!AuthorizeManager.isAdmin(context)) + { + throw new AuthorizeException( + "Only system admin are allowed to manage community policies"); + } + } + + public static void requireAdminRole(Context context) + throws AuthorizeException, SQLException + { + if (!AuthorizeManager.isAdmin(context)) + { + throw new AuthorizeException( + "Only system admin are allowed to perform this action"); + } + } + + public static void authorizeManageCCLicense(Context context, Item item) + throws AuthorizeException, SQLException + { + try + { + AuthorizeManager.authorizeAction(context, item, Constants.ADD); + AuthorizeManager.authorizeAction(context, item, Constants.REMOVE); + } + catch (AuthorizeException authex) + { + if (AuthorizeConfiguration.canItemAdminManageCCLicense()) + { + AuthorizeManager + .authorizeAction(context, item, Constants.ADMIN); + } + else if (AuthorizeConfiguration.canCollectionAdminManageCCLicense()) + { + AuthorizeManager.authorizeAction(context, item + .getParentObject(), Constants.ADMIN); + } + else if (AuthorizeConfiguration.canCommunityAdminManageCCLicense()) + { + AuthorizeManager.authorizeAction(context, item + .getParentObject().getParentObject(), Constants.ADMIN); + } + else + { + requireAdminRole(context); + } + } + } + + public static void authorizeManageTemplateItem(Context context, + Collection collection) throws AuthorizeException, SQLException + { + boolean isAuthorized = collection.canEditBoolean(false); + + if (!isAuthorized + && AuthorizeConfiguration + .canCollectionAdminManageTemplateItem()) + { + AuthorizeManager.authorizeAction(context, collection, + Constants.ADMIN); + } + else if (!isAuthorized + && AuthorizeConfiguration + .canCommunityAdminManageCollectionTemplateItem()) + { + Community[] communities = collection.getCommunities(); + Community parent = communities != null && communities.length > 0 ? communities[0] + : null; + AuthorizeManager.authorizeAction(context, parent, Constants.ADMIN); + } + else if (!AuthorizeManager.isAdmin(context)) + { + throw new AuthorizeException( + "You are not authorized to create a template item for the collection"); + } + } + + public static void authorizeManageSubmittersGroup(Context context, + Collection collection) throws AuthorizeException, SQLException + { + if (AuthorizeConfiguration.canCollectionAdminManageSubmitters()) + { + AuthorizeManager.authorizeAction(context, collection, + Constants.ADMIN); + } + else if (AuthorizeConfiguration + .canCommunityAdminManageCollectionSubmitters()) + { + AuthorizeManager.authorizeAction(context, collection + .getCommunities()[0], Constants.ADMIN); + } + else if (!AuthorizeManager.isAdmin(context)) + { + throw new AuthorizeException( + "Only system admin are allowed to manage collection submitters"); + } + } + + public static void authorizeManageWorkflowsGroup(Context context, + Collection collection) throws AuthorizeException, SQLException + { + if (AuthorizeConfiguration.canCollectionAdminManageWorkflows()) + { + AuthorizeManager.authorizeAction(context, collection, + Constants.ADMIN); + } + else if (AuthorizeConfiguration + .canCommunityAdminManageCollectionWorkflows()) + { + AuthorizeManager.authorizeAction(context, collection + .getCommunities()[0], Constants.ADMIN); + } + else if (!AuthorizeManager.isAdmin(context)) + { + throw new AuthorizeException( + "Only system admin are allowed to manage collection workflow"); + } + } + + public static void authorizeManageAdminGroup(Context context, + Collection collection) throws AuthorizeException, SQLException + { + if (AuthorizeConfiguration.canCollectionAdminManageAdminGroup()) + { + AuthorizeManager.authorizeAction(context, collection, + Constants.ADMIN); + } + else if (AuthorizeConfiguration + .canCommunityAdminManageCollectionAdminGroup()) + { + AuthorizeManager.authorizeAction(context, collection + .getCommunities()[0], Constants.ADMIN); + } + else if (!AuthorizeManager.isAdmin(context)) + { + throw new AuthorizeException( + "Only system admin are allowed to manage collection admin"); + } + } + + public static void authorizeRemoveAdminGroup(Context context, + Collection collection) throws AuthorizeException, SQLException + { + Community[] parentCommunities = collection.getCommunities(); + if (AuthorizeConfiguration + .canCommunityAdminManageCollectionAdminGroup() + && parentCommunities != null && parentCommunities.length > 0) + { + AuthorizeManager.authorizeAction(context, collection + .getCommunities()[0], Constants.ADMIN); + } + else if (!AuthorizeManager.isAdmin(context)) + { + throw new AuthorizeException( + "Only system admin can remove the admin group of a collection"); + } + } + + public static void authorizeManageAdminGroup(Context context, + Community community) throws AuthorizeException, SQLException + { + if (AuthorizeConfiguration.canCommunityAdminManageAdminGroup()) + { + AuthorizeManager.authorizeAction(context, community, + Constants.ADMIN); + } + else if (!AuthorizeManager.isAdmin(context)) + { + throw new AuthorizeException( + "Only system admin are allowed to manage community admin"); + } + } + + public static void authorizeRemoveAdminGroup(Context context, + Community community) throws SQLException, AuthorizeException + { + Community parentCommunity = community.getParentCommunity(); + if (AuthorizeConfiguration.canCommunityAdminManageAdminGroup() + && parentCommunity != null) + { + AuthorizeManager.authorizeAction(context, parentCommunity, + Constants.ADMIN); + } + else if (!AuthorizeManager.isAdmin(context)) + { + throw new AuthorizeException( + "Only system admin can remove the admin group of the community"); + } + } + + public static void authorizeManagePolicy(Context c, ResourcePolicy rp) + throws SQLException, AuthorizeException + { + switch (rp.getResourceType()) + { + case Constants.BITSTREAM: + authorizeManageBitstreamPolicy(c, Bitstream.find(c, rp + .getResourceID())); + break; + case Constants.BUNDLE: + authorizeManageBundlePolicy(c, Bundle.find(c, rp.getResourceID())); + break; + + case Constants.ITEM: + authorizeManageItemPolicy(c, Item.find(c, rp.getResourceID())); + break; + case Constants.COLLECTION: + authorizeManageCollectionPolicy(c, Collection.find(c, rp + .getResourceID())); + break; + case Constants.COMMUNITY: + authorizeManageCommunityPolicy(c, Community.find(c, rp + .getResourceID())); + break; + + default: + requireAdminRole(c); + break; + } + } + + public static void authorizeWithdrawItem(Context context, Item item) + throws SQLException, AuthorizeException + { + boolean authorized = false; + if (AuthorizeConfiguration.canCollectionAdminPerformItemWithdrawn()) + { + authorized = AuthorizeManager.authorizeActionBoolean(context, item + .getOwningCollection(), Constants.ADMIN); + } + else if (AuthorizeConfiguration.canCommunityAdminPerformItemWithdrawn()) + { + authorized = AuthorizeManager + .authorizeActionBoolean(context, item.getOwningCollection() + .getCommunities()[0], Constants.ADMIN); + } + + if (!authorized) + { + authorized = AuthorizeManager.authorizeActionBoolean(context, item + .getOwningCollection(), Constants.REMOVE, false); + } + + // authorized + if (!authorized) + { + throw new AuthorizeException( + "To withdraw item must be COLLECTION_ADMIN or have REMOVE authorization on owning Collection"); + } + } + + public static void authorizeReinstateItem(Context context, Item item) + throws SQLException, AuthorizeException + { + Collection[] colls = item.getCollections(); + + for (int i = 0; i < colls.length; i++) + { + if (!AuthorizeConfiguration + .canCollectionAdminPerformItemReinstatiate()) + { + if (AuthorizeConfiguration + .canCommunityAdminPerformItemReinstatiate() + && AuthorizeManager.authorizeActionBoolean(context, + colls[i].getCommunities()[0], Constants.ADMIN)) + { + // authorized + } + else + { + AuthorizeManager.authorizeAction(context, colls[i], + Constants.ADD, false); + } + } + else + { + AuthorizeManager.authorizeAction(context, colls[i], + Constants.ADD); + } + } + } +} diff --git a/dspace-api/src/main/java/org/dspace/authorize/AuthorizeConfiguration.java b/dspace-api/src/main/java/org/dspace/authorize/AuthorizeConfiguration.java new file mode 100644 index 0000000000..1eba116561 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/authorize/AuthorizeConfiguration.java @@ -0,0 +1,556 @@ +/* + * AuthorizeConfiguration.java + * + * Version: $Revision: 3980 $ + * + * Date: $Date: 2009-06-26 19:07:25 +0200 (ven, 26 giu 2009) $ + * + * Copyright (c) 2002-2009, The DSpace Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the DSpace Foundation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ +package org.dspace.authorize; + +import org.dspace.core.ConfigurationManager; + +/** + * This class is responsible to provide access to the configuration of the + * Authorization System + * + * @author bollini + * + */ +public class AuthorizeConfiguration +{ + + private static boolean can_communityAdmin_group = ConfigurationManager + .getBooleanProperty("core.authorization.community-admin.group", + true); + + // subcommunities and collections + private static boolean can_communityAdmin_createSubelement = ConfigurationManager + .getBooleanProperty( + "core.authorization.community-admin.create-subelement", + true); + + private static boolean can_communityAdmin_deleteSubelement = ConfigurationManager + .getBooleanProperty( + "core.authorization.community-admin.delete-subelement", + true); + + private static boolean can_communityAdmin_policies = ConfigurationManager + .getBooleanProperty("core.authorization.community-admin.policies", + true); + + private static boolean can_communityAdmin_adminGroup = ConfigurationManager + .getBooleanProperty( + "core.authorization.community-admin.admin-group", true); + + private static boolean can_communityAdmin_collectionPolicies = ConfigurationManager + .getBooleanProperty( + "core.authorization.community-admin.collection.policies", + true); + + private static boolean can_communityAdmin_collectionTemplateItem = ConfigurationManager + .getBooleanProperty( + "core.authorization.community-admin.collection.template-item", + true); + + private static boolean can_communityAdmin_collectionSubmitters = ConfigurationManager + .getBooleanProperty( + "core.authorization.community-admin.collection.submitters", + true); + + private static boolean can_communityAdmin_collectionWorkflows = ConfigurationManager + .getBooleanProperty( + "core.authorization.community-admin.collection.workflows", + true); + + private static boolean can_communityAdmin_collectionAdminGroup = ConfigurationManager + .getBooleanProperty( + "core.authorization.community-admin.collection.admin-group", + true); + + private static boolean can_communityAdmin_itemDelete = ConfigurationManager + .getBooleanProperty( + "core.authorization.community-admin.item.delete", true); + + private static boolean can_communityAdmin_itemWithdraw = ConfigurationManager + .getBooleanProperty( + "core.authorization.community-admin.item.withdraw", true); + + private static boolean can_communityAdmin_itemReinstatiate = ConfigurationManager + .getBooleanProperty( + "core.authorization.community-admin.item.reinstatiate", + true); + + private static boolean can_communityAdmin_itemPolicies = ConfigurationManager + .getBooleanProperty( + "core.authorization.community-admin.item.policies", true); + + // # also bundle + private static boolean can_communityAdmin_itemCreateBitstream = ConfigurationManager + .getBooleanProperty( + "core.authorization.community-admin.item.create-bitstream", + true); + + private static boolean can_communityAdmin_itemDeleteBitstream = ConfigurationManager + .getBooleanProperty( + "core.authorization.community-admin.item.delete-bitstream", + true); + + private static boolean can_communityAdmin_itemAdminccLicense = ConfigurationManager + .getBooleanProperty( + "core.authorization.community-admin.item-admin.cc-license", + true); + + // # COLLECTION ADMIN + private static boolean can_collectionAdmin_policies = ConfigurationManager + .getBooleanProperty("core.authorization.collection-admin.policies", + true); + + private static boolean can_collectionAdmin_templateItem = ConfigurationManager + .getBooleanProperty( + "core.authorization.collection-admin.template-item", true); + + private static boolean can_collectionAdmin_submitters = ConfigurationManager + .getBooleanProperty( + "core.authorization.collection-admin.submitters", true); + + private static boolean can_collectionAdmin_workflows = ConfigurationManager + .getBooleanProperty( + "core.authorization.collection-admin.workflows", true); + + private static boolean can_collectionAdmin_adminGroup = ConfigurationManager + .getBooleanProperty( + "core.authorization.collection-admin.admin-group", true); + + private static boolean can_collectionAdmin_itemDelete = ConfigurationManager + .getBooleanProperty( + "core.authorization.collection-admin.item.delete", true); + + private static boolean can_collectionAdmin_itemWithdraw = ConfigurationManager + .getBooleanProperty( + "core.authorization.collection-admin.item.withdraw", true); + + private static boolean can_collectionAdmin_itemReinstatiate = ConfigurationManager + .getBooleanProperty( + "core.authorization.collection-admin.item.reinstatiate", + true); + + private static boolean can_collectionAdmin_itemPolicies = ConfigurationManager + .getBooleanProperty( + "core.authorization.collection-admin.item.policies", true); + + // # also bundle + private static boolean can_collectionAdmin_itemCreateBitstream = ConfigurationManager + .getBooleanProperty( + "core.authorization.collection-admin.item.create-bitstream", + true); + + private static boolean can_collectionAdmin_itemDeleteBitstream = ConfigurationManager + .getBooleanProperty( + "core.authorization.collection-admin.item.delete-bitstream", + true); + + private static boolean can_collectionAdmin_itemAdminccLicense = ConfigurationManager + .getBooleanProperty( + "core.authorization.collection-admin.item-admin.cc-license", + true); + + // # ITEM ADMIN + private static boolean can_itemAdmin_policies = ConfigurationManager + .getBooleanProperty("core.authorization.item-admin.policies", true); + + // # also bundle + private static boolean can_itemAdmin_createBitstream = ConfigurationManager + .getBooleanProperty( + "core.authorization.item-admin.create-bitstream", true); + + private static boolean can_itemAdmin_deleteBitstream = ConfigurationManager + .getBooleanProperty( + "core.authorization.item-admin.delete-bitstream", true); + + private static boolean can_itemAdmin_ccLicense = ConfigurationManager + .getBooleanProperty("core.authorization.item-admin.cc-license", + true); + + /** + * Are community admins allowed to create new, not strictly community + * related, group? + * + * @return + */ + public static boolean canCommunityAdminPerformGroupCreation() + { + return can_communityAdmin_group; + } + + /** + * Are community admins allowed to create collections or subcommunities? + * + * @return + */ + public static boolean canCommunityAdminPerformSubelementCreation() + { + return can_communityAdmin_createSubelement; + } + + /** + * Are community admins allowed to remove collections or subcommunities? + * + * @return + */ + public static boolean canCommunityAdminPerformSubelementDeletion() + { + return can_communityAdmin_deleteSubelement; + } + + /** + * Are community admins allowed to manage the community's and + * subcommunities' policies? + * + * @return + */ + public static boolean canCommunityAdminManagePolicies() + { + return can_communityAdmin_policies; + } + + /** + * Are community admins allowed to create/edit them community's and + * subcommunities' admin groups? + * + * @return + */ + public static boolean canCommunityAdminManageAdminGroup() + { + return can_communityAdmin_adminGroup; + } + + /** + * Are community admins allowed to create/edit the community's and + * subcommunities' admin group? + * + * @return + */ + public static boolean canCommunityAdminManageCollectionPolicies() + { + return can_communityAdmin_collectionPolicies; + } + + /** + * Are community admins allowed to manage the item template of them + * collections? + * + * @return + */ + public static boolean canCommunityAdminManageCollectionTemplateItem() + { + return can_communityAdmin_collectionTemplateItem; + } + + /** + * Are community admins allowed to manage (create/edit/remove) the + * submitters group of them collections? + * + * @return + */ + public static boolean canCommunityAdminManageCollectionSubmitters() + { + return can_communityAdmin_collectionSubmitters; + } + + /** + * Are community admins allowed to manage (create/edit/remove) the workflows + * group of them collections? + * + * @return + */ + public static boolean canCommunityAdminManageCollectionWorkflows() + { + return can_communityAdmin_collectionWorkflows; + } + + /** + * Are community admins allowed to manage (create/edit/remove) the admin + * group of them collections? + * + * @return + */ + public static boolean canCommunityAdminManageCollectionAdminGroup() + { + return can_communityAdmin_collectionAdminGroup; + } + + /** + * Are community admins allowed to remove an item from them collections? + * + * @return + */ + public static boolean canCommunityAdminPerformItemDeletion() + { + return can_communityAdmin_itemDelete; + } + + /** + * Are community admins allowed to withdrawn an item from them collections? + * + * @return + */ + public static boolean canCommunityAdminPerformItemWithdrawn() + { + return can_communityAdmin_itemWithdraw; + } + + /** + * Are community admins allowed to reinstatiate an item from them + * collections? + * + * @return + */ + public static boolean canCommunityAdminPerformItemReinstatiate() + { + return can_communityAdmin_itemReinstatiate; + } + + /** + * Are community admins allowed to manage the policies of an item owned by + * one of them collections? + * + * @return + */ + public static boolean canCommunityAdminManageItemPolicies() + { + return can_communityAdmin_itemPolicies; + } + + /** + * Are community admins allowed to add a bitstream to an item owned by one + * of them collections? + * + * @return + */ + public static boolean canCommunityAdminPerformBitstreamCreation() + { + return can_communityAdmin_itemCreateBitstream; + } + + /** + * Are community admins allowed to remove a bitstream from an item owned by + * one of them collections? + * + * @return + */ + public static boolean canCommunityAdminPerformBitstreamDeletion() + { + return can_communityAdmin_itemDeleteBitstream; + } + + /** + * Are community admins allowed to perform CC License replace or addition to + * an item owned by one of them collections? + * + * @return + */ + public static boolean canCommunityAdminManageCCLicense() + { + return can_communityAdmin_itemAdminccLicense; + } + + /** + * Are collection admins allowed to manage the collection's policies? + * + * @return + */ + public static boolean canCollectionAdminManagePolicies() + { + return can_collectionAdmin_policies; + } + + /** + * Are collection admins allowed to manage (create/edit/delete) the + * collection's item template? + * + * @return + */ + public static boolean canCollectionAdminManageTemplateItem() + { + return can_collectionAdmin_templateItem; + } + + /** + * Are collection admins allowed to manage (create/edit/delete) the + * collection's submitters group? + * + * @return + */ + public static boolean canCollectionAdminManageSubmitters() + { + return can_collectionAdmin_submitters; + } + + /** + * Are collection admins allowed to manage (create/edit/delete) the + * collection's workflows group? + * + * @return + */ + public static boolean canCollectionAdminManageWorkflows() + { + return can_collectionAdmin_workflows; + } + + /** + * Are collection admins allowed to manage (create/edit) the collection's + * admins group? + * + * @return + */ + public static boolean canCollectionAdminManageAdminGroup() + { + return can_collectionAdmin_adminGroup; + } + + /** + * Are collection admins allowed to remove an item from the collection? + * + * @return + */ + public static boolean canCollectionAdminPerformItemDeletion() + { + return can_collectionAdmin_itemDelete; + } + + /** + * Are collection admins allowed to withdrawn an item from the collection? + * + * @return + */ + public static boolean canCollectionAdminPerformItemWithdrawn() + { + return can_collectionAdmin_itemWithdraw; + } + + /** + * Are collection admins allowed to reinstatiate an item from the + * collection? + * + * @return + */ + public static boolean canCollectionAdminPerformItemReinstatiate() + { + return can_collectionAdmin_itemReinstatiate; + } + + /** + * Are collection admins allowed to manage the policies of item owned by the + * collection? + * + * @return + */ + public static boolean canCollectionAdminManageItemPolicies() + { + return can_collectionAdmin_itemPolicies; + } + + /** + * Are collection admins allowed to add a bitstream to an item owned by the + * collections? + * + * @return + */ + public static boolean canCollectionAdminPerformBitstreamCreation() + { + return can_collectionAdmin_itemCreateBitstream; + } + + /** + * Are collection admins allowed to remove a bitstream from an item owned by + * the collections? + * + * @return + */ + public static boolean canCollectionAdminPerformBitstreamDeletion() + { + return can_collectionAdmin_itemDeleteBitstream; + } + + /** + * Are collection admins allowed to replace or adding a CC License to an + * item owned by the collections? + * + * @return + */ + public static boolean canCollectionAdminManageCCLicense() + { + return can_collectionAdmin_itemAdminccLicense; + } + + /** + * Are item admins allowed to manage the item's policies? + * + * @return + */ + public static boolean canItemAdminManagePolicies() + { + return can_itemAdmin_policies; + } + + /** + * Are item admins allowed to add bitstreams to the item? + * + * @return + */ + public static boolean canItemAdminPerformBitstreamCreation() + { + return can_itemAdmin_createBitstream; + } + + /** + * Are item admins allowed to remove bitstreams from the item? + * + * @return + */ + public static boolean canItemAdminPerformBitstreamDeletion() + { + return can_itemAdmin_deleteBitstream; + } + + /** + * Are item admins allowed to replace or adding CC License to the item? + * + * @return + */ + public static boolean canItemAdminManageCCLicense() + { + return can_itemAdmin_ccLicense; + } + +} diff --git a/dspace-api/src/main/java/org/dspace/authorize/AuthorizeManager.java b/dspace-api/src/main/java/org/dspace/authorize/AuthorizeManager.java index d641e0316f..c7504146be 100644 --- a/dspace-api/src/main/java/org/dspace/authorize/AuthorizeManager.java +++ b/dspace-api/src/main/java/org/dspace/authorize/AuthorizeManager.java @@ -132,6 +132,30 @@ public class AuthorizeManager */ public static void authorizeAction(Context c, DSpaceObject o, int action) throws AuthorizeException, SQLException + { + authorizeAction(c, o, action, true); + } + + /** + * Checks that the context's current user can perform the given action on + * the given object. Throws an exception if the user is not authorized, + * otherwise the method call does nothing. + * + * @param c + * context + * @param o + * a DSpaceObject + * @param useInheritance + * flag to say if ADMIN action on the current object or parent + * object can be used + * @param action + * action to perform from org.dspace.core.Constants + * + * @throws AuthorizeException + * if the user is denied + */ + public static void authorizeAction(Context c, DSpaceObject o, int action, boolean useInheritance) + throws AuthorizeException, SQLException { if (o == null) { @@ -164,7 +188,7 @@ public class AuthorizeManager + actionText + " by user " + userid); } - if (!authorize(c, o, action, c.getCurrentUser())) + if (!authorize(c, o, action, c.getCurrentUser(), useInheritance)) { // denied, assemble and throw exception int otype = o.getType(); @@ -218,6 +242,30 @@ public class AuthorizeManager */ public static boolean authorizeActionBoolean(Context c, DSpaceObject o, int a) throws SQLException + { + return authorizeActionBoolean(c, o, a, true); + } + + /** + * same authorize, returns boolean for those who don't want to deal with + * catching exceptions. + * + * @param c + * DSpace context, containing current user + * @param o + * DSpaceObject + * @param a + * action being attempted, from + * org.dspace.core.Constants + * @param useInheritance + * flag to say if ADMIN action on the current object or parent + * object can be used + * + * @return true if the current user in the context is + * authorized to perform the given action on the given object + */ + public static boolean authorizeActionBoolean(Context c, DSpaceObject o, + int a, boolean useInheritance) throws SQLException { boolean isAuthorized = true; @@ -228,7 +276,7 @@ public class AuthorizeManager try { - authorizeAction(c, o, a); + authorizeAction(c, o, a, useInheritance); } catch (AuthorizeException e) { @@ -253,12 +301,15 @@ public class AuthorizeManager * org.dspace.core.Constants * @param e * user attempting action + * @param useInheritance + * flag to say if ADMIN action on the current object or parent + * object can be used * @return true if user is authorized to perform the given * action, false otherwise * @throws SQLException */ private static boolean authorize(Context c, DSpaceObject o, int action, - EPerson e) throws SQLException + EPerson e, boolean useInheritance) throws SQLException { int userid; @@ -285,7 +336,9 @@ public class AuthorizeManager // perform isAdmin check to see // if user is an Admin on this object - if (isAdmin(c,o)) + DSpaceObject testObject = useInheritance?o.getAdminObject(action):null; + + if (isAdmin(c, testObject)) { return true; } @@ -319,25 +372,31 @@ public class AuthorizeManager // admin check methods /////////////////////////////////////////////// - - /** - * Check to see if the current user is an Administrator of a given - * object within DSpace. Always return true if the - * user is a System Admin - * + /** + * Check to see if the current user is an Administrator of a given object + * within DSpace. Always return true if the user is a System + * Admin + * * @param c * current context * @param o - * current DSpace Object - * - * @return true if user has administrative privileges - * on the given DSpace object + * current DSpace Object, if null the call will be + * equivalent to a call to the isAdmin(Context c) + * method + * + * @return true if user has administrative privileges on the + * given DSpace object */ public static boolean isAdmin(Context c, DSpaceObject o) throws SQLException { if (isAdmin(c)) { return true; } + + if (o == null) + { + return false; + } // // First, check all Resource Policies directly on this object @@ -365,152 +424,15 @@ public class AuthorizeManager } } - // // If user doesn't have specific Admin permissions on this object, // check the *parent* objects of this object. This allows Admin // permissions to be inherited automatically (e.g. Admin on Community // is also an Admin of all Collections/Items in that Community) - switch (o.getType()) { - case Constants.BITSTREAM: - { - Bitstream bitstream = (Bitstream) o; - Bundle[] bundles = bitstream.getBundles(); - if (bundles != null && (bundles.length > 0 && bundles[0] != null)) - { - return isAdmin(c,bundles[0]); - } - else - { - // is the bitstream a logo for a community or a collection? - TableRow qResult = DatabaseManager.querySingle(c, - "SELECT collection_id FROM collection " + - "WHERE logo_bitstream_id = ?",o.getID()); - if (qResult != null) - { - Collection collection = Collection.find(c,qResult.getIntColumn("collection_id")); - return isAdmin(c,collection); - } - else - { - // is the group releated to a community? - qResult = DatabaseManager.querySingle(c, - "SELECT community_id FROM community " + - "WHERE logo_bitstream_id = ?",o.getID()); - - if (qResult != null) - { - Community community = Community.find(c,qResult.getIntColumn("community_id")); - return isAdmin(c,community); - } - else - { - return false; - } - } - } - } - - case Constants.BUNDLE: - { - Bundle bundle = (Bundle) o; - Item[] items = bundle.getItems(); - - if (items != null && (items.length > 0 && items[0] != null)) - { - return isAdmin(c,items[0]); - } - else - { - return false; - } - } - - case Constants.ITEM: - { - Item item = (Item) o; - Collection ownCollection = item.getOwningCollection(); - if (ownCollection != null) - { - return isAdmin(c,ownCollection); - } - else - { - // is a template item? - TableRow qResult = DatabaseManager.querySingle(c, - "SELECT collection_id FROM collection " + - "WHERE template_item_id = ?",o.getID()); - if (qResult != null) - { - Collection collection = Collection.find(c,qResult.getIntColumn("collection_id")); - return isAdmin(c,collection); - } - return false; - } - } - - case Constants.COLLECTION: - { - Collection collection = (Collection) o; - Community[] communities = collection.getCommunities(); - if (communities != null && (communities.length > 0 && communities[0] != null)) - { - return isAdmin(c,communities[0]); - } - else - { - return false; - } - } - - case Constants.COMMUNITY: - { - Community community = (Community) o; - Community pCommunity = community.getParentCommunity(); - if (pCommunity != null) - { - return isAdmin(c,pCommunity); - } - else - { - return false; - } - } - - case Constants.GROUP: - { - // is the group releated to a collection? - TableRow qResult = DatabaseManager.querySingle(c, - "SELECT collection_id FROM collection " + - "WHERE workflow_step_1 = ? OR " + - " workflow_step_2 = ? OR " + - " workflow_step_3 = ? OR " + - " submitter = ? OR " + - " admin = ?",o.getID(),o.getID(),o.getID(),o.getID(),o.getID()); - if (qResult != null) - { - Collection collection = Collection.find(c,qResult.getIntColumn("collection_id")); - return isAdmin(c,collection); - } - else - { // is the group releated to a community? - qResult = DatabaseManager.querySingle(c, - "SELECT community_id FROM community " + - "WHERE admin = ?",o.getID()); - - if (qResult != null) - { - Community community = Community.find(c,qResult.getIntColumn("community_id")); - return isAdmin(c,community); - } - else - { - return false; - } - } - - } - } - + DSpaceObject parent = o.getParentObject(); + if (parent != null) + { + return isAdmin(c, parent); + } return false; } diff --git a/dspace-api/src/main/java/org/dspace/content/Bitstream.java b/dspace-api/src/main/java/org/dspace/content/Bitstream.java index f9a2e9960a..84f45ceacc 100644 --- a/dspace-api/src/main/java/org/dspace/content/Bitstream.java +++ b/dspace-api/src/main/java/org/dspace/content/Bitstream.java @@ -640,4 +640,51 @@ public class Bitstream extends DSpaceObject public int getStoreNumber() { return bRow.getIntColumn("store_number"); } + + public DSpaceObject getParentObject() throws SQLException + { + Bundle[] bundles = getBundles(); + if (bundles != null && (bundles.length > 0 && bundles[0] != null)) + { + // the ADMIN action is not allowed on Bundle object so skip to the item + Item[] items = bundles[0].getItems(); + if (items != null && items.length > 0) + { + return items[0]; + } + else + { + return null; + } + } + else + { + // is the bitstream a logo for a community or a collection? + TableRow qResult = DatabaseManager.querySingle(bContext, + "SELECT collection_id FROM collection " + + "WHERE logo_bitstream_id = ?",getID()); + if (qResult != null) + { + Collection collection = Collection.find(bContext,qResult.getIntColumn("collection_id")); + return collection; + } + else + { + // is the bitstream related to a community? + qResult = DatabaseManager.querySingle(bContext, + "SELECT community_id FROM community " + + "WHERE logo_bitstream_id = ?",getID()); + + if (qResult != null) + { + Community community = Community.find(bContext,qResult.getIntColumn("community_id")); + return community; + } + else + { + return null; + } + } + } + } } diff --git a/dspace-api/src/main/java/org/dspace/content/Bundle.java b/dspace-api/src/main/java/org/dspace/content/Bundle.java index 5153975dda..590a194a2d 100644 --- a/dspace-api/src/main/java/org/dspace/content/Bundle.java +++ b/dspace-api/src/main/java/org/dspace/content/Bundle.java @@ -46,6 +46,7 @@ import java.util.List; import java.util.ListIterator; import org.apache.log4j.Logger; +import org.dspace.authorize.AuthorizeConfiguration; import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeManager; import org.dspace.authorize.ResourcePolicy; @@ -657,4 +658,79 @@ public class Bundle extends DSpaceObject AuthorizeManager.removeAllPolicies(ourContext, this); AuthorizeManager.addPolicies(ourContext, newpolicies, this); } + + public DSpaceObject getAdminObject(int action) throws SQLException + { + DSpaceObject adminObject = null; + Item[] items = getItems(); + Item item = null; + Collection collection = null; + Community community = null; + if (items != null && items.length > 0) + { + item = items[0]; + collection = item.getOwningCollection(); + if (collection != null) + { + Community[] communities = collection.getCommunities(); + if (communities != null && communities.length > 0) + { + community = communities[0]; + } + } + } + switch (action) + { + case Constants.REMOVE: + if (AuthorizeConfiguration.canItemAdminPerformBitstreamDeletion()) + { + adminObject = item; + } + else if (AuthorizeConfiguration.canCollectionAdminPerformBitstreamDeletion()) + { + adminObject = collection; + } + else if (AuthorizeConfiguration + .canCommunityAdminPerformBitstreamDeletion()) + { + adminObject = community; + } + break; + case Constants.ADD: + if (AuthorizeConfiguration.canItemAdminPerformBitstreamCreation()) + { + adminObject = item; + } + else if (AuthorizeConfiguration + .canCollectionAdminPerformBitstreamCreation()) + { + adminObject = collection; + } + else if (AuthorizeConfiguration + .canCommunityAdminPerformBitstreamCreation()) + { + adminObject = community; + } + break; + + default: + adminObject = this; + break; + } + return adminObject; + } + + public DSpaceObject getParentObject() throws SQLException + { + Item[] items = getItems(); + + if (items != null && (items.length > 0 && items[0] != null)) + { + return items[0]; + } + else + { + return null; + } + } } diff --git a/dspace-api/src/main/java/org/dspace/content/Collection.java b/dspace-api/src/main/java/org/dspace/content/Collection.java index 25845a5dad..28d56ef551 100644 --- a/dspace-api/src/main/java/org/dspace/content/Collection.java +++ b/dspace-api/src/main/java/org/dspace/content/Collection.java @@ -47,6 +47,8 @@ import java.util.List; import java.util.MissingResourceException; import org.apache.log4j.Logger; +import org.dspace.app.util.AuthorizeUtil; +import org.dspace.authorize.AuthorizeConfiguration; import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeManager; import org.dspace.authorize.ResourcePolicy; @@ -486,7 +488,7 @@ public class Collection extends DSpaceObject if (!((is == null) && AuthorizeManager.authorizeActionBoolean( ourContext, this, Constants.DELETE))) { - canEdit(); + canEdit(true); } // First, delete any existing logo @@ -541,8 +543,8 @@ public class Collection extends DSpaceObject public Group createWorkflowGroup(int step) throws SQLException, AuthorizeException { - // Check authorisation - Must be an Admin to create Submitters Group - AuthorizeManager.authorizeAction(ourContext, this, Constants.ADMIN); + // Check authorisation - Must be an Admin to create Workflow Group + AuthorizeUtil.authorizeManageWorkflowsGroup(ourContext, this); if (workflowGroup[step - 1] == null) { @@ -614,7 +616,7 @@ public class Collection extends DSpaceObject public Group createSubmitters() throws SQLException, AuthorizeException { // Check authorisation - Must be an Admin to create Submitters Group - AuthorizeManager.authorizeAction(ourContext, this, Constants.ADMIN); + AuthorizeUtil.authorizeManageSubmittersGroup(ourContext, this); if (submitters == null) { @@ -645,7 +647,7 @@ public class Collection extends DSpaceObject public void removeSubmitters() throws SQLException, AuthorizeException { // Check authorisation - Must be an Admin to delete Submitters Group - AuthorizeManager.authorizeAction(ourContext, this, Constants.ADMIN); + AuthorizeUtil.authorizeManageSubmittersGroup(ourContext, this); // just return if there is no administrative group. if (submitters == null) @@ -687,7 +689,7 @@ public class Collection extends DSpaceObject public Group createAdministrators() throws SQLException, AuthorizeException { // Check authorisation - Must be an Admin to create more Admins - AuthorizeManager.authorizeAction(ourContext, this, Constants.ADMIN); + AuthorizeUtil.authorizeManageAdminGroup(ourContext, this); if (admins == null) { @@ -706,13 +708,6 @@ public class Collection extends DSpaceObject // register this as the admin group collectionRow.setColumn("admin", admins.getID()); - // administrators also get ADD on the submitter group - if (submitters != null) - { - AuthorizeManager.addPolicy(ourContext, submitters, Constants.ADD, - admins); - } - modified = true; return admins; } @@ -726,19 +721,7 @@ public class Collection extends DSpaceObject public void removeAdministrators() throws SQLException, AuthorizeException { // Check authorisation - Must be an Admin of the parent community to delete Admin Group - Community[] parentCommunities = getCommunities(); - if (parentCommunities != null && parentCommunities.length > 0) - { - AuthorizeManager.authorizeAction(ourContext, this.getCommunities()[0], Constants.ADMIN); - } - else if (!AuthorizeManager.isAdmin(ourContext)) - { - // this should never happen, a collection should always have at least one parent community! - // anyway... - throw new AuthorizeException( - "Only system admin can remove the admin group of a collection outside any community", - this, Constants.ADMIN); - } + AuthorizeUtil.authorizeRemoveAdminGroup(ourContext, this); // just return if there is no administrative group. if (admins == null) @@ -847,7 +830,7 @@ public class Collection extends DSpaceObject public void createTemplateItem() throws SQLException, AuthorizeException { // Check authorisation - canEdit(); + AuthorizeUtil.authorizeManageTemplateItem(ourContext, this); if (template == null) { @@ -876,7 +859,7 @@ public class Collection extends DSpaceObject IOException { // Check authorisation - canEdit(); + AuthorizeUtil.authorizeManageTemplateItem(ourContext, this); collectionRow.setColumnNull("template_item_id"); DatabaseManager.update(ourContext, collectionRow); @@ -938,46 +921,27 @@ public class Collection extends DSpaceObject // Check authorisation AuthorizeManager.authorizeAction(ourContext, this, Constants.REMOVE); + // will be the item an orphan? + TableRow row = DatabaseManager.querySingle(ourContext, + "SELECT COUNT(DISTINCT collection_id) AS num FROM collection2item WHERE item_id= ? ", + item.getID()); + + DatabaseManager.setConstraintDeferred(ourContext, "coll2item_item_fk"); + if (row.getLongColumn("num") == 1) + { + // Orphan; delete it + item.delete(); + } log.info(LogManager.getHeader(ourContext, "remove_item", "collection_id=" + getID() + ",item_id=" + item.getID())); - + DatabaseManager.updateQuery(ourContext, "DELETE FROM collection2item WHERE collection_id= ? "+ "AND item_id= ? ", getID(), item.getID()); - + DatabaseManager.setConstraintImmediate(ourContext, "coll2item_item_fk"); + ourContext.addEvent(new Event(Event.REMOVE, Constants.COLLECTION, getID(), Constants.ITEM, item.getID(), item.getHandle())); - - // Is the item an orphan? - TableRowIterator tri = DatabaseManager.query(ourContext, - "SELECT * FROM collection2item WHERE item_id= ? ", - item.getID()); - - try - { - if (!tri.hasNext()) - { - //make the right to remove the item explicit because the implicit - // relation - //has been removed. This only has to concern the currentUser - // because - //he started the removal process and he will end it too. - //also add right to remove from the item to remove it's bundles. - AuthorizeManager.addPolicy(ourContext, item, Constants.DELETE, - ourContext.getCurrentUser()); - AuthorizeManager.addPolicy(ourContext, item, Constants.REMOVE, - ourContext.getCurrentUser()); - - // Orphan; delete it - item.delete(); - } - } - finally - { - // close the TableRowIterator to free up resources - if (tri != null) - tri.close(); - } } /** @@ -991,7 +955,7 @@ public class Collection extends DSpaceObject public void update() throws SQLException, IOException, AuthorizeException { // Check authorisation - canEdit(); + canEdit(true); log.info(LogManager.getHeader(ourContext, "update_collection", "collection_id=" + getID())); @@ -1010,12 +974,17 @@ public class Collection extends DSpaceObject clearDetails(); } } - + public boolean canEditBoolean() throws java.sql.SQLException + { + return canEditBoolean(true); + } + + public boolean canEditBoolean(boolean useInheritance) throws java.sql.SQLException { try { - canEdit(); + canEdit(useInheritance); return true; } @@ -1025,27 +994,31 @@ public class Collection extends DSpaceObject } } - public void canEdit() throws AuthorizeException, SQLException + public void canEdit() throws AuthorizeException, SQLException + { + canEdit(true); + } + + public void canEdit(boolean useInheritance) throws AuthorizeException, SQLException { Community[] parents = getCommunities(); for (int i = 0; i < parents.length; i++) { if (AuthorizeManager.authorizeActionBoolean(ourContext, parents[i], - Constants.WRITE)) + Constants.WRITE, useInheritance)) { return; } if (AuthorizeManager.authorizeActionBoolean(ourContext, parents[i], - Constants.ADD)) + Constants.ADD, useInheritance)) { return; } } - AuthorizeManager.authorizeAnyOf(ourContext, this, new int[] { - Constants.WRITE, Constants.ADMIN }); + AuthorizeManager.authorizeAction(ourContext, this, Constants.WRITE, useInheritance); } /** @@ -1400,4 +1373,54 @@ public class Collection extends DSpaceObject return itemcount; } + + public DSpaceObject getAdminObject(int action) throws SQLException + { + DSpaceObject adminObject = null; + Community community = null; + Community[] communities = getCommunities(); + if (communities != null && communities.length > 0) + { + community = communities[0]; + } + + switch (action) + { + case Constants.REMOVE: + if (AuthorizeConfiguration.canCollectionAdminPerformItemDeletion()) + { + adminObject = this; + } + else if (AuthorizeConfiguration.canCommunityAdminPerformItemDeletion()) + { + adminObject = community; + } + break; + + case Constants.DELETE: + if (AuthorizeConfiguration.canCommunityAdminPerformSubelementDeletion()) + { + adminObject = community; + } + break; + default: + adminObject = this; + break; + } + return adminObject; + } + + @Override + public DSpaceObject getParentObject() throws SQLException + { + Community[] communities = this.getCommunities(); + if (communities != null && (communities.length > 0 && communities[0] != null)) + { + return communities[0]; + } + else + { + return null; + } + } } diff --git a/dspace-api/src/main/java/org/dspace/content/Community.java b/dspace-api/src/main/java/org/dspace/content/Community.java index cfef6fbad8..7469f70337 100644 --- a/dspace-api/src/main/java/org/dspace/content/Community.java +++ b/dspace-api/src/main/java/org/dspace/content/Community.java @@ -45,6 +45,8 @@ import java.util.List; import java.util.MissingResourceException; import org.apache.log4j.Logger; +import org.dspace.app.util.AuthorizeUtil; +import org.dspace.authorize.AuthorizeConfiguration; import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeManager; import org.dspace.authorize.ResourcePolicy; @@ -525,7 +527,7 @@ public class Community extends DSpaceObject public Group createAdministrators() throws SQLException, AuthorizeException { // Check authorisation - Must be an Admin to create more Admins - AuthorizeManager.authorizeAction(ourContext, this, Constants.ADMIN); + AuthorizeUtil.authorizeManageAdminGroup(ourContext, this); if (admins == null) { @@ -556,17 +558,7 @@ public class Community extends DSpaceObject public void removeAdministrators() throws SQLException, AuthorizeException { // Check authorisation - Must be an Admin of the parent community (or system admin) to delete Admin group - Community parentCommunity = getParentCommunity(); - if (parentCommunity != null) - { - AuthorizeManager.authorizeAction(ourContext, parentCommunity, Constants.ADMIN); - } - else if (!AuthorizeManager.isAdmin(ourContext)) - { - throw new AuthorizeException( - "Only system admin can remove the admin group of a top community", - this, Constants.ADMIN); - } + AuthorizeUtil.authorizeRemoveAdminGroup(ourContext, this); // just return if there is no administrative group. if (admins == null) @@ -913,45 +905,29 @@ public class Community extends DSpaceObject // Check authorisation AuthorizeManager.authorizeAction(ourContext, this, Constants.REMOVE); + // will be the collection an orphan? + TableRow trow = DatabaseManager.querySingle(ourContext, + "SELECT COUNT(DISTINCT community_id) AS num FROM community2collection WHERE collection_id= ? ", + c.getID()); + DatabaseManager.setConstraintDeferred(ourContext, "comm2coll_collection_fk"); + + if (trow.getLongColumn("num") == 1) + { + // Orphan; delete it + c.delete(); + } + log.info(LogManager.getHeader(ourContext, "remove_collection", "community_id=" + getID() + ",collection_id=" + c.getID())); - + // Remove any mappings DatabaseManager.updateQuery(ourContext, "DELETE FROM community2collection WHERE community_id= ? "+ "AND collection_id= ? ", getID(), c.getID()); + DatabaseManager.setConstraintImmediate(ourContext, "comm2coll_collection_fk"); + ourContext.addEvent(new Event(Event.REMOVE, Constants.COMMUNITY, getID(), Constants.COLLECTION, c.getID(), c.getHandle())); - - // Is the community an orphan? - TableRowIterator tri = DatabaseManager.query(ourContext, - "SELECT * FROM community2collection WHERE collection_id= ? ", - c.getID()); - - try - { - if (!tri.hasNext()) - { - //make the right to remove the collection explicit because the - // implicit relation - //has been removed. This only has to concern the currentUser - // because - //he started the removal process and he will end it too. - //also add right to remove from the collection to remove it's - // items. - AuthorizeManager.addPolicy(ourContext, c, Constants.ADMIN, - ourContext.getCurrentUser()); - - // Orphan; delete it - c.delete(); - } - } - finally - { - // close the TableRowIterator to free up resources - if (tri != null) - tri.close(); - } } /** @@ -966,47 +942,29 @@ public class Community extends DSpaceObject // Check authorisation AuthorizeManager.authorizeAction(ourContext, this, Constants.REMOVE); + // will be the subcommunity an orphan? + TableRow trow = DatabaseManager.querySingle(ourContext, + "SELECT COUNT(DISTINCT parent_comm_id) AS num FROM community2community WHERE child_comm_id= ? ", + c.getID()); + + DatabaseManager.setConstraintDeferred(ourContext, "com2com_child_fk"); + if (trow.getLongColumn("num") == 1) + { + // Orphan; delete it + c.rawDelete(); + } + log.info(LogManager.getHeader(ourContext, "remove_subcommunity", "parent_comm_id=" + getID() + ",child_comm_id=" + c.getID())); - + // Remove any mappings DatabaseManager.updateQuery(ourContext, "DELETE FROM community2community WHERE parent_comm_id= ? " + " AND child_comm_id= ? ", getID(),c.getID()); ourContext.addEvent(new Event(Event.REMOVE, Constants.COMMUNITY, getID(), Constants.COMMUNITY, c.getID(), c.getHandle())); - - // Is the subcommunity an orphan? - TableRowIterator tri = DatabaseManager.query(ourContext, - "SELECT * FROM community2community WHERE child_comm_id= ? ", - c.getID()); - - try - { - if (!tri.hasNext()) - { - //make the right to remove the sub explicit because the implicit - // relation - //has been removed. This only has to concern the currentUser - // because - //he started the removal process and he will end it too. - //also add right to remove from the subcommunity to remove it's - // children. - AuthorizeManager.addPolicy(ourContext, c, Constants.DELETE, - ourContext.getCurrentUser()); - AuthorizeManager.addPolicy(ourContext, c, Constants.REMOVE, - ourContext.getCurrentUser()); - - // Orphan; delete it - c.delete(); - } - } - finally - { - // close the TableRowIterator to free up resources - if (tri != null) - tri.close(); - } + + DatabaseManager.setConstraintImmediate(ourContext, "com2com_child_fk"); } /** @@ -1030,7 +988,7 @@ public class Community extends DSpaceObject } // If not a top-level community, have parent remove me; this - // will call delete() after removing the linkage + // will call rawDelete() before removing the linkage Community parent = getParentCommunity(); if (parent != null) @@ -1040,6 +998,14 @@ public class Community extends DSpaceObject return; } + rawDelete(); + } + + /** + * Internal method to remove the community and all its childs from the database without aware of eventually parent + */ + private void rawDelete() throws SQLException, AuthorizeException, IOException + { log.info(LogManager.getHeader(ourContext, "delete_community", "community_id=" + getID())); @@ -1073,14 +1039,14 @@ public class Community extends DSpaceObject // get rid of the content count cache if it exists try { - ItemCounter ic = new ItemCounter(ourContext); - ic.remove(this); + ItemCounter ic = new ItemCounter(ourContext); + ic.remove(this); } catch (ItemCountException e) { - // FIXME: upside down exception handling due to lack of good - // exception framework - throw new RuntimeException(e.getMessage(),e); + // FIXME: upside down exception handling due to lack of good + // exception framework + throw new RuntimeException(e.getMessage(),e); } // Delete community row @@ -1205,4 +1171,48 @@ public class Community extends DSpaceObject } return total; } + + public DSpaceObject getAdminObject(int action) throws SQLException + { + DSpaceObject adminObject = null; + switch (action) + { + case Constants.REMOVE: + if (AuthorizeConfiguration.canCommunityAdminPerformSubelementDeletion()) + { + adminObject = this; + } + break; + + case Constants.DELETE: + if (AuthorizeConfiguration.canCommunityAdminPerformSubelementDeletion()) + { + adminObject = getParentCommunity(); + } + break; + case Constants.ADD: + if (AuthorizeConfiguration.canCommunityAdminPerformSubelementCreation()) + { + adminObject = this; + } + break; + default: + adminObject = this; + break; + } + return adminObject; + } + + public DSpaceObject getParentObject() throws SQLException + { + Community pCommunity = getParentCommunity(); + if (pCommunity != null) + { + return pCommunity; + } + else + { + return null; + } + } } diff --git a/dspace-api/src/main/java/org/dspace/content/DSpaceObject.java b/dspace-api/src/main/java/org/dspace/content/DSpaceObject.java index 726dd08c0e..4746a4079d 100644 --- a/dspace-api/src/main/java/org/dspace/content/DSpaceObject.java +++ b/dspace-api/src/main/java/org/dspace/content/DSpaceObject.java @@ -141,4 +141,50 @@ public abstract class DSpaceObject } return null; } + + /** + * Return the dspace object where an ADMIN action right is sufficient to + * grant the initial authorize check. + *

+ * Default behaviour is ADMIN right on the object grant right on all other + * action on the object itself. Subclass should override this method as + * need. + * + * @param action + * ID of action being attempted, from + * org.dspace.core.Constants. The ADMIN action is + * not a valid parameter for this method, an + * IllegalArgumentException should be thrown + * @return the dspace object, if any, where an ADMIN action is sufficient to + * grant the original action + * @throws SQLException + * @throws IllegalArgumentException + * if the ADMIN action is supplied as parameter of the method + * call + */ + public DSpaceObject getAdminObject(int action) throws SQLException + { + if (action == Constants.ADMIN) + { + throw new IllegalArgumentException("Illegal call to the DSpaceObject.getAdminObject method"); + } + return this; + } + + /** + * Return the dspace object that "own" the current object in the hierarchy. + * Note that this method has a meaning slightly different from the + * getAdminObject because it is independent of the action but it is in a way + * related to it. It defines the "first" dspace object OTHER then the + * current one, where allowed ADMIN actions imply allowed ADMIN actions on + * the object self. + * + * @return the dspace object that "own" the current object in + * the hierarchy + * @throws SQLException + */ + public DSpaceObject getParentObject() throws SQLException + { + return null; + } } diff --git a/dspace-api/src/main/java/org/dspace/content/Item.java b/dspace-api/src/main/java/org/dspace/content/Item.java index d5f7599e6c..68a87708ea 100644 --- a/dspace-api/src/main/java/org/dspace/content/Item.java +++ b/dspace-api/src/main/java/org/dspace/content/Item.java @@ -50,6 +50,8 @@ import java.util.Map; import java.util.StringTokenizer; import org.apache.log4j.Logger; +import org.dspace.app.util.AuthorizeUtil; +import org.dspace.authorize.AuthorizeConfiguration; import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeManager; import org.dspace.authorize.ResourcePolicy; @@ -1696,6 +1698,10 @@ public class Item extends DSpaceObject { String timestamp = DCDate.getCurrent().toString(); + // Check permission. User either has to have REMOVE on owning collection + // or be COLLECTION_EDITOR of owning collection + AuthorizeUtil.authorizeWithdrawItem(ourContext, this); + // Build some provenance data while we're at it. String collectionProv = ""; Collection[] colls = getCollections(); @@ -1706,21 +1712,6 @@ public class Item extends DSpaceObject + " (ID: " + colls[i].getID() + ")\n"; } - // Check permission. User either has to have REMOVE on owning collection - // or be COLLECTION_EDITOR of owning collection - if (AuthorizeManager.authorizeActionBoolean(ourContext, - getOwningCollection(), Constants.ADMIN) - || AuthorizeManager.authorizeActionBoolean(ourContext, - getOwningCollection(), Constants.REMOVE)) - { - // authorized - } - else - { - throw new AuthorizeException( - "To withdraw item must be COLLECTION_ADMIN or have REMOVE authorization on owning Collection"); - } - // Set withdrawn flag. timestamp will be set; last_modified in update() itemRow.setColumn("withdrawn", true); @@ -1768,14 +1759,15 @@ public class Item extends DSpaceObject String collectionProv = ""; Collection[] colls = getCollections(); + // check authorization + AuthorizeUtil.authorizeReinstateItem(ourContext, this); + for (int i = 0; i < colls.length; i++) { collectionProv = collectionProv + colls[i].getMetadata("name") + " (ID: " + colls[i].getID() + ")\n"; - AuthorizeManager.authorizeAction(ourContext, colls[i], - Constants.ADD); } - + // Clear withdrawn flag itemRow.setColumn("withdrawn", false); @@ -2250,26 +2242,20 @@ public class Item extends DSpaceObject } // is this person an COLLECTION_EDITOR for the owning collection? - if (getOwningCollection().canEditBoolean()) - { - return true; - } - - // is this person an COLLECTION_EDITOR for the owning collection? - if (AuthorizeManager.authorizeActionBoolean(ourContext, - getOwningCollection(), Constants.ADMIN)) + if (getOwningCollection().canEditBoolean(false)) { return true; } return false; } + public String getName() { DCValue t[] = getMetadata("dc", "title", null, Item.ANY); return (t.length >= 1) ? t[0].value : null; } - + /** * Returns an iterator of Items possessing the passed metadata field, or only * those matching the passed value, if value is not Item.ANY @@ -2309,5 +2295,140 @@ public class Item extends DSpaceObject } return new ItemIterator(context, rows); } - + + public DSpaceObject getAdminObject(int action) throws SQLException + { + DSpaceObject adminObject = null; + Collection collection = getOwningCollection(); + Community community = null; + if (collection != null) + { + Community[] communities = collection.getCommunities(); + if (communities != null && communities.length > 0) + { + community = communities[0]; + } + } + else + { + // is a template item? + TableRow qResult = DatabaseManager.querySingle(ourContext, + "SELECT collection_id FROM collection " + + "WHERE template_item_id = ?",getID()); + if (qResult != null) + { + collection = Collection.find(ourContext, qResult.getIntColumn("collection_id")); + Community[] communities = collection.getCommunities(); + if (communities != null && communities.length > 0) + { + community = communities[0]; + } + } + } + + switch (action) + { + case Constants.ADD: + // ADD a cc license is less general then add a bitstream but we can't/wan't + // add complex logic here to know if the ADD action on the item is required by a cc or + // a generic bitstream so simply we ignore it.. UI need to enforce the requirements. + if (AuthorizeConfiguration.canItemAdminPerformBitstreamCreation()) + { + adminObject = this; + } + else if (AuthorizeConfiguration.canCollectionAdminPerformBitstreamCreation()) + { + adminObject = collection; + } + else if (AuthorizeConfiguration.canCommunityAdminPerformBitstreamCreation()) + { + adminObject = community; + } + break; + case Constants.REMOVE: + // see comments on ADD action, same things... + if (AuthorizeConfiguration.canItemAdminPerformBitstreamDeletion()) + { + adminObject = this; + } + else if (AuthorizeConfiguration.canCollectionAdminPerformBitstreamDeletion()) + { + adminObject = collection; + } + else if (AuthorizeConfiguration.canCommunityAdminPerformBitstreamDeletion()) + { + adminObject = community; + } + break; + case Constants.DELETE: + if (getOwningCollection() != null) + { + if (AuthorizeConfiguration.canCollectionAdminPerformItemDeletion()) + { + adminObject = collection; + } + else if (AuthorizeConfiguration.canCommunityAdminPerformItemDeletion()) + { + adminObject = community; + } + } + else + { + if (AuthorizeConfiguration.canCollectionAdminManageTemplateItem()) + { + adminObject = collection; + } + else if (AuthorizeConfiguration.canCommunityAdminManageCollectionTemplateItem()) + { + adminObject = community; + } + } + break; + case Constants.WRITE: + // if it is a template item we need to check the + // collection/community admin configuration + if (getOwningCollection() == null) + { + if (AuthorizeConfiguration.canCollectionAdminManageTemplateItem()) + { + adminObject = collection; + } + else if (AuthorizeConfiguration.canCommunityAdminManageCollectionTemplateItem()) + { + adminObject = community; + } + } + else + { + adminObject = this; + } + break; + default: + adminObject = this; + break; + } + return adminObject; + } + + public DSpaceObject getParentObject() throws SQLException + { + Collection ownCollection = getOwningCollection(); + if (ownCollection != null) + { + return ownCollection; + } + else + { + // is a template item? + TableRow qResult = DatabaseManager.querySingle(ourContext, + "SELECT collection_id FROM collection " + + "WHERE template_item_id = ?",getID()); + if (qResult != null) + { + Collection collection = Collection.find(ourContext,qResult.getIntColumn("collection_id")); + return collection; + } + return null; + } + } } diff --git a/dspace-api/src/main/java/org/dspace/core/Constants.java b/dspace-api/src/main/java/org/dspace/core/Constants.java index f5eea117cb..fb1bb02c6e 100644 --- a/dspace-api/src/main/java/org/dspace/core/Constants.java +++ b/dspace-api/src/main/java/org/dspace/core/Constants.java @@ -205,7 +205,7 @@ public class Constants 0, // 8 - WORKFLOW_ABORT RCOLLECTION, // 9 - DEFAULT_BITSTREAM_READ RCOLLECTION, // 10 - DEFAULT_ITEM_READ - RBUNDLE | RITEM | RCOLLECTION | RCOMMUNITY // 11 - ADMIN + RITEM | RCOLLECTION | RCOMMUNITY // 11 - ADMIN }; public static final String DEFAULT_ENCODING = "UTF-8"; diff --git a/dspace-api/src/main/java/org/dspace/eperson/Group.java b/dspace-api/src/main/java/org/dspace/eperson/Group.java index caae51ada9..f5becdf289 100644 --- a/dspace-api/src/main/java/org/dspace/eperson/Group.java +++ b/dspace-api/src/main/java/org/dspace/eperson/Group.java @@ -48,8 +48,12 @@ import java.util.Set; import java.io.IOException; import org.apache.log4j.Logger; +import org.dspace.app.util.AuthorizeUtil; +import org.dspace.authorize.AuthorizeConfiguration; import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeManager; +import org.dspace.content.Collection; +import org.dspace.content.Community; import org.dspace.content.DSpaceObject; import org.dspace.core.ConfigurationManager; import org.dspace.core.Constants; @@ -1325,4 +1329,91 @@ public class Group extends DSpaceObject return myChildren; } + + public DSpaceObject getParentObject() throws SQLException + { + // could a collection/community admin manage related groups? + // check before the configuration options could give a performance gain + // if all group management are disallowed + if (AuthorizeConfiguration.canCollectionAdminManageAdminGroup() + || AuthorizeConfiguration.canCollectionAdminManageSubmitters() + || AuthorizeConfiguration.canCollectionAdminManageWorkflows() + || AuthorizeConfiguration.canCommunityAdminManageAdminGroup() + || AuthorizeConfiguration + .canCommunityAdminManageCollectionAdminGroup() + || AuthorizeConfiguration + .canCommunityAdminManageCollectionSubmitters() + || AuthorizeConfiguration + .canCommunityAdminManageCollectionWorkflows()) + { + // is this a collection related group? + TableRow qResult = DatabaseManager + .querySingle( + myContext, + "SELECT collection_id, workflow_step_1, workflow_step_2, " + + " workflow_step_3, submitter, admin FROM collection " + + " WHERE workflow_step_1 = ? OR " + + " workflow_step_2 = ? OR " + + " workflow_step_3 = ? OR " + + " submitter = ? OR " + " admin = ?", + getID(), getID(), getID(), getID(), getID()); + if (qResult != null) + { + Collection collection = Collection.find(myContext, qResult + .getIntColumn("collection_id")); + + if ((qResult.getIntColumn("workflow_step_1") == getID() || + qResult.getIntColumn("workflow_step_2") == getID() || + qResult.getIntColumn("workflow_step_3") == getID())) + { + if (AuthorizeConfiguration.canCollectionAdminManageWorkflows()) + { + return collection; + } + else if (AuthorizeConfiguration.canCommunityAdminManageCollectionWorkflows()) + { + return collection.getParentObject(); + } + } + if (qResult.getIntColumn("submitter") == getID()) + { + if (AuthorizeConfiguration.canCollectionAdminManageSubmitters()) + { + return collection; + } + else if (AuthorizeConfiguration.canCommunityAdminManageCollectionSubmitters()) + { + return collection.getParentObject(); + } + } + if (qResult.getIntColumn("admin") == getID()) + { + if (AuthorizeConfiguration.canCollectionAdminManageAdminGroup()) + { + return collection; + } + else if (AuthorizeConfiguration.canCommunityAdminManageCollectionAdminGroup()) + { + return collection.getParentObject(); + } + } + } + // is the group releated to a community and community admin allowed + // to manage it? + else if (AuthorizeConfiguration.canCommunityAdminManageAdminGroup()) + { + qResult = DatabaseManager.querySingle(myContext, + "SELECT community_id FROM community " + + "WHERE admin = ?", getID()); + + if (qResult != null) + { + Community community = Community.find(myContext, qResult + .getIntColumn("community_id")); + return community; + } + } + } + return null; + } } diff --git a/dspace-api/src/main/java/org/dspace/storage/rdbms/DatabaseManager.java b/dspace-api/src/main/java/org/dspace/storage/rdbms/DatabaseManager.java index 20342ca7f8..22b6a4c29b 100644 --- a/dspace-api/src/main/java/org/dspace/storage/rdbms/DatabaseManager.java +++ b/dspace-api/src/main/java/org/dspace/storage/rdbms/DatabaseManager.java @@ -125,6 +125,76 @@ public class DatabaseManager { } + /** + * Set the constraint check to deferred (commit time) + * + * @param context + * The context object + * @param constraintName + * the constraint name to deferred + * @throws SQLException + */ + public static void setConstraintDeferred(Context context, + String constraintName) throws SQLException + { + Statement statement = null; + try + { + statement = context.getDBConnection().createStatement(); + statement + .execute("SET CONSTRAINTS " + constraintName + " DEFERRED"); + statement.close(); + } + finally + { + if (statement != null) + { + try + { + statement.close(); + } + catch (SQLException sqle) + { + } + } + } + } + + /** + * Set the constraint check to immediate (every query) + * + * @param context + * The context object + * @param constraintName + * the constraint name to check immediately after every query + * @throws SQLException + */ + public static void setConstraintImmediate(Context context, + String constraintName) throws SQLException + { + Statement statement = null; + try + { + statement = context.getDBConnection().createStatement(); + statement.execute("SET CONSTRAINTS " + constraintName + + " IMMEDIATE"); + statement.close(); + } + finally + { + if (statement != null) + { + try + { + statement.close(); + } + catch (SQLException sqle) + { + } + } + } + } + /** * Return an iterator with the results of the query. The table parameter * indicates the type of result. If table is null, the column names are read diff --git a/dspace-api/src/main/resources/Messages.properties b/dspace-api/src/main/resources/Messages.properties index 30c22a85f1..1a184cb479 100644 --- a/dspace-api/src/main/resources/Messages.properties +++ b/dspace-api/src/main/resources/Messages.properties @@ -1077,6 +1077,7 @@ jsp.tools.edit-community.button.delete = Delete this Co jsp.tools.edit-community.form.button.add-logo = Upload new logo... jsp.tools.edit-community.form.button.cancel = Cancel jsp.tools.edit-community.form.button.create = Create +jsp.tools.edit-community.form.button.remove = Remove jsp.tools.edit-community.form.button.delete-logo = Delete (no logo) jsp.tools.edit-community.form.button.edit = Edit... jsp.tools.edit-community.form.button.set-logo = Upload a logo... diff --git a/dspace-jspui/dspace-jspui-api/src/main/java/org/dspace/app/webui/servlet/HandleServlet.java b/dspace-jspui/dspace-jspui-api/src/main/java/org/dspace/app/webui/servlet/HandleServlet.java index 931d23d37f..d32a4f459d 100644 --- a/dspace-jspui/dspace-jspui-api/src/main/java/org/dspace/app/webui/servlet/HandleServlet.java +++ b/dspace-jspui/dspace-jspui-api/src/main/java/org/dspace/app/webui/servlet/HandleServlet.java @@ -546,7 +546,7 @@ public class HandleServlet extends DSpaceServlet subscribed = Subscribe.isSubscribed(context, e, collection); // is the user a COLLECTION_EDITOR? - if (collection.canEditBoolean()) + if (collection.canEditBoolean(true)) { // set a variable to create an edit button request.setAttribute("editor_button", new Boolean(true)); diff --git a/dspace-jspui/dspace-jspui-api/src/main/java/org/dspace/app/webui/servlet/admin/AuthorizeAdminServlet.java b/dspace-jspui/dspace-jspui-api/src/main/java/org/dspace/app/webui/servlet/admin/AuthorizeAdminServlet.java index de7db4a76e..1fbef00eee 100644 --- a/dspace-jspui/dspace-jspui-api/src/main/java/org/dspace/app/webui/servlet/admin/AuthorizeAdminServlet.java +++ b/dspace-jspui/dspace-jspui-api/src/main/java/org/dspace/app/webui/servlet/admin/AuthorizeAdminServlet.java @@ -44,11 +44,14 @@ import java.sql.SQLException; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.dspace.app.util.AuthorizeUtil; import org.dspace.app.webui.servlet.DSpaceServlet; import org.dspace.app.webui.util.JSPManager; import org.dspace.app.webui.util.UIUtil; @@ -93,6 +96,10 @@ public class AuthorizeAdminServlet extends DSpaceServlet { String button = UIUtil.getSubmitButton(request, "submit"); + // check authorization!! the authorize servlet is available to all registred users + // it is need because also item/collection/community admin could be + // allowed to manage policies + if (button.equals("submit_collection")) { // select a collection to work on @@ -176,6 +183,7 @@ public class AuthorizeAdminServlet extends DSpaceServlet Item item = Item .find(c, UIUtil.getIntParameter(request, "item_id")); + AuthorizeUtil.authorizeManageItemPolicy(c, item); ResourcePolicy policy = ResourcePolicy.create(c); policy.setResource(item); policy.update(); @@ -201,6 +209,7 @@ public class AuthorizeAdminServlet extends DSpaceServlet Item item = Item .find(c, UIUtil.getIntParameter(request, "item_id")); + AuthorizeUtil.authorizeManageItemPolicy(c, item); int policy_id = UIUtil.getIntParameter(request, "policy_id"); ResourcePolicy policy = null; @@ -227,6 +236,7 @@ public class AuthorizeAdminServlet extends DSpaceServlet Bundle bundle = Bundle.find(c, UIUtil.getIntParameter(request, "bundle_id")); + AuthorizeUtil.authorizeManageBundlePolicy(c, bundle); ResourcePolicy policy = ResourcePolicy.create(c); policy.setResource(bundle); policy.update(); @@ -255,6 +265,7 @@ public class AuthorizeAdminServlet extends DSpaceServlet Bitstream bitstream = Bitstream.find(c, UIUtil.getIntParameter( request, "bitstream_id")); + AuthorizeUtil.authorizeManageBitstreamPolicy(c, bitstream); ResourcePolicy policy = ResourcePolicy.create(c); policy.setResource(bitstream); policy.update(); @@ -280,6 +291,8 @@ public class AuthorizeAdminServlet extends DSpaceServlet // delete a permission from an item Item item = Item .find(c, UIUtil.getIntParameter(request, "item_id")); + + AuthorizeUtil.authorizeManageItemPolicy(c, item); ResourcePolicy policy = ResourcePolicy.find(c, UIUtil .getIntParameter(request, "policy_id")); @@ -299,6 +312,7 @@ public class AuthorizeAdminServlet extends DSpaceServlet Collection collection = Collection.find(c, UIUtil.getIntParameter( request, "collection_id")); + AuthorizeUtil.authorizeManageCollectionPolicy(c, collection); ResourcePolicy policy = ResourcePolicy.create(c); policy.setResource(collection); policy.update(); @@ -336,6 +350,8 @@ public class AuthorizeAdminServlet extends DSpaceServlet // delete a permission from a collection Collection collection = Collection.find(c, UIUtil.getIntParameter( request, "collection_id")); + + AuthorizeUtil.authorizeManageCollectionPolicy(c, collection); ResourcePolicy policy = ResourcePolicy.find(c, UIUtil .getIntParameter(request, "policy_id")); @@ -356,6 +372,8 @@ public class AuthorizeAdminServlet extends DSpaceServlet // delete a permission from a community Community community = Community.find(c, UIUtil.getIntParameter( request, "community_id")); + + AuthorizeUtil.authorizeManageCommunityPolicy(c, community); ResourcePolicy policy = ResourcePolicy.find(c, UIUtil .getIntParameter(request, "policy_id")); @@ -377,6 +395,7 @@ public class AuthorizeAdminServlet extends DSpaceServlet Collection collection = Collection.find(c, UIUtil.getIntParameter( request, "collection_id")); + AuthorizeUtil.authorizeManageCollectionPolicy(c, collection); int policy_id = UIUtil.getIntParameter(request, "policy_id"); ResourcePolicy policy = null; @@ -411,6 +430,8 @@ public class AuthorizeAdminServlet extends DSpaceServlet // edit a community's policy - set up and call policy editor Community community = Community.find(c, UIUtil.getIntParameter( request, "community_id")); + + AuthorizeUtil.authorizeManageCommunityPolicy(c, community); int policy_id = UIUtil.getIntParameter(request, "policy_id"); ResourcePolicy policy = null; @@ -448,6 +469,7 @@ public class AuthorizeAdminServlet extends DSpaceServlet Collection collection = Collection.find(c, UIUtil.getIntParameter( request, "collection_id")); + AuthorizeUtil.authorizeManageCollectionPolicy(c, collection); ResourcePolicy policy = ResourcePolicy.create(c); policy.setResource(collection); policy.update(); @@ -474,6 +496,7 @@ public class AuthorizeAdminServlet extends DSpaceServlet Community community = Community.find(c, UIUtil.getIntParameter( request, "community_id")); + AuthorizeUtil.authorizeManageCommunityPolicy(c, community); ResourcePolicy policy = ResourcePolicy.create(c); policy.setResource(community); policy.update(); @@ -511,6 +534,7 @@ public class AuthorizeAdminServlet extends DSpaceServlet String display_page = null; ResourcePolicy policy = ResourcePolicy.find(c, policy_id); + AuthorizeUtil.authorizeManagePolicy(c, policy); Group group = Group.find(c, group_id); if (collection_id != -1) @@ -602,6 +626,7 @@ public class AuthorizeAdminServlet extends DSpaceServlet { int policy_id = UIUtil.getIntParameter(request, "policy_id"); ResourcePolicy rp = ResourcePolicy.find(c, policy_id); + AuthorizeUtil.authorizeManagePolicy(c, rp); rp.delete(); } @@ -647,6 +672,7 @@ public class AuthorizeAdminServlet extends DSpaceServlet } else if (button.equals("submit_advanced_clear")) { + AuthorizeUtil.requireAdminRole(c); // remove all policies for a set of objects int collection_id = UIUtil .getIntParameter(request, "collection_id"); @@ -668,6 +694,7 @@ public class AuthorizeAdminServlet extends DSpaceServlet } else if (button.equals("submit_advanced_add")) { + AuthorizeUtil.requireAdminRole(c); // add a policy to a set of objects int collection_id = UIUtil .getIntParameter(request, "collection_id"); diff --git a/dspace-jspui/dspace-jspui-api/src/main/java/org/dspace/app/webui/servlet/admin/CollectionWizardServlet.java b/dspace-jspui/dspace-jspui-api/src/main/java/org/dspace/app/webui/servlet/admin/CollectionWizardServlet.java index cb0f8edae6..ce13655267 100644 --- a/dspace-jspui/dspace-jspui-api/src/main/java/org/dspace/app/webui/servlet/admin/CollectionWizardServlet.java +++ b/dspace-jspui/dspace-jspui-api/src/main/java/org/dspace/app/webui/servlet/admin/CollectionWizardServlet.java @@ -52,6 +52,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; +import org.dspace.app.util.AuthorizeUtil; import org.dspace.app.webui.servlet.DSpaceServlet; import org.dspace.app.webui.util.FileUploadRequest; import org.dspace.app.webui.util.JSPManager; @@ -174,16 +175,49 @@ public class CollectionWizardServlet extends DSpaceServlet // Create the collection Collection newCollection = c.createCollection(); request.setAttribute("collection", newCollection); - if (AuthorizeManager.isAdmin(context,c)) - { - // set a variable to show all locale admin buttons - request.setAttribute("admin_button", new Boolean(true)); - } + if (AuthorizeManager.isAdmin(context)) { // set a variable to show all buttons request.setAttribute("sysadmin_button", new Boolean(true)); } + + try + { + AuthorizeUtil.authorizeManageAdminGroup(context, newCollection); + request.setAttribute("admin_create_button", new Boolean(true)); + } + catch (AuthorizeException authex) { + request.setAttribute("admin_create_button", new Boolean(false)); + } + + try + { + AuthorizeUtil.authorizeManageSubmittersGroup(context, newCollection); + request.setAttribute("submitters_button", new Boolean(true)); + } + catch (AuthorizeException authex) { + request.setAttribute("submitters_button", new Boolean(false)); + } + + try + { + AuthorizeUtil.authorizeManageWorkflowsGroup(context, newCollection); + request.setAttribute("workflows_button", new Boolean(true)); + } + catch (AuthorizeException authex) { + request.setAttribute("workflows_button", new Boolean(false)); + } + + try + { + AuthorizeUtil.authorizeManageTemplateItem(context, newCollection); + request.setAttribute("template_button", new Boolean(true)); + } + catch (AuthorizeException authex) { + request.setAttribute("template_button", new Boolean(false)); + } + JSPManager.showJSP(request, response, "/dspace-admin/wizard-questions.jsp"); context.complete(); @@ -718,11 +752,7 @@ public class CollectionWizardServlet extends DSpaceServlet Community[] communities = collection.getCommunities(); request.setAttribute("community", communities[0]); - if (AuthorizeManager.isAdmin(context, collection)) - { - // set a variable to show all buttons - request.setAttribute("admin_button", new Boolean(true)); - } + EditCommunitiesServlet.storeAuthorizeAttributeCollectionEdit(context, request, collection); } JSPManager.showJSP(request, response, "/tools/edit-collection.jsp"); diff --git a/dspace-jspui/dspace-jspui-api/src/main/java/org/dspace/app/webui/servlet/admin/EditCommunitiesServlet.java b/dspace-jspui/dspace-jspui-api/src/main/java/org/dspace/app/webui/servlet/admin/EditCommunitiesServlet.java index c185f2d85b..e3b36ae930 100644 --- a/dspace-jspui/dspace-jspui-api/src/main/java/org/dspace/app/webui/servlet/admin/EditCommunitiesServlet.java +++ b/dspace-jspui/dspace-jspui-api/src/main/java/org/dspace/app/webui/servlet/admin/EditCommunitiesServlet.java @@ -51,6 +51,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; +import org.dspace.app.util.AuthorizeUtil; import org.dspace.app.webui.servlet.DSpaceServlet; import org.dspace.app.webui.util.FileUploadRequest; import org.dspace.app.webui.util.JSPManager; @@ -170,19 +171,12 @@ public class EditCommunitiesServlet extends DSpaceServlet return; } - if ((collection != null && AuthorizeManager.isAdmin(context, collection)) - || (collection == null && community != null && AuthorizeManager.isAdmin(context, community)) - || (collection == null && parentCommunity != null && AuthorizeManager.isAdmin(context, parentCommunity))) - { - // set a variable to show all buttons - request.setAttribute("admin_button", new Boolean(true)); - } - // Now proceed according to "action" parameter switch (action) { case START_EDIT_COMMUNITY: - + storeAuthorizeAttributeCommunityEdit(context, request, community); + // Display the relevant "edit community" page JSPManager.showJSP(request, response, "/tools/edit-community.jsp"); @@ -197,6 +191,9 @@ public class EditCommunitiesServlet extends DSpaceServlet break; case START_CREATE_COMMUNITY: + // no authorize attribute will be given to the jsp so a "clean" creation form + // will be always supplied, advanced setting on policies and admin group creation + // will be possible after to have completed the community creation // Display edit community page with empty fields + create button JSPManager.showJSP(request, response, "/tools/edit-community.jsp"); @@ -209,6 +206,8 @@ public class EditCommunitiesServlet extends DSpaceServlet getIntParameter(request, "collection_id")); request.setAttribute("harvestInstance", hc); + storeAuthorizeAttributeCollectionEdit(context, request, collection); + // Display the relevant "edit collection" page JSPManager.showJSP(request, response, "/tools/edit-collection.jsp"); @@ -281,7 +280,9 @@ public class EditCommunitiesServlet extends DSpaceServlet // Delete the collection community.removeCollection(collection); - + // remove the collection object from the request, so that the user + // will be redirected on the community home page + request.removeAttribute("collection"); // Show main control page showControls(context, request, response); @@ -299,6 +300,140 @@ public class EditCommunitiesServlet extends DSpaceServlet } } + /** + * Store in the request attribute to teach to the jsp which button are + * needed/allowed for the community edit form + * + * @param context + * @param request + * @param community + * @throws SQLException + */ + private void storeAuthorizeAttributeCommunityEdit(Context context, + HttpServletRequest request, Community community) throws SQLException + { + try + { + AuthorizeUtil.authorizeManageAdminGroup(context, community); + request.setAttribute("admin_create_button", new Boolean(true)); + } + catch (AuthorizeException authex) { + request.setAttribute("admin_create_button", new Boolean(false)); + } + + try + { + AuthorizeUtil.authorizeRemoveAdminGroup(context, community); + request.setAttribute("admin_remove_button", new Boolean(true)); + } + catch (AuthorizeException authex) { + request.setAttribute("admin_remove_button", new Boolean(false)); + } + + if (AuthorizeManager.authorizeActionBoolean(context, community, Constants.DELETE)) + { + request.setAttribute("delete_button", new Boolean(true)); + } + else + { + request.setAttribute("delete_button", new Boolean(false)); + } + + try + { + AuthorizeUtil.authorizeManageCommunityPolicy(context, community); + request.setAttribute("policy_button", new Boolean(true)); + } + catch (AuthorizeException authex) { + request.setAttribute("policy_button", new Boolean(false)); + } + } + + /** + * Store in the request attribute to teach to the jsp which button are + * needed/allowed for the collection edit form + * + * @param context + * @param request + * @param community + * @throws SQLException + */ + static void storeAuthorizeAttributeCollectionEdit(Context context, + HttpServletRequest request, Collection collection) throws SQLException + { + if (AuthorizeManager.isAdmin(context, collection)) + { + request.setAttribute("admin_collection", new Boolean(true)); + } + else + { + request.setAttribute("admin_collection", new Boolean(false)); + } + + try + { + AuthorizeUtil.authorizeManageAdminGroup(context, collection); + request.setAttribute("admin_create_button", new Boolean(true)); + } + catch (AuthorizeException authex) { + request.setAttribute("admin_create_button", new Boolean(false)); + } + + try + { + AuthorizeUtil.authorizeRemoveAdminGroup(context, collection); + request.setAttribute("admin_remove_button", new Boolean(true)); + } + catch (AuthorizeException authex) { + request.setAttribute("admin_remove_button", new Boolean(false)); + } + + try + { + AuthorizeUtil.authorizeManageSubmittersGroup(context, collection); + request.setAttribute("submitters_button", new Boolean(true)); + } + catch (AuthorizeException authex) { + request.setAttribute("submitters_button", new Boolean(false)); + } + + try + { + AuthorizeUtil.authorizeManageWorkflowsGroup(context, collection); + request.setAttribute("workflows_button", new Boolean(true)); + } + catch (AuthorizeException authex) { + request.setAttribute("workflows_button", new Boolean(false)); + } + + try + { + AuthorizeUtil.authorizeManageTemplateItem(context, collection); + request.setAttribute("template_button", new Boolean(true)); + } + catch (AuthorizeException authex) { + request.setAttribute("template_button", new Boolean(false)); + } + + if (AuthorizeManager.authorizeActionBoolean(context, collection.getParentObject(), Constants.REMOVE)) + { + request.setAttribute("delete_button", new Boolean(true)); + } + else + { + request.setAttribute("delete_button", new Boolean(false)); + } + + try + { + AuthorizeUtil.authorizeManageCollectionPolicy(context, collection); + request.setAttribute("policy_button", new Boolean(true)); + } + catch (AuthorizeException authex) { + request.setAttribute("policy_button", new Boolean(false)); + } + } + /** * Show community home page with admin controls * @@ -394,6 +529,8 @@ public class EditCommunitiesServlet extends DSpaceServlet request.setAttribute("community", community); } + storeAuthorizeAttributeCommunityEdit(context, request, community); + community.setMetadata("name", request.getParameter("name")); community.setMetadata("short_description", request .getParameter("short_description")); @@ -452,7 +589,7 @@ public class EditCommunitiesServlet extends DSpaceServlet // Forward to policy edit page response.sendRedirect(response.encodeRedirectURL(request .getContextPath() - + "/dspace-admin/authorize?community_id=" + + "/tools/authorize?community_id=" + community.getID() + "&submit_community_select=1")); } else if (button.equals("submit_admins_create")) @@ -466,6 +603,15 @@ public class EditCommunitiesServlet extends DSpaceServlet .getContextPath() + "/tools/group-edit?group_id=" + newGroup.getID())); } + else if (button.equals("submit_admins_remove")) + { + Group g = community.getAdministrators(); + community.removeAdministrators(); + community.update(); + g.delete(); + // Show edit page again - attributes set in doDSPost() + JSPManager.showJSP(request, response, "/tools/edit-community.jsp"); + } else if (button.equals("submit_admins_edit")) { // Edit 'community administrators' group @@ -510,6 +656,8 @@ public class EditCommunitiesServlet extends DSpaceServlet collection = community.createCollection(); request.setAttribute("collection", collection); } + + storeAuthorizeAttributeCollectionEdit(context, request, collection); // Update the basic metadata collection.setMetadata("name", request.getParameter("name")); @@ -674,7 +822,7 @@ public class EditCommunitiesServlet extends DSpaceServlet // Forward to policy edit page response.sendRedirect(response.encodeRedirectURL(request .getContextPath() - + "/dspace-admin/authorize?collection_id=" + + "/tools/authorize?collection_id=" + collection.getID() + "&submit_collection_select=1")); } else if (button.startsWith("submit_wf_edit_")) @@ -830,6 +978,7 @@ public class EditCommunitiesServlet extends DSpaceServlet // Show community edit page request.setAttribute("community", community); + storeAuthorizeAttributeCommunityEdit(context, request, community); dso = community; jsp = "/tools/edit-community.jsp"; } @@ -840,6 +989,7 @@ public class EditCommunitiesServlet extends DSpaceServlet // Show collection edit page request.setAttribute("collection", collection); request.setAttribute("community", community); + storeAuthorizeAttributeCollectionEdit(context, request, collection); dso = collection; jsp = "/tools/edit-collection.jsp"; } diff --git a/dspace-jspui/dspace-jspui-api/src/main/java/org/dspace/app/webui/servlet/admin/EditItemServlet.java b/dspace-jspui/dspace-jspui-api/src/main/java/org/dspace/app/webui/servlet/admin/EditItemServlet.java index 5b3beb28eb..98039af4b5 100644 --- a/dspace-jspui/dspace-jspui-api/src/main/java/org/dspace/app/webui/servlet/admin/EditItemServlet.java +++ b/dspace-jspui/dspace-jspui-api/src/main/java/org/dspace/app/webui/servlet/admin/EditItemServlet.java @@ -59,10 +59,12 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; +import org.dspace.app.util.AuthorizeUtil; import org.dspace.app.webui.servlet.DSpaceServlet; import org.dspace.app.webui.util.FileUploadRequest; import org.dspace.app.webui.util.JSPManager; import org.dspace.app.webui.util.UIUtil; +import org.dspace.authorize.AuthorizeConfiguration; import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeManager; import org.dspace.content.Bitstream; @@ -392,9 +394,16 @@ public class EditItemServlet extends DSpaceServlet { if ( request.getParameter("cc_license_url") != null ) { - // set or replace existing CC license + // check authorization + AuthorizeUtil.authorizeManageCCLicense(context, item); + + // turn off auth system to allow replace also to user that can't + // remove/add bitstream to the item + context.turnOffAuthorisationSystem(); + // set or replace existing CC license CreativeCommons.setLicense( context, item, request.getParameter("cc_license_url") ); + context.restoreAuthSystemState(); context.commit(); } @@ -427,6 +436,82 @@ public class EditItemServlet extends DSpaceServlet } request.setAttribute("admin_button", AuthorizeManager.authorizeActionBoolean(context, item, Constants.ADMIN)); + try + { + AuthorizeUtil.authorizeManageItemPolicy(context, item); + request.setAttribute("policy_button", new Boolean(true)); + } + catch (AuthorizeException authex) + { + request.setAttribute("policy_button", new Boolean(false)); + } + + if (AuthorizeManager.authorizeActionBoolean(context, item + .getParentObject(), Constants.REMOVE)) + { + request.setAttribute("delete_button", new Boolean(true)); + } + else + { + request.setAttribute("delete_button", new Boolean(false)); + } + + try + { + AuthorizeManager.authorizeAction(context, item, Constants.ADD); + request.setAttribute("create_bitstream_button", new Boolean(true)); + } + catch (AuthorizeException authex) + { + request.setAttribute("create_bitstream_button", new Boolean(false)); + } + + try + { + AuthorizeManager.authorizeAction(context, item, Constants.REMOVE); + request.setAttribute("remove_bitstream_button", new Boolean(true)); + } + catch (AuthorizeException authex) + { + request.setAttribute("remove_bitstream_button", new Boolean(false)); + } + + try + { + AuthorizeUtil.authorizeManageCCLicense(context, item); + request.setAttribute("cclicense_button", new Boolean(true)); + } + catch (AuthorizeException authex) + { + request.setAttribute("cclicense_button", new Boolean(false)); + } + + if (!item.isWithdrawn()) + { + try + { + AuthorizeUtil.authorizeWithdrawItem(context, item); + request.setAttribute("withdraw_button", new Boolean(true)); + } + catch (AuthorizeException authex) + { + request.setAttribute("withdraw_button", new Boolean(false)); + } + } + else + { + try + { + AuthorizeUtil.authorizeReinstateItem(context, item); + request.setAttribute("reinstate_button", new Boolean(true)); + } + catch (AuthorizeException authex) + { + request.setAttribute("reinstate_button", new Boolean(false)); + } + } + + request.setAttribute("item", item); request.setAttribute("handle", handle); request.setAttribute("collections", collections); @@ -532,9 +617,7 @@ public class EditItemServlet extends DSpaceServlet item.addMetadata(schema, element, qualifier, language, value); } } - // only process bitstreams if admin - else if (p.startsWith("bitstream_name") - && AuthorizeManager.isAdmin(context)) + else if (p.startsWith("bitstream_name")) { // We have bitstream metadata // First, get the bundle and bitstream ID diff --git a/dspace-jspui/dspace-jspui-webapp/src/main/webapp/WEB-INF/web.xml b/dspace-jspui/dspace-jspui-webapp/src/main/webapp/WEB-INF/web.xml index 500ad83ab3..6293915d9a 100644 --- a/dspace-jspui/dspace-jspui-webapp/src/main/webapp/WEB-INF/web.xml +++ b/dspace-jspui/dspace-jspui-webapp/src/main/webapp/WEB-INF/web.xml @@ -428,7 +428,7 @@ authorize - /dspace-admin/authorize + /tools/authorize diff --git a/dspace-jspui/dspace-jspui-webapp/src/main/webapp/dspace-admin/authorize-collection-edit.jsp b/dspace-jspui/dspace-jspui-webapp/src/main/webapp/dspace-admin/authorize-collection-edit.jsp index 1b76b8489b..4773c4fd8e 100644 --- a/dspace-jspui/dspace-jspui-webapp/src/main/webapp/dspace-admin/authorize-collection-edit.jsp +++ b/dspace-jspui/dspace-jspui-webapp/src/main/webapp/dspace-admin/authorize-collection-edit.jsp @@ -105,7 +105,7 @@ -

+

" /> @@ -120,7 +120,7 @@ { ResourcePolicy rp = (ResourcePolicy) i.next(); %> - + diff --git a/dspace-jspui/dspace-jspui-webapp/src/main/webapp/dspace-admin/authorize-community-edit.jsp b/dspace-jspui/dspace-jspui-webapp/src/main/webapp/dspace-admin/authorize-community-edit.jsp index 2e17230274..b8e48f35df 100644 --- a/dspace-jspui/dspace-jspui-webapp/src/main/webapp/dspace-admin/authorize-community-edit.jsp +++ b/dspace-jspui/dspace-jspui-webapp/src/main/webapp/dspace-admin/authorize-community-edit.jsp @@ -100,7 +100,7 @@
- +

" /> @@ -134,14 +134,14 @@ <%= (rp.getGroup() == null ? "..." : rp.getGroup().getName() ) %> - --> + " />

-
--> + " /> diff --git a/dspace-jspui/dspace-jspui-webapp/src/main/webapp/dspace-admin/authorize-policy-edit.jsp b/dspace-jspui/dspace-jspui-webapp/src/main/webapp/dspace-admin/authorize-policy-edit.jsp index 89fc8dc309..5e4aa93418 100644 --- a/dspace-jspui/dspace-jspui-webapp/src/main/webapp/dspace-admin/authorize-policy-edit.jsp +++ b/dspace-jspui/dspace-jspui-webapp/src/main/webapp/dspace-admin/authorize-policy-edit.jsp @@ -111,7 +111,7 @@ - + diff --git a/dspace-jspui/dspace-jspui-webapp/src/main/webapp/dspace-admin/supervise-list.jsp b/dspace-jspui/dspace-jspui-webapp/src/main/webapp/dspace-admin/supervise-list.jsp index 8d5b85870f..d8ea030077 100644 --- a/dspace-jspui/dspace-jspui-webapp/src/main/webapp/dspace-admin/supervise-list.jsp +++ b/dspace-jspui/dspace-jspui-webapp/src/main/webapp/dspace-admin/supervise-list.jsp @@ -119,7 +119,7 @@
<%-- form to navigate to the item policies --%> - + "/> diff --git a/dspace-jspui/dspace-jspui-webapp/src/main/webapp/dspace-admin/wizard-questions.jsp b/dspace-jspui/dspace-jspui-webapp/src/main/webapp/dspace-admin/wizard-questions.jsp index b91939f32e..02118f2231 100644 --- a/dspace-jspui/dspace-jspui-webapp/src/main/webapp/dspace-admin/wizard-questions.jsp +++ b/dspace-jspui/dspace-jspui-webapp/src/main/webapp/dspace-admin/wizard-questions.jsp @@ -61,8 +61,21 @@ <% Boolean sysadmin_b = (Boolean)request.getAttribute("sysadmin_button"); boolean sysadmin_button = (sysadmin_b == null ? false : sysadmin_b.booleanValue()); - Boolean admin_b = (Boolean)request.getAttribute("admin_button"); - boolean admin_button = (admin_b == null ? false : admin_b.booleanValue()); %> + + Boolean adminCreateGroup = (Boolean)request.getAttribute("admin_create_button"); + boolean bAdminCreateGroup = (adminCreateGroup == null ? false : adminCreateGroup.booleanValue()); + + Boolean workflowsButton = (Boolean)request.getAttribute("workflows_button"); + boolean bWorkflowsButton = (workflowsButton == null ? false : workflowsButton.booleanValue()); + + Boolean submittersButton = (Boolean)request.getAttribute("submitters_button"); + boolean bSubmittersButton = (submittersButton == null ? false : submittersButton.booleanValue()); + + Boolean templateButton = (Boolean)request.getAttribute("template_button"); + boolean bTemplateButton = (templateButton == null ? false : templateButton.booleanValue()); +%> + +
- <% if(!admin_button ) { %> + <% if(!bSubmittersButton) { %> <% } else { %> @@ -121,7 +134,7 @@
- <% if(!admin_button ) { %> + <% if(!bWorkflowsButton) { %> <% } else { %> @@ -138,7 +151,7 @@
- <% if(!admin_button ) { %> + <% if(!bWorkflowsButton) { %> <% } else { %> @@ -155,7 +168,7 @@
- <% if(!admin_button ) { %> + <% if(!bWorkflowsButton) { %> <% } else { %> @@ -172,7 +185,7 @@ +<% if(bSubmittersButton || bWorkflowsButton || bAdminCreateGroup || (admins != null && bAdminRemoveGroup)) { %> -<% if(admin_button ) { %> +<% } + + if(bSubmittersButton) { %> <%-- =========================================================== Collection Submitters =========================================================== --%> @@ -267,7 +296,9 @@ <% } %> - +<% } %> + +<% if(bWorkflowsButton) { %> <%-- =========================================================== Workflow groups =========================================================== --%> @@ -292,24 +323,36 @@ <% } %> - +<% } %> - +<% if(bAdminCreateGroup || (admins != null && bAdminRemoveGroup)) { %> <%-- =========================================================== Collection Administrators =========================================================== --%> -<% } %> +<% } %> + +<% if(bTemplateButton) { %> <%-- =========================================================== Item template =========================================================== --%> @@ -324,8 +367,10 @@ " /> <% } %> - -<% if(isAdmin) { %> + +<% } %> + +<% if(bPolicyButton) { %> <%-- =========================================================== Edit collection's policies =========================================================== --%> @@ -345,7 +390,7 @@ -<% if(admin_button ) { %> +<% if(bAdminCollection) { %> <%-- =========================================================== Harvesting Settings =========================================================== --%> diff --git a/dspace-jspui/dspace-jspui-webapp/src/main/webapp/tools/edit-community.jsp b/dspace-jspui/dspace-jspui-webapp/src/main/webapp/tools/edit-community.jsp index 2c449e8cd7..e0c007fe49 100644 --- a/dspace-jspui/dspace-jspui-webapp/src/main/webapp/tools/edit-community.jsp +++ b/dspace-jspui/dspace-jspui-webapp/src/main/webapp/tools/edit-community.jsp @@ -63,12 +63,22 @@ <% Community community = (Community) request.getAttribute("community"); int parentID = UIUtil.getIntParameter(request, "parent_community_id"); - Boolean admin_b = (Boolean)request.getAttribute("admin_button"); - boolean admin_button = (admin_b == null ? false : admin_b.booleanValue()); // Is the logged in user a sys admin Boolean admin = (Boolean)request.getAttribute("is.admin"); boolean isAdmin = (admin == null ? false : admin.booleanValue()); + Boolean adminCreateGroup = (Boolean)request.getAttribute("admin_create_button"); + boolean bAdminCreateGroup = (adminCreateGroup == null ? false : adminCreateGroup.booleanValue()); + + Boolean adminRemoveGroup = (Boolean)request.getAttribute("admin_remove_button"); + boolean bAdminRemoveGroup = (adminRemoveGroup == null ? false : adminRemoveGroup.booleanValue()); + + Boolean policy = (Boolean)request.getAttribute("policy_button"); + boolean bPolicy = (policy == null ? false : policy.booleanValue()); + + Boolean delete = (Boolean)request.getAttribute("delete_button"); + boolean bDelete = (delete == null ? false : delete.booleanValue()); + String name = ""; String shortDesc = ""; String intro = ""; @@ -113,7 +123,7 @@ <%= community.getHandle() %> - <% if(admin_button ) { %> + <% if(bDelete) { %>
- <% if(!admin_button ) { %> + <% if(!bAdminCreateGroup) { %> <% } else { %> @@ -188,7 +201,12 @@ - + + <% } %> <%-- --%> diff --git a/dspace-jspui/dspace-jspui-webapp/src/main/webapp/layout/navbar-admin.jsp b/dspace-jspui/dspace-jspui-webapp/src/main/webapp/layout/navbar-admin.jsp index 0cb23a3220..565cc08f46 100644 --- a/dspace-jspui/dspace-jspui-webapp/src/main/webapp/layout/navbar-admin.jsp +++ b/dspace-jspui/dspace-jspui-webapp/src/main/webapp/layout/navbar-admin.jsp @@ -135,10 +135,10 @@ diff --git a/dspace-jspui/dspace-jspui-webapp/src/main/webapp/tools/edit-collection.jsp b/dspace-jspui/dspace-jspui-webapp/src/main/webapp/tools/edit-collection.jsp index 5d022a8b07..8929528373 100644 --- a/dspace-jspui/dspace-jspui-webapp/src/main/webapp/tools/edit-collection.jsp +++ b/dspace-jspui/dspace-jspui-webapp/src/main/webapp/tools/edit-collection.jsp @@ -67,8 +67,30 @@ <% Collection collection = (Collection) request.getAttribute("collection"); Community community = (Community) request.getAttribute("community"); - Boolean admin_b = (Boolean)request.getAttribute("admin_button"); - boolean admin_button = (admin_b == null ? false : admin_b.booleanValue()); + + Boolean adminCollection = (Boolean)request.getAttribute("admin_collection"); + boolean bAdminCollection = (adminCollection == null ? false : adminCollection.booleanValue()); + + Boolean adminCreateGroup = (Boolean)request.getAttribute("admin_create_button"); + boolean bAdminCreateGroup = (adminCreateGroup == null ? false : adminCreateGroup.booleanValue()); + + Boolean adminRemoveGroup = (Boolean)request.getAttribute("admin_remove_button"); + boolean bAdminRemoveGroup = (adminRemoveGroup == null ? false : adminRemoveGroup.booleanValue()); + + Boolean workflowsButton = (Boolean)request.getAttribute("workflows_button"); + boolean bWorkflowsButton = (workflowsButton == null ? false : workflowsButton.booleanValue()); + + Boolean submittersButton = (Boolean)request.getAttribute("submitters_button"); + boolean bSubmittersButton = (submittersButton == null ? false : submittersButton.booleanValue()); + + Boolean templateButton = (Boolean)request.getAttribute("template_button"); + boolean bTemplateButton = (templateButton == null ? false : templateButton.booleanValue()); + + Boolean policyButton = (Boolean)request.getAttribute("policy_button"); + boolean bPolicyButton = (policyButton == null ? false : policyButton.booleanValue()); + + Boolean deleteButton = (Boolean)request.getAttribute("delete_button"); + boolean bDeleteButton = (deleteButton == null ? false : deleteButton.booleanValue()); // Is the logged in user a sys admin Boolean admin = (Boolean)request.getAttribute("is.admin"); @@ -158,17 +180,21 @@ <%= collection.getHandle() %> - <% if(admin_button ) { %> +
+ <% if(!bTemplateButton) { %> + + <% } else { %> + New submissions will have some metadata already filled out with defaults
+<% if(bDeleteButton) { %>
" />
+<% } else { %> +   +<% } %>
@@ -176,7 +202,7 @@
- <% } %> + <% } %>
@@ -250,9 +276,12 @@
 

 
-<% if (admins == null) {%> +<% if (admins == null) { + if (bAdminCreateGroup) { +%> " /> -<% } else { %> +<% } + } + else { + if (bAdminCreateGroup) { + %> " /> + <% } + if (bAdminRemoveGroup) { + %> " /> -<% } %> +<% } + } %>
@@ -194,24 +204,35 @@ <% } %> - <% if(admin_button ) { %> + <% if(bAdminCreateGroup || (admins != null && bAdminRemoveGroup)) { %> <%-- =========================================================== Community Administrators =========================================================== --%> <% } - if (isAdmin) { + if (bPolicy) { %> diff --git a/dspace-jspui/dspace-jspui-webapp/src/main/webapp/tools/edit-item-form.jsp b/dspace-jspui/dspace-jspui-webapp/src/main/webapp/tools/edit-item-form.jsp index a8384e0b56..015bf5513b 100644 --- a/dspace-jspui/dspace-jspui-webapp/src/main/webapp/tools/edit-item-form.jsp +++ b/dspace-jspui/dspace-jspui-webapp/src/main/webapp/tools/edit-item-form.jsp @@ -86,14 +86,31 @@ // Is anyone logged in? EPerson user = (EPerson) request.getAttribute("dspace.current.user"); - - // Is the logged in user an admin - Boolean admin = (Boolean)request.getAttribute("is.admin"); - boolean isAdmin = (admin == null ? false : admin.booleanValue()); // Is the logged in user an admin of the item Boolean itemAdmin = (Boolean)request.getAttribute("admin_button"); boolean isItemAdmin = (itemAdmin == null ? false : itemAdmin.booleanValue()); + + Boolean policy = (Boolean)request.getAttribute("policy_button"); + boolean bPolicy = (policy == null ? false : policy.booleanValue()); + + Boolean delete = (Boolean)request.getAttribute("delete_button"); + boolean bDelete = (delete == null ? false : delete.booleanValue()); + + Boolean createBits = (Boolean)request.getAttribute("create_bitstream_button"); + boolean bCreateBits = (createBits == null ? false : createBits.booleanValue()); + + Boolean removeBits = (Boolean)request.getAttribute("remove_bitstream_button"); + boolean bRemoveBits = (removeBits == null ? false : removeBits.booleanValue()); + + Boolean ccLicense = (Boolean)request.getAttribute("cclicense_button"); + boolean bccLicense = (ccLicense == null ? false : ccLicense.booleanValue()); + + Boolean withdraw = (Boolean)request.getAttribute("withdraw_button"); + boolean bWithdraw = (withdraw == null ? false : withdraw.booleanValue()); + + Boolean reinstate = (Boolean)request.getAttribute("reinstate_button"); + boolean bReinstate = (reinstate == null ? false : reinstate.booleanValue()); %> @@ -123,7 +140,7 @@ <% - if (isAdmin) + if (bPolicy) { %> <%-- =========================================================== @@ -210,7 +233,7 @@ <%-- --%> <% @@ -421,10 +447,13 @@
- <% if (admins == null) {%> + <% if (admins == null) { + if (bAdminCreateGroup) { + %> " /> - <% } else { %> + <% } + } + else + { + if (bAdminCreateGroup) { %> " /> - <% } %> + <% } + if (bAdminRemoveGroup) { %> + " /> + <% } + } + %>
<%= item.getID() %> <% - if (!item.isWithdrawn()) + if (!item.isWithdrawn() && bWithdraw) { %> @@ -134,7 +151,7 @@ <% } - else + else if (item.isWithdrawn() && bReinstate) { %>
@@ -148,6 +165,10 @@ %>
+<% + if (bDelete) + { +%> @@ -155,6 +176,8 @@ "/>
<% + } + if (isItemAdmin) { %>
@@ -200,7 +223,7 @@
Item's Authorizations: - + " /> <%-- --%> @@ -404,7 +427,10 @@ <%-- View  --%> -  " /> +   + <% if (bRemoveBits) { %> + " /> + <% } %>
- "/> <% + if (bCreateBits) { + %> + "/> + <% } - if (ConfigurationManager.getBooleanProperty("webui.submit.enable-cc")) + if (ConfigurationManager.getBooleanProperty("webui.submit.enable-cc") && bccLicense) { String s; Bundle[] ccBundle = item.getBundles("CC-LICENSE"); diff --git a/dspace-xmlui/dspace-xmlui-api/src/main/java/org/dspace/app/xmlui/aspect/administrative/FlowAuthorizationUtils.java b/dspace-xmlui/dspace-xmlui-api/src/main/java/org/dspace/app/xmlui/aspect/administrative/FlowAuthorizationUtils.java index f3da0f9e21..79ee010bdc 100644 --- a/dspace-xmlui/dspace-xmlui-api/src/main/java/org/dspace/app/xmlui/aspect/administrative/FlowAuthorizationUtils.java +++ b/dspace-xmlui/dspace-xmlui-api/src/main/java/org/dspace/app/xmlui/aspect/administrative/FlowAuthorizationUtils.java @@ -43,6 +43,7 @@ package org.dspace.app.xmlui.aspect.administrative; import java.sql.SQLException; import java.util.List; +import org.dspace.app.util.AuthorizeUtil; import org.dspace.app.xmlui.wing.Message; import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeManager; @@ -151,7 +152,13 @@ public class FlowAuthorizationUtils { boolean added = false; ResourcePolicy policy = ResourcePolicy.find(context, policyID); - + + // check authorization to edit an existent policy + if (policy != null) + { + AuthorizeUtil.authorizeManagePolicy(context, policy); + } + /* First and foremost, if no group or action was selected, throw an error back to the user */ if (actionID == -1) { result.setContinue(false); @@ -168,15 +175,41 @@ public class FlowAuthorizationUtils { DSpaceObject policyParent = null; if (policy == null) { - policy = ResourcePolicy.create(context); - switch (objectType) { - case Constants.COMMUNITY: policyParent = Community.find(context, objectID); break; - case Constants.COLLECTION: policyParent = Collection.find(context, objectID); break; - case Constants.ITEM: policyParent = Item.find(context, objectID); break; - case Constants.BUNDLE: policyParent = Bundle.find(context, objectID); break; - case Constants.BITSTREAM: policyParent = Bitstream.find(context, objectID); break; + case Constants.COMMUNITY: + { + policyParent = Community.find(context, objectID); + AuthorizeUtil.authorizeManageCommunityPolicy(context, (Community)policyParent); + break; + } + case Constants.COLLECTION: + { + policyParent = Collection.find(context, objectID); + AuthorizeUtil.authorizeManageCollectionPolicy(context, (Collection)policyParent); + break; + } + case Constants.ITEM: + { + policyParent = Item.find(context, objectID); + AuthorizeUtil.authorizeManageItemPolicy(context, (Item) policyParent); + break; + } + case Constants.BUNDLE: + { + policyParent = Bundle.find(context, objectID); + AuthorizeUtil.authorizeManageItemPolicy(context, (Item) (policyParent.getParentObject())); + break; + } + case Constants.BITSTREAM: + { + policyParent = Bitstream.find(context, objectID); + AuthorizeUtil + .authorizeManageItemPolicy(context, (Item) (policyParent + .getParentObject())); + break; + } } + policy = ResourcePolicy.create(context); policy.setResource(policyParent); added = true; } @@ -231,13 +264,15 @@ public class FlowAuthorizationUtils { * @param policyIDs The unique ids of the policies being deleted. * @return A process result's object. */ - public static FlowResult processDeletePolicies(Context context, String[] policyIDs) throws NumberFormatException, SQLException + public static FlowResult processDeletePolicies(Context context, String[] policyIDs) throws NumberFormatException, SQLException, AuthorizeException { FlowResult result = new FlowResult(); for (String id : policyIDs) { ResourcePolicy policyDeleted = ResourcePolicy.find(context, Integer.valueOf(id)); + // check authorization + AuthorizeUtil.authorizeManagePolicy(context, policyDeleted); policyDeleted.delete(); } @@ -262,6 +297,7 @@ public class FlowAuthorizationUtils { public static FlowResult processAdvancedPolicyAdd(Context context, String[] groupIDs, int actionID, int resourceID, String [] collectionIDs) throws NumberFormatException, SQLException, AuthorizeException { + AuthorizeUtil.requireAdminRole(context); FlowResult result = new FlowResult(); for (String groupID : groupIDs) @@ -300,6 +336,7 @@ public class FlowAuthorizationUtils { public static FlowResult processAdvancedPolicyDelete(Context context, int resourceID, String [] collectionIDs) throws NumberFormatException, SQLException, AuthorizeException { + AuthorizeUtil.requireAdminRole(context); FlowResult result = new FlowResult(); for (String collectionID : collectionIDs) diff --git a/dspace-xmlui/dspace-xmlui-api/src/main/java/org/dspace/app/xmlui/aspect/administrative/Navigation.java b/dspace-xmlui/dspace-xmlui-api/src/main/java/org/dspace/app/xmlui/aspect/administrative/Navigation.java index c019265ee7..9d3eb6e6ab 100644 --- a/dspace-xmlui/dspace-xmlui-api/src/main/java/org/dspace/app/xmlui/aspect/administrative/Navigation.java +++ b/dspace-xmlui/dspace-xmlui-api/src/main/java/org/dspace/app/xmlui/aspect/administrative/Navigation.java @@ -234,7 +234,6 @@ public class Navigation extends AbstractDSpaceTransformer implements CacheablePr DSpaceObject dso = HandleUtil.obtainHandle(objectModel); if (dso instanceof Item) { - Item item = (Item) dso; if (item.canEdit()) { @@ -248,9 +247,8 @@ public class Navigation extends AbstractDSpaceTransformer implements CacheablePr { Collection collection = (Collection) dso; - // can they admin this collection? - if (AuthorizeManager.authorizeActionBoolean(this.context, collection, Constants.ADMIN)) + if (collection.canEditBoolean(true)) { context.setHead(T_context_head); context.addItemXref(contextPath+"/admin/collection?collectionID=" + collection.getID(), T_context_edit_collection); @@ -276,14 +274,8 @@ public class Navigation extends AbstractDSpaceTransformer implements CacheablePr if (AuthorizeManager.authorizeActionBoolean(this.context, community,Constants.ADD)) { context.setHead(T_context_head); - context.addItemXref(contextPath+"/admin/collection?createNew&communityID=" + community.getID(), T_context_create_collection); - } - - // Only System & Community administrators can create sub-communities - if (isSystemAdmin || AuthorizeManager.authorizeActionBoolean(this.context, community, Constants.ADMIN)) - { - context.setHead(T_context_head); - context.addItemXref(contextPath+"/admin/community?createNew&communityID=" + community.getID(), T_context_create_subcommunity); + context.addItemXref(contextPath+"/admin/collection?createNew&communityID=" + community.getID(), T_context_create_collection); + context.addItemXref(contextPath+"/admin/community?createNew&communityID=" + community.getID(), T_context_create_subcommunity); } } diff --git a/dspace-xmlui/dspace-xmlui-api/src/main/java/org/dspace/app/xmlui/aspect/administrative/collection/AssignCollectionRoles.java b/dspace-xmlui/dspace-xmlui-api/src/main/java/org/dspace/app/xmlui/aspect/administrative/collection/AssignCollectionRoles.java index 5c385bfabd..258e9e9416 100644 --- a/dspace-xmlui/dspace-xmlui-api/src/main/java/org/dspace/app/xmlui/aspect/administrative/collection/AssignCollectionRoles.java +++ b/dspace-xmlui/dspace-xmlui-api/src/main/java/org/dspace/app/xmlui/aspect/administrative/collection/AssignCollectionRoles.java @@ -41,6 +41,7 @@ package org.dspace.app.xmlui.aspect.administrative.collection; import java.sql.SQLException; +import org.dspace.app.util.AuthorizeUtil; import org.dspace.app.xmlui.aspect.administrative.FlowContainerUtils; import org.dspace.app.xmlui.cocoon.AbstractDSpaceTransformer; import org.dspace.app.xmlui.wing.Message; @@ -104,6 +105,7 @@ public class AssignCollectionRoles extends AbstractDSpaceTransformer private static final Message T_role_buttons = message("xmlui.administrative.collection.AssignCollectionRoles.role_buttons"); private static final Message T_label_admins = message("xmlui.administrative.collection.AssignCollectionRoles.label_admins"); + private static final Message T_label_wf = message("xmlui.administrative.collection.AssignCollectionRoles.label_wf"); private static final Message T_label_wf_step1 = message("xmlui.administrative.collection.AssignCollectionRoles.label_wf_step1"); private static final Message T_label_wf_step2 = message("xmlui.administrative.collection.AssignCollectionRoles.label_wf_step2"); private static final Message T_label_wf_step3 = message("xmlui.administrative.collection.AssignCollectionRoles.label_wf_step3"); @@ -111,6 +113,7 @@ public class AssignCollectionRoles extends AbstractDSpaceTransformer private static final Message T_label_default_read = message("xmlui.administrative.collection.AssignCollectionRoles.label_default_read"); private static final Message T_sysadmins_only = message("xmlui.administrative.collection.AssignCollectionRoles.sysadmins_only"); + private static final Message T_not_allowed = message("xmlui.administrative.collection.AssignCollectionRoles.not_allowed"); public void addPageMeta(PageMeta pageMeta) throws WingException @@ -168,13 +171,37 @@ public class AssignCollectionRoles extends AbstractDSpaceTransformer tableRow.addCell(Cell.ROLE_HEADER).addContent(T_label_admins); if (admins != null) { - tableRow.addCell().addXref(baseURL + "&submit_edit_admin", admins.getName()); - tableRow.addCell().addButton("submit_delete_admin").setValue(T_delete); + try + { + AuthorizeUtil.authorizeManageAdminGroup(context, thisCollection); + tableRow.addCell().addXref(baseURL + "&submit_edit_admin", admins.getName()); + } + catch (AuthorizeException authex) { + // add a notice, the user is not authorized to create/edit collection's admin group + tableRow.addCell().addContent(T_not_allowed); + } + try + { + AuthorizeUtil.authorizeRemoveAdminGroup(context, thisCollection); + tableRow.addCell().addButton("submit_delete_admin").setValue(T_delete); + } + catch (AuthorizeException authex) + { + // nothing to add, the user is not allowed to delete the group + } } else { tableRow.addCell().addContent(T_no_role); - tableRow.addCell().addButton("submit_create_admin").setValue(T_create); + try + { + AuthorizeUtil.authorizeManageAdminGroup(context, thisCollection); + tableRow.addCell().addButton("submit_create_admin").setValue(T_create); + } + catch (AuthorizeException authex) { + // add a notice, the user is not authorized to create/edit collection's admin group + tableRow.addCell().addContent(T_not_allowed); + } } // help and directions row tableRow = rolesTable.addRow(Row.ROLE_DATA); @@ -186,75 +213,93 @@ public class AssignCollectionRoles extends AbstractDSpaceTransformer * Workflow steps 1-3 */ // data row - tableRow = rolesTable.addRow(Row.ROLE_DATA); - tableRow.addCell(Cell.ROLE_HEADER).addContent(T_label_wf_step1); - if (wfStep1 != null) - { - tableRow.addCell().addXref(baseURL + "&submit_edit_wf_step1", wfStep1.getName()); - tableRow.addCell().addButton("submit_delete_wf_step1").setValue(T_delete); - } - else - { - tableRow.addCell().addContent(T_no_role); - tableRow.addCell().addButton("submit_create_wf_step1").setValue(T_create); - } - // help and directions row - tableRow = rolesTable.addRow(Row.ROLE_DATA); - tableRow.addCell(); - tableRow.addCell(1,2).addHighlight("fade offset").addContent(T_help_wf_step1); - - - // data row - tableRow = rolesTable.addRow(Row.ROLE_DATA); - tableRow.addCell(Cell.ROLE_HEADER).addContent(T_label_wf_step2); - if (wfStep2 != null) - { - tableRow.addCell().addXref(baseURL + "&submit_edit_wf_step2", wfStep2.getName()); - tableRow.addCell().addButton("submit_delete_wf_step2").setValue(T_delete); - } - else - { - tableRow.addCell().addContent(T_no_role); - tableRow.addCell().addButton("submit_create_wf_step2").setValue(T_create); - } - // help and directions row - tableRow = rolesTable.addRow(Row.ROLE_DATA); - tableRow.addCell(); - tableRow.addCell(1,2).addHighlight("fade offset").addContent(T_help_wf_step2); - - - // data row - tableRow = rolesTable.addRow(Row.ROLE_DATA); - tableRow.addCell(Cell.ROLE_HEADER).addContent(T_label_wf_step3); - if (wfStep3 != null) - { - tableRow.addCell().addXref(baseURL + "&submit_edit_wf_step3", wfStep3.getName()); - tableRow.addCell().addButton("submit_delete_wf_step3").setValue(T_delete); - } - else - { - tableRow.addCell().addContent(T_no_role); - tableRow.addCell().addButton("submit_create_wf_step3").setValue(T_create); - } - // help and directions row - tableRow = rolesTable.addRow(Row.ROLE_DATA); - tableRow.addCell(); - tableRow.addCell(1,2).addHighlight("fade offset").addContent(T_help_wf_step3); + try + { + AuthorizeUtil.authorizeManageWorkflowsGroup(context, thisCollection); + tableRow = rolesTable.addRow(Row.ROLE_DATA); + tableRow.addCell(Cell.ROLE_HEADER).addContent(T_label_wf_step1); + if (wfStep1 != null) + { + tableRow.addCell().addXref(baseURL + "&submit_edit_wf_step1", wfStep1.getName()); + tableRow.addCell().addButton("submit_delete_wf_step1").setValue(T_delete); + } + else + { + tableRow.addCell().addContent(T_no_role); + tableRow.addCell().addButton("submit_create_wf_step1").setValue(T_create); + } + // help and directions row + tableRow = rolesTable.addRow(Row.ROLE_DATA); + tableRow.addCell(); + tableRow.addCell(1,2).addHighlight("fade offset").addContent(T_help_wf_step1); + + + // data row + tableRow = rolesTable.addRow(Row.ROLE_DATA); + tableRow.addCell(Cell.ROLE_HEADER).addContent(T_label_wf_step2); + if (wfStep2 != null) + { + tableRow.addCell().addXref(baseURL + "&submit_edit_wf_step2", wfStep2.getName()); + tableRow.addCell().addButton("submit_delete_wf_step2").setValue(T_delete); + } + else + { + tableRow.addCell().addContent(T_no_role); + tableRow.addCell().addButton("submit_create_wf_step2").setValue(T_create); + } + // help and directions row + tableRow = rolesTable.addRow(Row.ROLE_DATA); + tableRow.addCell(); + tableRow.addCell(1,2).addHighlight("fade offset").addContent(T_help_wf_step2); + + + // data row + tableRow = rolesTable.addRow(Row.ROLE_DATA); + tableRow.addCell(Cell.ROLE_HEADER).addContent(T_label_wf_step3); + if (wfStep3 != null) + { + tableRow.addCell().addXref(baseURL + "&submit_edit_wf_step3", wfStep3.getName()); + tableRow.addCell().addButton("submit_delete_wf_step3").setValue(T_delete); + } + else + { + tableRow.addCell().addContent(T_no_role); + tableRow.addCell().addButton("submit_create_wf_step3").setValue(T_create); + } + // help and directions row + tableRow = rolesTable.addRow(Row.ROLE_DATA); + tableRow.addCell(); + tableRow.addCell(1,2).addHighlight("fade offset").addContent(T_help_wf_step3); + } + catch (AuthorizeException authex) { + // add a notice, the user is not allowed to manage workflow group + tableRow = rolesTable.addRow(Row.ROLE_DATA); + tableRow.addCell(Cell.ROLE_HEADER).addContent(T_label_wf); + tableRow.addCell().addContent(T_not_allowed); + } /* * The collection submitters */ tableRow = rolesTable.addRow(Row.ROLE_DATA); tableRow.addCell(Cell.ROLE_HEADER).addContent(T_label_submitters); - if (submitters != null) + try { - tableRow.addCell().addXref(baseURL + "&submit_edit_submit", submitters.getName()); - tableRow.addCell().addButton("submit_delete_submit").setValue(T_delete); + AuthorizeUtil.authorizeManageSubmittersGroup(context, thisCollection); + if (submitters != null) + { + tableRow.addCell().addXref(baseURL + "&submit_edit_submit", submitters.getName()); + tableRow.addCell().addButton("submit_delete_submit").setValue(T_delete); + } + else + { + tableRow.addCell().addContent(T_no_role); + tableRow.addCell().addButton("submit_create_submit").setValue(T_create); + } } - else + catch (AuthorizeException authex) { - tableRow.addCell().addContent(T_no_role); - tableRow.addCell().addButton("submit_create_submit").setValue(T_create); + tableRow.addCell().addContent(T_not_allowed); } // help and directions row tableRow = rolesTable.addRow(Row.ROLE_DATA); @@ -290,13 +335,16 @@ public class AssignCollectionRoles extends AbstractDSpaceTransformer tableRow.addCell(); tableRow.addCell(1,2).addHighlight("fade offset").addContent(T_help_default_read); - - if (AuthorizeManager.isAdmin(context)) + try { + AuthorizeUtil.authorizeManageCollectionPolicy(context, thisCollection); // add one last link to edit the raw authorizations Cell authCell =rolesTable.addRow().addCell(1,3); authCell.addXref(baseURL + "&submit_authorizations", T_edit_authorization); } + catch (AuthorizeException authex) { + // nothing to add, the user is not authorized to edit collection's policies + } Para buttonList = main.addPara(); buttonList.addButton("submit_return").setValue(T_submit_return); diff --git a/dspace-xmlui/dspace-xmlui-api/src/main/java/org/dspace/app/xmlui/aspect/administrative/community/AssignCommunityRoles.java b/dspace-xmlui/dspace-xmlui-api/src/main/java/org/dspace/app/xmlui/aspect/administrative/community/AssignCommunityRoles.java index 2bf66685d5..7bc4a2f118 100644 --- a/dspace-xmlui/dspace-xmlui-api/src/main/java/org/dspace/app/xmlui/aspect/administrative/community/AssignCommunityRoles.java +++ b/dspace-xmlui/dspace-xmlui-api/src/main/java/org/dspace/app/xmlui/aspect/administrative/community/AssignCommunityRoles.java @@ -41,6 +41,7 @@ package org.dspace.app.xmlui.aspect.administrative.community; import java.sql.SQLException; +import org.dspace.app.util.AuthorizeUtil; import org.dspace.app.xmlui.cocoon.AbstractDSpaceTransformer; import org.dspace.app.xmlui.wing.Message; import org.dspace.app.xmlui.wing.WingException; @@ -142,26 +143,55 @@ public class AssignCommunityRoles extends AbstractDSpaceTransformer tableRow.addCell(Cell.ROLE_HEADER).addContent(T_label_admins); if (admins != null) { - tableRow.addCell().addXref(baseURL + "&submit_edit_admin", admins.getName()); - tableRow.addCell().addButton("submit_delete_admin").setValue(T_delete); + try + { + AuthorizeUtil.authorizeManageAdminGroup(context, thisCommunity); + tableRow.addCell().addXref(baseURL + "&submit_edit_admin", admins.getName()); + } + catch (AuthorizeException authex) { + // add a notice, the user is not authorized to create/edit community's admin group + tableRow.addCell().addContent(T_sysadmins_only); + } + try + { + AuthorizeUtil.authorizeRemoveAdminGroup(context, thisCommunity); + tableRow.addCell().addButton("submit_delete_admin").setValue(T_delete); + } + catch (AuthorizeException authex) + { + // nothing to add, the user is not allowed to delete the group + } } else { tableRow.addCell().addContent(T_no_role); - tableRow.addCell().addButton("submit_create_admin").setValue(T_create); + Cell commAdminCell = tableRow.addCell(); + try + { + AuthorizeUtil.authorizeManageAdminGroup(context, thisCommunity); + commAdminCell.addButton("submit_create_admin").setValue(T_create); + } + catch (AuthorizeException authex) + { + // add a notice, the user is not authorized to create/edit community's admin group + addAdministratorOnlyButton(commAdminCell, "submit_create_admin", T_create); + } } // help and directions row tableRow = rolesTable.addRow(Row.ROLE_DATA); tableRow.addCell(); tableRow.addCell(1,2).addHighlight("fade offset").addContent(T_help_admins); - - if (AuthorizeManager.isAdmin(context)) + try { + AuthorizeUtil.authorizeManageCommunityPolicy(context, thisCommunity); // add one last link to edit the raw authorizations Cell authCell =rolesTable.addRow().addCell(1,3); authCell.addXref(baseURL + "&submit_authorizations", T_edit_authorizations); } + catch (AuthorizeException authex) { + // nothing to add, the user is not authorized to manage community's policies + } Para buttonList = main.addPara(); buttonList.addButton("submit_return").setValue(T_submit_return); diff --git a/dspace-xmlui/dspace-xmlui-api/src/main/java/org/dspace/app/xmlui/aspect/administrative/community/EditCommunityMetadataForm.java b/dspace-xmlui/dspace-xmlui-api/src/main/java/org/dspace/app/xmlui/aspect/administrative/community/EditCommunityMetadataForm.java index 9c61b7b4fa..a45f262e37 100644 --- a/dspace-xmlui/dspace-xmlui-api/src/main/java/org/dspace/app/xmlui/aspect/administrative/community/EditCommunityMetadataForm.java +++ b/dspace-xmlui/dspace-xmlui-api/src/main/java/org/dspace/app/xmlui/aspect/administrative/community/EditCommunityMetadataForm.java @@ -41,6 +41,7 @@ package org.dspace.app.xmlui.aspect.administrative.community; import java.sql.SQLException; +import org.dspace.app.util.AuthorizeUtil; import org.dspace.app.xmlui.aspect.administrative.FlowContainerUtils; import org.dspace.app.xmlui.cocoon.AbstractDSpaceTransformer; import org.dspace.app.xmlui.wing.Message; @@ -56,6 +57,7 @@ import org.dspace.app.xmlui.wing.element.TextArea; import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeManager; import org.dspace.content.Community; +import org.dspace.core.Constants; /** * Presents the user (in this case an administrator over the community) with the @@ -175,8 +177,8 @@ public class EditCommunityMetadataForm extends AbstractDSpaceTransformer Para buttonList = main.addPara(); buttonList.addButton("submit_save").setValue(T_submit_update); - //Only System Admins can Delete Communities - if (AuthorizeManager.isAdmin(context)) + + if (AuthorizeManager.authorizeActionBoolean(context, thisCommunity, Constants.DELETE)) { buttonList.addButton("submit_delete").setValue(T_submit_delete); } diff --git a/dspace-xmlui/dspace-xmlui-api/src/main/java/org/dspace/app/xmlui/aspect/administrative/item/EditItemBitstreamsForm.java b/dspace-xmlui/dspace-xmlui-api/src/main/java/org/dspace/app/xmlui/aspect/administrative/item/EditItemBitstreamsForm.java index fcaddd936d..dee54df4f4 100644 --- a/dspace-xmlui/dspace-xmlui-api/src/main/java/org/dspace/app/xmlui/aspect/administrative/item/EditItemBitstreamsForm.java +++ b/dspace-xmlui/dspace-xmlui-api/src/main/java/org/dspace/app/xmlui/aspect/administrative/item/EditItemBitstreamsForm.java @@ -234,7 +234,7 @@ public class EditItemBitstreamsForm extends AbstractDSpaceTransformer { // PARA: actions Para actions = main.addPara("editItemActionsP","editItemActionsP" ); // Only System Administrators can delete bitstreams - if (AuthorizeManager.isAdmin(context)) + if (AuthorizeManager.authorizeActionBoolean(context, item, Constants.REMOVE)) actions.addButton("submit_delete").setValue(T_submit_delete); else { diff --git a/dspace-xmlui/dspace-xmlui-api/src/main/java/org/dspace/app/xmlui/aspect/administrative/item/EditItemStatusForm.java b/dspace-xmlui/dspace-xmlui-api/src/main/java/org/dspace/app/xmlui/aspect/administrative/item/EditItemStatusForm.java index bb257dc44b..4f44fd1113 100644 --- a/dspace-xmlui/dspace-xmlui-api/src/main/java/org/dspace/app/xmlui/aspect/administrative/item/EditItemStatusForm.java +++ b/dspace-xmlui/dspace-xmlui-api/src/main/java/org/dspace/app/xmlui/aspect/administrative/item/EditItemStatusForm.java @@ -41,6 +41,7 @@ package org.dspace.app.xmlui.aspect.administrative.item; import java.sql.SQLException; +import org.dspace.app.util.AuthorizeUtil; import org.dspace.app.xmlui.cocoon.AbstractDSpaceTransformer; import org.dspace.app.xmlui.wing.Message; import org.dspace.app.xmlui.wing.WingException; @@ -49,10 +50,12 @@ import org.dspace.app.xmlui.wing.element.Button; import org.dspace.app.xmlui.wing.element.Division; import org.dspace.app.xmlui.wing.element.List; import org.dspace.app.xmlui.wing.element.PageMeta; +import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeManager; import org.dspace.content.Collection; import org.dspace.content.Item; import org.dspace.core.ConfigurationManager; +import org.dspace.core.Constants; /** * Display basic meta-meta information about the item and allow the user to change @@ -95,7 +98,7 @@ public class EditItemStatusForm extends AbstractDSpaceTransformer { private static final Message T_submit_delete = message("xmlui.administrative.item.EditItemStatusForm.submit_delete"); private static final Message T_na = message("xmlui.administrative.item.EditItemStatusForm.na"); - private static final Message T_sysadmins_only = message("xmlui.administrative.item.EditItemStatusForm.sysadmins_only"); + private static final Message T_not_allowed = message("xmlui.administrative.item.EditItemStatusForm.not_allowed"); private static final Message T_collectionadmins_only = message("xmlui.administrative.item.EditItemStatusForm.collection_admins_only"); @@ -170,24 +173,55 @@ public class EditItemStatusForm extends AbstractDSpaceTransformer { } itemInfo.addLabel(T_label_auth); - addAdministratorOnlyButton(itemInfo.addItem(), "submit_authorization", T_submit_authorizations); + try + { + AuthorizeUtil.authorizeManageItemPolicy(context, item); + itemInfo.addItem().addButton("submit_authorization").setValue(T_submit_authorizations); + } + catch (AuthorizeException authex) + { + addNotAllowedButton(itemInfo.addItem(), "submit_authorization", T_submit_authorizations); + } if(!item.isWithdrawn()) { itemInfo.addLabel(T_label_withdraw); - addAdministratorOnlyButton(itemInfo.addItem(), "submit_withdraw", T_submit_withdraw); + try + { + AuthorizeUtil.authorizeWithdrawItem(context, item); + itemInfo.addItem().addButton("submit_withdraw").setValue(T_submit_withdraw); + } + catch (AuthorizeException authex) + { + addNotAllowedButton(itemInfo.addItem(), "submit_withdraw", T_submit_withdraw); + } } else { itemInfo.addLabel(T_label_reinstate); - addAdministratorOnlyButton(itemInfo.addItem(), "submit_reinstate", T_submit_reinstate); + try + { + AuthorizeUtil.authorizeReinstateItem(context, item); + itemInfo.addItem().addButton("submit_reinstate").setValue(T_submit_reinstate); + } + catch (AuthorizeException authex) + { + addNotAllowedButton(itemInfo.addItem(), "submit_reinstate", T_submit_reinstate); + } } itemInfo.addLabel(T_label_move); addCollectionAdminOnlyButton(itemInfo.addItem(), item.getOwningCollection(), "submit_move", T_submit_move); itemInfo.addLabel(T_label_delete); - addAdministratorOnlyButton(itemInfo.addItem(), "submit_delete", T_submit_delete); + if (AuthorizeManager.authorizeActionBoolean(context, item, Constants.DELETE)) + { + itemInfo.addItem().addButton("submit_delete").setValue(T_submit_delete); + } + else + { + addNotAllowedButton(itemInfo.addItem(), "submit_delete", T_submit_delete); + } @@ -197,17 +231,21 @@ public class EditItemStatusForm extends AbstractDSpaceTransformer { main.addHidden("administrative-continue").setValue(knot.getId()); } - - private void addAdministratorOnlyButton(org.dspace.app.xmlui.wing.element.Item item, String buttonName, Message buttonLabel) throws WingException, SQLException + + /** + * Add a disabled button with a "not allowed" notice + * @param item + * @param buttonName + * @param buttonLabel + * @throws WingException + * @throws SQLException + */ + private void addNotAllowedButton(org.dspace.app.xmlui.wing.element.Item item, String buttonName, Message buttonLabel) throws WingException, SQLException { Button button = item.addButton(buttonName); button.setValue(buttonLabel); - if (!AuthorizeManager.isAdmin(context)) - { - // Only admins can create or delete - button.setDisabled(); - item.addHighlight("fade").addContent(T_sysadmins_only); - } + button.setDisabled(); + item.addHighlight("fade").addContent(T_not_allowed); } private void addCollectionAdminOnlyButton(org.dspace.app.xmlui.wing.element.Item item, Collection collection, String buttonName, Message buttonLabel) throws WingException, SQLException diff --git a/dspace-xmlui/dspace-xmlui-api/src/main/resources/aspects/Administrative/administrative.js b/dspace-xmlui/dspace-xmlui-api/src/main/resources/aspects/Administrative/administrative.js index 3c8234a794..6543a2ecb5 100644 --- a/dspace-xmlui/dspace-xmlui-api/src/main/resources/aspects/Administrative/administrative.js +++ b/dspace-xmlui/dspace-xmlui-api/src/main/resources/aspects/Administrative/administrative.js @@ -377,25 +377,10 @@ function assertAdminCommunity(communityID) { * Assert that the currently authenticated eperson can edit the given group. If they can * not then this method will never return. */ -function assertEditGroup(groupName) +function assertEditGroup(groupID) { // Check authorizations - var collectionID = FlowGroupUtils.getCollectionId(groupName); - var communityID = FlowGroupUtils.getCommunityId(groupName); - if (collectionID >= 0) - { - // This group is associated with a collection, check that group's permission - assertEditCollection(collectionID); - } - else if (communityID >= 0) - { - assertEditCommunity(communityID); - } - else - { - // Otherwise they need to be a super admin. - assertAdministrator(); - } + assertAuthorized(Constants.GROUP, groupID, Constants.WRITE); } /** @@ -921,7 +906,7 @@ function doEditGroup(groupID) var memberEPeopleIDs = FlowGroupUtils.getEPeopleMembers(getDSContext(),groupID); var memberGroupIDs = FlowGroupUtils.getGroupMembers(getDSContext(),groupID); - assertEditGroup(groupName); + assertEditGroup(groupID); var highlightEPersonID; var highlightGroupID; @@ -931,7 +916,7 @@ function doEditGroup(groupID) var result = null; do { sendPageAndWait("admin/group/edit",{"groupID":groupID,"groupName":groupName,"memberGroupIDs":memberGroupIDs.join(','),"memberEPeopleIDs":memberEPeopleIDs.join(','),"highlightEPersonID":highlightEPersonID,"highlightGroupID":highlightGroupID,"query":escape(query),"page":page,"type":type},result); - assertEditGroup(groupName); + assertEditGroup(groupID); result = null; highlightEPersonID = null; @@ -990,8 +975,6 @@ function doEditGroup(groupID) else if (cocoon.request.get("submit_edit_group") && cocoon.request.get("groupID")) { // Jump to another group. - assertAdministrator(); - var newGroupID = cocoon.request.get("groupID"); result = doEditGroup(newGroupID); // ahhh recursion! @@ -1469,7 +1452,7 @@ function doEditItemStatus(itemID) } else if (cocoon.request.get("submit_delete")) { - assertAdministrator(); + assertAuthorized(Constants.ITEM, itemID, Constants.DELETE); // Confirm the item's deletion result = doDeleteItem(itemID); @@ -1497,7 +1480,8 @@ function doEditItemStatus(itemID) else if (cocoon.request.get("submit_authorization")) { // Edit the authorizations for this - assertAdministrator(); + // authorization check performed by the doAuthorize methods in FlowAuthorizationUtils + // assertAdministrator(); doAuthorizeItem(itemID); } @@ -1585,14 +1569,14 @@ function doEditItemMetadata(itemID, templateCollectionID) */ function doDeleteItem(itemID) { - assertAdministrator(); + assertAuthorized(Constants.ITEM, itemID, Constants.DELETE); sendPageAndWait("admin/item/delete",{"itemID":itemID}); if (cocoon.request.get("submit_confirm")) { // It's been confirmed, delete the item. - assertAdministrator(); + assertAuthorized(Constants.ITEM, itemID, Constants.DELETE); var result = FlowItemUtils.processDeleteItem(getDSContext(),itemID); if (result.getContinue()) { @@ -1611,14 +1595,16 @@ function doDeleteItem(itemID) */ function doWithdrawItem(itemID) { - assertAdministrator(); + // authorization check performed directly by the dspace-api + // assertAdministrator(); sendPageAndWait("admin/item/withdraw",{"itemID":itemID}); if (cocoon.request.get("submit_confirm")) { // Actualy withdraw the item - assertAdministrator(); + // authorization check performed directly by the dspace-api + // assertAdministrator(); var result = FlowItemUtils.processWithdrawItem(getDSContext(),itemID); return result; } @@ -1630,14 +1616,16 @@ function doWithdrawItem(itemID) */ function doReinstateItem(itemID) { - assertAdministrator(); + // authorization check performed directly by the dspace-api + // assertAdministrator(); sendPageAndWait("admin/item/reinstate",{"itemID":itemID}); if (cocoon.request.get("submit_confirm")) { // Actually reinstate the item - assertAdministrator(); + // authorization check performed directly by the dspace-api + // assertAdministrator(); var result = FlowItemUtils.processReinstateItem(getDSContext(),itemID); return result; @@ -1855,7 +1843,8 @@ function doMapItemBrowse(collectionID) */ function doManageAuthorizations() { - assertAdministrator(); + // authorization check moved to FlowAuthorizationUtils + // assertAdministrator(); var result = null; var query = ""; @@ -1863,7 +1852,8 @@ function doManageAuthorizations() do { sendPageAndWait("admin/authorize/main",{"query":escape(query)},result); - assertAdministrator(); + // authorization check moved to FlowAuthorizationUtils + // assertAdministrator(); result = null; @@ -1930,15 +1920,17 @@ function doAuthorizeCommunity(communityID) */ function doAuthorizeContainer(containerType, containerID) { - //must be an ADMIN on the container to change its authorizations - assertAuthorized(containerType, containerID, Constants.ADMIN); + // authorization check moved to FlowAuthorizationUtils + // must be an ADMIN on the container to change its authorizations + // assertAuthorized(containerType, containerID, Constants.ADMIN); var result; var highlightID; do { sendPageAndWait("admin/authorize/container",{"containerType":containerType,"containerID":containerID,"highlightID":highlightID},result); - assertAuthorized(containerType, containerID, Constants.ADMIN); + // authorization check moved to FlowAuthorizationUtils + // assertAuthorized(containerType, containerID, Constants.ADMIN); result = null; // Cancel out the operation @@ -1979,14 +1971,16 @@ function doAuthorizeContainer(containerType, containerID) */ function doAuthorizeItem(itemID) { - assertAdministrator(); + // authorization check moved to FlowAuthorizationUtils + // assertAdministrator(); var result; var highlightID; do { sendPageAndWait("admin/authorize/item",{"itemID":itemID,"highlightID":highlightID},result); - assertAdministrator(); + // authorization check moved to FlowAuthorizationUtils + // assertAdministrator(); result = null; var bundleID = extractSubmitSuffix("submit_add_bundle_"); @@ -2088,7 +2082,8 @@ function doAdvancedAuthorization() */ function doEditPolicy(objectType,objectID,policyID) { - assertAdministrator(); + // authorize check moved to FlowAuthorizationUtils.processEditPolicy + // assertAdministrator(); var result; var query= "-1"; @@ -2101,7 +2096,8 @@ function doEditPolicy(objectType,objectID,policyID) * policy ID, the group search query (if a search was performed), the ID of the currenly associated group, the * current action and the currently viewed page (if a search returned more than one page of results) */ sendPageAndWait("admin/authorize/edit",{"objectType":objectType,"objectID":objectID,"policyID":policyID,"query":escape(query),"groupID":groupID,"actionID":actionID,"page":page},result); - assertAdministrator(); + // authorize check moved to FlowAuthorizationUtils.processEditPolicy + // assertAdministrator(); result = null; // Figure out which button was pressed on the group search results page @@ -2166,13 +2162,15 @@ function doEditPolicy(objectType,objectID,policyID) */ function doDeletePolicies(policyIDs) { - assertAdministrator(); + // authorization check moved to FlowAuthorizationUtils + // assertAdministrator(); sendPageAndWait("admin/authorize/delete",{"policyIDs":policyIDs.join(',')}); if (cocoon.request.get("submit_confirm")) { // The user has confirmed, actualy delete these policies - assertAdministrator(); + // authorization check moved to FlowAuthorizationUtils + // assertAdministrator(); var result = FlowAuthorizationUtils.processDeletePolicies(getDSContext(),policyIDs); return result; @@ -2316,7 +2314,7 @@ function doAssignCollectionRoles(collectionID) else if (cocoon.request.get("submit_authorizations")) { // general authorizations - assertAdminCollection(collectionID); + // assertAdminCollection(collectionID); result = doAuthorizeCollection(collectionID); } @@ -2407,7 +2405,7 @@ function doAssignCollectionRoles(collectionID) */ function doSetupCollectionHarvesting(collectionID) { - assertEditCollection(collectionID); + assertAdminCollection(collectionID); var result = null; var oaiProviderValue = null; @@ -2423,7 +2421,7 @@ function doSetupCollectionHarvesting(collectionID) metadataFormatValue = cocoon.request.get("metadata_format"); harvestLevelValue = cocoon.request.get("harvest_level"); - assertEditCollection(collectionID); + assertAdminCollection(collectionID); if (cocoon.request.get("submit_return") || cocoon.request.get("submit_metadata") || cocoon.request.get("submit_roles") || cocoon.request.get("submit_harvesting")) @@ -2453,7 +2451,7 @@ function doSetupCollectionHarvesting(collectionID) */ function doEditCollectionHarvesting(collectionID) { - assertEditCollection(collectionID); + assertAdminCollection(collectionID); var result = null; do @@ -2470,7 +2468,7 @@ function doEditCollectionHarvesting(collectionID) } result = null; - assertEditCollection(collectionID); + assertAdminCollection(collectionID); if (cocoon.request.get("submit_return") || cocoon.request.get("submit_metadata") || cocoon.request.get("submit_roles") || cocoon.request.get("submit_harvesting")) @@ -2544,10 +2542,10 @@ function doDeleteCollectionRole(collectionID,role) */ function doDeleteCollection(collectionID) { - assertAdministrator(); + assertAuthorized(Constants.COLLECTION, collectionID, Constants.DELETE); sendPageAndWait("admin/collection/delete",{"collectionID":collectionID}); - assertAdministrator(); + assertAuthorized(Constants.COLLECTION, collectionID, Constants.DELETE); if (cocoon.request.get("submit_confirm")) { @@ -2668,7 +2666,7 @@ function doEditCommunity(communityID) } else if (cocoon.request.get("submit_delete")) { - assertAdministrator(); + assertAuthorized(Constants.COMMUNITY, communityID, Constants.DELETE); result = doDeleteCommunity(communityID); } else if (cocoon.request.get("submit_delete_logo")) @@ -2677,7 +2675,8 @@ function doEditCommunity(communityID) } if (cocoon.request.get("submit_authorizations")) { - assertAdministrator(); + // authorization check moved to FlowAuthorizationUtils + // assertAdministrator(); result = doAuthorizeCommunity(communityID); } @@ -2692,10 +2691,10 @@ function doEditCommunity(communityID) * Delete an entire community, asking for a confirmation first */ function doDeleteCommunity(communityID) { - assertAdministrator(); + assertAuthorized(Constants.COMMUNITY, communityID, Constants.DELETE); sendPageAndWait("admin/community/delete",{"communityID":communityID}); - assertAdministrator(); + assertAuthorized(Constants.COMMUNITY, communityID, Constants.DELETE); if (cocoon.request.get("submit_confirm")) { @@ -2731,8 +2730,8 @@ function doAssignCommunityRoles(communityID) else if (cocoon.request.get("submit_authorizations")) { - // general authorizations - assertAdministrator(); + // authorization check moved to FlowAuthorizationUtils + // assertAdministrator(); result = doAuthorizeCommunity(communityID); } @@ -2756,11 +2755,13 @@ function doAssignCommunityRoles(communityID) */ function doDeleteCommunityRole(communityID,role) { - assertAdminCommunity(communityID); - var groupID = FlowContainerUtils.getCommunityRole(getDSContext(), communityID, role); + // authorization check performed directly by the dspace-api + // assertAdminCommunity(communityID); + var groupID = FlowContainerUtils.getCommunityRole(getDSContext(), communityID, role); sendPageAndWait("admin/community/deleteRole",{"communityID":communityID,"role":role,"groupID":groupID}); - assertAdminCommunity(communityID); + // authorization check performed directly by the dspace-api + // assertAdminCommunity(communityID); if (cocoon.request.get("submit_confirm")) { diff --git a/dspace-xmlui/dspace-xmlui-webapp/src/main/webapp/i18n/messages.xml b/dspace-xmlui/dspace-xmlui-webapp/src/main/webapp/i18n/messages.xml index 724713906a..692f121667 100644 --- a/dspace-xmlui/dspace-xmlui-webapp/src/main/webapp/i18n/messages.xml +++ b/dspace-xmlui/dspace-xmlui-webapp/src/main/webapp/i18n/messages.xml @@ -1346,7 +1346,7 @@ n/a (system administrators only) (collection administrators only) - + (you are not allowed to performe this action) View Item @@ -1421,12 +1421,14 @@ Associated group Administrators + Workflow steps Accept/Reject Step Accept/Reject/Edit Metadata Step Edit Metadata Step Submitters Default read access (system administrators only) + (you are not allowed to configure this) Confirm Deletion diff --git a/dspace/CHANGES b/dspace/CHANGES index 5a686d0c6e..630e8d8467 100644 --- a/dspace/CHANGES +++ b/dspace/CHANGES @@ -79,6 +79,7 @@ - [DS-271] Make the OAI DC crosswalk configurable - [DS-260] Template item some times has owningCollection filled and some times not - [DS-309] Shiboleth default roles are applied also to anonymous user and user logged-in with other methods + - [DS-270] Make delegate admin permissions configurable (Tim Donohue) - [DS-218] Cannot add/remove email subscriptions from Profile page in XMLUI diff --git a/dspace/config/dspace.cfg b/dspace/config/dspace.cfg index 0106b1503f..568f31d345 100644 --- a/dspace/config/dspace.cfg +++ b/dspace/config/dspace.cfg @@ -292,6 +292,53 @@ handle.prefix = 123456789 # Directory for installing Handle server files handle.dir = ${dspace.dir}/handle-server +##### Authorization system configuration - Delegate ADMIN ##### + +# COMMUNITY ADMIN configuration +# subcommunities and collections +#core.authorization.community-admin.create-subelement = true +#core.authorization.community-admin.delete-subelement = true +# his community +#core.authorization.community-admin.policies = true +#core.authorization.community-admin.admin-group = true +# collections in his community +#core.authorization.community-admin.collection.policies = true +#core.authorization.community-admin.collection.template-item = true +#core.authorization.community-admin.collection.submitters = true +#core.authorization.community-admin.collection.workflows = true +#core.authorization.community-admin.collection.admin-group = true +# item owned by collections in his community +#core.authorization.community-admin.item.delete = true +#core.authorization.community-admin.item.withdraw = true +#core.authorization.community-admin.item.reinstatiate = true +#core.authorization.community-admin.item.policies = true +# also bundle... +#core.authorization.community-admin.item.create-bitstream = true +#core.authorization.community-admin.item.delete-bitstream = true +#core.authorization.community-admin.item-admin.cc-license = true + +# COLLECTION ADMIN +#core.authorization.collection-admin.policies = true +#core.authorization.collection-admin.template-item = true +#core.authorization.collection-admin.submitters = true +#core.authorization.collection-admin.workflows = true +#core.authorization.collection-admin.admin-group = true +# item owned by his collection +#core.authorization.collection-admin.item.delete = true +#core.authorization.collection-admin.item.withdraw = true +#core.authorization.collection-admin.item.reinstatiate = true +#core.authorization.collection-admin.item.policies = true +# also bundle... +#core.authorization.collection-admin.item.create-bitstream = true +#core.authorization.collection-admin.item.delete-bitstream = true +#core.authorization.collection-admin.item-admin.cc-license = true + +# ITEM ADMIN +#core.authorization.item-admin.policies = true +# also bundle... +#core.authorization.item-admin.create-bitstream = true +#core.authorization.item-admin.delete-bitstream = true +#core.authorization.item-admin.cc-license = true #### Stackable Authentication Methods ##### diff --git a/dspace/etc/database_schema.sql b/dspace/etc/database_schema.sql index 8b8960f1ff..38978522e9 100644 --- a/dspace/etc/database_schema.sql +++ b/dspace/etc/database_schema.sql @@ -385,7 +385,8 @@ CREATE TABLE Community2Community ( id INTEGER PRIMARY KEY, parent_comm_id INTEGER REFERENCES Community(community_id), - child_comm_id INTEGER REFERENCES Community(community_id) + child_comm_id INTEGER, + CONSTRAINT com2com_child_fk FOREIGN KEY (child_comm_id) REFERENCES Community(community_id) DEFERRABLE ); CREATE INDEX com2com_parent_fk_idx ON Community2Community(parent_comm_id); @@ -398,7 +399,8 @@ CREATE TABLE Community2Collection ( id INTEGER PRIMARY KEY, community_id INTEGER REFERENCES Community(community_id), - collection_id INTEGER REFERENCES Collection(collection_id) + collection_id INTEGER, + CONSTRAINT comm2coll_collection_fk FOREIGN KEY (collection_id) REFERENCES Collection(collection_id) DEFERRABLE ); -- Index on community ID @@ -413,7 +415,8 @@ CREATE TABLE Collection2Item ( id INTEGER PRIMARY KEY, collection_id INTEGER REFERENCES Collection(collection_id), - item_id INTEGER REFERENCES Item(item_id) + item_id INTEGER, + CONSTRAINT coll2item_item_fk FOREIGN KEY (item_id) REFERENCES Item(item_id) DEFERRABLE ); -- index by collection_id diff --git a/dspace/etc/database_schema_15-16.sql b/dspace/etc/database_schema_15-16.sql index 867608e89e..3e3b07cb47 100644 --- a/dspace/etc/database_schema_15-16.sql +++ b/dspace/etc/database_schema_15-16.sql @@ -95,3 +95,12 @@ CREATE INDEX harvested_item_fk_idx ON harvested_item(item_id); ------------------------------------------------------------------------- UPDATE item SET owning_collection = null WHERE item_id IN (SELECT template_item_id FROM collection WHERE template_item_id IS NOT null); + +ALTER TABLE community2collection DROP CONSTRAINT community2collection_collection_id_fkey; +ALTER TABLE community2collection ADD CONSTRAINT comm2coll_collection_fk FOREIGN KEY (collection_id) REFERENCES collection DEFERRABLE; + +ALTER TABLE community2community DROP CONSTRAINT community2community_child_comm_id_fkey; +ALTER TABLE community2community ADD CONSTRAINT com2com_child_fk FOREIGN KEY (child_comm_id) REFERENCES community DEFERRABLE; + +ALTER TABLE collection2item DROP CONSTRAINT collection2item_item_id_fkey; +ALTER TABLE collection2item ADD CONSTRAINT coll2item_item_fk FOREIGN KEY (item_id) REFERENCES item DEFERRABLE; diff --git a/dspace/etc/oracle/database_schema.sql b/dspace/etc/oracle/database_schema.sql index cf75b563c8..506d9f2b64 100644 --- a/dspace/etc/oracle/database_schema.sql +++ b/dspace/etc/oracle/database_schema.sql @@ -350,7 +350,8 @@ CREATE TABLE Community2Community ( id INTEGER PRIMARY KEY, parent_comm_id INTEGER REFERENCES Community(community_id), - child_comm_id INTEGER REFERENCES Community(community_id) + child_comm_id INTEGER, + CONSTRAINT com2com_child_fk FOREIGN KEY (child_comm_id) REFERENCES Community(community_id) DEFERRABLE ); CREATE INDEX com2com_parent_fk_idx ON Community2Community(parent_comm_id); @@ -363,7 +364,8 @@ CREATE TABLE Community2Collection ( id INTEGER PRIMARY KEY, community_id INTEGER REFERENCES Community(community_id), - collection_id INTEGER REFERENCES Collection(collection_id) + collection_id INTEGER, + CONSTRAINT comm2coll_collection_fk FOREIGN KEY (collection_id) REFERENCES Collection(collection_id) DEFERRABLE ); -- Improve mapping tables @@ -377,7 +379,8 @@ CREATE TABLE Collection2Item ( id INTEGER PRIMARY KEY, collection_id INTEGER REFERENCES Collection(collection_id), - item_id INTEGER REFERENCES Item(item_id) + item_id INTEGER, + CONSTRAINT coll2item_item_fk FOREIGN KEY (item_id) REFERENCES Item(item_id) DEFERRABLE ); -- index by collection_id diff --git a/dspace/etc/oracle/database_schema_15-16.sql b/dspace/etc/oracle/database_schema_15-16.sql index f0e38bab46..1d72c04c8d 100644 --- a/dspace/etc/oracle/database_schema_15-16.sql +++ b/dspace/etc/oracle/database_schema_15-16.sql @@ -50,8 +50,45 @@ ALTER TABLE community ADD admin INTEGER REFERENCES epersongroup ( eperson_group_ CREATE INDEX community_admin_fk_idx ON Community(admin); ------------------------------------------------------------------------- --- DS-260 Cleanup of Owning collection column for template item created +-- DS-260 Cleanup of Owning collection column for template item created -- with the JSPUI after the collection creation ------------------------------------------------------------------------- -UPDATE item SET owning_collection = null WHERE item_id IN - (SELECT template_item_id FROM collection WHERE template_item_id IS NOT null); \ No newline at end of file +UPDATE item SET owning_collection = null WHERE item_id IN + (SELECT template_item_id FROM collection WHERE template_item_id IS NOT null); + +------------------------------------------------------------------------------------------------------ +-- You need to remove the already in place constraints to add the deferrable option +-- because the constraints name was generated by your oracle instance you need to discovery it before +-- Just copy and paste the commands printed by these three queries: + +-- 1. community2collection +select 'ALTER TABLE '||c1.table_name||' DROP CONSTRAINT '|| + c1.constraint_name||';' command from user_constraints c1, user_constraints c2 + where c1.constraint_type = 'R' and c1.r_constraint_name = c2.constraint_name + and c1.table_name like 'COMMUNITY2COLLECTION' + and c2.table_name LIKE 'COLLECTION'; + +-- 2. community2community +select 'ALTER TABLE '||c1.table_name||' DROP CONSTRAINT '|| + c1.constraint_name||';' command from user_constraints c1, user_constraints c2 + where c1.constraint_type = 'R' and c1.r_constraint_name = c2.constraint_name + and c1.table_name like 'COMMUNITY2COMMUNITY' + and c2.table_name LIKE 'COMMUNITY'; + +-- 3. collection2item +select 'ALTER TABLE '||c1.table_name||' DROP CONSTRAINT '|| + c1.constraint_name||';' command from user_constraints c1, user_constraints c2 + where c1.constraint_type = 'R' and c1.r_constraint_name = c2.constraint_name + and c1.table_name like 'COLLECTION2ITEM' + and c2.table_name LIKE 'ITEM'; + +-- +-- e.g. +-- ALTER TABLE community2collection DROP CONSTRAINT THECONSTRAINTNAMETHATYOUHAVEFINDWITHTHE1stQUERY; +-- ALTER TABLE community2community DROP CONSTRAINT THECONSTRAINTNAMETHATYOUHAVEFINDWITHTHE2ndQUERY; +-- ALTER TABLE collection2item DROP CONSTRAINT THECONSTRAINTNAMETHATYOUHAVEFINDWITHTHE3rdQUERY; + +-- now recreate them with a know name and deferrable option! +select 'ALTER TABLE community2collection ADD CONSTRAINT comm2coll_collection_fk FOREIGN KEY (collection_id) REFERENCES collection DEFERRABLE;' from dual; +select 'ALTER TABLE community2community ADD CONSTRAINT com2com_child_fk FOREIGN KEY (child_comm_id) REFERENCES community DEFERRABLE;' from dual; +select 'ALTER TABLE collection2item ADD CONSTRAINT coll2item_item_fk FOREIGN KEY (item_id) REFERENCES item DEFERRABLE;' from dual; \ No newline at end of file