UserCredentialsImpl.java

package org.example.websecurity;

import java.io.Serializable;
import java.security.Principal;
import java.util.Arrays;
import java.util.Iterator;

import javax.security.auth.Subject;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/*
 * This is free and unencumbered software released into the public domain.
 * Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, 
 * either in source code form or as a compiled binary, for any purpose, commercial or 
 * non-commercial, and by any means.
 * 
 * In jurisdictions that recognize copyright laws, the author or authors of this 
 * software dedicate any and all copyright interest in the software to the public domain. 
 * We make this dedication for the benefit of the public at large and to the detriment of 
 * our heirs and successors. We intend this dedication to be an overt act of relinquishment in 
 * perpetuity of all present and future rights to this software under copyright law.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
 * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES 
 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,  
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 * 
 * For more information, please refer to: https://unlicense.org/
*/

/**
 * This is the customized Credentials container.
 * 
 * This is a thin wrapper around a JAAS Subject object.
 * 
 * @author Jonathan Earl
 * @version 1.0
 *
 */
public final class UserCredentialsImpl
    implements Serializable, UserCredentials
{
    private static final long serialVersionUID = 1L;
    private static final Logger LOG = LogManager.getLogger();
    
    private Subject subject;

    /**
     * This will create an empty UserCredentials with the inner Subject having
     * default values.
     */
    public UserCredentialsImpl()
    {
        LOG.debug("Constructing a UserCredentials object.");
        subject = new Subject();
    }


    /**
     * {@inheritDoc}
     */
    public void addRole(final String name)
    {
        LOG.debug("Adding a role: " + name);
        subject.getPrincipals().add(new PrincipalComponent(name));
    }


    /**
     * {@inheritDoc}
     */
    public String[] getRoles()
    {
        LOG.debug("Returning the Roles");
        PrincipalComponent[] principals =
                subject.getPrincipals().toArray(new PrincipalComponent[0]);
        
        String[] roles = new String[principals.length];
        for (int i = 0; i < roles.length; i++)
        {
            roles[i] = principals[i].getName();
        }
        return roles;
    }
    

    /**
     * {@inheritDoc}
     */
    public boolean hasRole(final String role)
    {
        LOG.debug("Checking if the role exists");
        return Arrays.asList(getRoles()).contains(role);
    }
    
    /**
     * {@inheritDoc}
     */
    @Override
    public void removeRole(final String role)
    {
        LOG.debug("Removing the role: " + role);
        if (!hasRole(role))
        {
            LOG.error("Role is not found");
            throw new IllegalArgumentException("Role is not found");
        }
        Iterator<Principal> iterator = subject.getPrincipals().iterator();
        while (iterator.hasNext()) 
        {
            if (iterator.next().getName().equals(role))
            {
                iterator.remove();
                break;
            }
         }
        
    }

    /**
     * Inner class to create a custom Principal implementation.
     * 
     * @author Jonathan Earl
     * @version 1.0
     *
     */
    private class PrincipalComponent implements Serializable, Principal
    {
        private static final long serialVersionUID = 1L;

        private String name;

        /**
         * This sets the Role for the customer Principal.
         * 
         * @param name the role to set
         */
        PrincipalComponent(final String nameValue)
        {
            LOG.debug("Constructing the Principal");
            if (nameValue == null)
            {
                LOG.error("Name is required");
                throw new IllegalArgumentException("Name must be provided");
            }
            this.name = nameValue;
        }

        /**
         * Returns the role for this Principal.
         * 
         * @return the role name for this Principal
         */
        @Override
        public String getName()
        {
            LOG.debug("Returning the Principal name: " + name);
            return name;
        }
    }

  
}