    001    // Copyright 2008, 2009, 2010, 2011 The Apache Software Foundation
    002    //
    003    // Licensed under the Apache License, Version 2.0 (the "License");
    004    // you may not use this file except in compliance with the License.
    005    // You may obtain a copy of the License at
    006    //
    007    // http://www.apache.org/licenses/LICENSE-2.0
    008    //
    009    // Unless required by applicable law or agreed to in writing, software
    010    // distributed under the License is distributed on an "AS IS" BASIS,
    011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    012    // See the License for the specific language governing permissions and
    013    // limitations under the License.
    014
    015    package org.apache.tapestry5.internal.services;
    016
    017    import org.apache.tapestry5.Link;
    018    import org.apache.tapestry5.MetaDataConstants;
    019    import org.apache.tapestry5.SymbolConstants;
    020    import org.apache.tapestry5.ioc.annotations.Symbol;
    021    import org.apache.tapestry5.services.*;
    022
    023    import java.io.IOException;
    024
    025    public class RequestSecurityManagerImpl implements RequestSecurityManager
    026    {
    027        private final Request request;
    028
    029        private final Response response;
    030
    031        private final MetaDataLocator locator;
    032
    033        private final boolean securityEnabled;
    034
    035        private final ComponentEventLinkEncoder componentEventLinkEncoder;
    036
    037        public RequestSecurityManagerImpl(Request request, Response response,
    038                                          ComponentEventLinkEncoder componentEventLinkEncoder, MetaDataLocator locator, @Symbol(SymbolConstants.SECURE_ENABLED)
    039        boolean securityEnabled)
    040        {
    041            this.request = request;
    042            this.response = response;
    043            this.componentEventLinkEncoder = componentEventLinkEncoder;
    044            this.locator = locator;
    045            this.securityEnabled = securityEnabled;
    046        }
    047
    048        public boolean checkForInsecureComponentEventRequest(ComponentEventRequestParameters parameters) throws IOException
    049        {
    050            if (!needsRedirect(parameters.getActivePageName()))
    051            {
    052                return false;
    053            }
    054
    055            // Page is secure but request is not, so redirect.
    056            // We can safely ignore the forForm parameter since secure form requests are always done from
    057            // an already secured page
    058
    059            Link link = componentEventLinkEncoder.createComponentEventLink(parameters, false);
    060
    061            response.sendRedirect(link);
    062
    063            return true;
    064        }
    065
    066        public boolean checkForInsecurePageRenderRequest(PageRenderRequestParameters parameters) throws IOException
    067        {
    068            if (!needsRedirect(parameters.getLogicalPageName()))
    069                return false;
    070
    071            // Page is secure but request is not, so redirect.
    072
    073            Link link = componentEventLinkEncoder.createPageRenderLink(parameters);
    074
    075            response.sendRedirect(link);
    076
    077            return true;
    078        }
    079
    080        private boolean needsRedirect(String pageName)
    081        {
    082            if (!securityEnabled)
    083            {
    084                return false;
    085            }
    086
    087            // We don't (at this time) redirect from secure to insecure, just from insecure to secure.
    088
    089            if (request.isSecure())
    090            {
    091                return false;
    092            }
    093
    094            if (!isSecure(pageName))
    095            {
    096                return false;
    097            }
    098
    099            return true;
    100        }
    101
    102        private boolean isSecure(String pageName)
    103        {
    104            return locator.findMeta(MetaDataConstants.SECURE_PAGE, pageName, Boolean.class);
    105        }
    106
    107        public LinkSecurity checkPageSecurity(String pageName)
    108        {
    109            if (!securityEnabled)
    110            {
    111                return request.isSecure() ? LinkSecurity.SECURE : LinkSecurity.INSECURE;
    112            }
    113
    114            boolean securePage = isSecure(pageName);
    115
    116            if (request.isSecure() == securePage)
    117            {
    118                return securePage ? LinkSecurity.SECURE : LinkSecurity.INSECURE;
    119            }
    120
    121            // Return a value that will, ultimately, force an absolute URL.
    122
    123            return securePage ? LinkSecurity.FORCE_SECURE : LinkSecurity.FORCE_INSECURE;
    124        }
    125    }