1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jetspeed.administration;
18
19 import java.io.FileReader;
20 import java.io.StringWriter;
21 import java.security.Principal;
22 import java.security.PrivilegedAction;
23 import java.util.Collection;
24 import java.util.HashMap;
25 import java.util.Iterator;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.prefs.Preferences;
29
30 import javax.portlet.PortletConfig;
31 import javax.portlet.PortletRequest;
32 import javax.portlet.PortletResponse;
33
34 import org.apache.commons.configuration.Configuration;
35 import org.apache.commons.logging.Log;
36 import org.apache.commons.logging.LogFactory;
37 import org.apache.jetspeed.Jetspeed;
38 import org.apache.jetspeed.PortalReservedParameters;
39 import org.apache.jetspeed.exception.JetspeedException;
40 import org.apache.jetspeed.om.folder.Folder;
41 import org.apache.jetspeed.om.folder.FolderNotFoundException;
42 import org.apache.jetspeed.om.folder.InvalidFolderException;
43 import org.apache.jetspeed.page.PageManager;
44 import org.apache.jetspeed.page.document.NodeException;
45 import org.apache.jetspeed.prefs.PreferencesProvider;
46 import org.apache.jetspeed.prefs.om.Node;
47 import org.apache.jetspeed.profiler.Profiler;
48 import org.apache.jetspeed.profiler.rules.ProfilingRule;
49 import org.apache.jetspeed.request.RequestContext;
50 import org.apache.jetspeed.security.GroupManager;
51 import org.apache.jetspeed.security.JSSubject;
52 import org.apache.jetspeed.security.RoleManager;
53 import org.apache.jetspeed.security.SecurityHelper;
54 import org.apache.jetspeed.security.User;
55 import org.apache.jetspeed.security.UserManager;
56 import org.apache.jetspeed.security.UserPrincipal;
57 import org.apache.velocity.VelocityContext;
58 import org.apache.velocity.app.VelocityEngine;
59 import org.springframework.mail.MailException;
60 import org.springframework.mail.SimpleMailMessage;
61 import org.springframework.mail.javamail.JavaMailSender;
62
63 /***
64 * PortalAdministrationImpl
65 * Implements aggregate portal administration functions:
66 * - Emails
67 * - Registration
68 * - Password Generation
69 * -
70 *
71 * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
72 * @author <a href="mailto:chris@bluesunrise.com">Chris Schaefer</a>
73 * @version $Id: $
74 */
75
76 public class PortalAdministrationImpl implements PortalAdministration
77 {
78 private final static Log log = LogFactory.getLog(PortalAdministrationImpl.class);
79
80 /*** administration services */
81 protected Configuration config;
82 protected UserManager userManager;
83 protected RoleManager roleManager;
84 protected GroupManager groupManager;
85 protected PageManager pageManager;
86 private PreferencesProvider preferences;
87 protected Profiler profiler;
88 protected JavaMailSender mailSender;
89 protected VelocityEngine velocityEngine;
90 protected AdminUtil adminUtil;
91
92 /*** list of default roles for a registered user */
93 protected List defaultRoles;
94 /*** list of default groups for a registered user */
95 protected List defaultGroups;
96 /*** map of default profiling rules for a registered user */
97 protected Map defaultRules;
98 /*** name of PSML Folder Template to clone from when registering new user */
99 protected String folderTemplate;
100 /*** default administrative user */
101 protected String adminUser;
102
103 public PortalAdministrationImpl( UserManager userManager,
104 RoleManager roleManager,
105 GroupManager groupManager,
106 PageManager pageManager,
107 PreferencesProvider preferences,
108 Profiler profiler,
109 JavaMailSender mailSender,
110 VelocityEngine velocityEngine)
111 {
112 this.userManager = userManager;
113 this.roleManager = roleManager;
114 this.groupManager = groupManager;
115 this.pageManager = pageManager;
116 this.preferences = preferences;
117 this.profiler = profiler;
118 this.mailSender = mailSender;
119 this.velocityEngine = velocityEngine;
120 this.adminUtil = new AdminUtil();
121 }
122
123 public void start()
124 {
125 this.config = (Configuration) Jetspeed.getComponentManager().getComponent("portal_configuration");
126
127 this.defaultRoles =
128 config.getList(PortalConfigurationConstants.REGISTRATION_ROLES_DEFAULT);
129 this.defaultGroups =
130 config.getList(PortalConfigurationConstants.REGISTRATION_GROUPS_DEFAULT);
131
132 Object[] profileRuleNames = config.getList(PortalConfigurationConstants.PROFILER_RULE_NAMES_DEFAULT).toArray();
133 Object[] profileRuleValues = config.getList(PortalConfigurationConstants.PROFILER_RULE_VALUES_DEFAULT).toArray();
134 defaultRules = new HashMap();
135 if (profileRuleNames != null && profileRuleValues != null)
136 {
137 for (int ix = 0; ix < ((profileRuleNames.length < profileRuleValues.length) ? profileRuleNames.length : profileRuleValues.length); ix++)
138 {
139 defaultRules.put(profileRuleNames[ix], profileRuleValues[ix]);
140 }
141 }
142 this.folderTemplate =
143 config.getString(PortalConfigurationConstants.PSML_TEMPLATE_FOLDER);
144 this.adminUser = config.getString(PortalConfigurationConstants.USERS_DEFAULT_ADMIN);
145
146 }
147
148 public void registerUser(String userName, String password)
149 throws RegistrationException
150 {
151 registerUser(userName, password, (List)null, null, null, null, null);
152 }
153
154 public void registerUser(
155 String userName,
156 String password,
157 List roles,
158 List groups,
159 Map userInfo,
160 Map rules,
161 String folderTemplate)
162 throws RegistrationException
163 {
164 registerUser(userName, password, roles, groups, userInfo, rules, folderTemplate, null);
165 }
166
167
168
169
170 public void registerUser(
171 String userName,
172 String password,
173 List roles,
174 List groups,
175 Map userInfo,
176 Map rules,
177 String folderTemplate,
178 String subsite)
179 throws RegistrationException
180 {
181 try
182 {
183
184 userManager.addUser(userName, password);
185 User user = userManager.getUser(userName);
186
187
188 if (roles == null || roles.isEmpty())
189 {
190 roles = this.defaultRoles;
191 }
192 if (roles != null)
193 {
194 Iterator roleList = roles.iterator();
195 while (roleList.hasNext())
196 {
197 String role = (String)roleList.next();
198 if (role.trim().length() > 0)
199 roleManager.addRoleToUser(userName, role);
200 }
201 }
202
203
204 if (groups == null || groups.isEmpty())
205 {
206 groups = this.defaultGroups;
207 }
208 if (groups != null)
209 {
210 Iterator groupsList = groups.iterator();
211 while (groupsList.hasNext())
212 {
213 String group = (String)groupsList.next();
214 if (group.trim().length() > 0)
215 {
216 groupManager.addUserToGroup(userName, group);
217 }
218 }
219 }
220
221
222 if (userInfo != null)
223 {
224 Iterator info = userInfo.entrySet().iterator();
225 while (info.hasNext())
226 {
227 Map.Entry entry = (Map.Entry)info.next();
228 user.getUserAttributes().put((String)entry.getKey(), (String)entry.getValue());
229 }
230 }
231
232
233 if (rules == null || rules.isEmpty())
234 {
235 rules = this.defaultRules;
236 }
237 if (rules != null)
238 {
239 Iterator ruleEntries = rules.entrySet().iterator();
240 while (ruleEntries.hasNext())
241 {
242 Map.Entry entry = (Map.Entry)ruleEntries.next();
243 ProfilingRule rule = profiler.getRule((String)entry.getValue());
244 if (rule != null)
245 {
246 Principal principal = SecurityHelper.getBestPrincipal(user.getSubject(), UserPrincipal.class);
247 profiler.setRuleForPrincipal(principal, rule, (String)entry.getKey());
248 }
249 }
250 }
251
252 if (folderTemplate == null)
253 {
254 folderTemplate = this.folderTemplate;
255 }
256
257 if (subsite == null)
258 {
259 subsite = Folder.USER_FOLDER + userName;
260 }
261 else
262 {
263 subsite = subsite + Folder.USER_FOLDER + userName;
264 }
265
266
267
268
269
270 final String innerFolderTemplate = folderTemplate;
271 final String innerSubsite = subsite;
272 final PageManager innerPageManager = pageManager;
273 final String innerUserName = userName;
274 final User innerUser = user;
275 User powerUser = userManager.getUser(this.adminUser);
276 JetspeedException pe = (JetspeedException) JSSubject.doAsPrivileged(powerUser.getSubject(), new PrivilegedAction()
277 {
278 public Object run()
279 {
280 try
281 {
282 if (innerSubsite != null)
283 {
284 Preferences attributes = innerUser.getUserAttributes();
285 attributes.put(User.USER_INFO_SUBSITE, innerSubsite);
286 }
287
288
289
290 Folder source = innerPageManager.getFolder(innerFolderTemplate);
291
292
293 innerPageManager.deepCopyFolder(source, innerSubsite, innerUserName);
294 Folder newFolder = pageManager.getFolder(innerSubsite);
295 newFolder.setTitle("Home Folder");
296 newFolder.setShortTitle("Home");
297
298 return null;
299 }
300 catch (FolderNotFoundException e1) {
301 return e1;
302 } catch (InvalidFolderException e1){
303 return e1;
304 } catch (NodeException e1){
305 return e1;
306 }
307 }
308 }, null);
309
310 if(pe != null)
311 {
312
313 try
314 {
315 if (userManager.getUser(userName) != null)
316 {
317 userManager.removeUser(userName);
318 }
319 }
320 catch (Exception e)
321 {
322 log.error("Registration Error: Failed to rollback user " + userName);
323 }
324 log.error("Registration Error: Failed to create user folders for " + userName + ", " + pe.toString());
325 throw pe;
326 }
327
328 }
329 catch (Exception e)
330 {
331 log.error("Registration Error: Failed to create registered user " + userName + ", " + e.toString());
332 throw new RegistrationException(e);
333 }
334 }
335
336
337
338
339
340 public String generatePassword()
341 {
342 return adminUtil.generatePassword();
343 }
344
345
346
347
348 public void sendEmail(PortletConfig portletConfig,
349 String emailAddress,
350 String localizedSubject,
351 String localizedTemplatePath,
352 Map userAttributes)
353 throws AdministrationEmailException
354 {
355
356 String from = config.getString(PortalConfigurationConstants.EMAIL_SENDER);
357 String subject = localizedSubject;
358 String to = emailAddress;
359 String text = mergeEmailTemplate(portletConfig, userAttributes, "map", localizedTemplatePath);
360 sendEmail(from, subject, to, text);
361
362 }
363
364 /***
365 * @param from
366 * @param subject
367 * @param to
368 * @param text
369 * @throws AdministrationEmailException
370 */
371 public void sendEmail(String from, String subject, String to, String text) throws AdministrationEmailException
372 {
373 SimpleMailMessage msg = new SimpleMailMessage();
374 if(from == null)
375 {
376 from = "jetspeed-admin@apache.org";
377 }
378 msg.setFrom(from);
379 if(subject == null)
380 {
381 subject = "message from jetspeed";
382 }
383 msg.setSubject(subject);
384 msg.setTo(to);
385 msg.setText(text);
386 try
387 {
388 mailSender.send(msg);
389 }
390 catch (MailException ex)
391 {
392 throw new AdministrationEmailException(
393 "Failed to send forgotten password email to user with email address because "+ex.getMessage()
394 );
395 }
396 }
397
398 public String mergeEmailTemplate(PortletConfig portletConfig, Map attributes, String attributesName, String template)
399 throws AdministrationEmailException
400 {
401 VelocityContext context = new VelocityContext();
402 context.put(attributesName, attributes);
403 StringWriter writer = new StringWriter();
404
405 try
406 {
407 String realTemplatePath = portletConfig.getPortletContext().getRealPath(template);
408 FileReader templateReader = new FileReader(realTemplatePath);
409 velocityEngine.evaluate(context, writer, "UserEmailProcessor", templateReader);
410 } catch (Exception e)
411 {
412 throw new AdministrationEmailException(
413 "Failed to generate email text for email template "
414 + template, e);
415 }
416
417 String buffer = writer.getBuffer().toString();
418
419 return buffer;
420 }
421
422 private static final String USER_NOT_FOUND_FROM_EMAIL = "User not found for Email address: ";
423
424 public User lookupUserFromEmail(String email)
425 throws AdministrationEmailException
426 {
427 Collection result = preferences.lookupPreference("userinfo", "user.business-info.online.email", email);
428 if (result.size() == 0)
429 {
430 throw new AdministrationEmailException(USER_NOT_FOUND_FROM_EMAIL + email);
431 }
432 Iterator nodes = result.iterator();
433 Node node = (Node)nodes.next();
434 String nodePath = node.getFullPath();
435 if (nodePath == null)
436 {
437 throw new AdministrationEmailException(USER_NOT_FOUND_FROM_EMAIL + email);
438 }
439 String[] paths = nodePath.split("/");
440 if (paths == null || paths.length != 4)
441 {
442 throw new AdministrationEmailException(USER_NOT_FOUND_FROM_EMAIL + email);
443 }
444 String userName = paths[2];
445 try
446 {
447 return userManager.getUser(userName);
448 }
449 catch (Exception e)
450 {
451 throw new AdministrationEmailException(USER_NOT_FOUND_FROM_EMAIL + email);
452 }
453 }
454
455 /***
456 * Helper for admin portlets to generate portal urls
457 */
458 public String getPortalURL(PortletRequest request, PortletResponse response, String path)
459 {
460
461 RequestContext context = (RequestContext)
462 request.getAttribute(PortalReservedParameters.REQUEST_CONTEXT_ATTRIBUTE);
463 String baseUrl = context.getPortalURL().getBaseURL();
464 String jetspeedPath = adminUtil.concatenatePaths(baseUrl, context.getPortalURL().getBasePath());
465 if (path == null)
466 return jetspeedPath;
467 return adminUtil.concatenatePaths(jetspeedPath, response.encodeURL(path));
468 }
469
470
471 Map forgottenPasswordData = new HashMap();
472
473
474
475
476 public Map getNewLoginInfo(String guid)
477 {
478 synchronized(forgottenPasswordData) {
479 return (Map) forgottenPasswordData.get(guid);
480 }
481 }
482
483
484
485
486 public void putNewLoginInfo(String guid, Map info)
487 {
488 synchronized(forgottenPasswordData) {
489 forgottenPasswordData.put(guid,info);
490 }
491 }
492
493
494
495
496 public void removeNewLoginInfo(String guid)
497 {
498 synchronized(forgottenPasswordData) {
499 forgottenPasswordData.remove(guid);
500 }
501 }
502
503
504
505
506
507 }