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 }