Commit 0b70bf1f authored by Dele Olajide's avatar Dele Olajide

ofmeet plugin version 0.1.7

Logs openfire meeting audit events with Openfire security auditor
Logs meeting SIP calls via SIP plugin
Added support for audio conferencing meetings (no video)
Updated Jitsi Videobridge
parent 0d48af65
......@@ -49,6 +49,15 @@
Openfire Meetings Plugin Changelog
</h1>
<p><b>0.1.7</b> -- May 13th, 2015</p>
<ul>
<li>Logs openfire meeting audit events with Openfire security auditor</li>
<li>Logs meeting SIP calls via SIP plugin</li>
<li>Added support for audio conferencing meetings (no video)</li>
<li>Updated Jitsi Videobridge</li>
</ul>
<p><b>0.1.6</b> -- May 9th, 2015</p>
<ul>
......
......@@ -5,8 +5,8 @@
<name>Openfire Meetings</name>
<description>Provides high quality, scalable video conferences using Jitsi Meet and Jitsi Videobridge</description>
<author>Ignite Realtime</author>
<version>0.1.6</version>
<date>05/09/2015</date>
<version>0.1.7</version>
<date>05/13/2015</date>
<minServerVersion>3.9.9</minServerVersion>
<adminconsole>
......
......@@ -17,6 +17,13 @@
var visible = false;
var joined = false;
function urlParam(name)
{
var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(window.location.href);
if (!results) { return undefined; }
return unescape(results[1] || undefined);
};
$(document).bind('ofmeet.connected', function (event, connection)
{
console.log("ofmeet connected", connection);
......@@ -55,7 +62,7 @@
$(document).bind('ofmeet.ready', function ()
{
console.log("ofmeet.ready");
ofmeet.connect();
ofmeet.connect(urlParam("novideo"));
});
$(document).ready(function ()
......
......@@ -211,8 +211,20 @@ function obtainAudioAndVideoPermissions(callback) {
video: stream.getVideoTracks().length
});
}
var media = ['audio', 'video'];
var resolution = config.resolution || '360';
if (urlParam("novideo"))
{
media = ['audio'];
resolution = null;
}
console.log("using media", media);
getUserMediaWithConstraints(
['audio', 'video'],
media,
cb,
function (error) {
console.error('failed to obtain audio/video stream - trying audio only', error);
......@@ -231,7 +243,7 @@ function obtainAudioAndVideoPermissions(callback) {
}
);
},
config.resolution || '360');
resolution);
}
function maybeDoJoin() {
......@@ -285,6 +297,13 @@ function doJoin() {
roomName, doJoinAfterFocus);
}
function urlParam(name)
{
var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(window.location.href);
if (!results) { return undefined; }
return unescape(results[1] || undefined);
};
function doJoinAfterFocus() {
var roomjid;
......
......@@ -24047,6 +24047,11 @@ var ofmeet = (function(of)
VideoLayout.updateLargeVideo(localVideoSrc, 0,
myResourceJid);
if (stream.getVideoTracks().length == 0)
{
localVideoSelector.css("display", "none");
}
};
/**
......@@ -31184,7 +31189,7 @@ var ofmeet = (function(of)
var sessionTerminated = false;
function connectOpenfire(jid, password)
function connectOpenfire(jid, password, novideo)
{
//console.log("connect", jid, password);
......@@ -31269,7 +31274,7 @@ var ofmeet = (function(of)
}
$(document).trigger('ofmeet.connected', [connection]);
});
}, novideo);
} else if (status === Strophe.Status.CONNFAIL) {
......@@ -31293,18 +31298,30 @@ var ofmeet = (function(of)
* We ask for audio and video combined stream in order to get permissions and
* not to ask twice.
*/
function obtainAudioAndVideoPermissions(callback) {
function obtainAudioAndVideoPermissions(callback, novideo) {
// Get AV
var cb = function (stream) {
//console.log('got', stream, stream.getAudioTracks().length, stream.getVideoTracks().length);
console.log('got', stream, stream.getAudioTracks().length, stream.getVideoTracks().length);
callback(stream);
trackUsage('localMedia', {
audio: stream.getAudioTracks().length,
video: stream.getVideoTracks().length
});
}
var media = ['audio', 'video'];
var resolution = config.resolution || '360';
if (novideo)
{
media = ['audio'];
resolution = null;
}
console.log("using media", media);
getUserMediaWithConstraints(
['audio', 'video'],
media,
cb,
function (error) {
console.error('failed to obtain audio/video stream - trying audio only', error);
......@@ -31323,7 +31340,7 @@ var ofmeet = (function(of)
}
);
},
config.resolution || '360');
resolution);
}
function generateRoomName() {
......@@ -32534,7 +32551,9 @@ var ofmeet = (function(of)
if (username && password)
{
headers = {"Authorization": "Basic " + btoa(username + ":" + password)}
headers = {"Authorization": "Basic " + btoa(username + ":" + password)};
of.username = username;
of.password = password;
}
$.ajax({type: "GET", url: "/ofmeet/config", dataType: "script", headers: headers}).done(function()
......@@ -32631,7 +32650,7 @@ var ofmeet = (function(of)
setAudioMuted(!isAudioMuted());
}
of.connect = function connect(username, password)
of.connect = function connect(novideo)
{
RTC = setupRTC();
......@@ -32642,7 +32661,7 @@ var ofmeet = (function(of)
}
var jid = config.hosts.domain;
if (username) jid = username + "@" + config.hosts.domain;
if (of.username) jid = of.username + "@" + config.hosts.domain;
if (config.userName)
{
......@@ -32650,7 +32669,7 @@ var ofmeet = (function(of)
authenticatedUser = true;
}
connectOpenfire(jid, password);
connectOpenfire(jid, of.password, novideo);
}
of.leaveRoom = function leaveRoom()
......@@ -89,6 +89,10 @@ window.addEventListener("load", function()
$(document).bind('inum.cleared', function(event, callId)
{
console.log("inum.cleared", callId);
dialer.setLabel("Call");
dialer.setState("inactive");
dialer.call = null
stopTone();
});
$(document).bind('inum.dialled', function (event, confId, to, callId)
......
......@@ -143,6 +143,8 @@ public class CallSession
public String callId;
public String focusJID;
public String roomJID;
public String username;
public long startTimestamp = 0;
private CallControlComponent callControl;
......
......@@ -57,7 +57,7 @@ public class JicofoPlugin
{
Log.info("JicofoPlugin - using focus " + focusUserJid + ":" + hostName);
System.setProperty("org.jitsi.videobridge.ofmeet.audio.mixer", JiveGlobals.getProperty("org.jitsi.videobridge.ofmeet.audio.mixer", "false"));
//System.setProperty("org.jitsi.videobridge.ofmeet.audio.mixer", JiveGlobals.getProperty("org.jitsi.videobridge.ofmeet.audio.mixer", "false"));
System.setProperty("net.java.sip.communicator.service.gui.ALWAYS_TRUST_MODE_ENABLED", "true");
System.setProperty(FocusManager.HOSTNAME_PNAME, hostName);
......
......@@ -25,6 +25,8 @@ import org.jivesoftware.openfire.SessionManager;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.muc.*;
import org.jivesoftware.openfire.session.*;
import org.jivesoftware.database.DbConnectionManager;
import java.sql.*;
import org.slf4j.*;
import org.slf4j.Logger;
......@@ -159,7 +161,7 @@ public class CallControlComponent extends AbstractComponent
sendPacket(iq);
}
private void makeCall(Conference conference, String confJid, String to, String callId)
private void makeCall(Conference conference, String confJid, String to, String callId, String username, long startTimestamp)
{
Log.info("CallControlComponent - makeCall " + confJid + " " + to + " " + callId);
......@@ -267,6 +269,8 @@ public class CallControlComponent extends AbstractComponent
cs.jabberRemote = to;
cs.jabberLocal = from;
cs.username = username;
cs.startTimestamp = startTimestamp;
SipService.sendInvite(cs);
......@@ -280,11 +284,12 @@ public class CallControlComponent extends AbstractComponent
{
Log.info("hangupCall " + callId);
CallSession cs = callSessions.get(callId);
CallSession cs = callSessions.remove(callId);
if (cs != null)
{
SipService.sendBye(cs);
updateCallRecord(cs.startTimestamp, (int)(System.currentTimeMillis() - cs.startTimestamp));
} else {
Log.error("CallControlComponent hangup. cannot fine callid " + callId);
......@@ -379,6 +384,12 @@ public class CallControlComponent extends AbstractComponent
}
}
if (session != null)
{
long startTimestamp = System.currentTimeMillis();
session.startTimestamp = startTimestamp;
createCallRecord("admin", from, confJID, startTimestamp, 0, "received");
}
return session;
}
......@@ -455,7 +466,12 @@ public class CallControlComponent extends AbstractComponent
hangup.addElement("header").addAttribute("name", "caller_id").addAttribute("value", session.jabberRemote);
hangup.addElement("header").addAttribute("name", "called_id").addAttribute("value", session.jabberLocal);
callSessions.remove(callId);
CallSession cs = callSessions.remove(callId);
if (cs != null)
{
updateCallRecord(cs.startTimestamp, (int)(System.currentTimeMillis() - cs.startTimestamp));
}
}
sendPacket(presence);
......@@ -548,7 +564,11 @@ public class CallControlComponent extends AbstractComponent
if (conference != null)
{
makeCall(conference, confJid, to, callId);
String username = iq.getFrom().getNode();
long startTimestamp = System.currentTimeMillis();
makeCall(conference, confJid, to, callId, username, startTimestamp);
createCallRecord(username, confJid, to, startTimestamp, 0, "dialed");
} else {
Log.error("CallControlComponent - can't find conference " + confId);
......@@ -711,4 +731,70 @@ public class CallControlComponent extends AbstractComponent
Log.error("CallControlComponent sendPacket ", e);
}
}
private void createCallRecord(String username, String addressFrom, String addressTo, long datetime, int duration, String calltype)
{
boolean sipPlugin = XMPPServer.getInstance().getPluginManager().getPlugin("sip") != null;
if (sipPlugin)
{
Log.info("createCallRecord " + username + " " + addressFrom + " " + addressTo + " " + datetime);
String sql = "INSERT INTO ofSipPhoneLog (username, addressFrom, addressTo, datetime, duration, calltype) values (?, ?, ?, ?, ?, ?)";
Connection con = null;
PreparedStatement psmt = null;
ResultSet rs = null;
try {
con = DbConnectionManager.getConnection();
psmt = con.prepareStatement(sql);
psmt.setString(1, username);
psmt.setString(2, addressFrom);
psmt.setString(3, addressTo);
psmt.setLong(4, datetime);
psmt.setInt(5, duration);
psmt.setString(6, calltype);
psmt.executeUpdate();
} catch (SQLException e) {
Log.error(e.getMessage(), e);
} finally {
DbConnectionManager.closeConnection(rs, psmt, con);
}
}
}
private void updateCallRecord(long datetime, int duration)
{
boolean sipPlugin = XMPPServer.getInstance().getPluginManager().getPlugin("sip") != null;
if (sipPlugin)
{
Log.info("updateCallRecord " + datetime + " " + duration);
String sql = "UPDATE ofSipPhoneLog SET duration = ? WHERE datetime = ?";
Connection con = null;
PreparedStatement psmt = null;
try {
con = DbConnectionManager.getConnection();
psmt = con.prepareStatement(sql);
psmt.setInt(1, duration);
psmt.setLong(2, (datetime / 1000));
psmt.executeUpdate();
} catch (SQLException e) {
Log.error(e.getMessage(), e);
} finally {
DbConnectionManager.closeConnection(psmt, con);
}
}
}
}
......@@ -18,6 +18,11 @@ import java.util.concurrent.*;
import org.slf4j.*;
import org.slf4j.Logger;
import org.jivesoftware.openfire.security.SecurityAuditManager;
import org.jivesoftware.util.*;
import org.xmpp.packet.*;
/**
* Allows logging of {@link org.jitsi.videobridge.log.Event}s using an
* <tt>Openfire</tt> instance.
......@@ -55,7 +60,7 @@ public class OpenfireEventService implements LoggingService
*/
@SuppressWarnings("unchecked")
@Override
public void logEvent(Event e)
public void logEvent(final Event e)
{
// The following is a sample JSON message in the format used by InfluxDB
// [
......@@ -101,7 +106,7 @@ public class OpenfireEventService implements LoggingService
@Override
public void run()
{
sendPost(jsonString);
sendPost(e.getName(), jsonString);
}
});
}
......@@ -111,11 +116,19 @@ public class OpenfireEventService implements LoggingService
* {@link #url}.
* @param s the content of the POST request.
*/
private void sendPost(final String s)
private void sendPost(final String summary, final String detail)
{
try
{
Log.info("OpenfireEventService sendPost " + s);
String focusUsername = "focus";
String focusUserJid = JiveGlobals.getProperty("org.jitsi.videobridge.ofmeet.focus.user.jid");
if (focusUserJid != null)
{
focusUsername = (new JID(focusUserJid)).getNode();
}
Log.info("OpenfireEventService sendPost " + focusUsername + " " + detail);
SecurityAuditManager.getInstance().logEvent(focusUsername, summary, detail);
}
catch (Exception e)
{
......
......@@ -43,6 +43,7 @@ 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.security.SecurityAuditManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -295,7 +296,7 @@ public class OfMeetPlugin implements Plugin, ClusterEventListener {
public void processMeetingPlanner()
{
Log.info("OfMeet Plugin - processMeetingPlanner");
Log.debug("OfMeet Plugin - processMeetingPlanner");
final Collection<Bookmark> bookmarks = BookmarkManager.getBookmarks();
......@@ -392,6 +393,7 @@ public class OfMeetPlugin implements Plugin, ClusterEventListener {
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) {
......
......@@ -675,6 +675,7 @@ function getUserMediaWithConstraints(um, success_callback, failure_callback, res
}
}
if (constraints.video) {
// Check if we are running on Android device
var isAndroid = navigator.userAgent.indexOf('Android') != -1;
......@@ -724,6 +725,8 @@ function getUserMediaWithConstraints(um, success_callback, failure_callback, res
}
break;
}
}
if (constraints.video)
{
if (constraints.video.mandatory.minWidth)
......
......@@ -108,8 +108,12 @@ var VideoLayout = (function (my) {
{
myResourceJid = Strophe.getResourceFromJid(connection.emuc.myroomjid);
}
VideoLayout.updateLargeVideo(localVideoSrc, 0,
myResourceJid);
VideoLayout.updateLargeVideo(localVideoSrc, 0, myResourceJid);
if (stream.getVideoTracks().length == 0)
{
localVideoSelector.css("display", "none");
}
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment