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