-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This is the state of the prototype that was created at the The Hague sprint, at IPerity. The code is functional, to the extend that it has been observed to trigger notifications in Conversations. There's not much rhyme or reason to the frequency in which notifications are sent (currently: on any message that is sent to a user of Openfire, that has a non-empty body).
- Loading branch information
0 parents
commit 5b5e85e
Showing
12 changed files
with
903 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# EditorConfig helps developers define and maintain consistent coding styles between different editors and IDEs. | ||
# | ||
# EditorConfig is awesome: http://EditorConfig.org | ||
|
||
# top-most EditorConfig file | ||
root = true | ||
|
||
[*] | ||
end_of_line = lf | ||
insert_final_newline = true | ||
charset = utf-8 | ||
indent_style = space | ||
indent_size = 4 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
target/ | ||
work/ | ||
*.class | ||
|
||
# Ignore Intellij Idea project files | ||
*.iml | ||
*.ipr | ||
.idea | ||
atlassian-ide-plugin.xml | ||
out/ | ||
|
||
# Ignore Eclipse project files | ||
.settings | ||
.project | ||
.classpath | ||
|
||
# Ignore MacOSX files | ||
.DS_Store | ||
|
||
# Ignore Netbeans project files | ||
nbproject/ | ||
nbbuild/ | ||
/bin/ | ||
|
||
# Microsoft Visual Studio Code | ||
.vscode/ | ||
|
||
# build temp folders | ||
rpmbuild/ | ||
debian/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<parent> | ||
<artifactId>plugins</artifactId> | ||
<groupId>org.igniterealtime.openfire</groupId> | ||
<version>4.3.0</version> | ||
</parent> | ||
|
||
<groupId>org.igniterealtime.openfire.plugins</groupId> | ||
<artifactId>pushnotification</artifactId> | ||
<version>0.5.0-SNAPSHOT</version> | ||
|
||
<name>Push Notification</name> | ||
<description>Adds Push Notification (XEP-0357) support to Openfire.</description> | ||
|
||
<build> | ||
<plugins> | ||
<plugin> | ||
<!-- this generates the JAR files in the Openfire-plugin specific format --> | ||
<artifactId>maven-assembly-plugin</artifactId> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
|
||
<repositories> | ||
<!-- Here, we get our dependencies, like the parent project. --> | ||
<repository> | ||
<id>igniterealtime</id> | ||
<name>Ignite Realtime Repository</name> | ||
<url>https://igniterealtime.org/archiva/repository/maven/</url> | ||
</repository> | ||
</repositories> | ||
|
||
<pluginRepositories> | ||
<!-- Used for the dependencies used by the plugins that we'll use. --> | ||
<pluginRepository> | ||
<id>igniterealtime</id> | ||
<name>Ignite Realtime Repository</name> | ||
<url>https://igniterealtime.org/archiva/repository/maven/</url> | ||
</pluginRepository> | ||
</pluginRepositories> | ||
|
||
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> | ||
|
||
<html> | ||
<head> | ||
<title>Push Notification Plugin Changelog</title> | ||
<style type="text/css"> | ||
BODY { | ||
font-size : 100%; | ||
} | ||
BODY, TD, TH { | ||
font-family : tahoma, verdana, arial, helvetica, sans-serif; | ||
font-size : 0.8em; | ||
} | ||
H2 { | ||
font-size : 10pt; | ||
font-weight : bold; | ||
padding-left : 1em; | ||
} | ||
A:hover { | ||
text-decoration : none; | ||
} | ||
H1 { | ||
font-family : tahoma, arial, helvetica, sans-serif; | ||
font-size : 1.4em; | ||
font-weight: bold; | ||
border-bottom : 1px #ccc solid; | ||
padding-bottom : 2px; | ||
} | ||
|
||
TT { | ||
font-family : courier new; | ||
font-weight : bold; | ||
color : #060; | ||
} | ||
PRE { | ||
font-family : courier new; | ||
font-size : 100%; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
|
||
<h1> | ||
Push Notification Plugin Changelog | ||
</h1> | ||
|
||
<p><b>0.5.0</b> -- (to be determined)</p> | ||
<ul> | ||
<li>Initial release.</li> | ||
</ul> | ||
|
||
</body> | ||
</html> |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
181 changes: 181 additions & 0 deletions
181
src/main/java/org/igniterealtime/openfire/plugins/pushnotification/Push0IQHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
/* | ||
* Copyright (C) 2019 Ignite Realtime Foundation. 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.igniterealtime.openfire.plugins.pushnotification; | ||
|
||
import org.dom4j.Element; | ||
import org.dom4j.QName; | ||
import org.jivesoftware.openfire.IQHandlerInfo; | ||
import org.jivesoftware.openfire.XMPPServer; | ||
import org.jivesoftware.openfire.auth.UnauthorizedException; | ||
import org.jivesoftware.openfire.handler.IQHandler; | ||
import org.jivesoftware.openfire.user.User; | ||
import org.jivesoftware.openfire.user.UserNotFoundException; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.xmpp.packet.IQ; | ||
import org.xmpp.packet.JID; | ||
import org.xmpp.packet.PacketError; | ||
|
||
/** | ||
* An IQ handler implementation for the protocol defined by namespace "urn:xmpp:push:0" | ||
* in XEP-0357. | ||
* | ||
* @author Guus der Kinderen, [email protected] | ||
* @see <a href="https://xmpp.org/extensions/xep-0357.html">XEP-0357: "Push Notifications"</a> | ||
*/ | ||
public class Push0IQHandler extends IQHandler | ||
{ | ||
private static final Logger Log = LoggerFactory.getLogger( Push0IQHandler.class ); | ||
|
||
public static final String ELEMENT_NAME = "enable"; | ||
public static final String ELEMENT_NAMESPACE = "urn:xmpp:push:0"; | ||
|
||
public Push0IQHandler() | ||
{ | ||
super( "Push Notification IQ Handler (enable)." ); | ||
} | ||
|
||
/** | ||
* Handles the received IQ packet. | ||
* | ||
* @param packet the IQ packet to handle. | ||
* @return the response to send back. | ||
* @throws UnauthorizedException if the user that sent the packet is not | ||
* authorized to request the given operation. | ||
*/ | ||
@Override | ||
public IQ handleIQ( final IQ packet ) throws UnauthorizedException | ||
{ | ||
if ( packet.isResponse() ) { | ||
Log.trace( "Silently ignoring an unexpected response stanza: {}", packet ); | ||
return null; | ||
} | ||
|
||
if ( IQ.Type.get.equals( packet.getType() ) ) | ||
{ | ||
Log.trace( "Ignoring an unexpected request stanza of type 'get': {}", packet ); | ||
final IQ result = IQ.createResultIQ( packet ); | ||
result.setError( PacketError.Condition.bad_request ); | ||
return result; | ||
} | ||
|
||
String action; | ||
JID pushService; | ||
String node; | ||
try | ||
{ | ||
action = packet.getChildElement().getName(); | ||
pushService = new JID( packet.getChildElement().attributeValue( "jid" ) ); | ||
node = packet.getChildElement().attributeValue( "node" ); | ||
} | ||
catch ( Exception e ) | ||
{ | ||
Log.debug( "An exception occurred while trying to to parse push service and node from stanza: {}", packet, e ); | ||
action = null; | ||
pushService = null; | ||
node = null; | ||
} | ||
|
||
if ( action == null || pushService == null || (!action.equals( "disable" ) && node == null) ) | ||
{ | ||
Log.trace( "Ignoring a request stanza that could not be parsed: {}", packet ); | ||
final IQ result = IQ.createResultIQ( packet ); | ||
result.setError( PacketError.Condition.bad_request ); | ||
return result; | ||
} | ||
|
||
if ( !XMPPServer.getInstance().getUserManager().isRegisteredUser( packet.getFrom() ) ) | ||
{ | ||
Log.info( "Denying service for an entity that's not recognized as a registered user: {}", packet.getFrom() ); | ||
throw new UnauthorizedException( "This service is only available to registered, local users." ); | ||
} | ||
|
||
final User user; | ||
try | ||
{ | ||
user = XMPPServer.getInstance().getUserManager().getUser( packet.getFrom().getNode() ); | ||
} | ||
catch ( UserNotFoundException e ) | ||
{ | ||
Log.error( "Unable to load user, while user was confirmed to be a registered user: {}", packet.getFrom() ); | ||
final IQ result = IQ.createResultIQ( packet ); | ||
result.setError( PacketError.Condition.internal_server_error ); | ||
return result; | ||
} | ||
|
||
Log.trace( "intercepted {}", packet ); | ||
|
||
final IQ response; | ||
switch( action ) | ||
{ | ||
case "enable": | ||
final Element publishOptions = parsePublishOptions( packet ); | ||
PushServiceManager.register( user, pushService, node, publishOptions ); | ||
|
||
Log.debug( "Registered push service '{}', node '{}', for user '{}'.", new Object[]{ pushService.toString(), node, user.getUsername() } ); | ||
response = IQ.createResultIQ( packet ); | ||
break; | ||
|
||
case "disable": | ||
PushServiceManager.deregister( user, pushService, node ); | ||
|
||
Log.debug( "Deregistered push service '{}', node '{}', for user '{}'.", new Object[] { pushService.toString(), node, user.getUsername() } ); | ||
response = IQ.createResultIQ( packet ); | ||
break; | ||
|
||
default: | ||
Log.debug( "Unknown namespace element: {}", action ); | ||
response = IQ.createResultIQ( packet ); | ||
response.setError( PacketError.Condition.bad_request ); | ||
break; | ||
} | ||
return response; | ||
} | ||
|
||
private Element parsePublishOptions( final IQ packet ) | ||
{ | ||
final Element x = packet.getChildElement().element( QName.get( "x", "jabber:x:data" ) ); | ||
if ( x == null ) { | ||
return null; | ||
} | ||
|
||
for (final Element element : x.elements( "field" ) ) | ||
{ | ||
if ( "FORM_TYPE".equals( element.attributeValue( "var" ) ) ) | ||
{ | ||
final Element value = element.element( "value" ); | ||
if ( value != null && "http://jabber.org/protocol/pubsub#publish-options".equals( value.getText() ) ) | ||
{ | ||
return x; | ||
} | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
/** | ||
* Returns the handler information to help generically handle IQ packets. | ||
* IQHandlers that aren't local server iq handlers (e.g. chatbots, transports, etc) | ||
* return <tt>null</tt>. | ||
* | ||
* @return The IQHandlerInfo for this handler | ||
*/ | ||
@Override | ||
public IQHandlerInfo getInfo() | ||
{ | ||
return new IQHandlerInfo( ELEMENT_NAME, ELEMENT_NAMESPACE ); | ||
} | ||
} |
Oops, something went wrong.