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.frontedition; 017 018import java.util.List; 019import java.util.Map; 020 021import org.apache.avalon.framework.service.ServiceException; 022import org.apache.avalon.framework.service.ServiceManager; 023import org.apache.cocoon.environment.ObjectModelHelper; 024import org.apache.cocoon.environment.Request; 025import org.apache.commons.lang3.StringUtils; 026 027import org.ametys.core.DevMode; 028import org.ametys.core.DevMode.DEVMODE; 029import org.ametys.core.user.CurrentUserProvider; 030import org.ametys.core.user.UserIdentity; 031import org.ametys.core.util.I18nizableSerializer; 032import org.ametys.plugins.repository.AmetysObjectResolver; 033import org.ametys.plugins.repository.UnknownAmetysObjectException; 034import org.ametys.runtime.authentication.AccessDeniedException; 035import org.ametys.web.CheckNotFrontAction; 036import org.ametys.web.WebAuthenticateAction; 037import org.ametys.web.repository.page.Page; 038 039/** 040 * Dispatch generator for the front edition 041 */ 042public class DispatchGenerator extends org.ametys.core.ui.dispatcher.DispatchGenerator 043{ 044 private static final List<String> __UNPROTECTED_FOEDITION_METHODS = List.of("pageExists"); 045 046 private AmetysObjectResolver _resolver; 047 private CurrentUserProvider _currentUserProvider; 048 049 @Override 050 public void service(ServiceManager smanager) throws ServiceException 051 { 052 super.service(smanager); 053 _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE); 054 _currentUserProvider = (CurrentUserProvider) smanager.lookup(CurrentUserProvider.ROLE); 055 } 056 057 @Override 058 protected void _setContextInRequestAttributes(Map<String, Object> contextAsMap) 059 { 060 super._setContextInRequestAttributes(contextAsMap); 061 062 Request request = ObjectModelHelper.getRequest(objectModel); 063 if (contextAsMap.containsKey("pageId")) 064 { 065 String pageId = (String) contextAsMap.get("pageId"); 066 if (!StringUtils.isBlank(pageId)) 067 { 068 try 069 { 070 Page page = _resolver.resolveById(pageId); 071 request.setAttribute(Page.class.getName(), page); 072 } 073 catch (UnknownAmetysObjectException e) 074 { 075 getLogger().debug("Page with id '" + pageId + "' does not exist anymore. It may have been deleted or unpublished after recent modifications"); 076 } 077 078 } 079 } 080 081 // Force locale to FO edition locale 082 request.setAttribute(I18nizableSerializer.REQUEST_ATTR_LOCALE, contextAsMap.get("locale")); 083 084 request.setAttribute(CheckNotFrontAction.CAN_COME_FROM_FRONT_ATTRIBUTE, true); 085 } 086 087 @Override 088 protected String _createUrl(String pluginOrWorkspace, String relativeUrl, Map<String, Object> requestParameters) 089 { 090 if (!_skipRightProtection(relativeUrl, requestParameters) && !AmetysFrontEditionHelper.hasFrontEditionRight()) 091 { 092 throw new AccessDeniedException("User " + _currentUserProvider.getUser() + " is not allowed to access front edition"); 093 } 094 095 return super._createUrl(pluginOrWorkspace, relativeUrl, requestParameters); 096 } 097 098 private boolean _skipRightProtection(String relativeUrl, Map<String, Object> requestParameters) 099 { 100 if ("client-call".equals(relativeUrl)) 101 { 102 String methodName = (String) requestParameters.get("methodName"); 103 String role = (String) requestParameters.get("role"); 104 105 if (FrontEditionHelper.ROLE.equals(role) && __UNPROTECTED_FOEDITION_METHODS.contains(methodName)) 106 { 107 return true; 108 } 109 } 110 return false; 111 } 112 113 @Override 114 protected Map<String, Object> transmitAttributes(Map<String, Object> attributes) 115 { 116 Map<String, Object> transmitAttributes = super.transmitAttributes(attributes); 117 118 if (attributes.containsKey(WebAuthenticateAction.REQUEST_ATTRIBUTE_FRONTOFFICE_USERIDENTITY)) 119 { 120 UserIdentity frontUserIdentity = (UserIdentity) attributes.get(WebAuthenticateAction.REQUEST_ATTRIBUTE_FRONTOFFICE_USERIDENTITY); 121 transmitAttributes.put(WebAuthenticateAction.REQUEST_ATTRIBUTE_FRONTOFFICE_USERIDENTITY, frontUserIdentity); 122 } 123 124 if (attributes.containsKey("rendering-context")) 125 { 126 transmitAttributes.put("rendering-context", attributes.get("rendering-context")); 127 } 128 129 if (attributes.containsKey(CheckNotFrontAction.CAN_COME_FROM_FRONT_ATTRIBUTE)) 130 { 131 transmitAttributes.put(CheckNotFrontAction.CAN_COME_FROM_FRONT_ATTRIBUTE, attributes.get(CheckNotFrontAction.CAN_COME_FROM_FRONT_ATTRIBUTE)); 132 } 133 134 if (attributes.containsKey("site")) 135 { 136 transmitAttributes.put("site", attributes.get("site")); 137 } 138 139 return transmitAttributes; 140 } 141 142 @Override 143 protected String _exceptionToStackTraceInformation(Throwable t) 144 { 145 if (DevMode.getDeveloperMode() == DEVMODE.PRODUCTION) 146 { 147 return "The exception is hidden for security purposes"; 148 } 149 else 150 { 151 return super._exceptionToStackTraceInformation(t); 152 } 153 } 154}