How is this project different from the original jRDC2 server?
In jRDC2, a client makes a query (or nonquery) by calling a named command to the server.
It is a simple server to starts with.
But in some cases, we want to restrict certain users to access a command.
1. Maybe some users belongs to certain group are not allow to call that command.
e.g some commands only allowed for "admin" user group. "normal" user group is blocked.
2. Maybe we want to keep an audit log for who login and what command he has called at a specific timestamp.
3. Maybe we want to implement session expiration.
4. Different user groups and client types can have different session expiration.
5. In case of account misused or hacked, changing password can block the unauthorized access.
There can be many other cases.
While jRDC2 is safe since the communication is going through in bytes, implementing session can add extra layer of security and make user administration possible.
Keep in mind, my solution is a bit different from using web server build in session.
Here I am storing the session ids in a database table. Admin can revoke a user access or analyze the recorded data.
In original client's DBRequestManager.bas, you have the following code in ExecuteQuery sub.
Dim data() As Byte = ser.ConvertObjectToBytes(CreateMap("command": Command, "limit": Limit, "version": VERSION))
This allows a client to send a query to jRDC2 server, provided the programmer already knows the rdcLink and command's name.
My idea is to make minimum changes to jRDC2, so that B4X programmers can continue to use jRDC2 as it use to be.
What I do is to modify it by adding a new "session" item into the map.
Dim data() As Byte = ser.ConvertObjectToBytes(CreateMap("command": Command, "limit": Limit, "session": B4XPages.MainPage.session , "version": VERSION))
Now, every time a client app wants to make a query, he needs to send this additional key-value (session).
This mean the original version of jRDC2 client app will fail to make request because a required value is not provided.
The session id must be also matched the value stored in the database session table.
But how does a client make a query for the first time?
It can't make a query using the same ExecuteQuery sub because it doesn't have a session id now.
So I have introduced a new sub call ExecuteLogin.
This is the method to call for "login" using a user credentials to retrieve the session id.
It has a different "method" set to "login" to differentiate itself from ExecuteQuery sub (which is "query").
I also modified DBResult by adding Message and Error properties.
In the event of successful queries or errors, the response from the server will let the client know what happen in a graceful way.
So the client app will not crash unexpectedly and provide bad user experience.
For further understanding, I welcome you to check the code.
This project is made in a short time as a proof of concept. It has a lot of space for improvement.