001/**
002 * Copyright 2015 DuraSpace, Inc.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.fcrepo.auth.common;
017
018import static java.util.Collections.emptySet;
019
020import org.modeshape.jcr.api.ServletCredentials;
021
022import javax.jcr.Credentials;
023import javax.servlet.http.HttpServletRequest;
024
025import java.security.Principal;
026import java.util.HashSet;
027import java.util.Set;
028
029/**
030 * An example principal provider that extracts principals from request headers.
031 *
032 * @author Gregory Jansen
033 * @author Mike Daines
034 * @see PrincipalProvider
035 */
036public class HttpHeaderPrincipalProvider implements PrincipalProvider {
037
038    protected static class HttpHeaderPrincipal implements Principal {
039
040        private final String name;
041
042        HttpHeaderPrincipal(final String name) {
043            this.name = name;
044        }
045
046        @Override
047        public String getName() {
048            return name;
049        }
050
051        @Override
052        public String toString() {
053            return name;
054        }
055
056        @Override
057        public boolean equals(final Object o) {
058            if (o instanceof HttpHeaderPrincipal) {
059                return ((HttpHeaderPrincipal) o).getName().equals(
060                        this.getName());
061            }
062            return false;
063        }
064
065        @Override
066        public int hashCode() {
067            if (name == null) {
068                return 0;
069            }
070            return name.hashCode();
071        }
072
073    }
074
075    private String headerName;
076
077    private String separator = "";
078
079    /**
080     * @param headerName The name of the header from which to extract principals
081     */
082    public void setHeaderName(final String headerName) {
083        this.headerName = headerName;
084    }
085
086    /**
087     * @param separator The string by which to split header values
088     */
089    public void setSeparator(final String separator) {
090        this.separator = separator;
091    }
092
093    /*
094     * (non-Javadoc)
095     * @see
096     * org.fcrepo.auth.PrincipalProvider#getPrincipals(javax.jcr.Credentials)
097     */
098    @Override
099    public Set<Principal> getPrincipals(final Credentials credentials) {
100
101        if (headerName == null || separator == null) {
102            return emptySet();
103        }
104
105        if (!(credentials instanceof ServletCredentials)) {
106            return emptySet();
107        }
108
109        final ServletCredentials servletCredentials =
110                (ServletCredentials) credentials;
111
112        final HttpServletRequest request = servletCredentials.getRequest();
113
114        if (request == null) {
115            return emptySet();
116        }
117
118        final String value = request.getHeader(headerName);
119
120        if (value == null) {
121            return emptySet();
122        }
123
124        final String[] names = value.split(separator);
125
126        final Set<Principal> principals = new HashSet<>();
127
128        for (final String name : names) {
129            principals.add(new HttpHeaderPrincipal(name.trim()));
130        }
131
132        return principals;
133
134    }
135
136}