/** * Get an array of all the collections that the current SWORD context will allow deposit onto in * the given DSpace context * * <p>The user may submit to a community if the following conditions are met: * * <p>IF: the authenticated user is an administrator AND: (the on-behalf-of user is an * administrator OR the on-behalf-of user is authorised to READ OR the on-behalf-of user is null) * OR IF: the authenticated user is authorised to READ AND: (the on-behalf-of user is an * administrator OR the on-behalf-of user is authorised to READ OR the on-behalf-of user is null) * * @param community * @return the array of allowed collections * @throws DSpaceSwordException */ public List<Community> getCommunities(SwordContext swordContext, Community community) throws DSpaceSwordException { // a community is allowed if the following conditions are met // // - the authenticated user is an administrator // -- the on-behalf-of user is an administrator // -- the on-behalf-of user is authorised to READ // -- the on-behalf-of user is null // - the authenticated user is authorised to READ // -- the on-behalf-of user is an administrator // -- the on-behalf-of user is authorised to READ // -- the on-behalf-of user is null try { Community[] comms = community.getSubcommunities(); List<Community> allowed = new ArrayList<Community>(); for (int i = 0; i < comms.length; i++) { boolean authAllowed = false; boolean oboAllowed = false; // check for obo null if (swordContext.getOnBehalfOf() == null) { oboAllowed = true; } // look up the READ policy on the community. This will include determining if the user is // an administrator // so we do not need to check that separately if (!authAllowed) { authAllowed = AuthorizeManager.authorizeActionBoolean( swordContext.getAuthenticatorContext(), comms[i], Constants.READ); } // if we have not already determined that the obo user is ok to submit, look up the READ // policy on the // community. THis will include determining if the user is an administrator. if (!oboAllowed) { oboAllowed = AuthorizeManager.authorizeActionBoolean( swordContext.getOnBehalfOfContext(), comms[i], Constants.READ); } // final check to see if we are allowed to READ if (authAllowed && oboAllowed) { allowed.add(comms[i]); } } return allowed; } catch (SQLException e) { log.error("Caught exception: ", e); throw new DSpaceSwordException(e); } }
/** * Is the given onBehalfOf user DSpace administrator? This translates as asking the question of * whether the given eperson is a member of the special DSpace group Administrator, with id 1 * * @param swordContext * @return true if administrator, false if not * @throws java.sql.SQLException */ public boolean isOnBehalfOfAdmin(SwordContext swordContext) throws DSpaceSwordException { EPerson onBehalfOf = swordContext.getOnBehalfOf(); try { if (onBehalfOf != null) { return AuthorizeManager.isAdmin(swordContext.getOnBehalfOfContext()); } return false; } catch (SQLException e) { log.error("Caught exception: ", e); throw new DSpaceSwordException(e); } }
/** * Is the authenticated user a DSpace administrator? This translates as asking the question of * whether the given eperson is a member of the special DSpace group Administrator, with id 1 * * @param swordContext * @return true if administrator, false if not * @throws java.sql.SQLException */ public boolean isUserAdmin(SwordContext swordContext) throws DSpaceSwordException { try { EPerson authenticated = swordContext.getAuthenticated(); if (authenticated != null) { return AuthorizeManager.isAdmin(swordContext.getAuthenticatorContext()); } return false; } catch (SQLException e) { log.error("Caught exception: ", e); throw new DSpaceSwordException(e); } }
/** * Get an array of all the collections that the current SWORD context will allow deposit onto in * the given DSpace context * * <p>IF: the authenticated user is an administrator AND: (the on-behalf-of user is an * administrator OR the on-behalf-of user is authorised to ADD OR the on-behalf-of user is null) * OR IF: the authenticated user is authorised to ADD AND: (the on-behalf-of user is an * administrator OR the on-behalf-of user is authorised to ADD OR the on-behalf-of user is null) * * @param swordContext * @return the array of allowed collections * @throws DSpaceSwordException */ public List<org.dspace.content.Collection> getAllowedCollections( SwordContext swordContext, Community community) throws DSpaceSwordException { // a collection is allowed if the following conditions are met // // - the authenticated user is an administrator // -- the on-behalf-of user is an administrator // -- the on-behalf-of user is authorised to ADD // -- the on-behalf-of user is null // - the authenticated user is authorised to ADD // -- the on-behalf-of user is an administrator // -- the on-behalf-of user is authorised to ADD // -- the on-behalf-of user is null try { // get the context of the authenticated user Context authContext = swordContext.getAuthenticatorContext(); // short cut by obtaining the collections to which the authenticated user can submit org.dspace.content.Collection[] cols = org.dspace.content.Collection.findAuthorized(authContext, community, Constants.ADD); List<org.dspace.content.Collection> allowed = new ArrayList<org.dspace.content.Collection>(); // now find out if the obo user is allowed to submit to any of these collections for (int i = 0; i < cols.length; i++) { boolean oboAllowed = false; // check for obo null if (swordContext.getOnBehalfOf() == null) { oboAllowed = true; } // if we have not already determined that the obo user is ok to submit, look up the READ // policy on the // community. THis will include determining if the user is an administrator. if (!oboAllowed) { oboAllowed = AuthorizeManager.authorizeActionBoolean( swordContext.getOnBehalfOfContext(), cols[i], Constants.ADD); } // final check to see if we are allowed to READ if (oboAllowed) { allowed.add(cols[i]); } } return allowed; } catch (SQLException e) { log.error("Caught exception: ", e); throw new DSpaceSwordException(e); } }
public boolean canSubmitTo(SwordContext swordContext, Item item) throws DSpaceSwordException { // a context can submit to an item if the following are satisfied // // 1/ the primary authenticating user is authenticated (which is implicit // in there being a context in the first place) // 2/ If an On-Behalf-Of request, the On-Behalf-Of user is authorised to // carry out the action and the authenticating user is in the list // of allowed mediaters // 3/ If not an On-Behalf-Of request, the authenticating user is authorised // to carry out the action try { boolean isObo = swordContext.getOnBehalfOf() != null; Context allowContext = null; if (isObo) { // we need to find out if the authenticated user is permitted to mediate if (!this.allowedToMediate(swordContext.getAuthenticatorContext())) { return false; } allowContext = swordContext.getOnBehalfOfContext(); } else { allowContext = swordContext.getAuthenticatorContext(); } // we now need to check whether the selected context that we are authorising // has the appropriate permissions boolean write = AuthorizeManager.authorizeActionBoolean(allowContext, item, Constants.WRITE); Bundle[] bundles = item.getBundles("ORIGINAL"); boolean add = false; if (bundles.length == 0) { add = AuthorizeManager.authorizeActionBoolean(allowContext, item, Constants.ADD); } else { for (int i = 0; i < bundles.length; i++) { add = AuthorizeManager.authorizeActionBoolean(allowContext, bundles[i], Constants.ADD); if (!add) { break; } } } boolean allowed = write && add; return allowed; } catch (SQLException e) { log.error("Caught exception: ", e); throw new DSpaceSwordException(e); } }
/** * Can the current SWORD Context permit deposit into the given collection in the given DSpace * Context * * <p>IF: the authenticated user is an administrator AND: (the on-behalf-of user is an * administrator OR the on-behalf-of user is authorised to ADD OR the on-behalf-of user is null) * OR IF: the authenticated user is authorised to ADD AND: (the on-behalf-of user is an * administrator OR the on-behalf-of user is authorised to ADD OR the on-behalf-of user is null) * * @param swordContext * @param collection * @return * @throws DSpaceSwordException */ public boolean canSubmitTo(SwordContext swordContext, org.dspace.content.Collection collection) throws DSpaceSwordException { // a user can submit to a collection in the following conditions: // // - the authenticated user is an administrator // -- the on-behalf-of user is an administrator // -- the on-behalf-of user is authorised to ADD/in the submission group // -- the on-behalf-of user is null // - the authenticated user is authorised to ADD/in the submission group // -- the on-behalf-of user is an administrator // -- the on-behalf-of user is authorised to ADD/in the submission group // -- the on-behalf-of user is null try { boolean authAllowed = false; boolean oboAllowed = false; // check for obo null if (swordContext.getOnBehalfOf() == null) { oboAllowed = true; } // look up the READ policy on the collection. This will include determining if the user is an // administrator // so we do not need to check that separately if (!authAllowed) { authAllowed = AuthorizeManager.authorizeActionBoolean( swordContext.getAuthenticatorContext(), collection, Constants.ADD); } // if we have not already determined that the obo user is ok to submit, look up the READ // policy on the // community. THis will include determining if the user is an administrator. if (!oboAllowed) { oboAllowed = AuthorizeManager.authorizeActionBoolean( swordContext.getOnBehalfOfContext(), collection, Constants.ADD); } // final check to see if we are allowed to READ return (authAllowed && oboAllowed); } catch (SQLException e) { log.error("Caught exception: ", e); throw new DSpaceSwordException(e); } }
/** * Is the onBehalfOf user a member of the given group or one of its sub groups * * @param group * @return */ public boolean isOnBehalfOfInGroup(SwordContext swordContext, Group group) { EPerson onBehalfOf = swordContext.getOnBehalfOf(); if (onBehalfOf != null) { return isInGroup(group, onBehalfOf); } return false; }
/** * Is the authenticated user a member of the given group or one of its sub groups? * * @param group * @return */ public boolean isUserInGroup(SwordContext swordContext, Group group) { EPerson authenticated = swordContext.getAuthenticated(); if (authenticated != null) { return isInGroup(group, authenticated); } return false; }
/** * Get a list of all the items that the current SWORD context will allow deposit onto in the given * DSpace context * * <p>IF: the authenticated user is an administrator AND: (the on-behalf-of user is an * administrator OR the on-behalf-of user is authorised to WRITE on the item and ADD on the * ORIGINAL bundle OR the on-behalf-of user is null) OR IF: the authenticated user is authorised * to WRITE on the item and ADD on the ORIGINAL bundle AND: (the on-behalf-of user is an * administrator OR the on-behalf-of user is authorised to WRITE on the item and ADD on the * ORIGINAL bundle OR the on-behalf-of user is null) * * @param swordContext * @return the array of allowed collections * @throws DSpaceSwordException */ public List<Item> getAllowedItems( SwordContext swordContext, org.dspace.content.Collection collection) throws DSpaceSwordException { // an item is allowed if the following conditions are met // // - the authenticated user is an administrator // -- the on-behalf-of user is an administrator // -- the on-behalf-of user is authorised to WRITE on the item and ADD on the ORIGINAL bundle // -- the on-behalf-of user is null // - the authenticated user is authorised to WRITE on the item and ADD on the ORIGINAL bundle // -- the on-behalf-of user is an administrator // -- the on-behalf-of user is authorised to WRITE on the item and ADD on the ORIGINAL bundle // -- the on-behalf-of user is null try { List<Item> allowed = new ArrayList<Item>(); ItemIterator ii = collection.getItems(); while (ii.hasNext()) { Item item = ii.next(); boolean authAllowed = false; boolean oboAllowed = false; // check for obo null if (swordContext.getOnBehalfOf() == null) { oboAllowed = true; } // get the "ORIGINAL" bundle(s) Bundle[] bundles = item.getBundles("ORIGINAL"); // look up the READ policy on the community. This will include determining if the user is // an administrator // so we do not need to check that separately if (!authAllowed) { boolean write = AuthorizeManager.authorizeActionBoolean( swordContext.getAuthenticatorContext(), item, Constants.WRITE); boolean add = false; if (bundles.length == 0) { add = AuthorizeManager.authorizeActionBoolean( swordContext.getAuthenticatorContext(), item, Constants.ADD); } else { for (int i = 0; i < bundles.length; i++) { add = AuthorizeManager.authorizeActionBoolean( swordContext.getAuthenticatorContext(), bundles[i], Constants.ADD); if (!add) { break; } } } authAllowed = write && add; } // if we have not already determined that the obo user is ok to submit, look up the READ // policy on the // community. THis will include determining if the user is an administrator. if (!oboAllowed) { boolean write = AuthorizeManager.authorizeActionBoolean( swordContext.getOnBehalfOfContext(), item, Constants.WRITE); boolean add = false; if (bundles.length == 0) { add = AuthorizeManager.authorizeActionBoolean( swordContext.getAuthenticatorContext(), item, Constants.ADD); } else { for (int i = 0; i < bundles.length; i++) { add = AuthorizeManager.authorizeActionBoolean( swordContext.getAuthenticatorContext(), bundles[i], Constants.ADD); if (!add) { break; } } } oboAllowed = write && add; } // final check to see if we are allowed to READ if (authAllowed && oboAllowed) { allowed.add(item); } } return allowed; } catch (SQLException e) { throw new DSpaceSwordException(e); } }
/** * Authenticate the given username/password pair, in conjunction with the onBehalfOf user. The * rules are that the username/password pair must successfully authenticate the user, and the * onBehalfOf user must exist in the user database. * * @param context * @param auth * @return a SWORD context holding the various user information * @throws SwordAuthException * @throws SwordError * @throws DSpaceSwordException */ private SwordContext authenticate(Context context, AuthCredentials auth) throws SwordAuthException, SwordError, DSpaceSwordException { String obo = auth.getOnBehalfOf(); String un = auth.getUsername(); String pw = auth.getPassword(); // smooth out the OnBehalfOf request, so that empty strings are // treated as null if ("".equals(obo)) { obo = null; } // first find out if we support on-behalf-of deposit boolean mediated = ConfigurationManager.getBooleanProperty("swordv2-server", "on-behalf-of.enable"); if (!mediated && obo != null) { // user is trying to do a mediated deposit on a repository which does not support it log.error("Attempted mediated deposit on service not configured to do so"); throw new SwordError( UriRegistry.ERROR_MEDIATION_NOT_ALLOWED, "Mediated deposit to this service is not permitted"); } log.info( LogManager.getHeader( context, "sword_authenticate", "username="******",on_behalf_of=" + obo)); try { // attempt to authenticate the primary user SwordContext sc = new SwordContext(); EPerson ep = null; boolean authenticated = false; if (this.authenticates(context, un, pw)) { // if authenticated, obtain the eperson object ep = context.getCurrentUser(); if (ep != null) { authenticated = true; sc.setAuthenticated(ep); // Set any special groups - invoke the authentication mgr. int[] groupIDs = AuthenticationManager.getSpecialGroups(context, null); for (int i = 0; i < groupIDs.length; i++) { context.setSpecialGroup(groupIDs[i]); log.debug("Adding Special Group id=" + String.valueOf(groupIDs[i])); } sc.setAuthenticatorContext(context); sc.setContext(context); } // if there is an onBehalfOfuser, then find their eperson // record, and if it exists set it. If not, then the // authentication process fails EPerson epObo = null; if (obo != null) { epObo = EPerson.findByEmail(context, obo); if (epObo == null) { epObo = EPerson.findByNetid(context, obo); } if (epObo != null) { sc.setOnBehalfOf(epObo); Context oboContext = this.constructContext(); oboContext.setCurrentUser(epObo); // Set any special groups - invoke the authentication mgr. int[] groupIDs = AuthenticationManager.getSpecialGroups(oboContext, null); for (int i = 0; i < groupIDs.length; i++) { oboContext.setSpecialGroup(groupIDs[i]); log.debug("Adding Special Group id=" + String.valueOf(groupIDs[i])); } sc.setContext(oboContext); } else { authenticated = false; throw new SwordError( UriRegistry.ERROR_TARGET_OWNER_UNKNOWN, "unable to identify on-behalf-of user: "******"sword_unable_to_set_user", "username="******"Unable to authenticate with the supplied credentials"); } else { // FIXME: this shouldn't ever happen now, but may as well leave it in just in case // there's a bug elsewhere log.info( LogManager.getHeader( context, "sword_unable_to_set_on_behalf_of", "username="******",on_behalf_of=" + obo)); throw new SwordAuthException("Unable to authenticate the onBehalfOf account"); } } return sc; } catch (SQLException e) { log.error("caught exception: ", e); throw new DSpaceSwordException( "There was a problem accessing the repository user database", e); } catch (AuthorizeException e) { log.error("caught exception: ", e); throw new SwordAuthException("There was a problem authenticating or authorising the user", e); } }
public Statement getStatement( String stateIRI, Map<String, String> accept, AuthCredentials authCredentials, SwordConfiguration swordConfig) throws SwordServerException, SwordError, SwordAuthException { SwordContext sc = null; try { SwordConfigurationDSpace config = (SwordConfigurationDSpace) swordConfig; SwordAuthenticator auth = new SwordAuthenticator(); sc = auth.authenticate(authCredentials); Context context = sc.getContext(); if (log.isDebugEnabled()) { log.debug(LogManager.getHeader(context, "sword_get_statement", "")); } // log the request String un = authCredentials.getUsername() != null ? authCredentials.getUsername() : "NONE"; String obo = authCredentials.getOnBehalfOf() != null ? authCredentials.getOnBehalfOf() : "NONE"; log.info( LogManager.getHeader( context, "sword_get_statement", "username="******",on_behalf_of=" + obo)); // first thing is to figure out what we're being asked to work on SwordUrlManager urlManager = config.getUrlManager(context, config); Item item = urlManager.getItem(context, stateIRI); if (item == null) { throw new SwordError(404); } // find out if we are allowed to read the item's statement AuthorizeManager.authorizeAction(context, item, Constants.READ); // find out, now we know what we're being asked for, whether this is allowed WorkflowManagerFactory.getInstance().retrieveStatement(context, item); String suffix = urlManager.getTypeSuffix(context, stateIRI); SwordStatementDisseminator disseminator = null; if (suffix != null) { Map<Float, List<String>> analysed = new HashMap<Float, List<String>>(); List<String> list = new ArrayList<String>(); list.add(suffix); analysed.put((float) 1.0, list); disseminator = SwordDisseminatorFactory.getStatementInstance(analysed); } else { // we rely on the content negotiation to do the work String acceptContentType = this.getHeader(accept, "Accept", null); // we extract from the Accept header the ordered list of content types TreeMap<Float, List<String>> analysed = this.analyseAccept(acceptContentType); // the meat of this is done by the package disseminator disseminator = SwordDisseminatorFactory.getStatementInstance(analysed); } Statement statement = disseminator.disseminate(context, item); return statement; } catch (AuthorizeException e) { throw new SwordAuthException(); } catch (SQLException e) { throw new SwordServerException(e); } catch (DSpaceSwordException e) { throw new SwordServerException(e); } finally { if (sc != null) { sc.abort(); } } }