001/* 002 * Copyright 2017 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.plugins.proxiedcontent; 017 018import java.io.UnsupportedEncodingException; 019import java.net.URLEncoder; 020import java.util.HashMap; 021import java.util.Map; 022 023import org.apache.avalon.framework.parameters.Parameters; 024import org.apache.avalon.framework.service.ServiceException; 025import org.apache.avalon.framework.service.ServiceManager; 026import org.apache.cocoon.acting.ServiceableAction; 027import org.apache.cocoon.environment.ObjectModelHelper; 028import org.apache.cocoon.environment.Redirector; 029import org.apache.cocoon.environment.Request; 030import org.apache.cocoon.environment.Session; 031import org.apache.cocoon.environment.SourceResolver; 032import org.jasig.cas.client.proxy.Cas20ProxyRetriever; 033import org.jasig.cas.client.util.AbstractCasFilter; 034import org.jasig.cas.client.validation.Assertion; 035 036import org.ametys.core.authentication.CredentialProvider; 037import org.ametys.core.user.population.UserPopulation; 038import org.ametys.core.user.population.UserPopulationDAO; 039import org.ametys.plugins.core.impl.authentication.CASCredentialProvider; 040import org.ametys.web.repository.page.ZoneItem; 041 042/** 043 * Get the page url to integrate 044 */ 045public class GetUrlAction extends ServiceableAction 046{ 047 /** The DAO for user populations */ 048 protected UserPopulationDAO _userPopulationDAO; 049 050 @Override 051 public void service(ServiceManager smanager) throws ServiceException 052 { 053 super.service(manager); 054 _userPopulationDAO = (UserPopulationDAO) smanager.lookup(UserPopulationDAO.ROLE); 055 } 056 057 @Override 058 public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception 059 { 060 Map<String, String> result = new HashMap<>(); 061 062 Request request = ObjectModelHelper.getRequest(objectModel); 063 064 String url = request.getParameter("url"); 065 String server = request.getParameter("server"); 066 String isForm = request.getParameter("isForm"); 067 String baseUrl = Utils.normalizeUrl(source); 068 String baseHost = Utils.getRemoteHostFromUrl(baseUrl); 069 String remoteHost; 070 String completeUrl = ""; 071 072 if (url == null) 073 { 074 url = source; 075 } 076 if (server == null) 077 { 078 server = source; 079 } 080 081 url = Utils.normalizeUrl(url); 082 server = Utils.normalizeUrl(server); 083 084 remoteHost = Utils.getRemoteHostFromUrl(url); 085 086 if (baseHost.equals(remoteHost)) 087 { 088 if (isForm != null) 089 { 090 result.put("queryString", "?" + request.getQueryString()); 091 } 092 093 completeUrl = url.substring(0, url.lastIndexOf("/") + 1); 094 095 result.put("url", url); 096 result.put("server", server); 097 result.put("remote-server", remoteHost); 098 result.put("complete-url", completeUrl); 099 ZoneItem zoneItem = (ZoneItem) request.getAttribute(ZoneItem.class.getName()); 100 result.put("zoneitemid", zoneItem.getId()); 101 102 if (zoneItem.getServiceParameters().getBoolean("cas", false)) 103 { 104 _addCasProxyTicketInUrl(request, url, result); 105 } 106 107 return result; 108 } 109 else 110 { 111 getLogger().error("The specified page '" + url + "' is not on the same host than the base page, and therefore could not be proxified."); 112 return null; 113 } 114 } 115 116 private void _addCasProxyTicketInUrl(Request request, String url, Map<String, String> result) throws UnsupportedEncodingException 117 { 118 String proxyTicket = null; 119 120 // Case BO: try to get a proxy ticket from the assertion in the current session 121 Session session = request.getSession(false); 122 if (session != null) 123 { 124 Assertion assertion = (Assertion) session.getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION); 125 if (assertion != null) 126 { 127 proxyTicket = assertion.getPrincipal().getProxyTicketFor(url); 128 } 129 } 130 131 // Case FO request 132 if ("true".equals(request.getHeader("X-Ametys-FO")) && request.getHeader("X-Ametys-FO-PGT") != null) 133 { 134 String populationId = request.getHeader("X-Ametys-FO-Population"); 135 UserPopulation population = _userPopulationDAO.getUserPopulation(populationId); 136 137 if (population != null) 138 { 139 String cpId = request.getHeader("X-Ametys-FO-Credential-Provider"); 140 CredentialProvider credentialProvider = population.getCredentialProvider(cpId); 141 if (credentialProvider instanceof CASCredentialProvider) 142 { 143 String casUrl = (String) credentialProvider.getParameterValues().get(CASCredentialProvider.PARAM_SERVER_URL); 144 String proxyGrantingTicket = request.getHeader("X-Ametys-FO-PGT"); 145 proxyTicket = new Cas20ProxyRetriever(casUrl, "UTF-8", null).getProxyTicketIdFor(proxyGrantingTicket, url); 146 } 147 } 148 } 149 150 // If proxy ticket was found, change url and append the ticket 151 if (proxyTicket != null) 152 { 153 StringBuilder urlWithTicket = new StringBuilder(url); 154 urlWithTicket.append(!url.contains("?") ? "?" : "&") 155 .append("ticket=") 156 .append(URLEncoder.encode(proxyTicket, "UTF-8")); 157 result.put("url", urlWithTicket.toString()); 158 } 159 else 160 { 161 getLogger().warn(String.format("The application was unable to retrieve a proxy ticket from CAS for target service '%s'", url)); 162 } 163 } 164}