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.util.HashMap; 019import java.util.Map; 020 021import org.apache.avalon.framework.parameters.Parameters; 022import org.apache.avalon.framework.service.ServiceException; 023import org.apache.avalon.framework.service.ServiceManager; 024import org.apache.cocoon.acting.ServiceableAction; 025import org.apache.cocoon.environment.ObjectModelHelper; 026import org.apache.cocoon.environment.Redirector; 027import org.apache.cocoon.environment.Request; 028import org.apache.cocoon.environment.Session; 029import org.apache.cocoon.environment.SourceResolver; 030import org.jasig.cas.client.proxy.Cas20ProxyRetriever; 031import org.jasig.cas.client.util.AbstractCasFilter; 032import org.jasig.cas.client.validation.Assertion; 033 034import org.ametys.core.authentication.CredentialProvider; 035import org.ametys.core.user.population.UserPopulation; 036import org.ametys.core.user.population.UserPopulationDAO; 037import org.ametys.core.util.URIUtils; 038import org.ametys.plugins.extrausermgt.authentication.cas.CASCredentialProvider; 039import org.ametys.web.repository.page.ZoneItem; 040 041/** 042 * Get the page url to integrate 043 */ 044public class GetUrlAction extends ServiceableAction 045{ 046 /** The DAO for user populations */ 047 protected UserPopulationDAO _userPopulationDAO; 048 049 @Override 050 public void service(ServiceManager smanager) throws ServiceException 051 { 052 super.service(manager); 053 _userPopulationDAO = (UserPopulationDAO) smanager.lookup(UserPopulationDAO.ROLE); 054 } 055 056 @Override 057 public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception 058 { 059 Map<String, String> result = new HashMap<>(); 060 061 Request request = ObjectModelHelper.getRequest(objectModel); 062 063 String url = request.getParameter("url"); 064 String server = request.getParameter("server"); 065 String isForm = request.getParameter("isForm"); 066 String baseUrl = Utils.normalizeUrl(source); 067 String baseHost = Utils.getRemoteHostFromUrl(baseUrl); 068 String remoteHost; 069 String completeUrl = ""; 070 071 if (url == null) 072 { 073 url = source; 074 } 075 if (server == null) 076 { 077 server = source; 078 } 079 080 url = Utils.normalizeUrl(url); 081 server = Utils.normalizeUrl(server); 082 083 remoteHost = Utils.getRemoteHostFromUrl(url); 084 085 if (baseHost.equals(remoteHost)) 086 { 087 if (isForm != null) 088 { 089 result.put("queryString", "?" + request.getQueryString()); 090 } 091 092 completeUrl = url.substring(0, url.lastIndexOf("/") + 1); 093 094 result.put("url", url); 095 result.put("server", server); 096 result.put("remote-server", remoteHost); 097 result.put("complete-url", completeUrl); 098 ZoneItem zoneItem = (ZoneItem) request.getAttribute(ZoneItem.class.getName()); 099 result.put("zoneitemid", zoneItem.getId()); 100 101 if (zoneItem.getServiceParameters().getValue("cas", false, false)) 102 { 103 _addCasProxyTicketInUrl(request, url, result); 104 } 105 106 return result; 107 } 108 else 109 { 110 getLogger().error("The specified page '" + url + "' is not on the same host than the base page, and therefore could not be proxified."); 111 return null; 112 } 113 } 114 115 private void _addCasProxyTicketInUrl(Request request, String url, Map<String, String> result) 116 { 117 String proxyTicket = null; 118 119 // Case BO: try to get a proxy ticket from the assertion in the current session 120 Session session = request.getSession(false); 121 if (session != null) 122 { 123 Assertion assertion = (Assertion) session.getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION); 124 if (assertion != null) 125 { 126 proxyTicket = assertion.getPrincipal().getProxyTicketFor(url); 127 } 128 } 129 130 // Case FO request 131 if ("true".equals(request.getHeader("X-Ametys-FO")) && request.getHeader("X-Ametys-FO-PGT") != null) 132 { 133 String populationId = request.getHeader("X-Ametys-FO-Population"); 134 UserPopulation population = _userPopulationDAO.getUserPopulation(populationId); 135 136 if (population != null) 137 { 138 String cpId = request.getHeader("X-Ametys-FO-Credential-Provider"); 139 CredentialProvider credentialProvider = population.getCredentialProvider(cpId); 140 if (credentialProvider instanceof CASCredentialProvider) 141 { 142 String casUrl = (String) credentialProvider.getParameterValues().get(CASCredentialProvider.PARAM_SERVER_URL); 143 String proxyGrantingTicket = request.getHeader("X-Ametys-FO-PGT"); 144 proxyTicket = new Cas20ProxyRetriever(casUrl, "UTF-8", null).getProxyTicketIdFor(proxyGrantingTicket, url); 145 } 146 } 147 } 148 149 // If proxy ticket was found, change url and append the ticket 150 if (proxyTicket != null) 151 { 152 StringBuilder urlWithTicket = new StringBuilder(url); 153 urlWithTicket.append(!url.contains("?") ? "?" : "&") 154 .append("ticket=") 155 .append(URIUtils.encodeParameter(proxyTicket)); 156 result.put("url", urlWithTicket.toString()); 157 } 158 else 159 { 160 getLogger().warn(String.format("The application was unable to retrieve a proxy ticket from CAS for target service '%s'", url)); 161 } 162 } 163}