Package org.zanata.security

Source Code of org.zanata.security.AuthenticationManager

/*
* Copyright 2010, Red Hat, Inc. and individual contributors as indicated by the
* @author tags. See the copyright.txt file in the distribution for a full
* listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this software; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
* site: http://www.fsf.org.
*/
package org.zanata.security;

import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Observer;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.faces.FacesMessages;
import org.zanata.ApplicationConfiguration;
import org.zanata.dao.AccountDAO;
import org.zanata.dao.CredentialsDAO;
import org.zanata.model.HAccount;
import org.zanata.model.security.HCredentials;
import org.zanata.security.openid.OpenIdAuthCallback;
import org.zanata.security.openid.OpenIdProviderType;
import org.zanata.service.UserAccountService;
import org.zanata.util.ServiceLocator;

/**
* Centralizes all attempts to authenticate locally or externally.
*
* The authenticate methods will perform the authentication but will not login
* the authenticated user against the session. The login methods will perform
* these two steps.
*
* @author Carlos Munoz <a
*         href="mailto:camunoz@redhat.com">camunoz@redhat.com</a>
*/
@Name("authenticationManager")
@Scope(ScopeType.STATELESS)
@AutoCreate
public class AuthenticationManager {
    /*
     * Event used to signal a successful login using the authentication manager.
     * It is a complement to the events in the Identity class.
     */
    public static final String EVENT_LOGIN_COMPLETED =
            "org.zanata.security.event.loginCompleted";

    @In
    private ZanataIdentity identity;

    @In
    private ZanataJpaIdentityStore identityStore;

    @In
    private ZanataCredentials credentials;

    @In
    private ZanataOpenId zanataOpenId;

    @In
    private UserAccountService userAccountServiceImpl;

    @In
    private CredentialsDAO credentialsDAO;

    @In
    private AccountDAO accountDAO;

    @In
    private UserRedirectBean userRedirect;

    @In
    private ApplicationConfiguration applicationConfiguration;

    /**
     * Logs in a user using a specified authentication type.
     *
     * @param authenticationType
     *            Authentication type to use.
     * @param username
     *            User's name.
     * @param password
     *            User's password. May be null for some authentication types.
     * @return A String with the result of the operation.
     */
    private String login(AuthenticationType authenticationType,
            String username, String password) {
        credentials.setUsername(username);
        credentials.setPassword(password);

        String result = identity.login(authenticationType);
        if (isLoggedIn(result)) {
            this.onLoginCompleted(authenticationType);
        }

        return result;
    }

    private boolean isLoggedIn(String result) {
        return result != null && result.equals("loggedIn");
    }

    /**
     * Logs in user with internal authentication type
     *
     * @return
     */
    public String internalLogin() {
        if (isAuthenticatedAccountWaitingForActivation()) {
            return "inactive";
        }

        return login(AuthenticationType.INTERNAL, credentials.getUsername(),
                credentials.getPassword());
    }

    /**
     * Logs in user with jaas authentication type
     *
     * @return
     */
    public String jaasLogin() {
        String result =
                login(AuthenticationType.JAAS, credentials.getUsername(),
                        credentials.getPassword());

        if (isLoggedIn(result)) {
            if (isAuthenticatedAccountWaitingForActivation()) {
                return "inactive";
            }
        }
        return result;
    }

    /**
     * Logs in with the kerberos authentication type using ticket based
     * authentication.
     */
    public void kerberosLogin() {
        if (applicationConfiguration.isKerberosAuth()) {
            SpNegoIdentity spNegoIdentity =
                    ServiceLocator.instance().getInstance(SpNegoIdentity.class);
            spNegoIdentity.authenticate();
            if (!isNewUser() && !isAuthenticatedAccountWaitingForActivation()
                    && isAccountEnabledAndActivated()) {
                spNegoIdentity.login();
                this.onLoginCompleted(AuthenticationType.KERBEROS);
            }
        }
    }

    /**
     * Logs in with kerberos using from based (username/password) authentication
     */
    public String formBasedKerberosLogin() {
        if (applicationConfiguration.isKerberosAuth()) {
            String loginResult = this.login(AuthenticationType.KERBEROS,
                credentials.getUsername(), credentials.getPassword());
            if (isAuthenticatedAccountWaitingForActivation()) {
                loginResult = "inactive";
            }
            return loginResult;
        }
        return null;
    }

    /**
     * Logs in an Open Id user. Uses the values set in {@link ZanataCredentials}
     * for authentication. This method should be invoked to authenticate AND log
     * a user into Zanata.
     *
     * @return A String with the result of the operation.
     */
    public String openIdLogin() {
        zanataOpenId.setProvider(credentials.getOpenIdProviderType());
        String loginResult = identity.login(AuthenticationType.OPENID);
        return loginResult;
    }

    /**
     * Authenticates an Open Id user. This method <b>will not</b> log in the
     * authenticated user. Because control needs to be handled over to the Open
     * Id provider, a callback may be provided to perform actions after the
     * authentication attempt is finished.
     *
     * @param openIdProviderType
     *            Open Id provider to use for authentication
     * @param callback
     *            Contains the logic to execute after the authentication
     *            attempt.
     */
    public void openIdAuthenticate(OpenIdProviderType openIdProviderType,
            OpenIdAuthCallback callback) {
        openIdAuthenticate(null, openIdProviderType, callback);
    }

    /**
     * Authenticates an Open Id user. This method <b>will not</b> log in the
     * authenticated user. Because control needs to be handled over to the Open
     * Id provider, a callback may be provided to perform actions after the
     * authentication attempt is finished.
     *
     * @param openId The Open Id identifier to be used.
     * @param openIdProviderType
     *            Open Id provider to use for authentication
     * @param callback
     *            Contains the logic to execute after the authentication
     *            attempt.
     */
    public void openIdAuthenticate(String openId,
            OpenIdProviderType openIdProviderType, OpenIdAuthCallback callback) {
        ZanataCredentials volatileCreds = new ZanataCredentials();
        volatileCreds.setUsername(openId);
        volatileCreds.setAuthType(AuthenticationType.OPENID);
        volatileCreds.setOpenIdProviderType(openIdProviderType);
        zanataOpenId.login(volatileCreds, callback);
    }

    /**
     * This method indicates where a user needs to be redirected for security
     * purposes. It should be used to determine where to direct a user when they
     * try to access secured content.
     *
     * @return A string containing a hint of where to redirect the user. <br/>
     *         Valid values are: <br/>
     *         edit - Redirect the user to the edit profile page.<br/>
     *         redirect - Allow the user to continue to the page they originally
     *         aimed for.<br/>
     *         home - Redirect the user to the home page.<br/>
     *         inactive - The user's account is inactive.<br/>
     *         login - Redirect the user to the login page.<br/>
     *         dashboard - Redirect the user to dashboard page.
     */
    public String getAuthenticationRedirect() {
        if (identity.getCredentials().getAuthType() == AuthenticationType.KERBEROS) {
            if (isAuthenticatedAccountWaitingForActivation()) {
                return "inactive";
            } else if (identity.isPreAuthenticated() && isNewUser()) {
                return "edit";
            } else if (identity.isLoggedIn()) {
                if (userRedirect != null) {
                    if (userRedirect.isRedirect()
                            && !userRedirect.isRedirectToHome()
                            && !userRedirect.isRedirectToRegister()) {
                        return "redirect";
                    }
                }
                return "dashboard";
            }
            return "home";
        } else {
            return "login";
        }
    }

    /**
     * Performs operations after a successful login is completed. Currently runs
     * the role assignment rules on the logged in account.
     *
     * @param authType
     *            Authentication type that was used to login.
     */
    @Observer(EVENT_LOGIN_COMPLETED)
    public void onLoginCompleted(AuthenticationType authType) {
        identity.setPreAuthenticated(true);
        if (isExternalLogin() && !isNewUser() && isAccountEnabledAndActivated()) {
            applyAuthentication();
        }
        // Get the authenticated account and credentials
        HAccount authenticatedAccount = null;
        HCredentials authenticatedCredentials = null;

        String username = credentials.getUsername();

        if (authType == AuthenticationType.OPENID) {
            authenticatedCredentials =
                    credentialsDAO.findByUser(zanataOpenId.getAuthResult()
                            .getAuthenticatedId());
            // on first Open Id login, there might not be any stored credentials
            if (authenticatedCredentials != null) {
                authenticatedAccount = authenticatedCredentials.getAccount();
            }
        } else {
            authenticatedCredentials = credentialsDAO.findByUser(username);
            authenticatedAccount = accountDAO.getByUsername(username);
        }

        if (authenticatedAccount != null) {
            userAccountServiceImpl.runRoleAssignmentRules(authenticatedAccount,
                    authenticatedCredentials, authType.name());
        }
    }

    public boolean isAccountWaitingForActivation(String username) {
        HAccount account = accountDAO.getByUsername(username);
        if (account != null && account.getAccountActivationKey() != null) {
            return true;
        }
        return false;
    }

    public boolean isAccountEnabled(String username) {
        if (StringUtils.isEmpty(username)) {
            return false;
        }
        return identityStore.isUserEnabled(username);
    }

    public boolean isAuthenticatedAccountWaitingForActivation() {
        boolean userIsAuthenticated = true;

        // For internal Authentication, the user must be re-authenticated
        // without
        // taking into account
        // the account's enabled flag
        if (credentials.getAuthType() == AuthenticationType.INTERNAL
                && applicationConfiguration.isInternalAuth()) {
            userIsAuthenticated =
                    identityStore.authenticateEvenIfDisabled(
                            credentials.getUsername(),
                            credentials.getPassword());
        }

        return userIsAuthenticated
                && !isAccountEnabled(credentials.getUsername())
                && isAccountWaitingForActivation(credentials.getUsername());
    }

    public boolean isNewUser(String username) {
        return identityStore.isNewUser(username);
    }

    public boolean isNewUser() {
        if (credentials.getAuthType() == AuthenticationType.OPENID
                && applicationConfiguration.isOpenIdAuth()) {
            return credentialsDAO.findByUser(zanataOpenId.getAuthResult()
                    .getAuthenticatedId()) == null;
        }
        return isNewUser(credentials.getUsername());
    }

    public void setAuthenticateUser(String username) {
        Object user = identityStore.lookupUser(username);
        identityStore.setAuthenticateUser(user);
    }

    public List<String> getImpliedRoles(String username) {
        return identityStore.getImpliedRoles(username);
    }

    public boolean isAuthenticated() {
        if (credentials.getAuthType() == AuthenticationType.OPENID
                && applicationConfiguration.isOpenIdAuth()) {
            return zanataOpenId.getAuthResult().isAuthenticated();
        }
        return identity.isLoggedIn();
    }

    private boolean isAccountEnabledAndActivated() {
        String username = identity.getCredentials().getUsername();
        if (isAccountEnabled(username)) {
            return true;
        } else {
            String message = "";
            if (isAccountWaitingForActivation(username)) {
                message = "#{msgs['org.jboss.seam.loginFailed']}";
            } else {
                message =
                        "User "
                                + username
                                + " has been disabled. Please contact server admin.";
            }

            FacesMessages.instance().clear();
            FacesMessages.instance().add(message);

            // identity.setPreAuthenticated(false);
            // identity.unAuthenticate();

            return false;
        }
    }

    private boolean isExternalLogin() {
        return identity.getCredentials().getAuthType() != AuthenticationType.INTERNAL
                && !identity.isApiRequest();
    }

    private void applyAuthentication() {
        String username = identity.getCredentials().getUsername();

        for (String role : getImpliedRoles(username)) {
            identity.addRole(role);
        }
        setAuthenticateUser(username);
    }

}
TOP

Related Classes of org.zanata.security.AuthenticationManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.