Ejemplo n.º 1
0
  /**
   * Method to check current status of the service and logged in user.
   *
   * <p>okay: true | false authenticated: true | false epersonEMAIL: [email protected] epersonNAME:
   * John Doe
   *
   * @param headers Request header which contains the header named "rest-dspace-token" containing
   *     the token as value.
   * @return status the Status object with information about REST API
   * @throws UnsupportedEncodingException The Character Encoding is not supported.
   */
  @GET
  @Path("/status")
  @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
  public Status status(@Context HttpHeaders headers) throws UnsupportedEncodingException {
    org.dspace.core.Context context = null;

    try {
      context = Resource.createContext();
      EPerson ePerson = context.getCurrentUser();

      if (ePerson != null) {
        // DB EPerson needed since token won't have full info, need context
        EPerson dbEPerson = epersonService.findByEmail(context, ePerson.getEmail());

        Status status = new Status(dbEPerson.getEmail(), dbEPerson.getFullName());
        return status;
      }
    } catch (ContextException e) {
      Resource.processException("Status context error: " + e.getMessage(), context);
    } catch (SQLException e) {
      Resource.processException("Status eperson db lookup error: " + e.getMessage(), context);
    } finally {
      context.abort();
    }

    // fallback status, unauth
    return new Status();
  }
  /*
   * Authenticate the given credentials.
   * This is the heart of the authentication method: test the
   * credentials for authenticity, and if accepted, attempt to match
   * (or optionally, create) an <code>EPerson</code>.  If an <code>EPerson</code> is found it is
   * set in the <code>Context</code> that was passed.
   *
   * @param context
   *  DSpace context, will be modified (ePerson set) upon success.
   *
   * @param username
   *  Username (or email address) when method is explicit. Use null for
   *  implicit method.
   *
   * @param password
   *  Password for explicit auth, or null for implicit method.
   *
   * @param realm
   *  Realm is an extra parameter used by some authentication methods, leave null if
   *  not applicable.
   *
   * @param request
   *  The HTTP request that started this operation, or null if not applicable.
   *
   * @return One of:
   *   SUCCESS, BAD_CREDENTIALS, CERT_REQUIRED, NO_SUCH_USER, BAD_ARGS
   * <p>Meaning:
   * <br>SUCCESS         - authenticated OK.
   * <br>BAD_CREDENTIALS - user exists, but credentials (e.g. passwd) don't match
   * <br>CERT_REQUIRED   - not allowed to login this way without X.509 cert.
   * <br>NO_SUCH_USER    - user not found using this method.
   * <br>BAD_ARGS        - user/pw not appropriate for this method
   */
  @Override
  public int authenticate(
      Context context, String netid, String password, String realm, HttpServletRequest request)
      throws SQLException {
    log.info(LogManager.getHeader(context, "auth", "attempting trivial auth of user="******"authentication-ldap", "search.anonymous");
    String adminUser = ConfigurationManager.getProperty("authentication-ldap", "search.user");
    String adminPassword =
        ConfigurationManager.getProperty("authentication-ldap", "search.password");
    String objectContext =
        ConfigurationManager.getProperty("authentication-ldap", "object_context");
    String idField = ConfigurationManager.getProperty("authentication-ldap", "id_field");
    String dn = "";

    // If adminUser is blank and anonymous search is not allowed, then we can't search so construct
    // the DN instead of searching it
    if ((StringUtils.isBlank(adminUser) || StringUtils.isBlank(adminPassword))
        && !anonymousSearch) {
      dn = idField + "=" + netid + "," + objectContext;
    } else {
      dn = ldap.getDNOfUser(adminUser, adminPassword, context, netid);
    }

    // Check a DN was found
    if ((dn == null) || (dn.trim().equals(""))) {
      log.info(LogManager.getHeader(context, "failed_login", "no DN found for user " + netid));
      return BAD_CREDENTIALS;
    }

    // if they entered a netid that matches an eperson
    if (eperson != null) {
      // e-mail address corresponds to active account
      if (eperson.getRequireCertificate()) {
        return CERT_REQUIRED;
      } else if (!eperson.canLogIn()) {
        return BAD_ARGS;
      }

      if (ldap.ldapAuthenticate(dn, password, context)) {
        context.setCurrentUser(eperson);

        // assign user to groups based on ldap dn
        assignGroups(dn, ldap.ldapGroup, context);

        log.info(LogManager.getHeader(context, "authenticate", "type=ldap"));
        return SUCCESS;
      } else {
        return BAD_CREDENTIALS;
      }
    } else {
      // the user does not already exist so try and authenticate them
      // with ldap and create an eperson for them

      if (ldap.ldapAuthenticate(dn, password, context)) {
        // Register the new user automatically
        log.info(LogManager.getHeader(context, "autoregister", "netid=" + netid));

        String email = ldap.ldapEmail;

        // Check if we were able to determine an email address from LDAP
        if (StringUtils.isEmpty(email)) {
          // If no email, check if we have a "netid_email_domain". If so, append it to the netid to
          // create email
          if (StringUtils.isNotEmpty(
              ConfigurationManager.getProperty("authentication-ldap", "netid_email_domain"))) {
            email =
                netid
                    + ConfigurationManager.getProperty("authentication-ldap", "netid_email_domain");
          } else {
            // We don't have a valid email address. We'll default it to 'netid' but log a warning
            log.warn(
                LogManager.getHeader(
                    context,
                    "autoregister",
                    "Unable to locate email address for account '"
                        + netid
                        + "', so it has been set to '"
                        + netid
                        + "'. "
                        + "Please check the LDAP 'email_field' OR consider configuring 'netid_email_domain'."));
            email = netid;
          }
        }

        if (StringUtils.isNotEmpty(email)) {
          try {
            eperson = ePersonService.findByEmail(context, email);
            if (eperson != null) {
              log.info(
                  LogManager.getHeader(context, "type=ldap-login", "type=ldap_but_already_email"));
              context.setIgnoreAuthorization(true);
              eperson.setNetid(netid.toLowerCase());
              ePersonService.update(context, eperson);
              context.dispatchEvents();
              context.setIgnoreAuthorization(false);
              context.setCurrentUser(eperson);

              // assign user to groups based on ldap dn
              assignGroups(dn, ldap.ldapGroup, context);

              return SUCCESS;
            } else {
              if (canSelfRegister(context, request, netid)) {
                // TEMPORARILY turn off authorisation
                try {
                  context.setIgnoreAuthorization(true);
                  eperson = ePersonService.create(context);
                  if (StringUtils.isNotEmpty(email)) {
                    eperson.setEmail(email);
                  }
                  if (StringUtils.isNotEmpty(ldap.ldapGivenName)) {
                    eperson.setFirstName(context, ldap.ldapGivenName);
                  }
                  if (StringUtils.isNotEmpty(ldap.ldapSurname)) {
                    eperson.setLastName(context, ldap.ldapSurname);
                  }
                  if (StringUtils.isNotEmpty(ldap.ldapPhone)) {
                    ePersonService.setMetadata(context, eperson, "phone", ldap.ldapPhone);
                  }
                  eperson.setNetid(netid.toLowerCase());
                  eperson.setCanLogIn(true);
                  authenticationService.initEPerson(context, request, eperson);
                  ePersonService.update(context, eperson);
                  context.dispatchEvents();
                  context.setCurrentUser(eperson);

                  // assign user to groups based on ldap dn
                  assignGroups(dn, ldap.ldapGroup, context);
                } catch (AuthorizeException e) {
                  return NO_SUCH_USER;
                } finally {
                  context.setIgnoreAuthorization(false);
                }

                log.info(
                    LogManager.getHeader(
                        context, "authenticate", "type=ldap-login, created ePerson"));
                return SUCCESS;
              } else {
                // No auto-registration for valid certs
                log.info(LogManager.getHeader(context, "failed_login", "type=ldap_but_no_record"));
                return NO_SUCH_USER;
              }
            }
          } catch (AuthorizeException e) {
            eperson = null;
          } finally {
            context.setIgnoreAuthorization(false);
          }
        }
      }
    }
    return BAD_ARGS;
  }