Pre-authentication steps in ejabberd - erlang

I am working on a project like whatsapp and using ejabberd as a backend server with Android/IOS clients. I want to do some whatsapp like step-
1. Client sends mobile number to server.
2. server sends OTP in return to the client and starts a timer say 2 minutes.
3. If client sends correct OTP, received from the server, to the server within the time specified. Client will be registerd.
I need help in which ejabberd module should I write the code of above steps. I know, to modify Ejabberd I can use Hooks and IQ handlers, but they can be used once the user is already registered. Right?
Should I use other language server, just for the above steps? Please help.

You should write new ejabberd module which starts a new SSL server on a specific port. Do your authentication on that.
If you are familiar with ejabberd's core, you can add your own module in listen part of config and write new module as backend of your server (same as ejabberd itself which wrote ejabberd_c2s, ejabberd_service, etc).
I just read its code and i recommend to read the code too.
For example in ejabberd version 17.01 here reads config and runs a tcp server for every section of listen key. every section has three parts Port, Module and Opts. For xmpp clients of ejabberd these are 5222, ejabberd_c2s and Opts is other values. in here for every accepted connection it calls ejabberd_socket:start(Module, gen_tcp, Sock, Opts). In ejabberd_socket:start/4 here starts a process say A for receiving from socket and parsing XML and send them to another process say B and here starts a process (B) from ejabberd_c2s. Process B receives XMLs from Process A and does all actions off XMPP clients in ejabberd.

I think you should create a restful service to do this.
Please consider following steps:
Client sends mobile number to restful service.
The restful service create a OTP and save it in Redis with expired is set.
The client sends OTP to restful service. If the OTP is correct, service sends a jwt Token to client and save it in Redis with expired is set.
The client sends jwt token to eJabberd server and the server authenticates with ejabberd_auth_jwt module.
This may meet your requirement.

Related

RabbitMQ - shovel plugin, accessing headers (properties) form Azure Service Bus

I need to implement rabbitMQ as sort of a middleware between Azure service bus and my rails app.
The message that is being sent uses headers which i also need to capture.
So, is there a way for shovel-plugin to also include headers with the shoveled payload?
Whenever i get the message from the shovel all the original headers are gone.
Also I am using Bunny as an amqp client in the app
Thanks!
EDIT:
Found this PR thanks to RabbitMQ slack:
https://github.com/rabbitmq/rabbitmq-server/issues/2745
It seems that they are aware of the issue
I just created a Python middleware that handles appending headers to the payload and passes the data to RabbitMQ queue later on since it's literally 30 lines of code

ROS service provider needs to subscribe to client topic

So in ROS I have a server which provides a greetService in which new clients send their greeting requests and the reserver responds with something. The important part is that I want them to continue communicating, I have Anonymous=True for clients as I launch multiple instances of them. Let's say I want the client's topic to be CLIENTNAME_POSITION how can I get the server to subscribe and keep track of that? I'm using python by the way but a c++ response is alright too as I'm fluent in both languages.
You could create two services that the server will provide. They would be used by the client to register and unregister from the server.
When a client wants to register, it provides the topic name it will use to get the greetings within the service request. The server adds a new Publisher corresponding to the new client in a list (or a dictionary). To unregister the client sends the topic it was using and the server removes the corresponding Publisher in the list.

Spring Web Socket not broadcasting message to all application servers

I am trying to setup load balanced environment having 2 application server instances. I am unable to make spring web socket relay messages to all instances. Let's take a example to describe my problem better:
Server 1 : Responsible for job executions and 35% user load.
Server 2 : 100% user load.
Both are connected to same database schema so job request can come for any server instance but will get executed on Server 1.
Now, I have used spring web socket plugin for my GRAILS application and I push messages to browser using
brokerMessagingTemplate.convertAndSend(user.notificationChannel, ((notification.toMap(user) as JSON)).toString())
It was working fine on single server setup. But on multi-server setup,
notifications are only received on Server 1 as that is the one calling the code block, if reverse the scenario, then vice-versa result is observed.
How can I push same notification to all server instances, so that user always gets the notification no matter what server instance he is on?
I initially thought of utilising a common queue like RabitMQ but that will add to system requirements and will get disapproved by client.
NOTE: Third party service solutions won't work in my case as applications are on intranet and don't have internet access.
websockets by default point to a hostname/ip address - whilst you could setup a dns record / hostname that points to multiple different ip's / servers. This itself would break communication flow of the websockets if it sent handshake to one and the message to another.
The most simplest approach would be to think of some db table that is shared across both and as each instance comes up/alive it records its local ip / socket port to a db table - each instance can then read this table and work out at any point which are the hosts to transmit a socket message to - (this table would need to managed somehow - upon a brand new bootup ) it would be empty and would popuplate as instances came up - something again to manage when a host is taken down shutdown.
Each instance would then be running an ws internal client. When a message is sent the ws client would be triggered attempting to find all alive websocket servers "from the db" to each using the ws client it would attempt to connect and send the message on. Each would then get the message and either broadcast to all connected users or if it is from user x meant for user x then like per chat plugin it would relay it only to user x if found on server y and so on.
this then keeps it all inline with 1 technology controlling the entire process websocket server that has its own client which relay to the end multiple instance ws socket server

Sending Message from TCP server in erlang

I have just started off on Erlang. I want to create a TCP server in Erlang. My TCP client runs on Android and connects to the server.
I have taken the TCP server implementation from
https://github.com/kevinlynx/erlang-tcpserver
I am able to run the server, connect the client to it and send messages from the client to the server. Also, the logic in the server is that whenever it receives a messages from the client, it sends back the same message to the client.
All this works fine, my only problem is how do I send a message to client from the erlang shell(without having to wait for a message from client). The gen_tcp:send() function requires as input the Socket handle, whenever client sends a message, there is a callback and it has the socket handle so it can be used to send message back to the client, but how to do it otherwise?
On the server side, you must be accepting the connection somewhere:
{ok, Sock} = gen_tcp:accept(LSock)
And I suppose you could send a message to that socket:
gen_tcp:send(Sock, YourPacket)
If you do not accept connections then it is not a server.
Updating to answer comment
One way is sharing the listener socket (LSock in the example). You could save it on an accessible ETS and call the acceptor from the shell despite it not been the owner of the listener.
Otherwise you are going to have to wrap everything on a server where you keep the opened socket/s in a State, and program a handle to send messages to opened sockets. A nice explanation of a socket server can be found here.
I have just started off on Erlang. I want to create a TCP server in Erlang.
I think the problem is that you are using software that sets up a communication channel between a client and a sever:
(client) ================== (server)
Now you have a third entity:
(client) ================== (server)
(erlang shell)
and you want the erlang shell to communicate with the client. That's all well and good, but the code you are using doesn't provide for that. It sounds like you also want your client to act as a server for the erlang shell. Why do you need the erlang shell to send messages to the client?
The erlang shell could become a second client of the server:
(client) ================== (server)
(erlang shell) ============ (server)
but that doesn't help the erlang shell communicate directly with the client. The erlang shell could send some information to the sever, and the server could store that information in the State, then the server could pass the State to the client the next time the client made a request.
If the erlang shell had the Pid of the client, the erlang shell could always do:
Pid ! "hello client"
and if the client were waiting in a receive-statement, then the client could extract that message from its mailbox. What does your client look like?

Connecting ruby application/script to a Ruby on Rails server

I am making an application where I want to have a sign-in within the ruby client app which is supposed to connects to a Ruby on Rails server. This is similar to what you do in applications such as Dropbox. The user somehow provides their username and password, and the ruby program should connect to the server establishing a session. After the initial sign-in I need to transfer data between the client and server (potentially a lot). I have looked at web-sockets for this, however I can't find a way to set this up properly.
The Rails server uses Devise for authentification, and I would prefer to keep it that way if possible.
I have not been able to figure out how I can set up this connection. Any hints for where I should start looking?
If you want to have a 'persisten' connection between your client and server, I suggest you use something like 0MQ socket which a kind of 'super-socket 'library with bindings for ruby. On the server side, you would 'bind' to an IP/port, on the client side you would 'connect' and then you could use a connection type of REQ/REP (Request/Response). If, at any time the client disconnects, this doesn't 'blow' the binding on the server side. If the server side disconnects, this doesn't blow up the client side (it just block on waiting for the answer unless you define a timeout).
There are other options also for non-blocking operation between the client and the server.

Resources