1 /*******************************************************************************
2 * Copyright � Igor Barma, Alexandre Desoubeaux, Christian Martel, Eric Brun, Mathieu Amblard, Gwenael Gevet, Pierre Guillot, 2012
3 * Copyright Alexandre Desoubeaux, Christian Martel, Cedric Lecarpentier, Alexandre Lefevre, Marc Salvat 2014-2016
4 * Copyright Alexandre Desoubeaux, Christian Martel, Cedric Lecarpentier, Marc Salvat, Marc Suarez, Harifetra Ramamonjy 2017
6 * This file is part of the work and learning management system Pentila Nero.
8 * Pentila Nero is free software. You can redistribute it and/or modify since
9 * you respect the terms of either (at least one of the both license) :
10 * - under the terms of the GNU Affero General Public License as
11 * published by the Free Software Foundation, either version 3 of the
12 * License, or (at your option) any later version.
13 * - the CeCILL-C as published by CeCILL-C; either version 1 of the
14 * License, or any later version
15 * - the GNU Lesser General Public License as published by the
16 * Free Software Foundation, either version 3 of the license,
17 * or (at your option) any later version.
19 * There are special exceptions to the terms and conditions of the
20 * licenses as they are applied to this software. View the full text of
21 * the exception in file LICENSE-PROJECT.txt in the directory of this software
24 * Pentila Nero is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * Licenses for more details.
29 * You should have received a copy of the GNU Affero General Public License
30 * and the CeCILL-C and the GNU Lesser General Public License along with
31 * Pentila Nero. If not, see :
32 * <http://www.gnu.org/licenses/> and
33 * <http://www.cecill.info/licences.fr.html>.
34 ******************************************************************************/
35 package com.pentila.entSavoie.utils;
37 import org.jivesoftware.smack.AccountManager;
38 import org.jivesoftware.smack.ConnectionConfiguration;
39 import org.jivesoftware.smack.Roster;
40 import org.jivesoftware.smack.XMPPConnection;
41 import org.jivesoftware.smack.XMPPException;
42 import org.jivesoftware.smack.packet.Presence;
44 import com.liferay.portal.kernel.log.Log;
45 import com.liferay.portal.kernel.log.LogFactoryUtil;
46 import com.liferay.portal.model.User;
47 import com.pentila.entSavoie.userProperties.model.UserProperties;
48 import com.pentila.entSavoie.userProperties.service.UserPropertiesLocalServiceUtil;
50 public class XmppUtil {
52 private static Log _log = LogFactoryUtil.getLog(XmppUtil.class);
54 public static void createAccount(User user) {
56 XMPPConnection con = getXMPPConnection(user);
57 AccountManager acm = new AccountManager(con);
60 String userName = user.getLogin();
61 String password = getPassword(8);
63 acm.createAccount(userName, password);
65 UserProperties prop = UserPropertiesLocalServiceUtil.getUserPropertiesByUserId(user.getUserId());
66 prop.setJabberId(userName);
67 prop.setJabberPwd(password);
69 UserPropertiesLocalServiceUtil.updateUserProperties(prop, true);
70 _log.info("Created Jabber account for user "+user.getFullName());
72 } catch (Exception e) {
73 _log.error("Create account error for user "+user.getFullName());
80 private static String getPassword(int n) {
81 char[] pw = new char[n];
84 for (int i=0; i < n; i++)
86 r1 = (int)(Math.random() * 3);
88 case 0: c = '0' + (int)(Math.random() * 10); break;
89 case 1: c = 'a' + (int)(Math.random() * 26); break;
90 case 2: c = 'A' + (int)(Math.random() * 26); break;
94 return new String(pw);
97 public static void deleteAccount(User user) {
99 XMPPConnection con = getXMPPConnection(user);
102 UserProperties prop = UserPropertiesLocalServiceUtil.getUserPropertiesByUserId(user.getUserId());
104 if (prop.getJabberId() != null && !prop.getJabberId().equals("")) {
105 con.login(prop.getJabberId(), prop.getJabberPwd());
106 con.getAccountManager().deleteAccount();
108 _log.info("Deleted Jabber account for user "+user.getFullName());
110 } catch (Exception e) {
111 _log.error("Delete account error : ", e);
118 public static void subscribeUsersToRoster(User user1, User user2) {
119 XMPPConnection conUser1 = getXMPPConnection(user1);
120 XMPPConnection conUser2 = getXMPPConnection(user2);
123 UserProperties propUser1 = UserPropertiesLocalServiceUtil.getUserPropertiesByUserId(user1.getUserId());
124 UserProperties propUser2 = UserPropertiesLocalServiceUtil.getUserPropertiesByUserId(user2.getUserId());
126 conUser1.login(propUser1.getJabberId(), propUser1.getJabberPwd(),"Cartable-de-savoie-server");
127 conUser2.login(propUser2.getJabberId(), propUser2.getJabberPwd(),"Cartable-de-savoie-server");
129 Roster.setDefaultSubscriptionMode(Roster.SubscriptionMode.accept_all);
131 Roster r1 = conUser1.getRoster();
132 Roster r2 = conUser2.getRoster();
134 r1.createEntry(propUser2.getJabberId() + "@" + ENTMainUtilsLocalServiceUtil.getXmppDomain(user1.getCompanyId()), user2.getFullName(), new String[0]);
135 r2.createEntry(propUser1.getJabberId() + "@" + ENTMainUtilsLocalServiceUtil.getXmppDomain(user2.getCompanyId()), user1.getFullName(), new String[0]);
137 // ADded this commented which runs the full subscription process
138 // This works but the nickname in ofroster table was not set, and that prevents the roster to be connected
139 // The workaround found was to add a trigger in the database, which updates the 3 colons of ofroster table like the following:
143 // These values enable the chat between 2 friends
145 // String user1Name = propUser1.getJabberId() + "@" + ENTMainUtilsLocalServiceUtil.getXmppDomain(user1.getCompanyId());
146 // String user2Name = propUser2.getJabberId() + "@" + ENTMainUtilsLocalServiceUtil.getXmppDomain(user2.getCompanyId());
148 // // User1 sends a request to user2
149 // Presence subscribe = new Presence(Presence.Type.subscribe);
150 // subscribe.setTo(user2Name);
151 // conUser1.sendPacket(subscribe);
153 // // User2 accepts it and send a request to User1
154 // Presence subscribed = new Presence(Presence.Type.subscribed);
155 // subscribed.setTo(user1Name);
156 // conUser2.sendPacket(subscribed);
158 // subscribe = new Presence(Presence.Type.subscribe);
159 // subscribe.setTo(user1Name);
160 // conUser2.sendPacket(subscribe);
162 // // User1 accepts it
163 // subscribed = new Presence(Presence.Type.subscribed);
164 // subscribed.setTo(user2Name);
165 // conUser1.sendPacket(subscribed);
167 _log.info("User "+user1.getFullName()+" and user "+user2.getFullName()+" are now friends in Jabber");
170 _log.error("subscribeUsersToRoster Error for users "+user1.getFullName()+" and "+user2.getFullName());
174 disconnect(conUser1);
175 disconnect(conUser2);
179 public static void unsubscribeUsersToRoster(User user1, User user2) {
180 XMPPConnection conUser1 = getXMPPConnection(user1);
181 XMPPConnection conUser2 = getXMPPConnection(user2);
184 UserProperties propUser1 = UserPropertiesLocalServiceUtil.getUserPropertiesByUserId(user1.getUserId());
185 UserProperties propUser2 = UserPropertiesLocalServiceUtil.getUserPropertiesByUserId(user2.getUserId());
187 conUser1.login(propUser1.getJabberId(), propUser1.getJabberPwd(),"Cartable-de-savoie-server");
188 conUser2.login(propUser2.getJabberId(), propUser2.getJabberPwd(),"Cartable-de-savoie-server");
190 Roster r1 = conUser1.getRoster();
191 Roster r2 = conUser2.getRoster();
193 r1.removeEntry(r1.getEntry(propUser2.getJabberId() + "@" + ENTMainUtilsLocalServiceUtil.getXmppDomain(user1.getCompanyId())));
194 r2.removeEntry(r2.getEntry(propUser1.getJabberId() + "@" + ENTMainUtilsLocalServiceUtil.getXmppDomain(user2.getCompanyId())));
197 _log.error("unsubscribeUsersToRoster Error");
201 disconnect(conUser1);
202 disconnect(conUser2);
205 public static void logoutUser(User user) {
207 XMPPConnection connection = getXMPPConnection(user);
209 Presence offlinePres = new Presence(Presence.Type.unavailable, "", 1, Presence.Mode.away);
210 offlinePres.setStatus(connection.getUser() + "unavailable");
213 connection.disconnect(offlinePres);
214 } catch (Exception exception) {
215 connection.disconnect();
218 disconnect(connection);
222 private static XMPPConnection getXMPPConnection(User user) {
223 ConnectionConfiguration config = new ConnectionConfiguration(ENTMainUtilsLocalServiceUtil.getXmppHost(user.getCompanyId()), 5222);
224 config.setSendPresence(true);
225 config.setRosterLoadedAtLogin(true);
227 XMPPConnection connection = new XMPPConnection(config);
229 connection.connect();
230 } catch (XMPPException e) {
231 _log.error("XMPP connection creation in error for user "+user.getFullName());
237 private static void disconnect(XMPPConnection con) {