001/* 002 * Copyright 2012 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.web.usermanagement; 017 018import java.io.IOException; 019import java.util.Collection; 020 021import javax.jcr.Repository; 022import javax.jcr.RepositoryException; 023import javax.jcr.Session; 024 025import org.apache.avalon.framework.service.ServiceException; 026import org.apache.avalon.framework.service.ServiceManager; 027import org.apache.cocoon.ProcessingException; 028import org.apache.cocoon.environment.ObjectModelHelper; 029import org.apache.cocoon.environment.Request; 030import org.apache.cocoon.generation.ServiceableGenerator; 031import org.apache.cocoon.xml.AttributesImpl; 032import org.apache.cocoon.xml.XMLUtils; 033import org.apache.commons.lang.StringUtils; 034import org.xml.sax.SAXException; 035 036import org.ametys.core.user.CurrentUserProvider; 037import org.ametys.core.user.UserIdentity; 038import org.ametys.plugins.repository.AmetysObjectResolver; 039import org.ametys.runtime.i18n.I18nizableText; 040import org.ametys.web.WebConstants; 041import org.ametys.web.cache.PageHelper; 042import org.ametys.web.repository.page.Page; 043import org.ametys.web.site.SiteConfigurationExtensionPoint; 044import org.ametys.web.skin.Skin; 045import org.ametys.web.skin.SkinsManager; 046import org.ametys.web.synchronization.SynchronizeComponent; 047 048import com.google.common.collect.Multimap; 049 050/** 051 * Generate information to render the user signup service. 052 */ 053public class UserSignupGenerator extends ServiceableGenerator 054{ 055 /** The user signup manager. */ 056 protected UserSignupManager _userSignupManager; 057 /** The site configuration EP. */ 058 protected SiteConfigurationExtensionPoint _siteConfiguration; 059 /** The ametys object resolver. */ 060 protected AmetysObjectResolver _resolver; 061 /** The component for live synchronization */ 062 protected SynchronizeComponent _synchronizeComponent; 063 /** The {@link SkinsManager}*/ 064 protected SkinsManager _skinManager; 065 /** The repository */ 066 protected Repository _repository; 067 /** Page helper */ 068 protected PageHelper _pageHelper; 069 /** The current user provider */ 070 protected CurrentUserProvider _currentUserProvider; 071 072 @Override 073 public void service(ServiceManager serviceManager) throws ServiceException 074 { 075 super.service(serviceManager); 076 _userSignupManager = (UserSignupManager) serviceManager.lookup(UserSignupManager.ROLE); 077 _siteConfiguration = (SiteConfigurationExtensionPoint) serviceManager.lookup(SiteConfigurationExtensionPoint.ROLE); 078 _resolver = (AmetysObjectResolver) serviceManager.lookup(AmetysObjectResolver.ROLE); 079 _skinManager = (SkinsManager) serviceManager.lookup(SkinsManager.ROLE); 080 _synchronizeComponent = (SynchronizeComponent) serviceManager.lookup(SynchronizeComponent.ROLE); 081 _repository = (Repository) serviceManager.lookup(Repository.class.getName()); 082 _pageHelper = (PageHelper) serviceManager.lookup(PageHelper.ROLE); 083 _currentUserProvider = (CurrentUserProvider) serviceManager.lookup(CurrentUserProvider.ROLE); 084 } 085 086 @Override 087 public void generate() throws IOException, SAXException, ProcessingException 088 { 089 Request request = ObjectModelHelper.getRequest(objectModel); 090 String siteName = (String) request.getAttribute("site"); 091 String language = (String) request.getAttribute("sitemapLanguage"); 092 Page page = (Page) request.getAttribute(Page.class.getName()); 093 094 Boolean publicSignup = _siteConfiguration.getValueAsBoolean(siteName, "public-signup"); 095 Page signupPage = _userSignupManager.getSignupPage(siteName, language); 096 Page pwdChangePage = _userSignupManager.getPwdChangePage(siteName, language); 097 Page userMainPrefsPage = _userSignupManager.getUserMainPrefsPage(siteName, language); 098 099 @SuppressWarnings("unchecked") 100 Multimap<String, I18nizableText> errors = (Multimap<String, I18nizableText>) request.getAttribute("errors"); 101 String firstName = request.getParameter("firstname"); 102 String lastName = request.getParameter("lastname"); 103 String email = request.getParameter("email"); 104 String token = request.getParameter("token"); 105 106 contentHandler.startDocument(); 107 108 AttributesImpl attrs = new AttributesImpl(); 109 if (page != null) 110 { 111 _addNotEmptyAttribute (attrs, "current-page", page.getId()); 112 } 113 if (publicSignup != null) 114 { 115 _addNotEmptyAttribute (attrs, "public-signup", publicSignup.toString()); 116 } 117 if (signupPage != null) 118 { 119 _addNotEmptyAttribute (attrs, "signup-page-id", signupPage.getId()); 120 } 121 if (pwdChangePage != null) 122 { 123 _addNotEmptyAttribute (attrs, "password-change-page-id", pwdChangePage.getId()); 124 } 125 if (userMainPrefsPage != null) 126 { 127 _addNotEmptyAttribute (attrs, "user-prefs-page-id", userMainPrefsPage.getId()); 128 } 129 130 UserIdentity userIdentity = _currentUserProvider.getUser(); 131 if (userIdentity != null) 132 { 133 _addNotEmptyAttribute (attrs, "fo-user-login", userIdentity.getLogin()); 134 _addNotEmptyAttribute (attrs, "fo-user-population", userIdentity.getPopulationId()); 135 } 136 _addNotEmptyAttribute (attrs, "firstname", firstName); 137 _addNotEmptyAttribute (attrs, "lastname", lastName); 138 _addNotEmptyAttribute (attrs, "email", email); 139 _addNotEmptyAttribute (attrs, "token", token); 140 141 XMLUtils.startElement(contentHandler, "user-signup", attrs); 142 143 if (errors != null) 144 { 145 saxErrors(errors); 146 } 147 148 saxWarnings(publicSignup, signupPage, pwdChangePage, userMainPrefsPage); 149 150 XMLUtils.createElement(contentHandler, "has-captcha", String.valueOf(_pageHelper.isCaptchaRequired(page))); 151 152 XMLUtils.endElement(contentHandler, "user-signup"); 153 154 contentHandler.endDocument(); 155 } 156 157 private void _addNotEmptyAttribute (AttributesImpl attrs, String name, String value) 158 { 159 if (StringUtils.isNotEmpty(value)) 160 { 161 attrs.addCDATAAttribute(name, value); 162 } 163 } 164 165 /** 166 * Generate errors. 167 * @param errors the error list. 168 * @throws SAXException if an error occurs. 169 */ 170 protected void saxErrors(Multimap<String, I18nizableText> errors) throws SAXException 171 { 172 XMLUtils.startElement(contentHandler, "errors"); 173 174 if (errors.containsKey("global")) 175 { 176 Collection<I18nizableText> globalErrors = errors.get("global"); 177 178 XMLUtils.startElement(contentHandler, "global"); 179 180 for (I18nizableText error : globalErrors) 181 { 182 AttributesImpl errorAttrs = new AttributesImpl(); 183 if (!error.isI18n()) 184 { 185 errorAttrs.addCDATAAttribute("type", error.getLabel()); 186 } 187 XMLUtils.createElement(contentHandler, "error", errorAttrs); 188 } 189 190 XMLUtils.endElement(contentHandler, "global"); 191 } 192 193 for (String field : errors.keySet()) 194 { 195 if (!field.equals("global")) 196 { 197 Collection<I18nizableText> fieldErrors = errors.get(field); 198 199 AttributesImpl attrs = new AttributesImpl(); 200 attrs.addCDATAAttribute("name", field); 201 202 XMLUtils.startElement(contentHandler, "field", attrs); 203 204 for (I18nizableText error : fieldErrors) 205 { 206 error.toSAX(contentHandler, "error"); 207 } 208 209 XMLUtils.endElement(contentHandler, "field"); 210 } 211 } 212 213 XMLUtils.endElement(contentHandler, "errors"); 214 } 215 216 /** 217 * Generate errors which could prevent the service from working. 218 * @param publicSignup indicate if public signup is enabled for the site. 219 * @param signupPage the signup page. 220 * @param pwdChangePage the lost password page. 221 * @param userMainPrefsPage the user main preferences page. 222 * @throws SAXException if an error occurs. 223 */ 224 protected void saxWarnings(Boolean publicSignup, Page signupPage, Page pwdChangePage, Page userMainPrefsPage) throws SAXException 225 { 226 227 XMLUtils.startElement(contentHandler, "warnings"); 228 229 if (publicSignup == null || !publicSignup) 230 { 231 XMLUtils.startElement(contentHandler, "warning"); 232 new I18nizableText("plugin.web", "PLUGINS_WEB_USER_SIGNUP_ERROR_NO_PUBLIC_SIGNUP").toSAX(contentHandler); 233 XMLUtils.endElement(contentHandler, "warning"); 234 } 235 236 if (signupPage == null) 237 { 238 XMLUtils.startElement(contentHandler, "warning"); 239 new I18nizableText("plugin.web", "PLUGINS_WEB_USER_SIGNUP_ERROR_NO_SIGNUP_PAGE").toSAX(contentHandler); 240 XMLUtils.endElement(contentHandler, "warning"); 241 } 242 else if (!_isValid(signupPage)) 243 { 244 XMLUtils.startElement(contentHandler, "warning"); 245 new I18nizableText("plugin.web", "PLUGINS_WEB_USER_SIGNUP_ERROR_INVALID_SIGNUP_PAGE").toSAX(contentHandler); 246 XMLUtils.endElement(contentHandler, "warning"); 247 } 248 249 if (pwdChangePage == null) 250 { 251 XMLUtils.startElement(contentHandler, "warning"); 252 new I18nizableText("plugin.web", "PLUGINS_WEB_USER_SIGNUP_ERROR_NO_PASSWORD_CHANGE_PAGE").toSAX(contentHandler); 253 XMLUtils.endElement(contentHandler, "warning"); 254 } 255 else if (!_isValid(pwdChangePage)) 256 { 257 XMLUtils.startElement(contentHandler, "warning"); 258 new I18nizableText("plugin.web", "PLUGINS_WEB_USER_SIGNUP_ERROR_INVALID_PASSWORD_CHANGE_PAGE").toSAX(contentHandler); 259 XMLUtils.endElement(contentHandler, "warning"); 260 } 261 262 if (userMainPrefsPage == null) 263 { 264 XMLUtils.startElement(contentHandler, "warning"); 265 new I18nizableText("plugin.web", "PLUGINS_WEB_USER_SIGNUP_ERROR_NO_PREFS_PAGE").toSAX(contentHandler); 266 XMLUtils.endElement(contentHandler, "warning"); 267 } 268 else if (!_isValid(userMainPrefsPage)) 269 { 270 XMLUtils.startElement(contentHandler, "warning"); 271 new I18nizableText("plugin.web", "PLUGINS_WEB_USER_SIGNUP_ERROR_INVALID_PREFS_PAGE").toSAX(contentHandler); 272 XMLUtils.endElement(contentHandler, "warning"); 273 } 274 275 XMLUtils.endElement(contentHandler, "warnings"); 276 } 277 278 private boolean _isValid(Page page) 279 { 280 Skin skin = _skinManager.getSkin(page.getSite().getSkinId()); 281 282 Session liveSession = null; 283 try 284 { 285 liveSession = _repository.login(WebConstants.LIVE_WORKSPACE); 286 287 if (!_synchronizeComponent.isPageValid(page, skin) || !_synchronizeComponent.isHierarchyValid(page, liveSession)) 288 { 289 return false; 290 } 291 return true; 292 } 293 catch (RepositoryException e) 294 { 295 throw new RuntimeException("Unable to check live workspace", e); 296 } 297 finally 298 { 299 if (liveSession != null) 300 { 301 liveSession.logout(); 302 } 303 } 304 } 305}