/** * 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); } }