Package org.zanata.security

Source Code of org.zanata.security.ZanataIdentity

/*
* 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 javax.annotation.Nullable;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;

import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Observer;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Startup;
import org.jboss.seam.annotations.intercept.BypassInterceptors;
import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.core.Events;
import org.jboss.seam.security.Configuration;
import org.jboss.seam.security.Identity;
import org.jboss.seam.security.NotLoggedInException;
import org.jboss.seam.security.management.JpaIdentityStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Lists;
import org.zanata.model.HAccount;
import org.zanata.security.permission.MultiTargetList;
import org.zanata.util.ServiceLocator;

import static org.jboss.seam.ScopeType.SESSION;
import static org.jboss.seam.annotations.Install.APPLICATION;

@Name("org.jboss.seam.security.identity")
@Scope(SESSION)
@Install(precedence = APPLICATION)
@BypassInterceptors
@Startup
public class ZanataIdentity extends Identity {
    private static final Logger log = LoggerFactory.getLogger(
            ZanataIdentity.class);

    public static final String USER_LOGOUT_EVENT = "user.logout";
    public static final String USER_ENTER_WORKSPACE = "user.enter";
    public static final String JAAS_DEFAULT = "default";

    private static final long serialVersionUID = -5488977241602567930L;

    private String apiKey;

    private boolean preAuthenticated;

    public String getApiKey() {
        return apiKey;
    }

    public void setApiKey(String apiKey) {
        this.apiKey = apiKey;
        getCredentials().setPassword(apiKey);
    }

    public boolean isApiRequest() {
        return apiKey != null;
    }

    public static ZanataIdentity instance() {
        if (!Contexts.isSessionContextActive()) {
            throw new IllegalStateException("No active session context");
        }

        ZanataIdentity instance =
                ServiceLocator.instance().getInstance(ZanataIdentity.class);

        if (instance == null) {
            throw new IllegalStateException("No Identity could be created");
        }

        return instance;
    }

    public void checkLoggedIn() {
        if (!isLoggedIn()) {
            throw new NotLoggedInException();
        }
    }

    @Override
    public ZanataCredentials getCredentials() {
        return (ZanataCredentials) super.getCredentials();
    }

    @Observer("org.jboss.seam.preDestroyContext.SESSION")
    public void logout() {
        if (Events.exists() && getCredentials() != null) {
            Events.instance().raiseEvent(USER_LOGOUT_EVENT,
                    getCredentials().getUsername());
        }
        super.logout();
    }

    @Override
    public boolean hasPermission(Object target, String action) {
        log.trace("ENTER hasPermission({}, {})", target, action);
        boolean result = super.hasPermission(target, action);
        if (result) {
            if (log.isDebugEnabled()) {
                log.debug("ALLOWED hasPermission({}, {}) for user {}",
                        target, action, getAccountUsername());
            }
        } else {
            if (log.isWarnEnabled()) {
                log.warn("DENIED hasPermission({}, {}) for user {}",
                        target, action, getAccountUsername());
            }
        }
        log.trace("EXIT hasPermission(): {}", result);
        return result;
    }

    @Override
    public boolean hasPermission(String name, String action, Object... arg) {
        if (log.isTraceEnabled()) {
            log.trace("ENTER hasPermission({})",
                    Lists.newArrayList(name, action, arg));
        }
        boolean result = super.hasPermission(name, action, arg);
        if (result) {
            if (log.isDebugEnabled()) {
                log.debug("ALLOWED hasPermission({}, {}, {}) for user {}",
                        name, action, arg, getAccountUsername());
            }
        } else {
            if (log.isWarnEnabled()) {
                log.warn("DENIED hasPermission({}, {}, {}) for user {}",
                        name, action, arg, getAccountUsername());
            }
        }
        log.trace("EXIT hasPermission(): {}", result);
        return result;
    }

    /**
     * Indicates if the user has permission to perform an action on a variable
     * number of targets. This is provided as an extension to Seam's single
     * target permission capabilities.
     *
     * @param action
     *            The permission action.
     * @param targets
     *            Targets for permissions.
     */
    public boolean hasPermission(String action, Object... targets) {
        return super
                .hasPermission(MultiTargetList.fromTargets(targets), action);
    }

    /**
     * Checks permissions on a variable number of targets.This is provided as an
     * extension to Seam's single target permission capabilities.
     *
     * @param action
     *            The permission action.
     * @param targets
     *            Targets for permissions.
     * @throws NotLoggedInException
     *             if not authorised and not logged in
     * @throws org.jboss.seam.security.AuthorizationException
     *             if logged in but not authorised
     */
    public void checkPermission(String action, Object... targets) {
        super.checkPermission(MultiTargetList.fromTargets(targets), action);
    }

    @Override
    public LoginContext getLoginContext() throws LoginException {
        if (isApiRequest()) {
            return new LoginContext(JAAS_DEFAULT, getSubject(),
                    getCredentials().createCallbackHandler(),
                    Configuration.instance());
        }
        if (getJaasConfigName() != null
                && !getJaasConfigName().equals(JAAS_DEFAULT)) {
            return new LoginContext(getJaasConfigName(), getSubject(),
                    getCredentials().createCallbackHandler());
        }

        return new LoginContext(JAAS_DEFAULT, getSubject(), getCredentials()
                .createCallbackHandler(), Configuration.instance());
    }

    public boolean isPreAuthenticated() {
        return preAuthenticated;
    }

    public void setPreAuthenticated(boolean var) {
        this.preAuthenticated = var;
    }

    public String login() {
        // Default to internal authentication
        return this.login(AuthenticationType.INTERNAL);
    }

    public String login(AuthenticationType authType) {
        getCredentials().setAuthType(authType);
        String result = super.login();
        if (result != null && result.equals("loggedIn")) {
            this.preAuthenticated = true;
        }
        return result;
    }

    /**
     * Utility method to get the authenticated account username. This differs
     * from {@link org.jboss.seam.security.Credentials#getUsername()} in that
     * this returns the actual account's username, not the user provided one
     * (which for some authentication systems is non-existent).
     *
     * @return The currently authenticated account username, or null if the
     *         session is not authenticated.
     */
    @Nullable
    public String getAccountUsername() {
        HAccount authenticatedAccount =
                ServiceLocator.instance().getInstance(
                        JpaIdentityStore.AUTHENTICATED_USER, HAccount.class);
        if (authenticatedAccount != null) {
            return authenticatedAccount.getUsername();
        }
        return null;
    }
}
TOP

Related Classes of org.zanata.security.ZanataIdentity

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.