/**
* $Revision $
* $Date $
*
* Copyright (C) 2005-2010 Jive Software. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.openfire.plugin.ofmeet;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.file.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.*;
import java.text.*;
import java.util.regex.*;
import javax.servlet.DispatcherType;
import org.apache.tomcat.InstanceManager;
import org.apache.tomcat.SimpleInstanceManager;
import org.xmpp.packet.*;
import org.jivesoftware.util.*;
import org.jivesoftware.openfire.plugin.spark.*;
import org.jivesoftware.openfire.container.Plugin;
import org.jivesoftware.openfire.container.PluginManager;
import org.jivesoftware.openfire.http.HttpBindManager;
import org.jivesoftware.openfire.SessionManager;
import org.jivesoftware.openfire.session.LocalClientSession;
import org.jivesoftware.openfire.cluster.ClusterEventListener;
import org.jivesoftware.openfire.cluster.ClusterManager;
import org.jivesoftware.openfire.auth.AuthToken;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.user.User;
import org.jivesoftware.openfire.user.UserManager;
import org.jivesoftware.openfire.user.UserNotFoundException;
import org.jivesoftware.openfire.muc.*;
import org.jivesoftware.openfire.group.*;
import org.jivesoftware.openfire.session.*;
import org.jivesoftware.openfire.event.*;
import org.jivesoftware.openfire.security.SecurityAuditManager;
import org.jivesoftware.openfire.handler.IQHandler;
import org.jivesoftware.openfire.IQHandlerInfo;
import org.jivesoftware.openfire.roster.RosterManager;
import org.xmpp.component.ComponentManager;
import org.xmpp.component.ComponentManagerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.eclipse.jetty.apache.jsp.JettyJasperInitializer;
import org.eclipse.jetty.plus.annotation.ContainerInitializer;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.util.security.*;
import org.eclipse.jetty.security.*;
import org.eclipse.jetty.security.authentication.*;
import org.ifsoft.websockets.*;
import org.jitsi.videobridge.openfire.PluginImpl;
import org.jitsi.jicofo.openfire.JicofoPlugin;
import org.jitsi.videobridge.*;
import net.sf.json.*;
import org.dom4j.*;
public class OfMeetPlugin implements Plugin, SessionEventListener, ClusterEventListener {
private static final Logger Log = LoggerFactory.getLogger(OfMeetPlugin.class);
private final ConcurrentHashMap<String, XMPPServlet.XMPPWebSocket> sockets = new ConcurrentHashMap<String, XMPPServlet.XMPPWebSocket>();
private PluginImpl jitsiPlugin;
private JicofoPlugin jicofoPlugin;
private PluginManager manager;
public File pluginDirectory;
private TaskEngine taskEngine = TaskEngine.getInstance();
private UserManager userManager = XMPPServer.getInstance().getUserManager();
private ComponentManager componentManager;
private OfMeetIQHandler ofmeetIQHandler = null;
public static OfMeetPlugin self;
public static String ofmeetHome = JiveGlobals.getHomeDirectory() + File.separator + "resources" + File.separator + "spank" + File.separator + "ofmeet-cdn";
public String sipRegisterStatus = "";
public String getName() {
return "ofmeet";
}
public String getDescription() {
return "OfMeet Plugin";
}
public PluginImpl getPlugin()
{
return jitsiPlugin;
}
public void initializePlugin(final PluginManager manager, final File pluginDirectory)
{
componentManager = ComponentManagerFactory.getComponentManager();
ContextHandlerCollection contexts = HttpBindManager.getInstance().getContexts();
this.manager = manager;
this.pluginDirectory = pluginDirectory;
self = this;
try {
try {
Log.info("OfMeet Plugin - Initialize jitsi videobridge ");
jitsiPlugin = new PluginImpl();
jitsiPlugin.initializePlugin(componentManager, manager, pluginDirectory);
}
catch (Exception e1) {
Log.error("Could NOT Initialize jitsi videobridge", e1);
}
// Determine the JID of the 'focus' user.
final String defaultValue = "focus@" + XMPPServer.getInstance().getServerInfo().getXMPPDomain();
final String propertyValue = JiveGlobals.getProperty( "org.jitsi.videobridge.ofmeet.focus.user.jid", defaultValue );
JID focusUserJid;
try {
focusUserJid = new JID( propertyValue );
} catch (IllegalArgumentException e) {
Log.warn( "The 'org.jitsi.videobridge.ofmeet.focus.user.jid' property contains a value ('{}') that appears to be in invalid JID.", propertyValue, e );
focusUserJid = new JID( defaultValue );
}
// Ensure that the 'focus' user exists if it is supposed to be a user of our domain.
if ( focusUserJid.getDomain().equalsIgnoreCase( XMPPServer.getInstance().getServerInfo().getXMPPDomain() ) )
{
try {
userManager.getUser( focusUserJid.getNode() );
}
catch (UserNotFoundException e) {
Log.info("OfMeet Plugin - Setup focus user " + focusUserJid);
String focusUserPassword = JiveGlobals.getProperty( "org.jitsi.videobridge.ofmeet.focus.user.password", "focus-password-" + StringUtils.randomString( 15 ) );
try {
userManager.createUser( focusUserJid.getNode(), focusUserPassword, "Openfire Meetings Focus User", focusUserJid.toString() );
JiveGlobals.setProperty("org.jitsi.videobridge.ofmeet.focus.user.jid", focusUserJid.toString() );
JiveGlobals.setProperty("org.jitsi.videobridge.ofmeet.focus.user.password", focusUserPassword);
}
catch (Exception e1) {
Log.error("Could NOT create focus user", e1);
}
}
}
// Ensure that the 'focus' user is a sysadmin of the conference service(s).
for ( MultiUserChatService mucService : XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatServices() )
{
if (!mucService.isSysadmin( focusUserJid ))
{
mucService.addSysadmin( focusUserJid );
}
}
new Timer().schedule( new TimerTask()
{
@Override
public void run()
{
try
{
Log.info( "OfMeet Plugin - Initialize jitsi conference focus" );
jicofoPlugin = new JicofoPlugin();
jicofoPlugin.initializePlugin( componentManager, manager, pluginDirectory );
}
catch ( Exception e1 )
{
Log.error( "Could NOT Initialize jicofo component", e1 );
}
}
}, 5000);
try {
boolean bookmarks = XMPPServer.getInstance().getPluginManager().getPlugin("bookmarks") != null;
if (bookmarks)
{
new Timer().scheduleAtFixedRate(new TimerTask()
{
@Override public void run()
{
processMeetingPlanner();
}
}, 0, 900000);
}
} catch (Exception e) {
Log.error("Meeting Planner Executor error", e);
}
ClusterManager.addListener(this);
Log.info("OfMeet Plugin - Initialize websockets ");
ServletContextHandler context = new ServletContextHandler(contexts, "/ofmeetws", ServletContextHandler.SESSIONS);
context.addServlet(new ServletHolder(new XMPPServlet()),"/server");
// Ensure the JSP engine is initialized correctly (in order to be able to cope with Tomcat/Jasper precompiled JSPs).
final List<ContainerInitializer> initializers = new ArrayList<>();
initializers.add(new ContainerInitializer(new JettyJasperInitializer(), null));
context.setAttribute("org.eclipse.jetty.containerInitializers", initializers);
context.setAttribute(InstanceManager.class.getName(), new SimpleInstanceManager());
Log.info("OfMeet Plugin - Initialize webservice");
WebAppContext context2 = new WebAppContext(contexts, pluginDirectory.getPath(), "/ofmeet");
context2.setClassLoader(this.getClass().getClassLoader());
// Ensure the JSP engine is initialized correctly (in order to be able to cope with Tomcat/Jasper precompiled JSPs).
final List<ContainerInitializer> initializers2 = new ArrayList<>();
initializers2.add(new ContainerInitializer(new JettyJasperInitializer(), null));
context2.setAttribute("org.eclipse.jetty.containerInitializers", initializers2);
context2.setAttribute(InstanceManager.class.getName(), new SimpleInstanceManager());
context2.setWelcomeFiles(new String[]{"index.html"});
String securityEnabled = JiveGlobals.getProperty("ofmeet.security.enabled", "true");
if ("true".equals(securityEnabled))
{
Log.info("OfMeet Plugin - Initialize security");
if (JiveGlobals.getProperty("org.jitsi.videobridge.ofmeet.windows.sso", "off").equals("on"))
{
waffle.servlet.NegotiateSecurityFilter securityFilter = new waffle.servlet.NegotiateSecurityFilter();
FilterHolder filterHolder = new FilterHolder();
filterHolder.setFilter(securityFilter);
EnumSet<DispatcherType> enums = EnumSet.of(DispatcherType.REQUEST);
enums.add(DispatcherType.REQUEST);
context2.addFilter(filterHolder, "/*", enums);
}
else {
context2.setSecurityHandler(basicAuth("ofmeet"));
}
}
Log.info("OfMeet Plugin - Initialize email listener");
checkDownloadFolder(pluginDirectory);
EmailListener.getInstance().start();
Log.info("OfMeet Plugin - Initialize IQ handler ");
ofmeetIQHandler = new OfMeetIQHandler();
XMPPServer.getInstance().getIQRouter().addHandler(ofmeetIQHandler);
SessionEventDispatcher.addListener(this);
} catch (Exception e) {
Log.error("Could NOT start open fire meetings", e);
}
}
public void destroyPlugin() {
try {
SessionEventDispatcher.removeListener(this);
XMPPServer.getInstance().getIQRouter().removeHandler(ofmeetIQHandler);
ofmeetIQHandler = null;
for (XMPPServlet.XMPPWebSocket socket : sockets.values())
{
try {
LocalClientSession session = socket.getSession();
session.close();
SessionManager.getInstance().removeSession( session );
session = null;
} catch ( Exception e ) { }
}
sockets.clear();
jitsiPlugin.destroyPlugin();
jicofoPlugin.destroyPlugin();
ClusterManager.removeListener(this);
EmailListener.getInstance().stop();
} catch (Exception e) {
}
}
private static final SecurityHandler basicAuth(String realm) {
OpenfireLoginService l = new OpenfireLoginService();
l.setName(realm);
Constraint constraint = new Constraint();
constraint.setName(Constraint.__BASIC_AUTH);
constraint.setRoles(new String[]{"ofmeet"});
constraint.setAuthenticate(true);
ConstraintMapping cm = new ConstraintMapping();
cm.setConstraint(constraint);
cm.setPathSpec("/*");
ConstraintSecurityHandler csh = new ConstraintSecurityHandler();
csh.setAuthenticator(new BasicAuthenticator());
csh.setRealmName(realm);
csh.addConstraintMapping(cm);
csh.setLoginService(l);
return csh;
}
public ConcurrentHashMap<String, XMPPServlet.XMPPWebSocket> getSockets()
{
return sockets;
}
private void checkDownloadFolder(File pluginDirectory)
{
try
{
File ofmeetFolderPath = new File(ofmeetHome);
if(!ofmeetFolderPath.exists())
{
ofmeetFolderPath.mkdirs();
}
List<String> lines = Arrays.asList("Move on, nothing here....");
Path file = Paths.get(ofmeetHome + File.separator + "index.html");
Files.write(file, lines, Charset.forName("UTF-8"));
File downloadHome = new File(ofmeetHome + File.separator + "download");
if(!downloadHome.exists())
{
downloadHome.mkdirs();
}
File recordingsHome = new File(ofmeetHome + File.separator + "recordings");
if(!recordingsHome.exists())
{
recordingsHome.mkdirs();
}
lines = Arrays.asList("Move on, nothing here....");
file = Paths.get(downloadHome + File.separator + "index.html");
Files.write(file, lines, Charset.forName("UTF-8"));
file = Paths.get(recordingsHome + File.separator + "index.html");
Files.write(file, lines, Charset.forName("UTF-8"));
}
catch (Exception e)
{
Log.error("checkDownloadFolder", e);
}
}
//-------------------------------------------------------
//
// clustering
//
//-------------------------------------------------------
@Override
public void joinedCluster()
{
Log.info("OfMeet Plugin - joinedCluster");
jitsiPlugin.destroyPlugin();
jicofoPlugin.destroyPlugin();
}
@Override
public void joinedCluster(byte[] arg0)
{
}
@Override
public void leftCluster()
{
Log.info("OfMeet Plugin - leftCluster");
jitsiPlugin.initializePlugin(componentManager, manager, pluginDirectory);
jicofoPlugin.initializePlugin(componentManager, manager, pluginDirectory);
}
@Override
public void leftCluster(byte[] arg0)
{
}
@Override
public void markedAsSeniorClusterMember()
{
Log.info("OfMeet Plugin - markedAsSeniorClusterMember");
jitsiPlugin.initializePlugin(componentManager, manager, pluginDirectory);
jicofoPlugin.initializePlugin(componentManager, manager, pluginDirectory);
}
//-------------------------------------------------------
//
// meeting planner
//
//-------------------------------------------------------
public void processMeetingPlanner()
{
Log.debug("OfMeet Plugin - processMeetingPlanner");
final Collection<Bookmark> bookmarks = BookmarkManager.getBookmarks();
String hostname = XMPPServer.getInstance().getServerInfo().getHostname();
for (Bookmark bookmark : bookmarks)
{
if (bookmark.getType() == Bookmark.Type.group_chat)
{
String url = bookmark.getProperty("url");
if (url == null)
{
String id = bookmark.getBookmarkID() + "" + System.currentTimeMillis();
String rootUrl = JiveGlobals.getProperty("ofmeet.root.url.secure", "https://" + hostname + ":" + JiveGlobals.getProperty("httpbind.port.secure", "7443"));
url = rootUrl + "/ofmeet/?b=" + id;
bookmark.setProperty("url", url);
}
}
String json = bookmark.getProperty("calendar");
if (json != null)
{
bookmark.setProperty("lock", "true");
JSONArray calendar = new JSONArray(json);
boolean done = false;
for(int i = 0; i < calendar.length(); i++)
{
try {
JSONObject meeting = calendar.getJSONObject(i);
boolean processed = meeting.getBoolean("processed");
long startLong = meeting.getLong("startTime");
Date rightNow = new Date(System.currentTimeMillis());
Date actionDate = new Date(startLong + 300000);
Date warnDate = new Date(startLong - 960000);
Log.debug("OfMeet Plugin - scanning meeting now " + rightNow + " action " + actionDate + " warn " + warnDate + "\n" + meeting );
if(rightNow.after(warnDate) && rightNow.before(actionDate))
{
for (String user : bookmark.getUsers())
{
processMeeting(meeting, user, bookmark.getProperty("url"));
}
for (String groupName : bookmark.getGroups())
{
try {
Group group = GroupManager.getInstance().getGroup(groupName);
for (JID memberJID : group.getMembers())
{
processMeeting(meeting, memberJID.getNode(), bookmark.getProperty("url"));
}
} catch (GroupNotFoundException e) { }
}
meeting.put("processed", true);
done = true;
}
} catch (Exception e) {
Log.error("processMeetingPlanner", e);
}
}
if (done)
{
json = calendar.toString();
bookmark.setProperty("calendar", json);
Log.debug("OfMeet Plugin - processed meeting\n" + json);
}
bookmark.setProperty("lock", "false");
}
}
}
public void processMeeting(JSONObject meeting, String username, String videourl)
{
Log.info("OfMeet Plugin - processMeeting " + username + " " + meeting);
try {
User user = userManager.getUser(username);
Date start = new Date(meeting.getLong("startTime"));
Date end = new Date(meeting.getLong("endTime"));
String name = user.getName();
String email = user.getEmail();
String description = meeting.getString("description");
String title = meeting.getString("title");
String room = meeting.getString("room");
//String videourl = "https://" + XMPPServer.getInstance().getServerInfo().getHostname() + ":" + JiveGlobals.getProperty("httpbind.port.secure", "7443") + "/ofmeet/?r=" + room;
String audiourl = videourl + "&novideo=true";
String template = JiveGlobals.getProperty("ofmeet.email.template", "Dear [name],\n\nYou have an online meeting from [start] to [end]\n\n[description]\n\nTo join, please click\n[videourl]\nFor audio only with no webcan, please click\n[audiourl]\n\nAdministrator - [domain]");
HashMap variables = new HashMap<String, String>();
if (email != null)
{
variables.put("name", name);
variables.put("email", email);
variables.put("start", start.toString());
variables.put("end", end.toString());
variables.put("description", description);
variables.put("title", title);
variables.put("room", room);
variables.put("videourl", videourl);
variables.put("audiourl", audiourl);
variables.put("domain", XMPPServer.getInstance().getServerInfo().getXMPPDomain());
sendEmail(name, email, title, replaceTokens(template, variables), null);
SecurityAuditManager.getInstance().logEvent(user.getUsername(), "sent email - " + title, description);
}
}
catch (Exception e) {
Log.error("processMeeting error", e);
}
}
public void sendEmail(String toName, String toAddress, String subject, String body, String htmlBody)
{
try {
String fromAddress = "no_reply@" + JiveGlobals.getProperty("ofmeet.email.domain", XMPPServer.getInstance().getServerInfo().getXMPPDomain());
String fromName = JiveGlobals.getProperty("ofmeet.email.fromname", "Openfire Meetings");
Log.debug( "sendEmail " + toAddress + " " + subject + "\n " + body + "\n " + htmlBody);
EmailService.getInstance().sendMessage(toName, toAddress, fromName, fromAddress, subject, body, htmlBody);
}
catch (Exception e) {
Log.error(e.toString());
}
}
public String replaceTokens(String text, Map<String, String> replacements)
{
Pattern pattern = Pattern.compile("\\[(.+?)\\]");
Matcher matcher = pattern.matcher(text);
StringBuffer buffer = new StringBuffer();
while (matcher.find())
{
String replacement = replacements.get(matcher.group(1));
if (replacement != null)
{
matcher.appendReplacement(buffer, "");
buffer.append(replacement);
}
}
matcher.appendTail(buffer);
return buffer.toString();
}
//-------------------------------------------------------
//
// session management
//
//-------------------------------------------------------
public void anonymousSessionCreated(Session session)
{
Log.debug("OfMeet Plugin - anonymousSessionCreated "+ session.getAddress().toString() + "\n" + ((ClientSession) session).getPresence().toXML());
}
public void anonymousSessionDestroyed(Session session)
{
Log.debug("OfMeet Plugin - anonymousSessionDestroyed "+ session.getAddress().toString() + "\n" + ((ClientSession) session).getPresence().toXML());
}
public void resourceBound(Session session)
{
Log.debug("OfMeet Plugin - resourceBound "+ session.getAddress().toString() + "\n" + ((ClientSession) session).getPresence().toXML());
}
public void sessionCreated(Session session)
{
Log.debug("OfMeet Plugin - sessionCreated "+ session.getAddress().toString() + "\n" + ((ClientSession) session).getPresence().toXML());
}
public void sessionDestroyed(Session session)
{
Log.debug("OfMeet Plugin - sessionDestroyed "+ session.getAddress().toString() + "\n" + ((ClientSession) session).getPresence().toXML());
boolean skypeAvailable = XMPPServer.getInstance().getPluginManager().getPlugin("ofskype") != null;
if (OpenfireLoginService.skypeids.containsKey(session.getAddress().getNode()))
{
String sipuri = OpenfireLoginService.skypeids.remove(session.getAddress().getNode());
IQ iq = new IQ(IQ.Type.set);
iq.setFrom(session.getAddress());
iq.setTo(XMPPServer.getInstance().getServerInfo().getXMPPDomain());
Element child = iq.setChildElement("request", "http://igniterealtime.org/protocol/ofskype");
child.setText("{'action':'stop_skype_user', 'sipuri':'" + sipuri + "'}");
XMPPServer.getInstance().getIQRouter().route(iq);
Log.info("OfMeet Plugin - closing skype session " + sipuri);
}
}
//-------------------------------------------------------
//
// custom IQ handler for JSON request/response
//
//-------------------------------------------------------
public class OfMeetIQHandler extends IQHandler
{
public OfMeetIQHandler()
{
super("Openfire Meetings IQ Handler");
}
@Override public IQ handleIQ(IQ iq)
{
IQ reply = IQ.createResultIQ(iq);
try {
Log.info("Openfire Meetings handleIQ \n" + iq.toString());
final Element element = iq.getChildElement();
JID from = iq.getFrom();
JSONObject requestJSON = new JSONObject(element.getText());
String action = requestJSON.getString("action");
if ("get_user_properties".equals(action)) getUserProperties(iq.getFrom().getNode(), reply, requestJSON);
if ("set_user_properties".equals(action)) setUserProperties(iq.getFrom().getNode(), reply, requestJSON);
if ("get_user_groups".equals(action)) getUserGroups(iq.getFrom().getNode(), reply, requestJSON);
if ("get_group".equals(action)) getGroup(iq.getFrom().getNode(), reply, requestJSON);
if ("get_conference_id".equals(action)) getConferenceId(iq.getFrom().getNode(), reply, requestJSON);
return reply;
} catch(Exception e) {
Log.error("Openfire Meetings handleIQ", e);
reply.setError(new PacketError(PacketError.Condition.internal_server_error, PacketError.Type.modify, e.toString()));
return reply;
}
}
@Override public IQHandlerInfo getInfo()
{
return new IQHandlerInfo("request", "http://igniterealtime.org/protocol/ofmeet");
}
private void setUserProperties(String username, IQ reply, JSONObject requestJSON)
{
Element childElement = reply.setChildElement("response", "http://igniterealtime.org/protocol/ofmeet");
try {
UserManager userManager = XMPPServer.getInstance().getUserManager();
User user = userManager.getUser(username);
if (requestJSON != null)
{
Iterator<?> keys = requestJSON.keys();
while( keys.hasNext() )
{
String key = (String)keys.next();
String value = requestJSON.getString(key);
user.getProperties().put(key, value);
}
}
} catch (Exception e) {
reply.setError(new PacketError(PacketError.Condition.not_allowed, PacketError.Type.modify, "User " + username + " " + requestJSON.toString() + " " + e));
return;
}
}
private void getUserProperties(String defaultUsername, IQ reply, JSONObject requestJSON)
{
Element childElement = reply.setChildElement("response", "http://igniterealtime.org/protocol/ofmeet");
try {
String username = requestJSON.getString("username");
if (username == null) username = defaultUsername;
UserManager userManager = XMPPServer.getInstance().getUserManager();
User user = userManager.getUser(username);
JSONObject userJSON = new JSONObject();
userJSON.put("username", JID.unescapeNode(user.getUsername()));
userJSON.put("name", user.isNameVisible() ? removeNull(user.getName()) : "");
userJSON.put("email", user.isEmailVisible() ? removeNull(user.getEmail()) : "");
for(Map.Entry<String, String> props : user.getProperties().entrySet())
{
userJSON.put(props.getKey(), props.getValue());
}
childElement.setText(userJSON.toString());
} catch (UserNotFoundException e) {
reply.setError(new PacketError(PacketError.Condition.not_allowed, PacketError.Type.modify, "User not found"));
return;
} catch (Exception e1) {
reply.setError(new PacketError(PacketError.Condition.not_allowed, PacketError.Type.modify, requestJSON.toString() + " " + e1));
return;
}
}
private void getConferenceId(String defaultUsername, IQ reply, JSONObject requestJSON)
{
Element childElement = reply.setChildElement("response", "http://igniterealtime.org/protocol/ofmeet");
try {
String roomName = requestJSON.getString("room");
String recordFlag = requestJSON.getString("record");
Videobridge videobridge = jitsiPlugin.component.getVideobridge();
for (Conference conference : videobridge.getConferences())
{
String room = conference.getName();
if (room != null && !"".equals(room) && roomName.equals(room))
{
if (recordFlag != null)
{
if (conference.isRecording() && "false".equals(recordFlag)) conference.setRecording(false);
if (!conference.isRecording() && "true".equals(recordFlag)) conference.setRecording(true);
}
String confId = conference.getID();
JSONObject userJSON = new JSONObject();
userJSON.put("room", roomName);
userJSON.put("id", confId);
userJSON.put("lastActivityTime", String.valueOf(conference.getLastActivityTime()));
userJSON.put("focus", conference.getFocus());
userJSON.put("recording", conference.isRecording() ? "yes" : "no");
userJSON.put("expired", conference.isExpired() ? "yes" : "no");
Path dir = Paths.get(JiveGlobals.getProperty("org.jitsi.videobridge.ofmeet.recording.path", ofmeetHome + File.separator + "recordings"));
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir))
{
for (Path file: stream)
{
String fileName = file.getFileName().toString();
if (fileName.indexOf(confId) > -1)
{
userJSON.put("folder", fileName);
}
}
} catch (IOException | DirectoryIteratorException x) {
Log.error("getConferenceId", x);
}
childElement.setText(userJSON.toString());
break;
}
}
} catch (Exception e1) {
Log.error("getConferenceId", e1);
reply.setError(new PacketError(PacketError.Condition.not_allowed, PacketError.Type.modify, requestJSON.toString() + " " + e1));
return;
}
}
private void getUserGroups(String defaultUsername, IQ reply, JSONObject requestJSON)
{
Element childElement = reply.setChildElement("response", "http://igniterealtime.org/protocol/ofmeet");
try {
String username = requestJSON.getString("username");
if (username == null) username = defaultUsername;
UserManager userManager = XMPPServer.getInstance().getUserManager();
User user = userManager.getUser(username);
Collection<Group> groups = GroupManager.getInstance().getGroups(user);
JSONArray groupsJSON = new JSONArray();
int index = 0;
for (Group group : groups)
{
groupsJSON.put(index++, getJsonFromGroupXml(group.getName()));
}
childElement.setText(groupsJSON.toString());
} catch (UserNotFoundException e) {
reply.setError(new PacketError(PacketError.Condition.not_allowed, PacketError.Type.modify, "User not found"));
return;
} catch (Exception e1) {
reply.setError(new PacketError(PacketError.Condition.not_allowed, PacketError.Type.modify, requestJSON.toString() + " " + e1));
return;
}
}
private void getGroup(String defaultUsername, IQ reply, JSONObject requestJSON)
{
Element childElement = reply.setChildElement("response", "http://igniterealtime.org/protocol/ofmeet");
try {
JSONObject groupJSON = getJsonFromGroupXml(requestJSON.getString("groupname"));
childElement.setText(groupJSON.toString());
} catch (Exception e1) {
reply.setError(new PacketError(PacketError.Condition.not_allowed, PacketError.Type.modify, requestJSON.toString() + " " + e1));
return;
}
}
private JSONObject getJsonFromGroupXml(String groupname)
{
JSONObject groupJSON = new JSONObject();
try {
Group group = GroupManager.getInstance().getGroup(groupname);
boolean isSharedGroup = RosterManager.isSharedGroup(group);
Map<String, String> properties = group.getProperties();
String showInRoster = (isSharedGroup ? properties.get("sharedRoster.showInRoster") : "");
groupJSON.put("name", group.getName());
groupJSON.put("desc", group.getDescription());
groupJSON.put("count", group.getMembers().size() + group.getAdmins().size());
groupJSON.put("shared", String.valueOf(isSharedGroup));
groupJSON.put("display", (isSharedGroup ? properties.get("sharedRoster.displayName") : ""));
groupJSON.put("specified_groups", String.valueOf("onlyGroup".equals(showInRoster) && properties.get("sharedRoster.groupList").trim().length() > 0));
groupJSON.put("visibility", showInRoster);
groupJSON.put("groups", (isSharedGroup ? properties.get("sharedRoster.groupList") : ""));
for(Map.Entry<String, String> props : properties.entrySet())
{
groupJSON.put(props.getKey(), props.getValue());
}
JSONArray membersJSON = new JSONArray();
JSONArray adminsJSON = new JSONArray();
int i = 0;
for (JID memberJID : group.getMembers())
{
JSONObject memberJSON = new JSONObject();
memberJSON.put("jid", memberJID.toString());
memberJSON.put("name", memberJID.getNode());
membersJSON.put(i++, memberJSON);
}
groupJSON.put("members", membersJSON);
i = 0;
for (JID memberJID : group.getAdmins())
{
JSONObject adminJSON = new JSONObject();
adminJSON.put("jid", memberJID.toString());
adminJSON.put("name", memberJID.getNode());
adminsJSON.put(i++, adminJSON);
}
groupJSON.put("admins", adminsJSON);
} catch (Exception e) {
Log.error("getJsonFromGroupXml", e);
}
return groupJSON;
}
private String removeNull(String s)
{
if (s == null)
{
return "";
}
return s.trim();
}
}
//-------------------------------------------------------
//
//
//
//-------------------------------------------------------
}