/** * Licensed to Apereo under one or more contributor license agreements. See the NOTICE file * distributed with this work for additional information regarding copyright ownership. Apereo * licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use * this file except in compliance with the License. You may obtain a copy of the License at the * following location: * * <p>http://www.apache.org/licenses/LICENSE-2.0 * * <p>Unless required by applicable law or agreed to in writing, software distributed under the * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ package org.apereo.portal.url; import java.security.Principal; import java.util.Collections; import java.util.Enumeration; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.Locale; import java.util.Map; import java.util.Set; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.Validate; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apereo.portal.EntityIdentifier; import org.apereo.portal.groups.IEntityGroup; import org.apereo.portal.groups.IGroupMember; import org.apereo.portal.i18n.LocaleManager; import org.apereo.portal.security.IPerson; import org.apereo.portal.services.GroupService; import org.apereo.portal.user.IUserInstance; import org.apereo.portal.user.IUserInstanceManager; import org.apereo.portal.utils.ArrayEnumerator; import org.apereo.portal.utils.web.AbstractHttpServletRequestWrapper; /** * Portal wide request wrapper. Provides portal specific information for request parameters, * attributes, user and role. * */ public class PortalHttpServletRequestWrapper extends AbstractHttpServletRequestWrapper { /** * {@link javax.servlet.http.HttpServletRequest} attribute that this {@link HttpServletRequest} * object will be available. */ public static final String ATTRIBUTE__HTTP_SERVLET_REQUEST = PortalHttpServletRequestWrapper.class.getName() + ".PORTAL_HTTP_SERVLET_REQUEST"; /** * {@link javax.servlet.http.HttpServletRequest} attribute that the {@link HttpServletResponse} * object will be available. */ public static final String ATTRIBUTE__HTTP_SERVLET_RESPONSE = PortalHttpServletRequestWrapper.class.getName() + ".PORTAL_HTTP_SERVLET_RESPONSE"; protected final Log logger = LogFactory.getLog(this.getClass()); private final Map<String, String> additionalHeaders = new LinkedHashMap<String, String>(); private final HttpServletResponse httpServletResponse; private final IUserInstanceManager userInstanceManager; /** * Construct a writable this.request wrapping a real this.request * * @param request Request to wrap, can not be null. */ public PortalHttpServletRequestWrapper( HttpServletRequest request, HttpServletResponse response, IUserInstanceManager userInstanceManager) { super(request); Validate.notNull(response); Validate.notNull(userInstanceManager); this.httpServletResponse = response; this.userInstanceManager = userInstanceManager; } public void setHeader(String name, String value) { this.additionalHeaders.put(name, value); } public void setDateHeader(String name, String value) { this.additionalHeaders.put(name, value); } public void setIntHeader(String name, String value) { this.additionalHeaders.put(name, value); } @Override public long getDateHeader(String name) { final String value = this.additionalHeaders.get(name); if (value == null) { return super.getDateHeader(name); } try { final long longValue = Long.parseLong(value); return longValue; } catch (NumberFormatException nfe) { throw new IllegalArgumentException( "Header '" + name + "' cannot be converted to long: '" + value + "'", nfe); } } @Override public String getHeader(String name) { final Object value = this.additionalHeaders.get(name); if (value == null) { return super.getHeader(name); } return String.valueOf(value); } @Override public Enumeration<String> getHeaders(String name) { final String value = this.additionalHeaders.get(name); if (value == null) { return super.getHeaders(name); } return Collections.enumeration(Collections.singleton(value)); } @Override public Enumeration<String> getHeaderNames() { final Set<String> headerNames = new LinkedHashSet<String>(); for (final Enumeration<String> headerNamesEnum = super.getHeaderNames(); headerNamesEnum.hasMoreElements(); ) { final String name = headerNamesEnum.nextElement(); headerNames.add(name); } headerNames.addAll(this.additionalHeaders.keySet()); return Collections.enumeration(headerNames); } @Override public int getIntHeader(String name) { final String value = this.additionalHeaders.get(name); if (value == null) { return super.getIntHeader(name); } try { final int intValue = Integer.parseInt(value); return intValue; } catch (NumberFormatException nfe) { throw new IllegalArgumentException( "Header '" + name + "' cannot be converted to int: '" + value + "'", nfe); } } @Override public Object getAttribute(String name) { if (ATTRIBUTE__HTTP_SERVLET_REQUEST.equals(name)) { return this; } if (ATTRIBUTE__HTTP_SERVLET_RESPONSE.equals(name)) { return this.httpServletResponse; } return super.getAttribute(name); } @Override public String getRemoteUser() { final Principal userPrincipal = this.getUserPrincipal(); if (userPrincipal == null) { return null; } return userPrincipal.getName(); } @Override public Principal getUserPrincipal() { if (super.getSession(false) == null) { return super.getUserPrincipal(); } final IUserInstance userInstance = this.userInstanceManager.getUserInstance(this.getWrappedRequest()); final IPerson person = userInstance.getPerson(); if (person == null || person.isGuest()) { return null; } return person; } /** * Determines whether or not the user is in the given role. The wrapped request is consulted * first then the {@link GroupService} is used to determine if a group exists for the specified * role and if the user is a member of it. * * @see * org.apereo.portal.utils.web.AbstractHttpServletRequestWrapper#isUserInRole(java.lang.String) */ @Override public boolean isUserInRole(String role) { if (super.getSession(false) == null) { return super.isUserInRole(role); } //Check the wrapped request first final boolean isUserInRole = super.isUserInRole(role); if (isUserInRole) { return true; } //Find the group for the role, if not found return false IEntityGroup groupForRole = GroupService.findGroup(role); if (groupForRole == null) { final EntityIdentifier[] results = GroupService.searchForGroups(role, GroupService.IS, IPerson.class); if (results == null || results.length == 0) { return false; } if (results.length > 1) { this.logger.warn( results.length + " groups were found for role '" + role + "'. The first result will be used."); } IGroupMember member = GroupService.getGroupMember(results[0]); if (member == null || !member.isGroup()) { return false; } groupForRole = member.asGroup(); } //Load the group information about the current user final IUserInstance userInstance = this.userInstanceManager.getUserInstance(this.getWrappedRequest()); final IPerson person = userInstance.getPerson(); final EntityIdentifier personEntityId = person.getEntityIdentifier(); final IGroupMember personGroupMember = GroupService.getGroupMember(personEntityId); return personGroupMember.isDeepMemberOf(groupForRole); } /* (non-Javadoc) * @see org.apereo.portal.url.AbstractHttpServletRequestWrapper#getLocale() */ @Override public Locale getLocale() { if (super.getSession(false) == null) { return super.getLocale(); } final IUserInstance userInstance = this.userInstanceManager.getUserInstance(this.getWrappedRequest()); final LocaleManager localeManager = userInstance.getLocaleManager(); final Locale[] locales = localeManager.getLocales(); return locales[0]; } /* (non-Javadoc) * @see org.apereo.portal.url.AbstractHttpServletRequestWrapper#getLocales() */ @Override public Enumeration<Locale> getLocales() { if (super.getSession(false) == null) { return super.getLocales(); } final IUserInstance userInstance = this.userInstanceManager.getUserInstance(this.getWrappedRequest()); final LocaleManager localeManager = userInstance.getLocaleManager(); final Locale[] locales = localeManager.getLocales(); return new ArrayEnumerator<Locale>(locales); } }