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 }