org.dspace.authenticate.AuthenticationServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.dspace.authenticate.AuthenticationServiceImpl.java

Source

/**
 * The contents of this file are subject to the license and copyright
 * detailed in the LICENSE and NOTICE files at the root of the source
 * tree and available online at
 * <p>
 * http://www.dspace.org/license/
 */
package org.dspace.authenticate;

import org.dspace.authenticate.service.AuthenticationService;
import org.dspace.authorize.AuthorizeException;
import org.dspace.core.Context;
import org.dspace.core.PluginManager;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.Group;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;

import javax.servlet.http.HttpServletRequest;
import java.sql.SQLException;
import java.util.*;

/**
 * Access point for the stackable authentication methods.
 * <p>
 * This class initializes the "stack" from the DSpace configuration,
 * and then invokes methods in the appropriate order on behalf of clients.
 * <p>
 * See the AuthenticationMethod interface for details about what each
 * function does.
 * <p>
 * <b>Configuration</b><br>
 * The stack of authentication methods is defined by one property in the DSpace configuration:
 * <pre>
 *   plugin.sequence.org.dspace.eperson.AuthenticationMethod = <em>a list of method class names</em>
 *     <em>e.g.</em>
 *   plugin.sequence.org.dspace.eperson.AuthenticationMethod = \
 *       org.dspace.eperson.X509Authentication, \
 *       org.dspace.eperson.PasswordAuthentication
 * </pre>
 * <p>
 * The "stack" is always traversed in order, with the methods
 * specified first (in the configuration) thus getting highest priority.
 *
 * @author Larry Stone
 * @version $Revision$
 * @see AuthenticationMethod
 */
public class AuthenticationServiceImpl implements AuthenticationService, InitializingBean {
    /**
     * List of authentication methods, highest precedence first.
     */
    protected List<AuthenticationMethod> methodStack;

    /**
     * SLF4J logging category
     */
    private final Logger log = (Logger) LoggerFactory.getLogger(AuthenticationServiceImpl.class);

    protected AuthenticationServiceImpl() {

    }

    /**
     * @param iKnowWhatImDoing  must be true otherwise all warranties are void
     */
    public AuthenticationServiceImpl(boolean iKnowWhatImDoing) {
        if (iKnowWhatImDoing) {
            afterPropertiesSet();
        }
    }

    @Override
    public void afterPropertiesSet() {
        this.methodStack = new LinkedList<>();
        AuthenticationMethod[] methodStack = (AuthenticationMethod[]) PluginManager
                .getPluginSequence("authentication", AuthenticationMethod.class);
        Collections.addAll(this.methodStack, methodStack);
    }

    @Override
    public int authenticate(Context context, String username, String password, String realm,
            HttpServletRequest request) {
        return authenticateInternal(context, username, password, realm, request, false);
    }

    @Override
    public int authenticateImplicit(Context context, String username, String password, String realm,
            HttpServletRequest request) {
        return authenticateInternal(context, username, password, realm, request, true);
    }

    protected int authenticateInternal(Context context, String username, String password, String realm,
            HttpServletRequest request, boolean implicitOnly) {
        // better is lowest, so start with the highest.
        int bestRet = AuthenticationMethod.BAD_ARGS;

        // return on first success, otherwise "best" outcome.
        for (AuthenticationMethod aMethodStack : methodStack) {
            if (!implicitOnly || aMethodStack.isImplicit()) {
                int ret = 0;
                try {
                    ret = aMethodStack.authenticate(context, username, password, realm, request);
                } catch (SQLException e) {
                    ret = AuthenticationMethod.NO_SUCH_USER;
                }
                if (ret == AuthenticationMethod.SUCCESS) {
                    EPerson me = context.getCurrentUser();
                    me.setLastActive(new Date());
                    try {
                        me.update();
                    } catch (SQLException ex) {
                        log.error("Could not update last-active stamp", ex);
                    } catch (AuthorizeException ex) {
                        log.error("Could not update last-active stamp", ex);
                    }
                    return ret;
                }
                if (ret < bestRet) {
                    bestRet = ret;
                }
            }
        }
        return bestRet;
    }

    @Override
    public boolean canSelfRegister(Context context, HttpServletRequest request, String username)
            throws SQLException {
        for (int i = 0; i < methodStack.size(); ++i) {
            if (methodStack.get(i).canSelfRegister(context, request, username)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean allowSetPassword(Context context, HttpServletRequest request, String username)
            throws SQLException {
        for (int i = 0; i < methodStack.size(); ++i) {
            if (methodStack.get(i).allowSetPassword(context, request, username)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public void initEPerson(Context context, HttpServletRequest request, EPerson eperson) throws SQLException {
        for (AuthenticationMethod method : methodStack) {
            method.initEPerson(context, request, eperson);
        }
    }

    @Override
    public List<Group> getSpecialGroups(Context context, HttpServletRequest request) throws SQLException {
        List<Group> result = new ArrayList<>();

        for (AuthenticationMethod aMethodStack : methodStack) {
            int[] specialGroupIDs = aMethodStack.getSpecialGroups(context, request);
            if (specialGroupIDs.length > 0) {
                for (int specialGroupID : specialGroupIDs) {
                    Group group = Group.find(context, specialGroupID);
                    result.add(group);
                }
            }
        }

        return result;
    }

    @Override
    public Iterator<AuthenticationMethod> authenticationMethodIterator() {
        return methodStack.iterator();
    }
}