Quantcast
Channel: XMPP – ProcessOne
Viewing all 36 articles
Browse latest View live

Thoughts on Code Style in Library Design

$
0
0

Designing the API for an XMPP client

I have been recently working on our Fluux XMPP library, a library that can be used to implement clients and server components in Go.

XMPP protocol is flexible and contains many extensions. It can be daunting to get into XMPP so it’s very tempting to add new tools to make it more convenient for newcomers to get into the protocol.

The challenge is about striking a right balance between keeping it close to the XML stream traffic, simple and powerful but easier to document and more welcoming for newcomers.

I have made some experiments recently that have sorted the developers into two groups, apparently depending on their taste.

The current way to write an XMPP disco IQ response is as follows:

iqResp := xmpp.NewIQ(xmpp.Attrs{Type: "result", To: "service.localhost", Id: iq.Id, Lang: "fr"})
identity := xmpp.Identity{
    Name:     "Test Component",
    Category: "gateway",
    Type:     "service",
}
payload := xmpp.DiscoInfo{
    XMLName: xml.Name{
        Space: xmpp.NSDiscoInfo,
        Local: "query",
    },
    Identity: identity,
    Features: []xmpp.Feature{
        {Var: xmpp.NSDiscoInfo},
        {Var: xmpp.NSDiscoItems},
        {Var: "jabber:iq:version"},
        {Var: "urn:xmpp:delegation:1"},
    },
}
iqResp.Payload = &payload

It is very close to the hierarchical nature of the XML structure.

My experiment leads to the following code:

b := stanza.NewBuilder().Lang("fr") // Create builder and set default language

iq := b.IQ(stanza.Attrs{Type: "result", To: "service.localhost", Id: "disco-get-1"})

identity := b.Identity("Test Component", "gateway", "service")

iq.payload := b.DiscoInfo().
    SetFeatures(stanza.NSDiscoInfo, stanza.NSDiscoItems, "jabber:iq:version", "urn:xmpp:delegation:1").
    SetIdentities(identity)

Some developers feel more comfortable with the first approach. Other feels more comfortable with the second one.

The second approach can still generate the first structure, so could please both types of developers. You can read the discussion on Github.

Still, designing an API is always a challenge. You have to spend a lot of effort to make it right, striking the right balance between its capabilities, yet trying to guide the developers as much as possible to help them write good and correct code. You need to make choices about which code styles you would like to promote. And most of all, you need to take the time to discuss, to be aware of difference in code-style preferences.

And you? What is your preferred coding style?


Uniting global football fans with an XMPP geocluster

$
0
0

When you are running one of the top sport brands, launching a new innovative app always means it comes with great expectations from your fans.

That’s why highly recognised brands turn to ProcessOne. They need to be sure that the project will launch in time, will perform well and will not collapse under the load, no matter what happens.

In early 2014, a top brand contacted us with a clear and ambitious project. We had 6 months to develop and host the infrastructure for a large-scale realtime communication and messaging project. The deadline was not flexible. The app needed to be live just before the FIFA World Cup in Brazil.

ProcessOne worked with the customer mobile team to help them accelerate their development. XMPP can be a complex protocol and if you wish to launch with a tight deadline, you need to take a “fast lane” approach and get help directly from experts.

We also had to host the project, providing low-latency for connection and messaging everywhere in the world. We deployed a geocluster, handling a single XMPP domain in four data centers across the world. We operated our deployment in 4 AWS regions: USA to serve North America, Brazil to serve South America, Singapour to serve Asia and Ireland to serve Europe.

We used our custom Erlang component to deploy a geocluster at scale, handling ourselves all database synchronization across regions and auto-recovery in case of netsplits.

The application was ready just in time to handle the load of fans installing and trying the app. Soon after the launch we had to handle an unexpected 10x peak load when Cristiano Rolnaldo, with tens of millions of followers, retweeted about the app — and the platform handled it without a flinch!

With a 100% uptime, the project was a success, and the app gathered hundreds of thousands of football fans from all over the world. Did you guess which brand it was?

Areas of expertise:

  • Realtime messaging
  • Push notifications
  • Platform management / hosting

Technologies:

ejabberd 19.08

$
0
0

We are pleased to announce ejabberd version 19.08. The main focus has been to further improve ease of use, consistency, performance, but also to start cleaning up our code base. As usual, we have kept on improving server performance and fixed several issues.

New Features and improvements

New authentication method using JWT tokens

You can now authenticate with JSON Web Token (JWT, see jwt.io for details).

This feature allows you to have your backend generate authentication tokens with a limited lifetime.

Generating JSON Web Key

You need to generate a secret key to be able to sign your JWT tokens.

To generate a JSON Web Key, you can for example use JSON Web Key Generator, or use your own local tool for production deployment.

The result looks like this:

{
  "kty": "oct",
  "use": "sig",
  "k": "PIozBFSFEntS_NIt...jXyok24AAJS8RksQ",
  "alg": "HS256"
}

Save you JSON Web Key in a file, e.g. secret.jwk.

Be careful: This key must never be shared or committed anywhere. With that key, you can generate credentials for any users on your server.

Configure ejabberd to use JWT auth

In ejabberd.yml change auth_method to jwt and add the jwt_key option pointing to secret.jwk:

auth_method: jwt
jwt_key: "/path/to/jwt/key"

Generate some JWT tokens

See jwt.io for an example of how to generate JSON Web Tokens. The payload must look like this:

{
  "jid": "test@example.org",
  "exp": 1564436511
}

And the encoded token looks like this:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqaWQiOiJ0ZXN0QGV4YW1wbGUub3JnIiwiZXhwIjoxNTY0NDM2NTExfQ.SMfzCVy8Nv5jJM0tMg4XwymIf7pCAzY8qisOSQ5IAqI

Authenticate on XMPP using encoded token as password

Now, the user test@example.org can use this token as a password before 1564436511 epoch time (i.e. July 29, 2019 21:41:51 GMT).

New configuration validator

With ejabberd 19.08, we introduce a new configuration checker, giving more precise configuration guidance in case of syntax errors or misconfiguration. This configuration checker has also been released as an independent open source project: yconf.

The new configuration validator makes it possible to improve the configuration parsing. For example, it supports the following:

Better handling of Erlang atom vs string

There is not need to quote string to express the fact you want an atom in the configuration file: the new configuration validator handles the Erlang types mapping automatically.

More flexible ways to express timeouts

Now, all timeout values can be expanded with suffixes, e.g.

negotiation_timeout: 30s
s2s_timeout: 10 minutes
cache_life_time: 1 hour

If the suffix is not given, the timeout is assumed in seconds

Atomic configuration reload

The configuration will either be fully reloaded or rolled back.

Better, more precise error reporting

Here are a couple of examples of the kind of message that the new configuration validator can produce.

In the following example, the validator will check against a value range:

14:15:48:32.582 [critical] Failed to start ejabberd application: Invalid value of option loglevel: expected integer from 0 to 5, got: 6

More generally, it can check value against expected types:

15:51:34.007 [critical] Failed to start ejabberd application: Invalid value of option modules->mod_roster->versioning: expected boolean, got string instead

It will report invalid values and suggest fixes in case error was possibly due to a typo:

15:50:06.800 [critical] Failed to start ejabberd application: Invalid value of option modules->mod_pubsub->plugins: unexpected value: pepp. Did you mean pep? Possible values are: flat, pep

Prevent use of duplicate options

Finally, it will also properly fail on duplicate options and properly report the error:

15:56:35.227 [critical] Failed to start ejabberd application: Configuration error: duplicated option: s2s_use_starttls

It was a source of error as an option could shadow another one, possibly in an included file.

Improved scalability

We improve scalability of several modules:

Multi-User chat

MUC Room modules is more scalable, allowing supporting more rooms, by hibernating the room after a timeout. Hibernating means removing it from memory when not used and reloading it on-demand.

The MUC messages processing has also been changed to now properly handle all the available CPU cores. MUC room message handling is now faster and support larger throughput on SMP architectures

SQL database handling

We improve the way the SQL pool is managed to better handle high load. We also improved MySQL schema a bit to help with indexing.

Changed implementation of mod_offline option use_mam_for_storage

Previous version was trying to determine the range of messages that should be fetched from MAM by storing time when last user resource disconnected. But that had couple edge cases that could cause problems, for example in case of hardware node crash we could not store information about user disconnect and with that we didn’t have data to initiate MAM query.

The new version doesn’t track user disconnects, but simply ensure that we have timestamp of first message that is gonna be put in storage, after some measurements cost of that check with caching on top is not that costly, and as it is much more robust we decided to move to that safer approach.

New option captcha_url

Option captcha_host is now deprecated in favor of captcha_url. However, it’s not replaced automatically at startup, i.e. both options are supported with ‘captcha_url’ being the preferred one.

Deprecated ‘route_subdomains’ option

This option was introduced to fulfil requirements of RFC3920 10.3, but in practice it was very inconvenient and many admins were forced to change its value to ‘s2s’ (i.e. to behaviour that violates the RFC). Also, it seems like in RFC6120 this requirement no longer presents.

Those admins who used this option to block s2s with their subdomains can use ‘s2s_access’ option for the same purpose.

API changes

Renamed arguments from ‘Server’ to ‘Host’

Several ejabberd commands still used as argument name ‘Server’, instead of the more common ‘Host’. Such arguments have been renamed, and backward support allows old calls to work correctly.

The eight affected commands are:
– add_rosteritem
– bookmarks_to_pep
– delete_rosteritem
– get_offline_count
– get_presence
– get_roster
– remove_mam_for_user
– remove_mam_for_user_with_peer

If you are using these calls, please start updating your parameter names to Host when moving to ejabberd 19.08. You will thus use a more consistent API and be future proof.

Technical changes

Removed Riak support

Reasons:

  • Riak DB development is almost halted after Basho
  • riak-erlang-client is abandoned and doesn’t work correctly with OTP22
  • Riak is slow in comparison to other databases
  • Missing key ordering makes it impossible to implement range queries efficiently (e.g. MAM queries)

If you are using Riak, you can contact ProcessOne to get assistance migrating to DynamoDB, an horizontally scalable key value datastore made by Amazon.

Erlang/OTP requirement

Erlang/OTP 19.1 is still the minimum supported Erlang version for this release.

Database schema changes

There is no change to perform on the database to move from ejabberd 19.05 to ejabberd 19.08.
Please, make a backup before upgrading.

It means that an old schema for ejabberd 19.05 will work on ejabberd 19.08. However, if you are using MySQL, you should not that we changed the type of the server_host field to perform better with indexes. The change is not mandatory, but changing it to varchar(191) will produce more efficient indexes.

You can check the upgrade page for details: Upgrading from ejabberd 19.05 to 19.08

Download and install ejabberd 19.08

The source package and binary installers are available at ProcessOne. If you installed a previous version, please read ejabberd upgrade notes.
As usual, the release is tagged in the Git source code repository on Github. If you suspect that you’ve found a bug, please search or fill a bug report in Issues.


Full changelog
===========

Administration
– Improve ejabberd halting procedure
– Process unexpected Erlang messages uniformly: logging a warning
– mod_configure: Remove modules management

Configuration
– Use new configuration validator
– ejabberd_http: Use correct virtual host when consulting trusted_proxies
– Fix Elixir modules detection in the configuration file
– Make option ‘validate_stream’ global
– Allow multiple definitions of host_config and append_host_config
– Introduce option ‘captcha_url’
– mod_stream_mgmt: Allow flexible timeout format
– mod_mqtt: Allow flexible timeout format in session_expiry option

Misc
– Fix SQL connections leakage
– New authentication method using JWT tokens
– extauth: Add ‘certauth’ command
– Improve SQL pool logic
– Add and improve type specs
– Improve extraction of translated strings
– Improve error handling/reporting when loading language translations
– Improve hooks validator and fix bugs related to hooks registration
– Gracefully close inbound s2s connections
– mod_mqtt: Fix usage of TLS
– mod_offline: Make count_offline_messages cache work when using mam for storage
– mod_privacy: Don’t attempt to query ‘undefined’ active list
– mod_privacy: Fix race condition

MUC
– Add code for hibernating inactive muc_room processes
– Improve handling of unexpected iq in mod_muc_room
– Attach mod_muc_room processes to a supervisor
– Restore room when receiving a message or a generic iq for not started room
– Distribute routing of MUC messages across all CPU cores

PubSub
– Fix pending nodes retrieval for SQL backend
– Check access_model when publishing PEP
– Remove deprecated pubsub plugins
– Expose access_model and publish_model in pubsub#metadata

Real-time Enterprise #23

$
0
0

ProcessOne curates the Real-time Radar – a newsletter focusing on articles about technology and business aspects of real-time solutions. Here are the articles we found interesting in Issue #23. To receive this newsletter straight to your inbox on the day it is published, subscribe here.

Six Ways IoT will Revolutionize Your Business

Technology continues to revolutionize the business world, and IoT is an excellent example of simple programs making a pivotal difference in business performance. Items connected to the internet can be used to gather data, automate tedious processes, and fulfill many other needs traditionally ignored.

Successful Migration to a Custom XMPP?Solution

This articles describes the challenges faced migrating from a third-party chat to a custom XMPP-based messaging solution for Forward Health, a UK based messaging solution for healthcare.

MQTT and CoAP: Security and Privacy Issues in IoT and IIoT Communication Protocols

Machine-to-machine communication protocols, which enable machines to “talk” with one another so that commands are communicated and data is transmitted, are indispensable to applications and systems that make use of the internet of things and the industrial internet of things.

Global Internet of Things Market Set to Reach $318bn by 2023

The global market for Internet of Things technologies will almost treble in size over the next five years, according to a new forecast.

What Are The Most Significant AI Advances We Will See In The Near Future?

What are the most significant AI advances we’ll see over the next few decades?

Tomorrows "General" AI Revolution Will Grow from Today's Technology

During his closing remarks at the I/O 2019 keynote last week, Jeff Dean, Google AI’s lead, noted that the company is looking at “AI that can work across disciplines,” suggesting the Silicon Valley giant may soon pursue Artificial general intelligence, a technology that eventually could match or exce

Blockchain is the Best Vehicle for IoT

IoT or Internet of Things is a much touted technology these days. All-pervasive, spanning multiple verticals, a humongous amount of data is being captured from all around us by millions of devices.

Real-time Stack #24

$
0
0

ProcessOne curates the Real-time Radar – a newsletter focusing on articles about technology and business aspects of real-time solutions. Here are the articles we found interesting in Issue #24. To receive this newsletter straight to your inbox on the day it is published, subscribe here.

MQTT for system administrators and for the IoT

They say MQTT is a PUB/SUB protocol for the Internet of Things, which it was originally designed for, but it’s also well suited for monitoring machines and services. Presentation given at BSDCan2019 in Ottawa.

Z-Wave to MQTT

Fully configurable Z-Wave to MQTT gateway and control panel. The Z-Wave to MQTT add-on allows you to decouple your Z-Wave network from your Home Assistant instance by leveraging your MQTT broker.

Migrating trashserver.net from Prosody to Ejabberd

Author writes: “Yesterday I moved my old Prosody setup to a new Ejabberd-based XMPP server setup. I’d like to leave you a few notes on why and how I did that. There ware multiple reasons for my decision to give Ejabberd a chance.”

Emoji avatars for personal website

Author writes: “My previous avatar was almost 3 years old, and I was getting tired of it. I decided to replace my avatar on my website for my IndieWebCamp Austin hack day project. But if you know me, you know I can’t do anything the easy way.”

Gotify server

A simple server for sending and receiving messages, written in Go and licensed under the MIT license.

LabPlot 2.6 released with MQTT support

The next release of LabPlot is announced! One big new feature is the support for the MQTT protocol. With LabPlot 2.6 is is possible now to read live data from MQTT brokers. This feature was contributed by Ferencz K. during Google Summer of Code 2018.

Real-time Enterprise #24

$
0
0

ProcessOne curates the Real-time Radar – a newsletter focusing on articles about technology and business aspects of real-time solutions. Here are the articles we found interesting in Issue #24. To receive this newsletter straight to your inbox on the day it is published, subscribe here.

ejabberd & Nintendo Switch NPNS

Last week, Taiyo Watanabe from Nintendo shared some insights about Nintendo Switch Push Notification infrastructure (NPNS) implementation. Here are some details from his presentation at ElixirFest conference. The Nintendo Switch NPNS is a large-scale realtime messaging service based on ejabberd.

80 Mind-Blowing IoT Statistics

In 2016, $737 billion was spent on the IoT. Global spending associated with the IoT in 2016 amounted to $737 billion. According to ACT, an organization that represents more than 5,000 tech companies, the healthcare IoT market alone will be worth more than $117 billion by 2020.

What is MQTT in IoT

Internet of Things (IoT) and machine-to-machine (M2M) technologies need to use a messaging and connectivity protocol in order to exchange information from a remote location.

Modern Data Transmission for Industry 4.0

A fully-networked factory floor is the future of automation and manufacturing. Robots, cobots, and information going into and out of the cloud are helping us create better products faster and with more accuracy.

Starting with MQTT using Docker and Home Assistant

MQTT is a great protocol to have in your automation arsenal. This article explains how to quickly get started with MQTT using Docker and Home Assistant. MQTT, which stands for Message Queuing Telemetry Transport, is often described as the protocol of the Internet of Things (IOT).

Integrating IoT with IEC 61850

Internet of Things continues to be one of the key technology trends in the recent years. According to Gartner’s estimations, IoT network will grow from 8,7 billion in 2017 to over 20 billion connected things by 2020.

Fight Against Unprotected s2s Connections

In the past, the certificates were worth the money. In the past, obtaining certificates was a difficult task. This forced the use of self-signed certificates in connections to preserve the federation. Invalid certificates are dangerous because unencrypted (without e2e) user communications can be intercepted and modified.

Real-time Stack #25

$
0
0

ProcessOne curates the Real-time Radar – a newsletter focusing on articles about technology and business aspects of real-time solutions. Here are the articles we found interesting in Issue #25. To receive this newsletter straight to your inbox on the day it is published, subscribe here.

Breaking 25 Trillion Notifications for the BBC

In 2012, BBC needed to add a push notification service to its portfolio of mobile applications, with main focus on BBC News and BBC Sports. At the scale of the BBC, there was several key requirements that made it difficult to use an off-the-shelf application.

Thoughts on Code Style in Library Design

XMPP protocol is flexible and contains many extensions. It can be daunting to get into XMPP so it’s very tempting to add new tools to make it more convenient for newcomers to get into the protocol.

Next Steps Toward Go 2

The release of Go 1.13 is on its way, hopefully in early August of this year. This is the first release that will include concrete changes to the language (rather than just minor adjustments to the spec), after a longer moratorium on any such changes.

Scaling from 2,000 to 25,000 Engineers on GitHub at Microsoft

At Microsoft today there are almost 25,000 engineers participating in the official GitHub organizations for open source, a great number of them contributing to open source communities throughout GitHub.

Air Pollution Tracking with Node.js, Elastic Stack, and MQTT

What can you do with a couple of IoT devices, Node.js, Elasticsearch, and MQTT? You can put together your own Internet of Things setup for measuring air pollution, like I have.

The State of Developer Ecosystem in 2019

Go started out with a share of 8% in 2017 and now it has reached 18%. In addition, the biggest number of developers (13%) chose Go as a language they would like to adopt or migrate to.

Merging Internet of Things and Blockchain in Preparation for the Future

The ‘Big Four’ technologies of the future are beginning to force themselves to the fore as companies start to dabble in the likes of Artificial Intelligence (AI), Blockchain and Internet of Things (IoT), as well as Big Data.

ejabberd 19.09

$
0
0

We are pleased to announce ejabberd version 19.09. The main focus has been to improve automatic certificate management stack (Let’s Encrypt). We also fixed bugs that had been introduced during previous big refactoring of the configuration management file, as well as the usual various bug fixes.

New Features and improvements

Better ACME support

In this release ACME support has been significantly improved. ACME is used to automatically obtain SSL certificates for the domains served by ejabberd.

The newest version of ACME (so called ACMEv2) is now supported. The implementation is now much more robust, and is able to perform certificate requests and renewals in a fully automated mode.

The automated mode is enabled by default, however, since ACME requires HTTP challenges (i.e. an ACME server will connect to ejabberd server on HTTP port 80 during certificate issuance), some configuration of ejabberd is still required. Namely, an HTTP listener for ejabberd_http module should be configured on non-TLS port with so called “ACME well known” request handler:

listen:
...
  -
    module: ejabberd_http
    port: 5280
    request_handlers:
      /.well-known/acme-challenge: ejabberd_acme
      ...
...

Note that the ACME protocol requires challenges to be sent on port 80. Since this is a privileged port, ejabberd cannot listen on it directly without root privileges. Thus you need some mechanism to forward port 80 to the port defined by the listener (port 5280 in the example above).

There are several ways to do this: using NAT or HTTP front-ends (e.g. sslh, nginx, haproxy and so on). Pick one that fits your installation the best, but DON’T run ejabberd as root.

If you see errors in the logs with ACME server problem reports, it’s highly recommended to change ca_url option of section acme to the URL pointing to some staging ACME environment, fix the problems until you obtain a certificate, and then change the URL back and retry using request-certificate ejabberdctl command (see below).

This is needed because ACME servers typically have rate limits, preventing you from requesting certificates too rapidly and you can get stuck for several hours or even days.

By default, ejabberd uses Let’s Encrypt authority. Thus, the default value of ca_url option is
https://acme-v02.api.letsencrypt.org/directory

and the staging URL will be https://acme-staging-v02.api.letsencrypt.org/directory

acme:
  ## Staging environment
  ca_url: https://acme-staging-v02.api.letsencrypt.org/directory
  ## Production environment (the default):
  # ca_url: https://acme-v02.api.letsencrypt.org/directory

The automated mode can be disabled by setting auto option of section acme to false:

acme:
  auto: false
  ...

In this case automated renewals are still enabled, however, in order to request a new certificate,
you need to run request-certificate ejabberdctl command:

$ ejabberdctl request-certificate all

If you only want to request certificates for a subset of the domains, run:

$ ejabberdctl request-certificate domain.tld,pubsub.domain.tld,server.com,conference.server.com...

You can view the certificates obtained using ACME:

$ ejabberdctl list-certificates
domain.tld /path/to/cert/file1 true
server.com /path/to/cert/file2 false
...

The output is mostly self-explained: every line contains the domain, the corresponding certificate file, and whether this certificate file is used or not. A certificate might not be used for several reasons: mostly because ejabberd detects a better certificate (i.e. not expired, or having a longer lifetime). It’s recommended to revoke unused certificates if they are not yet expired (see below).

At any point you can revoke a certificate: pick the certificate file from the listing above and run:

$ ejabberdctl revoke-certificate /path/to/cert/file

If the commands return errors, consult the log files for details.

Webadmin

Some people have reported having issues to connect to the web administration console. To solve that, the need to connect using a URL with domain corresponding to an XMPP domain has been reverted.

Technical changes

Erlang/OTP requirement

Erlang/OTP 19.3 is now the minimum supported Erlang version for this release.

Database schema changes

There is no change to perform on the database to move from ejabberd 19.08 to ejabberd 19.09. Still, as usual, please, make a backup before upgrading.

Download and install ejabberd 19.09

The source package and binary installers are available at ProcessOne. If you installed a previous version, there are no additional upgrade steps, but as a good practice, plase backup your data.

As usual, the release is tagged in the Git source code repository on Github. If you suspect that you’ve found a bug, please search or fill a bug report in Issues.


Full changelog
===========

* Admin
– The minimum required Erlang/OTP version is now 19.3
– Fix API call using OAuth (#2982)
– Rename MUC command arguments from Host to Service (#2976)

* Webadmin
– Don’t treat ‘Host’ header as a virtual XMPP host (#2989)
– Fix some links to Guide in WebAdmin and add new ones (#3003)
– Use select fields to input host in WebAdmin Backup (#3000)
– Check account auth provided in WebAdmin is a local host (#3000)

* ACME
– Improve ACME implementation
– Fix IDA support in ACME requests
– Fix unicode formatting in ACME module
– Log an error message on IDNA failure
– Support IDN hostnames in ACME requests
– Don’t attempt to create ACME directory on ejabberd startup
– Don’t allow requesting certificates for localhost or IP-like domains
– Don’t auto request certificate for localhost and IP-like domains
– Add listener for ACME challenge in example config

* Authentication
– JWT-only authentication for some users (#3012)

* MUC
– Apply default role after revoking admin affiliation (#3023)
– Custom exit message is not broadcast (#3004)
– Revert “Affiliations other than admin and owner cannot invite to members_only rooms” (#2987)
– When join new room with password, set pass and password_protected (#2668)
– Improve rooms_* commands to accept ‘global’ as MUC service argument (#2976)
– Rename MUC command arguments from Host to Service (#2976)

* SQL
– Fix transactions for Microsoft SQL Server (#2978)
– Spawn SQL connections on demand only

* Misc
– Add support for XEP-0328: JID Prep
– Added gsfonts for captcha
– Log Mnesia table type on creation
– Replicate Mnesia ‘bosh’ table when nodes are joined
– Fix certificate selection for s2s (#3015)
– Provide meaningful error when adding non-local users to shared roster (#3000)
– Websocket: don’t treat ‘Host’ header as a virtual XMPP host (#2989)
– Fix sm ack related c2s error (#2984)
– Don’t hide the reason why c2s connection has failed
– Unicode support
– Correctly handle unicode in log messages
– Fix unicode processing in ejabberd.yml


Understanding ejabberd OAuth Support & Roadmap

$
0
0

Login and password authentication is still the most commonly used auth mechanism on XMPP services. However, it is causing security concerns because it requires to store the credentials on the client app in order to login again without asking for the password.

Mobile APIs on iOS and Android can let you encrypt the data at REST, but still, it is best not to rely on storing any password at all.

Fortunately, several solutions exist – all supported by ejabberd. You can either use OAuth or Certificate-based authentication. Client certificate management being still quite a tricky issue, I will focus in this post on explaining how to set up and use ejabberd OAuth support.

Understanding ejabberd OAuth Support

The principle of OAuth is simple: OAuth offers a mechanism to let your users generate a token to connect to your service. The client can just keep that token to authenticate and is not required to store the password for subsequent authentications.

Implicit grant

As of ejabberd 19.09, ejabberd supports only the OAuth implicit grant. Implicit grant is often used to let third-party clients — clients you do not control — connect to your server.

The implicit grant requires redirecting the client to a web page, so the client does not even see the login and password of the user. Indeed, as you cannot trust third-party clients, this is the sane thing to do to keep your users’ passwords for being typed directly in any third-party client. You can never be sure that the client will not store it (locally, or worse, in the cloud).

With the implicit grant, the client app directs the user to the sign-in page on your server to authenticate and get the token, often with login and password (but the mechanism can be different and could involve 2FA, for example). Your website then uses a redirect URL that will be passed back to the client, containing the token to use for logging in. The redirect happens usually using client-registered domain or custom URL scheme.

… and password grant

The implicit grant workflow is not ideal if your ejabberd service is only useable with your own client. Using web view redirects can feel cumbersome in your onboarding workflow. As you trust the client, you probably would like to be able to directly call an API with the login and password, get the OAuth token back, and forget about the password. The user experience will be more pleasant and feel more native.

This flow is known in OAuth as the OAuth password grant.

In the upcoming ejabberd version, you will be able to use OAuth password grant as an addition to the implicit grant. The beta feature is already in ejabberd master branch, so you have a good opportunity to try it and share your feedback.

Let’s use ejabberd OAuth Password grant in practice

Step 1: ejabberd configuration

To support OAuth2 in ejabberd, you can add the following directives in ejabberd config file:

# Default duration for generated tokens (in seconds)
# Here the default value is 30 days
oauth_expire: 2592000
# OAuth token generation is enabled for all server users
oauth_access: all
# Check that the client ID is registered
oauth_client_id_check: db

In your web HTTPS ejabberd handler, you also need to add the oauth request handler:

listen:
  # ...
  -
    port: 5443
    ip: "::"
    module: ejabberd_http
    tls: true
    request_handlers:
      # ...
      "/oauth": ejabberd_oauth

Note: I am using HTTPS, even for a demo, as it is mandatory to work on iOS. During the development phase, you should create your own CA to add a trusted development certificate to ejabberd. Read the following blog post if you need guidance on how to do that: Using a local development trusted CA on MacOS

You can download my full test config file here: ejabberd.yml

Step 2: Registering an OAuth client

If you produce a first party client, you can bypass the need for OAuth to redirect to your browser to get the token.

As you trust the application you are developing, you can let the user of your app directly enter the login and password inside your client. However, you should never store the password directly, only the OAuth tokens.

In ejabberd, I recommend you first configure an OAuth client, so that it can check that the client id is registered.

You can use the ejabberdctl command oauth_add_client_password, or use the Erlang command line.

Here is how to use ejabberdctl to register a first-party client:

ejabberdctl oauth_add_client_password <client_id> <client_name> <secret>

As the feature is still in development, you may find it easier to register your client directly using Erlang command-line. Parameters are client_id, client_name and a secret:

1> ejabberd_oauth:oauth_add_client_password(<<"client-id-Iegh7ooK">>, <<"Demo client">>, <<"3dc8b0885b3043c0e38aa2e1dc64">>).
{ok,[]}

Once you have registered a client, you can start generating OAuth tokens for your users from your client, using an HTTPS API.

Step 3: Generation a password grant token

You can use the standard OAuth2 password grant query to get a bearer token for a given user. You will need to pass the user JID and the password. You need to require the OAuth scope sasl_auth so that the token can be used to authentication directly in the XMPP flow.

Note: As you are passing the client secret as a parameter, you must use HTTPS in production for those queries.

Here is an example query to get a token using the password grant flow:

curl -i -POST 'https://localhost:5443/oauth/token' -d grant_type=password -d username=test@localhost -d password=test -d client_id=client-id-Iegh7ooK  -d client_secret=3dc8b0885b3043c0e38aa2e1dc64 -d scope=sasl_auth

HTTP/1.1 200 OK
Content-Length: 114
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{"access_token":"DGV4JFzW15iZFmsnvzT7IymupTAYvo6U","token_type":"bearer","scope":"sasl_auth","expires_in":2592000}

As you can see, the token is a JSON string. You can easily extract the access_token from it. That’s the part you will use to authenticate on XMPP.

Step 4: Connecting on XMPP using an OAuth token

To authenticate over XMPP, you need to use the X-OAUTH2 mechanism. X-OAUTH2 was defined by Google for Google Talk and reused later by Facebook chat. You can find Google description here: XMPP OAuth 2.0 Authorization.

Basically, it encodes the JID and token as in the SASL PLAIN authorisation, but instead of passing the PLAIN keyword as mechanism, it uses X-OAUTH2. ejabberd will thus know that it has to check the secret against the token table in the database, instead of checking the credentials against the password table.

Quick demo

Next, let’s demonstrate the connection using Fluux Go XMPP library, which is the only library I know that supports OAuth tokens today.

Here is an example client login on XMPP with an OAuth2 token:

package main

import (
    "fmt"
    "log"
    "os"

    "gosrc.io/xmpp"
    "gosrc.io/xmpp/stanza"
)

func main() {
    config := xmpp.Config{
        Address:      "localhost:5222",
        Jid:          "test@localhost",
        Credential:   xmpp.OAuthToken("DGV4JFzW15iZFmsnvzT7IymupTAYvo6U"),
        StreamLogger: os.Stdout,
    }

    router := xmpp.NewRouter()
    router.HandleFunc("message", handleMessage)

    client, err := xmpp.NewClient(config, router)
    if err != nil {
        log.Fatalf("%+v", err)
    }

    // If you pass the client to a connection manager, it will handle the reconnect policy
    // for you automatically.
    cm := xmpp.NewStreamManager(client, nil)
    log.Fatal(cm.Run())
}

func handleMessage(s xmpp.Sender, p stanza.Packet) {
    msg, ok := p.(stanza.Message)
    if !ok {
        _, _ = fmt.Fprintf(os.Stdout, "Ignoring packet: %T\n", p)
        return
    }

    _, _ = fmt.Fprintf(os.Stdout, "Body = %s - from = %s\n", msg.Body, msg.From)
}

The important part for OAuth is that you are telling the library to use an OAuth2 token with the following value in the xmpp.Config struct:

xmpp.Config{
    // ...
        Credential:   xmpp.OAuthToken("DGV4JFzW15iZFmsnvzT7IymupTAYvo6U"),
        }

You can check the example in Fluux XMPP example directory: xmpp_oauth2.go

There is more

As I said, ejabberd OAuth support is not limited to generating password grant. Since ejabberd 15.09, we support implicit grant generation and it is still available. You can find more information in ejabberd documentation: OAuth

Moreover, there is more than XMPP authentication with OAuth 2. In the current development version, you can authenticate your devices on ejabberd MQTT service using MQTT 5.0 Enhanced Authentication. The authentication method to use is the same as for XMPP: We reuse the X-OAUTH2 method name. When trying to use this method, the server will confirm you are allowed to use that method and you can pass your token in return.

Please, note that you will need to use an MQTT 5.0 client library to use OAuth2 authentication with MQTT.

Conclusion

ejabberd OAuth XMPP and MQTT authentication is using the informal auth mechanism that was introduced by Google Talk and reused by Facebook. It does the job and fills an important security need.

That said, I would love to see more standard support from the XMPP Standard Foundation regarding OAuth authentication. For example, getting a specification translating OAuth authentication to XMPP flow would be of great help.

Still, in the meantime, I hope more libraries support that informal OAuth specification, so that client developers have good alternative to local password storage for subsequent authentications.

Please, give it a try from master and send us feedback if you want to help us shape the evolution of OAuth support in ejabberd.

… And let’s end password-oriented client authentication :)

ejabberd 19.09.1

$
0
0

We are announcing a supplemental bugfix release of ejabberd version 19.09.1. The main focus has been to fix the issue with webadmin returning 404 Not Found when Host header doesn’t match anything in configured hosts.

Bugfixes

Some people have reported still having issues when connecting to the web administration console. We solved that hopefully once and for all.

Technical changes

There is no change to perform on the database to move from ejabberd 19.09 to ejabberd 19.09.1. Still, as usual, please, make a backup before upgrading.

Download and install ejabberd 19.09.1

The source package and binary installers are available at ProcessOne. If you installed a previous version, there are no additional upgrade steps, but as a good practice, plase backup your data.

As usual, the release is tagged in the Git source code repository on Github. If you suspect that you’ve found a bug, please search or fill a bug report in Issues.


Full changelog
===========

* Bugfixes
– Fix issue with webadmin returning 404 when ‘Host’ header doesn’t match anything in configured hosts
– Change url to guide in webadmin to working one

Real-time Radar #26

$
0
0

ProcessOne curates the Real-time Radar – a newsletter focusing on articles about technology and business aspects of real-time solutions. Here are the articles we found interesting in Issue #26. To receive this newsletter straight to your inbox on the day it is published, subscribe here.

Uniting global football fans with an XMPP geocluster

When you are running one of the top sport brands, launching a new innovative app always means it comes with great expectations from your fans. That’s why highly recognised brands turn to ProcessOne.

Get started with NB-IoT and Quectel modules

The year is 2029. Humans are populating the Moon, starting at Moon Base One. Two Moon Base Operators are about to commit a grave mistake in the crop garden of beautiful red tomatoes…

Blockchain and?(I)IoT

Many people try to find a mix of Blockchain and IoT in order to simplify communication between nodes in IoT solutions, increase the communication security, and allow payments between nodes (e.g. a smart device can pay for some services when needed ).

An era of IoT

Message Queuing Telemetry Transport (MQTT) is a M2M and IoT connectivity protocol. It is an open protocol specified by IBM and Eurotech, and recently it is used by the Eclipse foundation in M2M applications.

Crocodile solar pool sensor

This instructable shows how to build a rather special pool sensor measuring the pool temperature and transmitting it via WiFi to Blynk App and to a MQTT broker. It uses the Arduino programming environment and an ESP8266 board (Wemos D1 mini pro).

Poets explore the language of push notifications

Has a poem ever made you cry? If you said yes, you’re just one of countless people who’ve been deeply moved by poetry. Now, has a push notification ever made you cry? Maybe not. In fact, we hope not.

New way to video conference

Remember when we had a video calling standard that worked with all mobile phones around the world so you could just call someone up and see them in live video on the other end while talking to them?? Me neither. That never happened.

Real-time Radar #27

$
0
0

ProcessOne curates the Real-time Radar – a newsletter focusing on articles about technology and business aspects of real-time solutions. Here are the articles we found interesting in Issue #27. To receive this newsletter straight to your inbox on the day it is published, subscribe here.

GopherCon 2019 Highlights

ProcessOne CEO had the chance to attend once more the big main annual Go conference: Gophercon 2019. For the first time this year, location changed from Denver to San Diego. Ocean, mild climate and extraordinary venue for the party (on the USS Midway) contributed to a relax and friendly atmosphere.

The State of the XMPP Community

This keynote gives an overview of what various XMPP projects have been doing (implementation wise) over the last ~12 month and will try to explain why some features have been adopted more quickly than others.

Cisco Scores Big with a New IETF-Approved Internet Standard

This June, Cisco achieved a milestone when the Internet Engineering Task Force (IETF) declared their XMPP-Grid architecture an official Internet standard?for security information exchange.

The Death of Jabber

Looking at the two previous links, it seems open XMPP and Cisco XMPP are going forward quite well – albeit in different directions. However, here’s an opposite point of view.

Deep Dive Into MQTT

Message Queuing Telemetry Transport (MQTT) has been relevant for years. It’s enjoying even wider attention now thanks to the explosive growth of IoT, with both consumer and industrial economies deploying distributed networks, edge computing and data-emitting devices as part of everyday operations.

Machine Vision Meets MQTT Messaging

This author covered recognizing objects with the JeVois sensor and sending the data to text-to-speech Processing scripts. Next, they describe passing the recognized object name and location data to other machines and systems, using MQTT.

go-xmpp 0.3.0

$
0
0

A new version of the go-xmpp library, which can be used to write XMPP clients or components in Go, as been released. It’s available on GitHub.

Upon new features, it adds a websocket transport. For this reason, the minimum go version to use it is now 1.13. It also adds a SendIQ method, to send iq stanza and receive the response asynchronously on a channel.
On the component side, it fixes a SIGSEGV in xmpp_component (#126) and adds more tests for the Component code.

A small example

Writing an XMPP component

Speaking of components, here is a simple example on how to create a simple one. As a reminder, components are external services that can communicate with an XMPP service using the Jabber Component Protocol as described in XEP-0114.

A component has its own XMPP domain and must know the server address and service port:

     const (
        domain  = "mycomponent.localhost"
        address = "localhost:8888"
    )

The options needed when creating a new component are defined as follow (secret must match the one define in the server config):

    opts := xmpp.ComponentOptions{
        TransportConfiguration: xmpp.TransportConfiguration{
            Address: address,
            Domain:  domain,
        },
        Domain:   domain,
        Secret:   "secret",
    }

To actually create the simplest component, just create a default route, and pass it to NewComponent, as well as the above options:

    router := xmpp.NewRouter()
    c, err := xmpp.NewComponent(opts, router)

Connect establishes the XMPP connection to the server, and authenticates with it:

      err := c.Connect()

Now we can try to send a disco iq to the server:

       iqReq := stanza.NewIQ(stanza.Attrs{Type: stanza.IQTypeGet,
        From: domain,
        To:   "localhost",
        Id:   "my-iq1"})
    disco := iqReq.DiscoInfo()
    iqReq.Payload = disco

In order to get the response asynchronously, the sendIq will return a channel where we expect to receive the result iq. We also need to pass it a context to set a timeout:

    ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
    res, _ := c.SendIQ(ctx, iqReq)

Now we just have to wait for our response:

    select {
    case iqResponse := <-res:
        // Got response from server
        fmt.Print(iqResponse.Payload)
    case <-time.After(100 * time.Millisecond):
        cancel()
        panic("No iq response was received in time")
    }

Full example

The full program that runs a component, connects it to a XMMP server and perform a disco on it to display the result is thus as is:

package main

import (
    "context"
    "fmt"
    "time"

    xmpp "github.com/FluuxIO/go-xmpp"
    "gosrc.io/xmpp/stanza"
)

const (
    domain  = "mycomponent.localhost"
    address = "build.vpn.p1:8888"
)

// Init and return a component
func makeComponent() *xmpp.Component {
    const (
        domain  = "mycomponent.localhost"
        address = "build.vpn.p1:8888"
    )
    opts := xmpp.ComponentOptions{
        TransportConfiguration: xmpp.TransportConfiguration{
            Address: address,
            Domain:  domain,
        },
        Domain: domain,
        Secret: "secret",
    }
    router := xmpp.NewRouter()
    c, err := xmpp.NewComponent(opts, router)
    if err != nil {
        panic(err)
    }
    return c
}

func main() {
    c := makeComponent()

    // Connect Component to the server
    fmt.Printf("Connecting to %v\n", address)
    err := c.Connect()
    if err != nil {
        panic(err)
    }

    // make a disco iq
    iqReq := stanza.NewIQ(stanza.Attrs{Type: stanza.IQTypeGet,
        From: domain,
        To:   "localhost",
        Id:   "my-iq1"})
    disco := iqReq.DiscoInfo()
    iqReq.Payload = disco

    // res is the channel used to receive the result iq
    ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
    res, _ := c.SendIQ(ctx, iqReq)

    select {
    case iqResponse := <-res:
        // Got response from server
        fmt.Print(iqResponse.Payload)
    case <-time.After(100 * time.Millisecond):
        cancel()
        panic("No iq response was received in time")
    }
}

go-xmpp v0.4.0

$
0
0

A new version of the go-xmpp library, which can be used to write XMPP clients or components in Go, has been released. It’s available on GitHub.

You can find the full changelog here : CHANGELOG
Some noteworthy features are the support of three new extensions :
– XEP-0060: Publish-Subscribe
– XEP-0050 : Ad-Hoc Commands
– XEP-0004: Data Forms
for both component and client.
Callbacks for error managment were also added to the client and component.

New Extensions

PubSub

Let’s create a very simple client that is both owner of a node, and subscribed to it.
This example assumes that you have a locally running jabber server listening on port 5222, like ejabberd.
First, let’s create the client. We need to provide a user JID, our identity, then the address of the server we wish to connect to.
Let’s also get a little ahead and put the node name and the service name in our constants :

const (
  domain = "mycomponent.localhost"
  address = "localhost:8888"
  nodeName = "example_node"
  serviceName = "pubsub.localhost"
)

Now, we need to fill a Config struct, that will be passed to the NewClient method :
“`go
config := xmpp.Config{
TransportConfiguration: xmpp.TransportConfiguration{
Address: serverAddress,
},
Jid: userJID,
Credential: xmpp.Password(“pass123”), // For the sake brievety
Insecure: true,
}

ejabberd 20.01

$
0
0

We are pleased to announce ejabberd version 20.01. This release focuses on OAUTH support, logging performances improvement and configuration helper, as well as the usual various bug fixes.

New Features and improvements

OAUTH

We are now supporting OAUTH to authenticate with the embedded MQTT server.

This will only work for MQTT 5.0 connections. A client MUST set “Authentication Method” property of CONNECT packet to “X-OAUTH2” and MUST set the token in “Authentication Data” property of the same CONNECT packet. The server responses as usual with CONNACK.

On the server, you just have to enable OAUTH authentication like for XMPP, as described in the post about understanding ejabberd OAuth support.

Logger

We are now using the new logger introduced in OTP22, instead of lagger. This should greatly improve performance of the logging infrastructure.

Configuration

A new configuration parser/validator was added, to check ejabberd.yml syntax and find configuration issues.

SCRAM support

The routine to convert password to SCRAM format now works for all backends, not only SQL.

CockroachDB

We’ve started to add to support to use CockroachDB as database backend.

Technical changes

Database schema changes

To migrate from 19.09 to 20.01, you have to use the following commands on your existing database, after you’ve made a backup of it:

MySQL

If you are using the legacy mysql.sql schema:

ALTER TABLE  oauth_client CHANGE `client` `client_id` text PRIMARY KEY;
ALTER TABLE  oauth_client CHANGE `secret` `client_name` text NOT NULL;

If you are using the newer mysql.new.sql schema:

CREATE TABLE oauth_client (
   client_id varchar(191) NOT NULL PRIMARY KEY,
   client_name text NOT NULL,
   grant_type text NOT NULL,
   options text NOT NULL

PostgreSQL

ALTER TABLE oauth_client RENAME COLUMN client TO client_id;
ALTER TABLE oauth_client RENAME COLUMN secret TO client_name;

Download and install ejabberd 20.01

The source package and binary installers are available at ProcessOne. If you installed a previous version, there are no additional upgrade steps, but as a good practice, plase backup your data.

As usual, the release is tagged in the Git source code repository on Github. If you suspect that you’ve found a bug, please search or fill a bug report in Issues.


Full changelog
===========

* New features
– Implement OAUTH authentication in MQTT
– Make logging infrastructure use new logger introduced
in Erlang (requires OTP22)
– New configuration parser/validator
– Initial work on being able to use CockroachDB as database backend
– Add gc command
– Add option to disable using prepared statements on Postgresql
– Implement routine for converting password to SCRAM format for all backends not only SQL
– Add infrastructure for having module documentation directly in individual module source code
– Generate man page automatically
– Implement copy feature in mod_carboncopy

* Fixes
– Make webadmin work with configurable paths
– Fix handling of result in xmlrpc module
– Make webadmin work even when accessed through not declared domain
– Better error reporting in xmlrpc
– Limit ammount of results returned by disco queries to pubsub nodes
– Improve validation of configured JWT keys
– Fix race condition in Redis/SQL startup
– Fix loading order of third party modules
– Fix reloading of ACL rules
– Make account removal requests properly route response
– Improve handling of malformed inputs in send_message command
– Omit push notification if storing message in offline storage failed
– Fix crash in stream management when timeout was not set


ejabberd on macOS with Homebrew package manager

$
0
0

Homebrew is now the de facto package manager for open source software on macOS. Thus, we have discontinued our macOS binary installer to focus on improving further ejabberd experience on macOS by polishing Homebrew ejabberd package.

We recently updated ejabberd on Homebrew and we will keep it in sync with ejabberd official releases. As of today, if you install ejabberd with Homebrew, you will always get the latest release.

If you have any suggestion on how to make ejabberd with Homebrew experience better, please open a Github issues, with the tag Packaging:Homebrew.

We have not yet tested it with Homebrew on Linux or on WSL, but still, pleae submit issues if you find some.

Here is the cheat sheet regarding ejabberd management with Homebrew.

Installing ejabberd

The following command will install ejabberd and its dependencies:

$ brew install ejabberd

Starting ejabberd and launching it on macOS start

brew services start ejabberd

Starting ejabberd

Alternatively, the following command start ejabberd in background, with trying to restart it automatically after reboot:

$ /usr/local/sbin/ejabberdctl start

You can check the status with the command:

$ /usr/local/sbin/ejabberdctl status
The node ejabberd@localhost is started with status: started
ejabberd 20.01 is running in that node

If ejabberd is not running the status command will display a nodedown error:

$ /usr/local/sbin/ejabberdctl status
Failed RPC connection to the node ejabberd@localhost: nodedown

Commands to start an ejabberd node:
  start      Start an ejabberd node in server mode
  debug      Attach an interactive Erlang shell to a running ejabberd node
  iexdebug   Attach an interactive Elixir shell to a running ejabberd node
  live       Start an ejabberd node in live (interactive) mode
  iexlive    Start an ejabberd node in live (interactive) mode, within an Elixir shell
  foreground Start an ejabberd node in server mode (attached)

Optional parameters when starting an ejabberd node:
  --config-dir dir   Config ejabberd:    /usr/local/etc/ejabberd
  --config file      Config ejabberd:    /usr/local/etc/ejabberd/ejabberd.yml
  --ctl-config file  Config ejabberdctl: /usr/local/etc/ejabberd/ejabberdctl.cfg
  --logs dir         Directory for logs: /usr/local/var/log/ejabberd
  --spool dir        Database spool dir: /usr/local/var/lib/ejabberd
  --node nodename    ejabberd node name: ejabberd@localhost

Stopping ejabberd

/usr/local/sbin/ejabberdctl stop

Configuration file

To change the configuration file, you can edit /usr/local/etc/ejabberd/ejabberd.yml

If you have upgraded ejabberd and want to apply possible change to config file, you can check the new ejabberd.yml default file ejabberd.yml-new in the same directory.

Checking the logs

To troubleshoot ejabberd, you can check the logs in the directory /usr/local/var/log/ejabberd/

ejabberd 20.02

$
0
0

We are pleased to announce ejabberd version 20.02. After a big release last month, this version is mostly a bugfix release.

Fixes

  • Fix problems when trying to use string format with Unicode values directly in XMPP nodes
  • Add missing oauth_client table declaration in lite.new.sql
  • Improve compatibility with CockroachDB
  • Fix importing of piefxis files that did use scram passwords
  • Fix importing of piefxis files that had multiple includes in them
  • Update jiffy dependency
  • Allow storage of emojis when using MSSQL database (Thanks to Christoph Scholz)
  • Make ejabberd_auth_http be able to use auth_opts
  • Make custom_headers options in HTTP modules correctly override built-in values
  • Fix return value of reload_config and dump_config commands

Downloads & Feedback

As usual, the release is tagged in the Git source code repository on Github.

The source package and binary installers are available at ProcessOne.

If you suspect that you’ve found a bug, please search or fill a bug report on Github.

xmpp-notifer v1.0.0

$
0
0

We just released a new GitHub Action called xmpp-notifier! It allows sending notifications to XMPP, and uses our go-xmpp library under the hood.

Let’s go through an example showing how to use it.

Small example

Say we want to get notifications when tests fail on a pull-request for our Go project. In the /.github/workflows/ directory of our project, we may setup actions as YAML configuration files. Let’s make a file, call it for example xmpp_notif.yaml, and add the following contents to it.

First add the event we want to trigger the jobs on (as an array):

on:
  [pull_request]

Following this, we can add a job that will notify us on test failures. Let’s call it notif-script:

jobs:
  notif-script:
    runs-on: ubuntu-latest
    name: job that pushes test failures to xmpp
    steps:
      - name: Run tests
        run: |
        go test ./... -v -race

      # Now lets write the notification action
      - name: Tests failed notif
        # If the previous step fails, start this one. Otherwise, skip it.
        if: failure()  
        id: test_fail_notif
        # Use the xmpp-notifier action
        uses: processone/xmpp-notifier@master
        # Set the secrets as inputs
        with: 
          # Login expects the bot's bare jid (user@domain)
          jid: ${{ secrets.jid }}
          # The bot's password
          password: ${{ secrets.password }}
          # The server we wish to connect to. 
          server_host: ${{ secrets.server_host }}
          # Intended recipient of the notification. Can be a user or room. Bare jid expected.
          recipient: ${{ secrets.recipient }}
          # Port is optional. Defaults to 5222
          server_port: ${{ secrets.server_port }}
          # This message will be sent as a <message> payload to the recipient.
          # It contains a link to the Pull Request page that triggered the action.
          # Test logs are only one click away.
          message: |
            tests for the following PR have failed : ${{ github.event.pull_request.html_url }}
          # Boolean to indicate if correspondent should be treated as a room (true) or a single user (false)
          recipient_is_room: true

That’s it! Now if tests fail on a pull request to any branch of our project, we will get notified through XMPP.

go-xmpp v0.5.0

$
0
0

A new version of the go-xmpp library, which can be used to write XMPP clients or components in Go, has been released. It’s available on GitHub.

You can find the full changelog here : CHANGELOG

This version essentially adds support for Stream Management (XEP-0198), and post-connect/post-reconnect hooks for XMPP clients. Read more below !

Support for Stream Management (XEP-0198)

Acking

“Acking” is the tracking of stanzas at the client level, meaning at higher levels than TCP for instance.
The receiving entity keeps a counter of successfully processed stanzas for a given session, and can communicate this counter to the other entity.

In go-xmpp, if Client.Config.StreamManagementEnable is set to “true”, all sent stanzas will be both sent and put into a queue.
If an ack request is made to the server, depending on the response, some stanzas will be discarded, because the server already handled them, or resent because the server never got them.

Here’s how one would ask for acks :

r := stanza.SMRequest{}
client.Send(r)

Resumption

Stream resume capabilities were also added in this release.

Stream resumption allows to resume a session with the server without going through the entire ceremony of the protocol; it essentially skips some steps.

When a client is created using go-xmpp, one can specify a handler for the client’s event manager. Basically, every time the client changes states (connected -> disconnected for instance), the handler is executed.

Here’s we would use the handler to resume an interrupted stream :

  // Create a client. Skipped for brevity

  // Create a handler for that client. Triggered when changing state
  handler := func(e Event) error {
        switch e.State.state {
      // Some states are skipped. 
      // See "StreamManager" in the lib for a more thorough example)
        case StateDisconnected:
            // Reconnect on disconnection
            return client.Resume()
        case StatePermanentError:
            // Do not attempt to reconnect
        }
        return nil
    }

  // Add the handler to the client
  client.SetHandler(handler)

Now a disconnection because of network outage would trigger a stream resumption.

Post-(re)connect hooks

To help with designing clients, two post connection hooks were added to Client :

  • PostConnectHook
    Will be triggered when calling Client.Connect(). Can be used to retrieve the roster for instance.
  • PostResumeHook
    Will be triggered when using Client.Resume(). Do different operations when reconnecting, and skipping roster if we already have it for example.

One would just assign them as follows :

   config := Config{
        TransportConfiguration: TransportConfiguration{
            Address: testServerAddress,
        },
        Jid:        "test@localhost",
        Credential: Password("test"),
        Insecure:   true}

    var client *Client
    var err error
    router := NewRouter()
  // client default handler omitted for brevity
    if client, err = NewClient(&config, router, clientDefaultErrorHandler); err != nil {
    log.Fatalf("connect create XMPP client: %s", err)
    }

    // Assign hooks to the client
    client.PostConnectHook = func() error {
        go func() {
            // ask server for roster, omitted here
        }()
        return nil
    }
    client.PostResumeHook = func() error {
        go func() {
            // do something else when we try to resume. We already have the roster if this gets triggered
        }()
        return nil
    }

And that’s it ! Hooks will be triggered automatically when relevant.

ProcessOne services continue as usual through COVID-19 outbreak

$
0
0

In case you were wondering, all ProcessOne services and operations are continuing as usual throughout COVID-19 outbreak. For more than a decade ProcessOne has been providing realtime messaging & communication services while its team was working 100% remotely, from various global locations. We continue to do so today without interruptions.

Realtime messaging is critical at this time and we are here to help. Let’s connect »

Viewing all 36 articles
Browse latest View live