001// Copyright 2008-2013 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 015package org.apache.tapestry5.internal.services; 016 017import org.apache.tapestry5.MetaDataConstants; 018import org.apache.tapestry5.SymbolConstants; 019import org.apache.tapestry5.beanmodel.services.*; 020import org.apache.tapestry5.http.Link; 021import org.apache.tapestry5.http.LinkSecurity; 022import org.apache.tapestry5.http.services.Request; 023import org.apache.tapestry5.http.services.Response; 024import org.apache.tapestry5.ioc.annotations.Symbol; 025import org.apache.tapestry5.services.ComponentEventLinkEncoder; 026import org.apache.tapestry5.services.ComponentEventRequestParameters; 027import org.apache.tapestry5.services.MetaDataLocator; 028import org.apache.tapestry5.services.PageRenderRequestParameters; 029 030import java.io.IOException; 031 032public class RequestSecurityManagerImpl implements RequestSecurityManager 033{ 034 private final Request request; 035 036 private final Response response; 037 038 private final MetaDataLocator locator; 039 040 private final boolean securityEnabled; 041 042 private final ComponentEventLinkEncoder componentEventLinkEncoder; 043 044 public RequestSecurityManagerImpl(Request request, Response response, 045 ComponentEventLinkEncoder componentEventLinkEncoder, MetaDataLocator locator, @Symbol(SymbolConstants.SECURE_ENABLED) 046 boolean securityEnabled) 047 { 048 this.request = request; 049 this.response = response; 050 this.componentEventLinkEncoder = componentEventLinkEncoder; 051 this.locator = locator; 052 this.securityEnabled = securityEnabled; 053 } 054 055 public boolean checkForInsecureComponentEventRequest(ComponentEventRequestParameters parameters) throws IOException 056 { 057 if (!needsRedirect(parameters.getActivePageName())) 058 { 059 return false; 060 } 061 062 // Page is secure but request is not, so redirect. 063 // We can safely ignore the forForm parameter since secure form requests are always done from 064 // an already secured page 065 066 Link link = componentEventLinkEncoder.createComponentEventLink(parameters, false); 067 068 response.sendRedirect(link); 069 070 return true; 071 } 072 073 public boolean checkForInsecurePageRenderRequest(PageRenderRequestParameters parameters) throws IOException 074 { 075 if (!needsRedirect(parameters.getLogicalPageName())) 076 return false; 077 078 // Page is secure but request is not, so redirect. 079 080 Link link = componentEventLinkEncoder.createPageRenderLink(parameters); 081 082 response.sendRedirect(link); 083 084 return true; 085 } 086 087 private boolean needsRedirect(String pageName) 088 { 089 if (!securityEnabled) 090 { 091 return false; 092 } 093 094 // We don't (at this time) redirect from secure to insecure, just from insecure to secure. 095 096 if (request.isSecure()) 097 { 098 return false; 099 } 100 101 if (!isSecure(pageName)) 102 { 103 return false; 104 } 105 106 return true; 107 } 108 109 private boolean isSecure(String pageName) 110 { 111 return locator.findMeta(MetaDataConstants.SECURE_PAGE, pageName, Boolean.class); 112 } 113 114 public LinkSecurity checkPageSecurity(String pageName) 115 { 116 if (!securityEnabled) 117 { 118 return request.isSecure() ? LinkSecurity.SECURE : LinkSecurity.INSECURE; 119 } 120 121 boolean securePage = isSecure(pageName); 122 123 if (request.isSecure() == securePage) 124 { 125 return securePage ? LinkSecurity.SECURE : LinkSecurity.INSECURE; 126 } 127 128 // Return a value that will, ultimately, force an absolute URL. 129 130 return securePage ? LinkSecurity.FORCE_SECURE : LinkSecurity.FORCE_INSECURE; 131 } 132}