Commit 7667c207 authored by Axel Brand's avatar Axel Brand Committed by daeva

Prototype of Gateway-Sessions / Gateway-Registrations Overview features....

Prototype of Gateway-Sessions / Gateway-Registrations Overview features. Currently only for postgres and some Features not working yet.

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@13669 b35dd754-fafc-0310-a699-88a17e54d16e
parent a3b84eb3
<?xml version="1.0" encoding="UTF-8"?>
<plugin>
<!-- Main plugin class -->
<class>org.jivesoftware.openfire.plugin.gojara.base.RemoteRosterPlugin</class>
<class>org.jivesoftware.openfire.plugin.gojara.base.RemoteRosterPlugin
</class>
<name>GoJara</name>
<description>ProtoXEP-xxxx: Remote Roster Management support</description>
<description>ProtoXEP-xxxx: Remote Roster Management support
</description>
<author>Holger Bergunde / Daniel Henninger / Axel-F. Brand</author>
<version>2.0.0</version>
<version>2.1.0</version>
<date>03/19/2013</date>
<databaseKey>gojara</databaseKey>
<databaseVersion>0</databaseVersion>
<databaseVersion>1</databaseVersion>
<minServerVersion>3.7.0</minServerVersion>
<!-- Admin console entries -->
......@@ -18,10 +20,19 @@
<adminconsole>
<tab id="tab-server">
<sidebar id="sidebar-server-settings">
<item id="remoteRoster" name="${rr.summary.title}"
url="rr-main.jsp"
<item id="remoteRoster" name="${rr.summary.title}" url="rr-main.jsp"
description="${rr.summary.title}" />
</sidebar>
</tab>
<tab id="tab-session">
<sidebar id="sidebar-session">
<item id="gojaraSessions" name="Gateway Sessions" url="gojara-activeSessions.jsp"
description="Click to manage Gateway sessions"></item>
</sidebar>
<sidebar id="sidebar-tools">
<item id="gojaraRegistrationAdministration" name="Gateway Registration Overview"
url="gojara-RegistrationsOverview.jsp" description="Manage existing Spectrum2 registrations"></item>
</sidebar>
</tab>
</adminconsole>
</plugin>
\ No newline at end of file
......@@ -9,4 +9,4 @@ CREATE TABLE ofGojaraStatistics (
);
INSERT INTO ofVersion (name, version) VALUES ('gojara', 0);
INSERT INTO ofVersion (name, version) VALUES ('gojara', 1);
-- Create SessionEntry
CREATE TABLE ofGojaraSessions(
username varchar(255) NOT NULL,
transport varchar(255) NOT NULL,
lastActivity BIGINT NOT NULL,
PRIMARY KEY(username, transport)
);
CREATE INDEX ofGojara_lastActivity_idx ON ofGojaraSessions(lastActivity);
-- Update database version
UPDATE ofVersion SET version=1 WHERE name = 'gojara';
\ No newline at end of file
......@@ -14,6 +14,7 @@ import org.jivesoftware.openfire.container.Plugin;
import org.jivesoftware.openfire.container.PluginManager;
import org.jivesoftware.openfire.interceptor.InterceptorManager;
import org.jivesoftware.openfire.plugin.gojara.messagefilter.MainInterceptor;
import org.jivesoftware.openfire.plugin.gojara.permissions.TransportSessionManager;
import org.jivesoftware.openfire.plugin.gojara.utils.XpathHelper;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.PropertyEventDispatcher;
......@@ -49,7 +50,6 @@ public class RemoteRosterPlugin implements Plugin {
private InterceptorManager iManager = InterceptorManager.getInstance();
private InternalComponentManager compManager = InternalComponentManager.getInstance();
public void initializePlugin(PluginManager manager, File pluginDirectory) {
Log.info("Starting RemoteRoster Plugin");
pluginManager = manager;
......
......@@ -16,7 +16,8 @@ import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.util.JiveGlobals;
/**
* @author Holger Bergunde This class is used to store logs in the database. A
* @author Holger Bergunde, Axel-Frederik Brand
* This class is used to store logs in the database. A
* log entry is representated by {@link LogEntry}
*/
public class DatabaseManager {
......@@ -24,6 +25,7 @@ public class DatabaseManager {
private static Logger Log = Logger.getLogger(DatabaseManager.class);
private static volatile DatabaseManager _myself;
//Logging
private static final String COUNT_LOG_ENTRIES = "SELECT count(*) FROM ofGojaraStatistics";
private static final String COUNT_PACKAGES_ODLER = "SELECT count(*) FROM ofGojaraStatistics WHERE messageType like ? AND component = ? AND messageDate > ?";
private static final String GET_ALL_LOGS = "SELECT * FROM ofGojaraStatistics ORDER BY logID desc LIMIT 100";
......@@ -33,7 +35,11 @@ public class DatabaseManager {
private static final String CLEAN_OLD_DATA = "DELETE FROM ofGojaraStatistics WHERE messageDate < ?";
private static final String GET_LOGS_DATE_LIMIT_COMPONENT = "SELECT * FROM ofGojaraStatistics WHERE messageDate > ? AND component = ? ORDER BY messageDate DESC LIMIT ?";
private final int _dbCleanMinutes;
//Session
private static final String ADD_SESSION_ENTRY = "INSERT INTO ofGojaraSessions(username, transport, lastActivity) VALUES (?,?,?)";
private static final String UPDATE_SESSION_ENTRY = "UPDATE ofGojaraSessions SET lastActivity = ? WHERE username = ? AND transport = ?";
private static final String GET_SESSION_ENTRIES_FOR_USERNAME = "SELECT * FROM ofGojaraSessions WHERE username = ? ORDER BY lastActivity DESC";
private static final String DELETE_SESSION_ENTRY = "DELETE FROM ofGojaraSessions WHERE username = ? AND transport = ?";
private DatabaseManager() {
/*
......@@ -281,4 +287,115 @@ public class DatabaseManager {
return -1;
}
/**
* Trys to update SessionEntry for given user/transport combination. If update does not
* work due to no record being there, it inserts record.
*/
public void insertOrUpdateSession(String transport, String user, long time) {
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(UPDATE_SESSION_ENTRY);
pstmt.setLong(1, time);
pstmt.setString(2, user);
pstmt.setString(3, transport);
if (pstmt.executeUpdate() == 0) {
pstmt.close();
pstmt = con.prepareStatement(ADD_SESSION_ENTRY);
pstmt.setString(1, user);
pstmt.setString(2, transport);
pstmt.setLong(3, time);
pstmt.executeUpdate();
Log.info("I have inserted " + user + " with " + transport + " at " + time);
} else
Log.info("I have updated " + user + " with " + transport + " at " + time);
} catch (SQLException sqle) {
Log.error(sqle);
} finally {
DbConnectionManager.closeConnection(pstmt, con);
}
}
public int removeSessionEntry(String transport, String user) {
int result = 0;
Log.info("I would now hit the DB and remove " + transport + " " + user);
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(DELETE_SESSION_ENTRY);
pstmt.setString(1, user);
pstmt.setString(2, transport);
result = pstmt.executeUpdate();
} catch (SQLException sqle) {
Log.error(sqle);
} finally {
DbConnectionManager.closeConnection(pstmt, con);
}
return result;
}
public ArrayList<SessionEntry> getSessionEntriesFor(String username) {
ArrayList<SessionEntry> result = new ArrayList<SessionEntry>();
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(GET_SESSION_ENTRIES_FOR_USERNAME);
pstmt.setString(1, username);
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
String user = rs.getString(1);
String transport = rs.getString(2);
long lastActivity = rs.getLong(3);
SessionEntry res = new SessionEntry(user,transport,lastActivity);
result.add(res);
}
pstmt.close();
} catch (SQLException sqle) {
Log.error(sqle);
} finally {
DbConnectionManager.closeConnection(pstmt, con);
}
return result;
}
public ArrayList<SessionEntry> getAllSessionEntries(String orderAttr, String order) {
String allowedAttr = "username transport lastActivity";
String allowedOrder = "ASC DESC";
if ((orderAttr == null || order == null)
|| (!allowedAttr.contains(orderAttr) || !allowedOrder.contains(order))) {
//Use default case if sorting attributes are not correct.
orderAttr = "username";
order = "DESC";
}
ArrayList<SessionEntry> result = new ArrayList<SessionEntry>();
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
String sql = "SELECT * FROM ofGojaraSessions ORDER BY " + orderAttr + " " + order + ";";
pstmt = con.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
String user = rs.getString(1);
String transport = rs.getString(2);
long lastActivity = rs.getLong(3);
SessionEntry res = new SessionEntry(user,transport,lastActivity);
result.add(res);
}
pstmt.close();
} catch (SQLException sqle) {
Log.error(sqle);
} finally {
DbConnectionManager.closeConnection(pstmt, con);
}
return result;
}
}
package org.jivesoftware.openfire.plugin.gojara.database;
import java.sql.Timestamp;
import java.util.Date;
/**
* This class should represent a Session Entry
*/
public class SessionEntry {
private String username;
private String transport;
private long last_activity;
/**
*/
public SessionEntry(String username, String transport, long last_activity) {
this.username = username;
this.transport = transport;
this.last_activity = last_activity;
}
public String getUsername() {
return username;
}
public String getTransport() {
return transport;
}
public long getLast_activity() {
return last_activity;
}
public Date getLast_activityAsDate() {
Timestamp stamp = new Timestamp(last_activity);
Date date = new Date(stamp.getTime());
return date;
}
}
......@@ -3,12 +3,14 @@ package org.jivesoftware.openfire.plugin.gojara.messagefilter;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Iterator;
import org.dom4j.Element;
import org.dom4j.Node;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.interceptor.PacketInterceptor;
import org.jivesoftware.openfire.interceptor.PacketRejectedException;
import org.jivesoftware.openfire.plugin.gojara.messagefilter.processors.*;
import org.jivesoftware.openfire.plugin.gojara.permissions.TransportSessionManager;
import org.jivesoftware.openfire.roster.RosterManager;
import org.jivesoftware.openfire.session.Session;
import org.jivesoftware.util.ConcurrentHashSet;
......@@ -24,6 +26,7 @@ public class MainInterceptor implements PacketInterceptor {
private static final Logger Log = LoggerFactory.getLogger(MainInterceptor.class);
private Set<String> activeTransports = new ConcurrentHashSet<String>();
private Map<String, AbstractRemoteRosterProcessor> packetProcessors = new HashMap<String, AbstractRemoteRosterProcessor>();
private TransportSessionManager tSessionManager = TransportSessionManager.getInstance();
private Boolean frozen;
public MainInterceptor() {
......@@ -51,17 +54,17 @@ public class MainInterceptor implements PacketInterceptor {
public boolean addTransport(String subDomain) {
Log.info("Trying to add " + subDomain + " to Set of watched Transports.");
return this.activeTransports.add(subDomain);
boolean retval = this.activeTransports.add(subDomain);
if (retval)
tSessionManager.addTransport(subDomain);
return retval;
}
public boolean removeTransport(String subDomain) {
Log.info("Trying to remove " + subDomain + " from Set of watched Transports.");
tSessionManager.removeTransport(subDomain);
return this.activeTransports.remove(subDomain);
// if (this.activeTransports.contains(subDomain)) {
// this.activeTransports.remove(subDomain);
// return true;
// }
// return false;
}
public void freeze() {
......@@ -152,6 +155,28 @@ public class MainInterceptor implements PacketInterceptor {
String subdomain = from_s.length() == 0 ? to_s : from_s;
if (!from.equals(to) && subdomain.length() > 0)
packetProcessors.get("statisticsProcessor").process(packet, subdomain, to, from);
// TransportSession Feature
if (packet instanceof Presence && activeTransports.contains(from)){
Presence presence_packet = (Presence) packet;
if (presence_packet.getType() == null) {
tSessionManager.connectUserTo(from, packet.getTo().getNode().toString());
}
else if (presence_packet.getType() != null && presence_packet.getType().equals(Presence.Type.unavailable)) {
tSessionManager.disconnectUserFrom(from, packet.getTo().getNode().toString());
}
} else if (packet instanceof IQ && activeTransports.contains(to)) {
IQ iqPacket = (IQ) packet;
Element query = iqPacket.getChildElement();
if (query == null)
return;
if (query.getNamespaceURI().equals("jabber:iq:register")) {
if (query.nodeCount() > 1)
tSessionManager.registerUserTo(to, iqPacket.getFrom().getNode().toString());
else
tSessionManager.removeRegistrationOfUser(to, iqPacket.getFrom().getNode().toString());
}
}
} else if (!incoming && !processed) {
......
......@@ -15,7 +15,7 @@ import org.xmpp.packet.Packet;
/**
* This packet and sub packet implements the command pattern. Every processor
* that extends this class have to implement the process function. The
* {@link RemoteRosterInterceptor} will register different implementations of
* {@link MainInterceptor} will register different implementations of
* this processor and redirect packages according to their functionality
*
* @author Holger Bergunde
......@@ -38,7 +38,7 @@ abstract public class AbstractRemoteRosterProcessor {
* the package should not be processed by openfire.
* See actual classes for info about their implementation.
* @param packet Packet itself
* @param subdomain String with subdomain contained in either from or to, or string with several watched subdomains that needs to be splitted (see Maininterceptor)
* @param subdomain String with subdomain contained in either from or to, may be ""
* @param to String with recipient of packet, may be ""
* @param from String with sender of packet, may be ""
* @throws PacketRejectedException
......
......@@ -12,16 +12,18 @@ import org.xmpp.packet.Packet;
/**
* This class implements the XEP-xxx Remote Roster Management standard
* "2.4 Client sends user update". Part of command pattern used in
* {@link RemoteRosterInterceptor}
* {@link MainInterceptor}
*
* Further information: <a
* href="http://jkaluza.fedorapeople.org/remote-roster.html#sect-id215516"
* >Here</a>
*
* @author Holger Bergunde <iq id="FSwIU-68" type="set"
* from="user@example/resource"> // <query xmlns="jabber:iq:roster"> //
* <item jid="123456789@subdomain" name="wulschti" subscription="both">
* // <group>General</group> // </item> // </query> // </iq>
* @author Holger Bergunde
*
* Example IQ:
* <iq id="FSwIU-68" type="set" from="user@example/resource">
* <query xmlns="jabber:iq:roster"> <item jid="123456789@subdomain" name="wulschti" subscription="both">
* <group>General</group> </item> </query> </iq>
*/
public class ClientToComponentUpdateProcessor extends AbstractRemoteRosterProcessor {
private Set<String> watchedSubdomains;
......
......@@ -20,7 +20,7 @@ import org.xmpp.packet.Packet;
* disco#info package send from external component for a <registered> tag.
* Because spectrum does not support this feature we have to modify the disco
* package from spectrum with the registered tag if the user is registered with
* this gateway. Part of command pattern used in {@link RemoteRosterInterceptor}
* this gateway. Part of command pattern used in {@link MainInterceptor}
*
* @author Holger Bergunde
*
......@@ -53,6 +53,7 @@ public class DiscoIQRegisteredProcessor extends AbstractRemoteRosterProcessor {
if (packetElement == null)
return;
String ns = iqPacket.getChildElement().getNamespace().getURI();
if (iqPacket.getType().equals(IQ.Type.result) && ns.equals("jabber:iq:register")
&& iqPacket.getFrom().toString().equals(subdomain)) {
// Check if we are already registered
......
......@@ -29,6 +29,7 @@ import org.xmpp.packet.Packet;
* >Here</a>
*
* @author Holger Bergunde
* @author axel.frederik.brand
*
*/
public class IQRosterPayloadProcessor extends AbstractRemoteRosterProcessor {
......
......@@ -45,6 +45,7 @@ public class NonPersistantRosterProcessor extends AbstractRemoteRosterProcessor
if (itemName.contains(subdomain) && !itemName.equals(subdomain)) {
Log.debug("Removing contact " + item.getJid().toString() + " from contact list.");
roster.deleteRosterItem(item.getJid(), false);
}
}
......
package org.jivesoftware.openfire.plugin.gojara.messagefilter.processors;
import org.jivesoftware.openfire.interceptor.PacketRejectedException;
import org.jivesoftware.openfire.plugin.gojara.database.DatabaseManager;
import org.xmpp.packet.Packet;
/**
*
* This class is only for logging messages between the gateway and the
* registered clients. It uses the database to save the packets from the past 60
* (configurable) minutes.
*
* @author Holger Bergunde
* @author axel.frederik.brand
*/
public class TransportSessionProcessor extends AbstractRemoteRosterProcessor{
private DatabaseManager _db;
public TransportSessionProcessor() {
Log.info("Created StatisticsProcessor");
_db = DatabaseManager.getInstance();
}
/**
* At this Point we Already know:
* neither of both JIDS is malformed (Package wouldn't have been intercepted)
* Package is incoming & processed
*
* Either From or To contains the watched,passed subdomain
* From does not Equal To (This way we exclude PING sent by spectrum To spectrum
* From AND To are NOT empty (null), this way we exclude packets sent to server itself...change Maininterceptor if we want to change this
*
*/
@Override
public void process(Packet packet, String subdomain, String to, String from)
throws PacketRejectedException {
String type = packet.getClass().getName();
_db.addNewLogEntry(subdomain, type, from, to);
}
}
package org.jivesoftware.openfire.plugin.gojara.permissions;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.jivesoftware.openfire.plugin.gojara.database.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xmpp.packet.JID;
public class TransportSessionManager {
private static TransportSessionManager myself;
private DatabaseManager db;
private Map<String, Map<String, Date>> transportSessions = new ConcurrentHashMap<String, Map<String, Date>>();
private static final Logger Log = LoggerFactory.getLogger(TransportSessionManager.class);
private TransportSessionManager() {
db = DatabaseManager.getInstance();
Log.info(" Created TransportSessionManager");
}
public static TransportSessionManager getInstance() {
if (myself == null) {
synchronized (TransportSessionManager.class) {
if (myself == null)
myself = new TransportSessionManager();
}
}
return myself;
}
public void addTransport(String subdomain) {
transportSessions.put(subdomain, new ConcurrentHashMap<String, Date>());
Log.info("Added key to transportSessionMap: " + subdomain);
}
public void removeTransport(String subdomain) {
Map<String, Date> disconnectedUsers = transportSessions.remove(subdomain);
Log.info("Removed " + subdomain + "from TransportSessionMap " + disconnectedUsers.toString());
}
public boolean isTransportActive(String subdomain) {
return transportSessions.containsKey(subdomain) ? true : false;
}
public void registerUserTo(String transport, String user) {
//This ofc is not a session yet, so we just keep the registration in db to track eventual unsuccessful registers
db.insertOrUpdateSession(transport, user, 0);
}
public boolean connectUserTo(String transport, String user) {
if (transportSessions.get(transport) != null) {
long millis = System.currentTimeMillis();
Timestamp stamp = new Timestamp(millis);
Date date = new Date(stamp.getTime());
transportSessions.get(transport).put(user, date);
db.insertOrUpdateSession(transport, user, millis);
return true;
}
return false;
}
public boolean disconnectUserFrom(String transport, String user) {
Log.info("Trying to remove User " + JID.nodeprep(user) + " from Session for Transport " + transport);
if (isUserConnectedTo(transport, user)) {
transportSessions.get(transport).remove(user);
return true;
}
return false;
}
public boolean isUserConnectedTo(String transport, String user) {
return transportSessions.get(transport).containsKey(user);
}
public String removeRegistrationOfUser(String transport, String user) {
int result = db.removeSessionEntry(transport, user);
if (result == 0) {
return "Did not remove entry for user: " + user + " and transport: " + transport + "\n";
} else if (result == 1) {
return "Successfully removed entry for user: " + user + " and transport: " + transport + " \n";
} else {
return "What is happening ???: " + result;
}
}
public final Map<String, Map<String, Date>> getSessions() {
return transportSessions;
}
public int getNumberOfActiveSessions() {
int result = 0;
for (String key : transportSessions.keySet()) {
result += transportSessions.get(key).size();
}
return result;
}
public final Map<String, Date> getConnectionsFor(String username) {
// Maybe i do too much with hashes
Map<String, Date> userconnections = null;
for (String transport : transportSessions.keySet()) {
if (transportSessions.get(transport).containsKey(username)) {
if (userconnections == null)
userconnections = new HashMap<String, Date>();
userconnections.put(transport, transportSessions.get(transport).get(username));
}
}
return userconnections;
}
public ArrayList<SessionEntry> getRegistrationsFor(String username) {
return db.getSessionEntriesFor(username);
}
/**
* Validation for correctness of attributes is done in DB Manager, returns default sorting: username ASC when not
* correct
*/
public ArrayList<SessionEntry> getAllRegistrations(String orderAttr, String order) {
return db.getAllSessionEntries(orderAttr, order);
}
}
<%@ page import="org.jivesoftware.openfire.plugin.gojara.permissions.TransportSessionManager"%>
<%@ page import="org.jivesoftware.openfire.plugin.gojara.database.SessionEntry" %>
<%@ page import="java.util.Map"%>
<%@ page import="java.util.HashMap"%>
<%@ page import="java.util.Set"%>
<%@ page import="java.util.Date"%>
<%@ page import="java.util.ArrayList" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<%
TransportSessionManager transportManager = TransportSessionManager.getInstance();
int current_page;
int current_limit;
//Helper object for restraining sorting to existing colums and nice generation of sorting links
Map<String, String> sortParams = new HashMap<String, String>();
if (request.getParameter("sortby") != null && request.getParameter("sortorder") != null) {
// prfen wenn ok, nehmen wir die, ansonsten
String allowedAttr = "username transport lastActivity";
String allowedOrder = "ASC DESC";
String sortAttr = request.getParameter("sortby");
String sortOrder = request.getParameter("sortorder");
if (allowedAttr.contains(sortAttr) && allowedOrder.contains(sortOrder)) {
sortParams.put("sortby", sortAttr);
sortParams.put("sortorder", sortOrder);
}
} else {
sortParams.put("sortby", "username");
sortParams.put("sortorder", "ASC");
}
//pagination
if (request.getParameter("page") == null) {
current_page = 1;
} else {
try {
current_page = Integer.parseInt(request.getParameter("page"));
} catch (Exception e){
current_page = 1;
}
}
if (request.getParameter("limit") == null) {
current_limit = 15;
} else {
try {
current_limit= Integer.parseInt(request.getParameter("limit"));
if (current_limit > 1000) { current_limit = 1000; }
} catch (Exception e){
current_limit = 15;
}
}
%>
<%!
public String sortingHelper(String column, Map<String, String> sortParams) {
String image_asc = "<img alt=\"sorted ASC\" src=\"/images/sort_ascending.gif\">";
String image_desc = "<img alt=\"sorted DESC\" src=\"/images/sort_descending.gif\">";
String link_beginning = "<a href=\"gojara-RegistrationsOverview.jsp?sortby=";
String ending = (column.equals("username") ? "User Name:" : column.equals("transport") ? "Resource:" : "Last Login was at:") + "</a>";
String sortinglink = "";
if (sortParams.containsValue(column)) {
if (sortParams.containsValue("ASC")) {
sortinglink = image_asc + link_beginning + column + "&sortorder=DESC\">" + ending;
} else if (sortParams.containsValue("DESC")) {
sortinglink = image_desc + link_beginning + column + "&sortorder=ASC\">" + ending;
}
} else {
// This is not the currently sorted colum so we want to sort with it, Ascending.
sortinglink = link_beginning + column + "&sortorder=ASC\">" + ending;
}
return sortinglink;
}
%>
<html>
<head>
<title>Overview of existing Registrations</title>
<meta name="pageID" content="gojaraRegistrationAdministration"/>
</head>
<body>
<%
//do unregisters if supplied
if (request.getParameterMap() != null) {
String uninteresting_params = "sortorder sortby page limit";
for (Object key : request.getParameterMap().keySet()) {
if (uninteresting_params.contains(key.toString())) {
continue;
}
String[] uservalues = request.getParameterValues(key.toString());
for (String transport : uservalues) { %>
<ul>
<%= transportManager.removeRegistrationOfUser(transport, key.toString())%>
</ul>
<% } %>
<% } %>
<% } %>
<%= current_page %>
<%= current_limit %>
<h1>For Loop in JSTL</h1>
<c:forEach var="i" begin="1" end="20" step="1" varStatus ="status">
<c:out value="${i}" />
</c:forEach>
<h6>Logintime 1970 means User did only register but never logged in, propably because of invalid credentials.</h6>
<form name="unregister-form" id="gojara-RegOverviewUnregister"method="POST">
<div class="jive-table">
<table cellpadding="0" cellspacing="0" border="0" width="100%">
<thead>
<tr>
<th nowrap><%= sortingHelper("username",sortParams) %></th>
<th nowrap><%= sortingHelper("transport",sortParams) %></th>
<th nowrap>Resource active?</th>
<th nowrap><%= sortingHelper("lastActivity",sortParams) %></th>
<th nowrap>Unregister?</th>
</tr>
</thead>
<tbody>
<%
//Here we do our nice query
ArrayList<SessionEntry> registrations = transportManager.getAllRegistrations(sortParams.get("sortby"), sortParams.get("sortorder"));
%>
<% for (SessionEntry registration : registrations) { %>
<tr class="jive-odd">
<td><a href="gojara-sessionDetails.jsp?username=<%=registration.getUsername()%>"><%= registration.getUsername()%></a></td>
<td><%= registration.getTransport()%></td>
<td>
<% if (transportManager.isTransportActive(registration.getTransport())) { %>
<img alt="Yes" src="/images/success-16x16.gif">
<% } else { %>
<img alt="No" src="/images/error-16x16.gif">
<% } %></td>
<td><%= registration.getLast_activityAsDate()%></td>
<td><input type="checkbox" name="<%= registration.getUsername() %>" value="<%= registration.getTransport() %>"></td>
</tr>
<% } %>
</tbody>
</table>
</div>
<br>
<center><input type="submit" value="Unregister"></center>
</form>
</body>
</html>
\ No newline at end of file
<%@ page import="org.jivesoftware.openfire.plugin.gojara.permissions.TransportSessionManager"%>
<%@ page import="java.util.Map"%>
<%@ page import="java.util.Set"%>
<%@ page import="java.util.Date"%>
<%
TransportSessionManager transportManager = TransportSessionManager.getInstance();
%>
<html>
<head>
<title>Gateway Sessions</title>
<meta name="pageID" content="gojaraSessions" />
</head>
<body>
<center>Please be aware that currently only users that connect
AFTER GoJara has been started are considered for these Sessions. This
affects Plugin-restarts.</center>
<%
Map<String, Map<String, Date>> sessions = transportManager.getSessions();
%><br>
<h4>
Current number of active Gateway Sessions: &emsp;
<%=transportManager.getNumberOfActiveSessions()%>
</h4>
<br>
<%
for (String transport : sessions.keySet()) {
%>
<%=transport.substring(0, 10)%>... :
<b><%=sessions.get(transport).size()%></b> &emsp;
<%
}
%>
<br>
<br>
<div class="jive-table">
<table cellpadding="0" cellspacing="0" border="0" width="100%">
<thead>
<tr>
<th nowrap>User Name</th>
<th nowrap>Resource</th>
<th nowrap>Login Time</th>
</tr>
</thead>
<tbody>
<%
for (String transport : sessions.keySet()) {
%>
<%
for (String user : sessions.get(transport).keySet()) {
%>
<tr class="jive-odd">
<td><a href="gojara-sessionDetails.jsp?username=<%=user%>"><%=user%></a></td>
<td><%=transport%></td>
<td><%=sessions.get(transport).get(user)%></td>
</tr>
<%
}
%>
<%
}
%>
</tbody>
</table>
</div>
</body>
</html>
\ No newline at end of file
<%@ page import="org.jivesoftware.openfire.plugin.gojara.permissions.TransportSessionManager"%>
<%@ page import="org.jivesoftware.openfire.plugin.gojara.database.SessionEntry" %>
<%@ page import="java.util.Map"%>
<%@ page import="java.util.Set"%>
<%@ page import="java.util.Date"%>
<%@ page import="java.util.ArrayList" %>
<%
TransportSessionManager transportManager = TransportSessionManager.getInstance();
String username = request.getParameter("username");
%>
<html>
<head>
<title>GatewaySession Details for: &emsp; <%=username%></title>
<meta name="pageID" content="gojaraSessions" />
<script language='JavaScript'>
checked = false;
function checkedAll () {
if (checked == false){checked = true}else{checked = false}
for (var i = 0; i < document.getElementById('gojara-sessDetailsUnregister').elements.length; i++) {
document.getElementById('gojara-sessDetailsUnregister').elements[i].checked = checked;
}
}
</script>
</head>
<body>
<%
if (request.getParameter(username) != null) {
String[] unregister = request.getParameterValues(username);
%>
<br><br>
<%
for (String key : unregister) {
%>
<%=transportManager.removeRegistrationOfUser(key, username) %><br>
<% } %>
<br> <br>
<%
}
Map<String, Date> userconnections = transportManager.getConnectionsFor(username);
if (userconnections == null) {
%>
<h2><center>User has no active sessions</center></h2>
<%
} else {
%>
<center><h1>Active Sessions:</h1></center><br>
<div class="jive-table">
<table cellpadding="0" cellspacing="0" border="0" width="100%">
<thead>
<tr>
<th nowrap>Resource</th>
<th nowrap>Login Time</th>
</tr>
</thead>
<tbody>
<% for (String transport : userconnections.keySet()) { %>
<tr class="jive-odd">
<td><%= transport%></td>
<td><%=userconnections.get(transport)%></td>
</tr>
<% } %>
</tbody>
</table>
</div>
<%
}
%>
<br><hr>
<center><h1>Associated Registrations:</h1></center><br>
<form name="unregister-form" id="gojara-sessDetailsUnregister"method="POST">
<div class="jive-table">
<table cellpadding="0" cellspacing="0" border="0" width="100%">
<thead>
<tr>
<th nowrap>User Name:</th>
<th nowrap>Resource:</th>
<th nowrap>Resource active?</th>
<th nowrap>Last login was at:</th>
<th nowrap>Unregister?</th>
</tr>
</thead>
<tbody>
<% ArrayList<SessionEntry> registrations = transportManager.getRegistrationsFor(username); %>
<% for (SessionEntry registration : registrations) { %>
<tr class="jive-odd">
<td><a href="/user-properties.jsp?username=<%=registration.getUsername()%>"><%= registration.getUsername()%></a></td>
<td><%= registration.getTransport()%></td>
<td><% if (transportManager.isTransportActive(registration.getTransport())) { %>
<img alt="Yes" src="/images/success-16x16.gif">
<% } else { %>
<img alt="No" src="/images/error-16x16.gif">
<% } %></td>
<td><%= registration.getLast_activityAsDate()%></td>
<td><input type="checkbox" name="<%= registration.getUsername() %>" value="<%= registration.getTransport() %>"></td>
</tr>
<% } %>
</tbody>
</table>
</div>
<br>
<center><input type="button" value="check/uncheck all" onclick='checkedAll();'></center>
<br>
<center><input type="submit" value="Unregister"></center>
</form>
</body>
</html>
......@@ -297,9 +297,10 @@
</tr>
<tr>
<td />
<td align="left" style="font-size: -3; color: grey">When Persistent-Roster is enabled, no contacts will be deleted
by GoJara automatically.<br>
When Persistent-Roster is disabled, GoJara will automatically delete all Legacy-RosterItems from the OF-Roster of a User upon logout. </td>
<td align="left" style="font-size: -3; color: grey">When Persistent-Roster is enabled, contacts will be saved to database and
no contacts will be deleted by GoJara automatically.<br>
When Persistent-Roster is disabled, contacts will not be saved to databse and
GoJara will automatically delete all Legacy-RosterItems from the OF-Roster of a User upon logout. </td>
</tr>
<tr>
<td><input type="checkbox" name="mucFilter" id="GO2" value="true"
......
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