org.jamwiki.authentication.WikiUserDetails.java Source code

Java tutorial

Introduction

Here is the source code for org.jamwiki.authentication.WikiUserDetails.java

Source

/**
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE, version 2.1, dated February 1999.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the latest version of the GNU Lesser General
 * Public License as published by the Free Software Foundation;
 *
 * This program 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 program (LICENSE.txt); if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package org.jamwiki.authentication;

import java.util.ArrayList;
import java.util.Collection;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Transient;

import org.apache.commons.lang.StringUtils;
import org.jamwiki.utils.WikiLogger;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

/**
 * JAMWiki implementation of the Spring Security <code>UserDetails</code> interface.
 * This object will be populated on successful login and made available as a way of
 * verifying user credentials.  Spring Security will use this object to determine
 * access rights.
 */
@Entity
public class WikiUserDetails implements UserDetails {

    private static final WikiLogger logger = WikiLogger.getLogger(WikiUserDetails.class.getName());
    /** The default anonymous username.  This value should match the Spring Security <code>AnonymousBeanDefinitionParser.DEF_USERNAME</code> value, which unfortunately is not public. */
    public static final String ANONYMOUS_USER_USERNAME = "roleAnonymous";
    private static final long serialVersionUID = -2818435399240684581L;
    @Id
    private String username = null;
    private String password = null;
    private boolean accountNonExpired = true;
    private boolean accountNonLocked = true;
    private boolean credentialsNonExpired = true;
    private boolean enabled = true;

    /**
     * GrantedAuthority is used by Spring Security to support several authorities
     * (roles). Anonymous users are assigned ROLE_ANONYMOUS by the Spring Security
     * filters.
     */
    @Transient
    private Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();

    public WikiUserDetails() {
        if (authorities == null) {
            authorities = new ArrayList<GrantedAuthority>();
        }
    }

    /**
     * Construct the <code>User</code> with the details required by Spring Security
     * <code>org.springframework.security.providers.dao.DaoAuthenticationProvider</code>.  This
     * method should be used by systems that do NOT use the default JAMWiki
     * user and group roles.  This method will NOT assign default roles to the
     * user, and as a result the Special:Roles functionality will be ignored.
     *
     * @param username the username presented to the
     *  <code>DaoAuthenticationProvider</code>
     * @param password the password that should be presented to the
     *  <code>DaoAuthenticationProvider</code>
     * @param enabled set to <code>true</code> if the user is enabled
     * @param accountNonExpired set to <code>true</code> if the account has not
     *  expired
     * @param credentialsNonExpired set to <code>true</code> if the credentials
     *  have not expired
     * @param accountNonLocked set to <code>true</code> if the account is not
     *  locked
     * @param authorities the authorities that should be granted to the caller
     *  if they presented the correct username and password and the user
     *  is enabled
     * @throws IllegalArgumentException if a <code>null</code> value was passed
     *  either as a parameter or as an element in the
     *  <code>GrantedAuthority[]</code> array.
     */
    public WikiUserDetails(String username, String password, boolean enabled, boolean accountNonExpired,
            boolean credentialsNonExpired, boolean accountNonLocked, Collection<GrantedAuthority> authorities) {
        if (StringUtils.isBlank(username) || password == null) {
            throw new IllegalArgumentException("Cannot pass null or empty values to constructor");
        }
        this.username = username;
        this.password = password;
        this.enabled = enabled;
        this.accountNonExpired = accountNonExpired;
        this.credentialsNonExpired = credentialsNonExpired;
        this.accountNonLocked = accountNonLocked;
        if (authorities == null) {
            authorities = new ArrayList<GrantedAuthority>();
        }
        this.setAuthorities(authorities);
    }

    /**
     * Private copy constructor.
     */
    private WikiUserDetails(UserDetails userDetails) {
        this.username = userDetails.getUsername();
        this.password = userDetails.getPassword();
        this.enabled = userDetails.isEnabled();
        this.accountNonExpired = userDetails.isAccountNonExpired();
        this.credentialsNonExpired = userDetails.isCredentialsNonExpired();
        this.accountNonLocked = userDetails.isAccountNonLocked();
        this.setAuthorities(userDetails.getAuthorities());
    }

    /**
     * Standard get method for determining the user's granted authorites (permissions).
     *
     * @return authorites, never null.
     */
    public Collection<GrantedAuthority> getAuthorities() {
        return authorities;
    }

    /**
     * Standard set method for setting an array of granted authorities (permissions) for
     * the user.  This method will overwrite any existing authorities.
     */
    protected void setAuthorities(Collection<GrantedAuthority> authorities) {
        if (authorities == null) {
            throw new IllegalArgumentException("Cannot pass a null GrantedAuthority array");
        }
        for (GrantedAuthority auth : authorities) {
            if (auth == null) {
                throw new IllegalArgumentException(
                        "Granted authorities contains null element - GrantedAuthority[] cannot contain any null elements");
            }
        }
        this.authorities = authorities;
    }

    /**
     * Standard get method to determine if the user account has expired.
     */
    public boolean isAccountNonExpired() {
        return this.accountNonExpired;
    }

    /**
     * Standard get method to determine if the user account has been locked.
     */
    public boolean isAccountNonLocked() {
        return this.accountNonLocked;
    }

    /**
     * Standard get method to determine if the user is still valid or if
     * re-validation is required.
     */
    public boolean isCredentialsNonExpired() {
        return this.credentialsNonExpired;
    }

    /**
     * Standard get method to determine if the current user account is enabled.
     */
    public boolean isEnabled() {
        return this.enabled;
    }

    /**
     *
     */
    public String getPassword() {
        return this.password;
    }

    /**
     * Standard get method for the username (login).
     */
    public String getUsername() {
        return this.username;
    }

    /**
     * Convenience method for determining if a user has been assigned a role
     * without the need to examine an array of Role objects.
     *
     * @param authority If the user has been assigned this role then the method will
     *  return <code>true</code>.
     * @return <code>true</code> if the user has been assigned the specified
     *  role, <code>false</code> otherwise.
     */
    public boolean hasRole(GrantedAuthority authority) {
        if (this.authorities == null) {
            logger.warning("No roles assigned for user " + this.getUsername());
            return false;
        }
        return authorities.contains(authority);
    }

    /**
     * Utility method for converting a Spring Security <code>Authentication</code>
     * object into a <code>WikiUserDetails</code>.  If the user is logged-in then the
     * <code>Authentication</code> object will have the <code>WikiUserDetails</code>
     * as its principal.  If the user is not logged in then create an empty
     * <code>WikiUserDetails</code> object and assign it the same authorities as the
     * <code>Authentication</code> object.
     *
     * @param auth The Spring Security <code>Authentication</code> object that is being
     *  converted into a <code>WikiUserDetails</code> object.
     * @return Returns a <code>WikiUserDetails</code> object that corresponds to the
     *  Spring Security <code>Authentication</code> object.  If the user is not currently
     *  logged-in then an empty <code>WikiUserDetails</code> with the same authorities
     *  as the <code>Authentication</code> object is returned.  This method
     *  will never return <code>null</code>.
     * @throws AuthenticationCredentialsNotFoundException If authentication
     *  credentials are unavailable.
     */
    public static WikiUserDetails initWikiUserDetails(Authentication auth)
            throws AuthenticationCredentialsNotFoundException {
        if (auth == null) {
            throw new AuthenticationCredentialsNotFoundException("No authentication credential available");
        }
        if (auth instanceof AnonymousAuthenticationToken || !(auth.getPrincipal() instanceof UserDetails)) {
            // anonymous user
            return new WikiUserDetails(ANONYMOUS_USER_USERNAME, "", true, true, true, true, auth.getAuthorities());
        }
        // logged-in (or remembered) user
        if (auth.getPrincipal() instanceof WikiUserDetails) {
            return (WikiUserDetails) auth.getPrincipal();
        }
        return new WikiUserDetails((UserDetails) auth.getPrincipal());
    }
}