001    /*
002        Licensed to the Apache Software Foundation (ASF) under one
003        or more contributor license agreements.  See the NOTICE file
004        distributed with this work for additional information
005        regarding copyright ownership.  The ASF licenses this file
006        to you under the Apache License, Version 2.0 (the
007        "License"); you may not use this file except in compliance
008        with the License.  You may obtain a copy of the License at
009    
010           http://www.apache.org/licenses/LICENSE-2.0
011    
012        Unless required by applicable law or agreed to in writing,
013        software distributed under the License is distributed on an
014        "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015        KIND, either express or implied.  See the License for the
016        specific language governing permissions and limitations
017        under the License.    
018     */
019    package org.apache.wiki.ui;
020    
021    import java.security.Principal;
022    
023    import javax.servlet.http.HttpServletRequest;
024    import javax.servlet.http.HttpServletRequestWrapper;
025    
026    import org.apache.wiki.WikiEngine;
027    import org.apache.wiki.WikiSession;
028    import org.apache.wiki.auth.SessionMonitor;
029    import org.apache.wiki.auth.authorize.Role;
030    
031    /**
032     * Servlet request wrapper that encapsulates an incoming HTTP request and
033     * overrides its security methods so that the request returns JSPWiki-specific
034     * values.
035     * 
036     * @since 2.8
037     */
038    public class WikiRequestWrapper extends HttpServletRequestWrapper
039    {
040        private final WikiSession m_session;
041    
042        /**
043         * Constructs a new wrapped request.
044         * 
045         * @param engine
046         *            the wiki engine
047         * @param request
048         *            the request to wrap
049         */
050        public WikiRequestWrapper(WikiEngine engine, HttpServletRequest request)
051        {
052            super(request);
053    
054            // Get and stash a reference to the current WikiSession
055            m_session = SessionMonitor.getInstance(engine).find(request.getSession());
056        }
057    
058        /**
059         * Returns the remote user for the HTTP request, taking into account both
060         * container and JSPWiki custom authentication status. Specifically, if the
061         * wrapped request contains a remote user, this method returns that remote
062         * user. Otherwise, if the user's WikiSession is an authenticated session
063         * (that is, {@link WikiSession#isAuthenticated()} returns <code>true</code>,
064         * this method returns the name of the principal returned by
065         * {@link WikiSession#getLoginPrincipal()}.
066         */
067        public String getRemoteUser()
068        {
069            if (super.getRemoteUser() != null)
070            {
071                return super.getRemoteUser();
072            }
073    
074            if (m_session.isAuthenticated())
075            {
076                return m_session.getLoginPrincipal().getName();
077            }
078            return null;
079        }
080    
081        /**
082         * Returns the user principal for the HTTP request, taking into account both
083         * container and JSPWiki custom authentication status. Specifically, if the
084         * wrapped request contains a user principal, this method returns that
085         * principal. Otherwise, if the user's WikiSession is an authenticated
086         * session (that is, {@link WikiSession#isAuthenticated()} returns
087         * <code>true</code>, this method returns the value of
088         * {@link WikiSession#getLoginPrincipal()}.
089         */
090        public Principal getUserPrincipal()
091        {
092            if (super.getUserPrincipal() != null)
093            {
094                return super.getUserPrincipal();
095            }
096    
097            if (m_session.isAuthenticated())
098            {
099                return m_session.getLoginPrincipal();
100            }
101            return null;
102        }
103    
104        /**
105         * Determines whether the current user possesses a supplied role, taking
106         * into account both container and JSPWIki custom authentication status.
107         * Specifically, if the wrapped request shows that the user possesses the
108         * role, this method returns <code>true</code>. If not, this method
109         * iterates through the built-in Role objects (<em>e.g.</em>, ANONYMOUS,
110         * ASSERTED, AUTHENTICATED) returned by {@link WikiSession#getRoles()} and
111         * checks to see if any of these principals' names match the supplied role.
112         */
113        public boolean isUserInRole(String role)
114        {
115            boolean hasContainerRole = super.isUserInRole(role);
116            if (hasContainerRole)
117            {
118                return true;
119            }
120    
121            // Iterate through all of the built-in roles and look for a match
122            Principal[] principals = m_session.getRoles();
123            for (int i = 0; i < principals.length; i++)
124            {
125                if (principals[i] instanceof Role)
126                {
127                    Role principal = (Role) principals[i];
128                    if (Role.isBuiltInRole(principal) && principal.getName().equals(role))
129                    {
130                        return true;
131                    }
132                }
133            }
134    
135            // None of the built-in roles match, so no luck
136            return false;
137        }
138    
139    }