001: /**
002: * Copyright (C) 2005 Jive Software. All rights reserved.
003: *
004: * This software is published under the terms of the GNU Public License (GPL),
005: * a copy of which is included in this distribution.
006: */package org.jivesoftware.openfire.plugin;
007:
008: import org.jivesoftware.openfire.MessageRouter;
009: import org.jivesoftware.openfire.XMPPServer;
010: import org.jivesoftware.openfire.container.Plugin;
011: import org.jivesoftware.openfire.container.PluginManager;
012: import org.jivesoftware.openfire.event.UserEventDispatcher;
013: import org.jivesoftware.openfire.event.UserEventListener;
014: import org.jivesoftware.openfire.group.Group;
015: import org.jivesoftware.openfire.group.GroupManager;
016: import org.jivesoftware.openfire.group.GroupNotFoundException;
017: import org.jivesoftware.openfire.user.User;
018: import org.jivesoftware.admin.AuthCheckFilter;
019: import org.jivesoftware.util.EmailService;
020: import org.jivesoftware.util.JiveGlobals;
021: import org.jivesoftware.util.Log;
022: import org.xmpp.packet.JID;
023: import org.xmpp.packet.Message;
024:
025: import java.io.File;
026: import java.util.ArrayList;
027: import java.util.Arrays;
028: import java.util.Collection;
029: import java.util.Collections;
030: import java.util.Iterator;
031: import java.util.List;
032: import java.util.Map;
033:
034: /**
035: * Registration plugin.
036: *
037: * @author Ryan Graham.
038: */
039: public class RegistrationPlugin implements Plugin {
040: private static final String URL = "registration/sign-up.jsp";
041:
042: /**
043: * The expected value is a boolean, if true all contacts specified in the property #IM_CONTACTS
044: * will receive a notification when a new user registers. The default value is false.
045: */
046: private static final String IM_NOTIFICATION_ENABLED = "registration.imnotification.enabled";
047:
048: /**
049: * The expected value is a boolean, if true all contacts specified in the property #EMAIL_CONTACTS
050: * will receive a notification when a new user registers. The default value is false.
051: */
052: private static final String EMAIL_NOTIFICATION_ENABLED = "registration.emailnotification.enabled";
053:
054: /**
055: * The expected value is a boolean, if true any user who registers will receive the welcome
056: * message specified in the property #WELCOME_MSG. The default value is false.
057: */
058: private static final String WELCOME_ENABLED = "registration.welcome.enabled";
059:
060: /**
061: * The expected value is a boolean, if true any user who registers will be added to the group
062: * specified in the property #REGISTRAION_GROUP. The default value is false.
063: */
064: private static final String GROUP_ENABLED = "registration.group.enabled";
065:
066: /**
067: * The expected value is a boolean, if true any users will be able to register at the following
068: * url http://[SERVER_NAME}:9090/plugins/registration/sign-up.jsp
069: */
070: private static final String WEB_ENABLED = "registration.web.enabled";
071:
072: /**
073: * The expected value is a comma separated String of usernames who will receive a instant
074: * message when a new user registers if the property #IM_NOTIFICATION_ENABLED is set to true.
075: */
076: private static final String IM_CONTACTS = "registration.notification.imContacts";
077:
078: /**
079: * The expected value is a comma separated String of email addresses who will receive an email
080: * when a new user registers, if the property #EMAIL_NOTIFICATION_ENABLED is set to true.
081: */
082: private static final String EMAIL_CONTACTS = "registration.notification.emailContacts";
083:
084: /**
085: * The expected value is a String that contains the message that will be sent to a new user
086: * when they register, if the property #WELCOME_ENABLED is set to true.
087: */
088: private static final String WELCOME_MSG = "registration.welcome.message";
089:
090: /**
091: * The expected value is a String that contains the name of the group that a new user will
092: * be added to when they register, if the property #GROUP_ENABLED is set to true.
093: */
094: private static final String REGISTRAION_GROUP = "registration.group";
095:
096: /**
097: * The expected value is a String that contains the text that will be displayed in the header
098: * of the sign-up.jsp, if the property #WEB_ENABLED is set to true.
099: */
100: private static final String HEADER = "registration.header";
101:
102: private RegistrationUserEventListener listener = new RegistrationUserEventListener();
103:
104: private String serverName;
105: private JID serverAddress;
106: private MessageRouter router;
107:
108: private List<String> imContacts = new ArrayList<String>();
109: private List<String> emailContacts = new ArrayList<String>();
110:
111: public RegistrationPlugin() {
112: serverName = XMPPServer.getInstance().getServerInfo().getName();
113: serverAddress = new JID(serverName);
114: router = XMPPServer.getInstance().getMessageRouter();
115:
116: String imcs = JiveGlobals.getProperty(IM_CONTACTS);
117: if (imcs != null) {
118: imContacts.addAll(Arrays.asList(imcs.split(",")));
119: }
120:
121: String ecs = JiveGlobals.getProperty(EMAIL_CONTACTS);
122: if (ecs != null) {
123: emailContacts.addAll(Arrays.asList(ecs.split(",")));
124: }
125:
126: UserEventDispatcher.addListener(listener);
127:
128: //delete properties from version 1.0
129: JiveGlobals.deleteProperty("registration.notification.contact");
130: JiveGlobals.deleteProperty("registration.notification.enabled");
131: }
132:
133: public void initializePlugin(PluginManager manager,
134: File pluginDirectory) {
135: AuthCheckFilter.addExclude(URL);
136: }
137:
138: public void destroyPlugin() {
139: AuthCheckFilter.removeExclude(URL);
140: UserEventDispatcher.removeListener(listener);
141: serverAddress = null;
142: listener = null;
143: router = null;
144: }
145:
146: public void setIMNotificationEnabled(boolean enable) {
147: JiveGlobals.setProperty(IM_NOTIFICATION_ENABLED,
148: enable ? "true" : "false");
149: }
150:
151: public boolean imNotificationEnabled() {
152: return JiveGlobals.getBooleanProperty(IM_NOTIFICATION_ENABLED,
153: false);
154: }
155:
156: public void setEmailNotificationEnabled(boolean enable) {
157: JiveGlobals.setProperty(EMAIL_NOTIFICATION_ENABLED,
158: enable ? "true" : "false");
159: }
160:
161: public boolean emailNotificationEnabled() {
162: return JiveGlobals.getBooleanProperty(
163: EMAIL_NOTIFICATION_ENABLED, false);
164: }
165:
166: public Collection<String> getIMContacts() {
167: Collections.sort(imContacts);
168: return imContacts;
169: }
170:
171: public void addIMContact(String contact) {
172: if (!imContacts.contains(contact.trim().toLowerCase())) {
173: imContacts.add(contact.trim().toLowerCase());
174: JiveGlobals.setProperty(IM_CONTACTS, propPrep(imContacts));
175: }
176: }
177:
178: public void removeIMContact(String contact) {
179: imContacts.remove(contact.trim().toLowerCase());
180: if (imContacts.size() == 0) {
181: JiveGlobals.deleteProperty(IM_CONTACTS);
182: } else {
183: JiveGlobals.setProperty(IM_CONTACTS, propPrep(imContacts));
184: }
185: }
186:
187: public Collection<String> getEmailContacts() {
188: Collections.sort(emailContacts);
189: return emailContacts;
190: }
191:
192: public void addEmailContact(String contact) {
193: if (!emailContacts.contains(contact.trim())) {
194: emailContacts.add(contact.trim());
195: JiveGlobals.setProperty(EMAIL_CONTACTS,
196: propPrep(emailContacts));
197: }
198: }
199:
200: public void removeEmailContact(String contact) {
201: emailContacts.remove(contact);
202: if (emailContacts.size() == 0) {
203: JiveGlobals.deleteProperty(EMAIL_CONTACTS);
204: } else {
205: JiveGlobals.setProperty(EMAIL_CONTACTS,
206: propPrep(emailContacts));
207: }
208: }
209:
210: public void setWelcomeEnabled(boolean enable) {
211: JiveGlobals.setProperty(WELCOME_ENABLED, enable ? "true"
212: : "false");
213: }
214:
215: public boolean welcomeEnabled() {
216: return JiveGlobals.getBooleanProperty(WELCOME_ENABLED, false);
217: }
218:
219: public void setWelcomeMessage(String message) {
220: JiveGlobals.setProperty(WELCOME_MSG, message);
221: }
222:
223: public String getWelcomeMessage() {
224: return JiveGlobals.getProperty(WELCOME_MSG,
225: "Welcome to Openfire!");
226: }
227:
228: public void setGroupEnabled(boolean enable) {
229: JiveGlobals.setProperty(GROUP_ENABLED, enable ? "true"
230: : "false");
231: }
232:
233: public boolean groupEnabled() {
234: return JiveGlobals.getBooleanProperty(GROUP_ENABLED, false);
235: }
236:
237: public void setWebEnabled(boolean enable) {
238: JiveGlobals.setProperty(WEB_ENABLED, enable ? "true" : "false");
239: }
240:
241: public boolean webEnabled() {
242: return JiveGlobals.getBooleanProperty(WEB_ENABLED, false);
243: }
244:
245: public String webRegistrationAddress() {
246: return "http://"
247: + XMPPServer.getInstance().getServerInfo().getName()
248: + ":" + JiveGlobals.getXMLProperty("adminConsole.port")
249: + "/plugins/" + URL;
250: }
251:
252: public void setGroup(String group) {
253: JiveGlobals.setProperty(REGISTRAION_GROUP, group);
254: }
255:
256: public String getGroup() {
257: return JiveGlobals.getProperty(REGISTRAION_GROUP);
258: }
259:
260: public void setHeader(String message) {
261: JiveGlobals.setProperty(HEADER, message);
262: }
263:
264: public String getHeader() {
265: return JiveGlobals.getProperty(HEADER, "Web Sign-In");
266: }
267:
268: private class RegistrationUserEventListener implements
269: UserEventListener {
270: public void userCreated(User user, Map params) {
271: if (imNotificationEnabled()) {
272: sendIMNotificatonMessage(user);
273: }
274:
275: if (emailNotificationEnabled()) {
276: sendAlertEmail(user);
277: }
278:
279: if (welcomeEnabled()) {
280: sendWelcomeMessage(user);
281: }
282:
283: if (groupEnabled()) {
284: addUserToGroup(user);
285: }
286: }
287:
288: public void userDeleting(User user, Map params) {
289: }
290:
291: public void userModified(User user, Map params) {
292: }
293:
294: private void sendIMNotificatonMessage(User user) {
295: String msg = " A new user with the username '"
296: + user.getUsername() + "' just registered.";
297:
298: for (String contact : getIMContacts()) {
299: router
300: .route(createServerMessage(contact + "@"
301: + serverName,
302: "Registration Notification", msg));
303: }
304: }
305:
306: private void sendAlertEmail(User user) {
307: String subject = "User Registration";
308: String body = " A new user with the username '"
309: + user.getUsername() + "' just registered.";
310:
311: EmailService emailService = EmailService.getInstance();
312: for (String toAddress : emailContacts) {
313: try {
314: emailService.sendMessage(null, toAddress,
315: "Openfire", "no_reply@" + serverName,
316: subject, body, null);
317: } catch (Exception e) {
318: Log.error(e);
319: }
320: }
321: }
322:
323: private void sendWelcomeMessage(User user) {
324: router.route(createServerMessage(user.getUsername() + "@"
325: + serverName, "Welcome", getWelcomeMessage()));
326: }
327:
328: private Message createServerMessage(String to, String subject,
329: String body) {
330: Message message = new Message();
331: message.setTo(to);
332: message.setFrom(serverAddress);
333: if (subject != null) {
334: message.setSubject(subject);
335: }
336: message.setBody(body);
337: return message;
338: }
339:
340: private void addUserToGroup(User user) {
341: try {
342: GroupManager groupManager = GroupManager.getInstance();
343: Group group = groupManager.getGroup(getGroup());
344: group.getMembers().add(
345: XMPPServer.getInstance().createJID(
346: user.getUsername(), null));
347: } catch (GroupNotFoundException e) {
348: Log.error(e);
349: }
350: }
351: }
352:
353: private String propPrep(Collection<String> props) {
354: StringBuilder buf = new StringBuilder();
355: Iterator<String> iter = props.iterator();
356: while (iter.hasNext()) {
357: String con = iter.next();
358: buf.append(con);
359:
360: if (iter.hasNext()) {
361: buf.append(",");
362: }
363: }
364: return buf.toString();
365: }
366:
367: public boolean isValidAddress(String address) {
368: if (address == null) {
369: return false;
370: }
371:
372: // Must at least match x@x.xx.
373: return address.matches(".{1,}[@].{1,}[.].{2,}");
374: }
375: }
|