# 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;
            }
        }

    }