001/*
002 * The contents of this file are subject to the license and copyright
003 * detailed in the LICENSE and NOTICE files at the root of the source
004 * tree.
005 */
006package org.fcrepo.auth.common;
007
008import static java.util.Collections.emptySet;
009
010import javax.servlet.http.HttpServletRequest;
011
012import java.security.Principal;
013import java.util.HashSet;
014import java.util.Iterator;
015import java.util.Set;
016
017import org.slf4j.Logger;
018import org.slf4j.LoggerFactory;
019
020/**
021 * Adds principals based on roles that are configured within the container and
022 * through a PrincipalProvider bean in the project.
023 *
024 * @author Kevin S. Clarke
025 * @see PrincipalProvider
026 */
027public class ContainerRolesPrincipalProvider extends AbstractPrincipalProvider {
028
029    private static final Logger LOGGER = LoggerFactory.getLogger(ContainerRolesPrincipalProvider.class);
030
031    /**
032     * @author Kevin S. Clarke
033     */
034    public static class ContainerRolesPrincipal implements Principal {
035
036        private final String name;
037
038        /**
039         * @param name principal name
040         */
041        public ContainerRolesPrincipal(final String name) {
042            this.name = name;
043        }
044
045        @Override
046        public String getName() {
047            return name;
048        }
049
050        @Override
051        public String toString() {
052            return name;
053        }
054
055        @Override
056        public boolean equals(final Object o) {
057            if (o instanceof ContainerRolesPrincipal) {
058                return ((ContainerRolesPrincipal) o).getName().equals(this.getName());
059            }
060
061            return false;
062        }
063
064        @Override
065        public int hashCode() {
066            if (name == null) {
067                return 0;
068            }
069
070            return name.hashCode();
071        }
072
073    }
074
075    private Set<String> roleNames;
076
077    /**
078     * Sets the role names which have been configured in the repo.xml file.
079     *
080     * @param roleNames The names of container roles that should be recognized
081     *        as principals
082     */
083    public void setRoleNames(final Set<String> roleNames) {
084        this.roleNames = roleNames;
085    }
086
087    /*
088     * (non-Javadoc)
089     * @see
090     * org.fcrepo.auth.PrincipalProvider#getPrincipals(javax.servlet.http.HttpServletRequest)
091     */
092    @Override
093    public Set<Principal> getPrincipals(final HttpServletRequest request) {
094        LOGGER.debug("Checking for principals using {}", ContainerRolesPrincipalProvider.class.getSimpleName());
095
096        if (request == null) {
097            LOGGER.debug("Servlet request was null");
098
099            return emptySet();
100        }
101
102        if (roleNames == null) {
103            LOGGER.debug("Role names Set was never initialized");
104
105            return emptySet();
106        }
107
108        final Iterator<String> iterator = roleNames.iterator();
109        final Set<Principal> principals = new HashSet<>();
110
111        while (iterator.hasNext()) {
112            final String role = iterator.next().trim();
113
114            if (request.isUserInRole(role)) {
115                LOGGER.debug("Adding container role as principal: {}", role);
116
117                principals.add(new ContainerRolesPrincipal(role));
118            }
119        }
120
121        return principals;
122    }
123
124}