Edited online authored by ciberkids's avatar ciberkids
# How to comunicate with TSC
In front of TSC there are some APIs provided by a WebServer that use POST as HTTP method and JSON for request and reply data format, there is a notification server next to the Webserver for the notification by the server or other user.
Here we will explain which are these APIs and how to comunicate with them.
In order to simplify the development of these APIs we chose the [SlimFramework](http://www.slimframework.com/).
## Web Socket ##
The system now uses a websocket feedback system over a WAMP server ([WAMP Site](http://wamp.ws/)) we decided to use this implementation for several reasons. One of these reasons is supported by the fact that the WAMP is a standard and open source.
Moreover there are several client library for the most languages. ([Libraries](http://wamp.ws/implementations/#libraries)).
### Web socket behaviour ###
A picture can examplain better than words:
![crossbar_application_scenario_1.png](https://bitbucket.org/repo/kKqzXr/images/3702786818-crossbar_application_scenario_1.png)
better two:
![crossbar_http_push.png](https://bitbucket.org/repo/kKqzXr/images/2968245320-crossbar_http_push.png)
Internal ref: [Implementation](http://crossbar.io/docs/HTTP-Pusher-Service/)
[Matteo Favaro Examples](https://github.com/ciberkids/crossbarconnect)
### Web Socket client configuration ###
In this implementation of web socket the clients can only subscribe certain topic.
The topics are (sperimental):
1. **com.tridas.statemachine.statechange**
2. **com.tridas.escalation. "token"** : the token received from the auth
e.g. "com.tridas.escalation.270f66f6bb4835656b692df7ca61f2ec"
3. **com.tridas.priviledged.change**
the web socket will answer on:
**url: 'ws://[WEB SERVER NAME]:8080/'**
**realm: 'realm1'**
## Malformed request
During the comunication with the TSC if some APIs are called with an unexpected JSON format the WebServer will reply with HTTP error:
* 400 Bad Request
Otherwise if an unkown API url is called the WebServer will reply with the HTTP error:
* 501 Not Implemented
## Login API
In order to access to the TSC information you need to call this api at the begining of the session.
API url: http://TscName.Domain/login
POST data:
```
#!json
{
username: "[username]",
password: "[password]",
}
```
If the login is required from the DATAMANAGER the webserver recognize him and it doesn't let his session to expire.
The password must be a sha256 hash of the password value.
Answers data:
* Answer:
```
#!json
{
role: "admin",
token: "cfc32ff100e72e159b83817f4cd56481",
action: "ok",
message: "User matteo succesfully logged in"
}
```
When a "OK Answer" is replied the WebServer will discriminate automatically if the login is issued from the DATAMANAGER program or by the web interface GUI. If the TSC WebServer identifies the DATAMANAGER, its session will never expire otherwise a session has a limited duration of 15 minutes (idle time). If the authorized user will continue to execute commands the session will be kept alive automatically.
If any other APIs will be called without having called this APIs first, the WebServer will reply always with an "Unauthorized" answer with HTTP error:
* 403 Forbiden
## check Token API ##
Thi API permits to the clients to use the old token in order to regrant th access to the server api.
API url: http://TscName.Domain/verifyToken
POST data:
```
#!json
{
authToken: "token",
}
```
If the login is required from the DATAMANAGER the webserver recognize him and it doesn't let his session to expire.
The password must be a sha256 hash of the password value.
Answers data:
* Answer:
```
#!json
{
role: "admin",
action: "ok",
message: "User matteo succesfully logged in"
}
```
When a "OK Answer" is replied the WebServer will discriminate automatically if the login is issued from the DATAMANAGER program or by the web interface GUI. If the TSC WebServer identifies the DATAMANAGER, its session will never expire otherwise a session has a limited duration of 15 minutes (idle time). If the authorized user will continue to execute commands the session will be kept alive automatically.
If any other APIs will be called without having called this APIs first, the WebServer will reply always with an "Unauthorized" answer with HTTP error:
* 403 Forbiden
## Lougout API ##
This api permits to explicity destroy the user session on the server.
API url: http://TscName.Domain/logout
POST data:
```
#!json
{
authToken: "token",
}
```
Answers data:
* Answer:
```
#!json
{
action: "ok",
message: "User matteo succesfully logged out"
}
```
## Command API ##
In order to control the TSC is necessary to use this API. As told previously this API can be called if and only if the "Login API" has been firstly called.
By design the TSC can accept command only from an "escalated" user, it can achieve this priviledge using the "Escalate API". If a command is issued from a user that is authenticated but hasn't completed the "Escalation Procedure" the WebServer will always answer with the HTTP error:
* 403 Forbidden
API url: http://TscName.Domain/commands
POST data:
```
#!json
{
command: "[init|configure|start|stop|reset]",
param: "[better explained afterwords]",
authToken: "[previously received token]"
}
```
the ``param`` key is REQUIRED with the command ``init`` and the request is:
```
#!json
{
command: "init",
param: "[runsetup]",
authToken: "[previously received token]"
}
```
in all other cases the ``param`` key will simply ignored.
When the request is recognized and it is permited the WebServer will try to issue the request to the backend in order to generate an answer. The answers can be different regarding the successful or failure of the TSC to satisfy the request.
The Answer can be as follow:
* Answer:
```
#!json
{
action: "ok|fail",
currentState: "idle|stanby|ready|running"
}
```
## Status API ##
This api can be used from any authenticated user, even if it didn't perform the "Escalation Procedure".
Is important to underline that at every statemachine event a PUSH notification is sent to the client in order to minimize the request to the server. The behaviour of the client is let to the developer decision.
**Attention**: when there is a change of the state of the state machine there will be a redundant information about the state. One will arrive from the answer of the command and another from the push notification, the developper must decide which filter in his client.
API url: http://TscName.Domain/status
POST data:
```
#!json
{
command: "statemachine|processes",
param: "[better explained afterwords]",
authToken: "[previously received token]"
}
```
the ``param`` key is REQUIRED with the command ``processes`` and the request is:
```
#!json
{
command: "processes",
param: "[HM|TSV|TCPU|EM|ALL]",
authToken: "[previously received token]"
}
```
in all other cases the ``param`` key will simply ignored.
The answers are different according to the request.
* ``statemachine`` command answer:
```
#!json
{
currentState: "idle|stanby|ready|running"
}
```
* ``processes`` command answer:
```
#!json
{
HM: "[n_of_processes]", |
TSV: "[n_of_processes]", |
TCPU: "[n_of_processes]", |
EM: "[n_of_processes]"
}
```
## RunSetup API ##
The RunSetup API is provided in orer to allow the DATAMANAGER to know the list of the avaiable RunSetup.
API url: http://TscName.Domain/runsetup
POST data:
```
#!json
{
command: "getRunSetupList",
param: "[TO: be decided, Maybe something useful for refine search]",
authToken: "[previously received token]"
}
```
Answer:
```
#!json
{
{
id: "ID",
name: "[RunSetup Name]",
othersKeys: "[maybe some other usefull information]"
},
{
id: "ID",
name: "[RunSetup Name]",
othersKeys: "[maybe some other usefull information]"
}
}
```
## Escalate API ##
In this paragraph we'll explore the whole set of commands provvided from the WebServer in order to allow the clients to obtain the authority to send commands to the Tridas system through the TSC.
API url: http://TscName.Domain/escalate
This service has different commands, the order with wich these commands might be used will explained on the next section "Escalation procedure". Here we'll only explain the format of the request/reply of the provvided set of commands.
* **"Am I Privivileged?"**
This command permit to know in every moment if the current user is allowed to send commands to the TSC.
If a "No answer" is replied, any attempts to use the "Command API" will be replied with an HTTP error:
* 403 Forbidden
POST data:
```
#!json
{
command: "amiprivileged",
authToken: "[previously received token]"
}
```
Answers data:
```
#!json
{
result: "true|false",
currentPriviledgedUserName: "username | '' ",
currentPriviledgedName: "name | '' "
currentEscalatingName: "name | '' "
message: "the current privileged user is XX | there aren't any priviledged user" + " user XX is escalating" | " "
priviledgeWillExpireInSeconds: "seconds to priviledge exipration"
}
```
* **"I would like to escalate".**
This command is useful if a client want become a Privileged users.
POST data:
```
#!json
{
command: "iwouldliketoescalate",
forceEscalation: "true|false"
authToken: "[previously received token]"
}
```
The key ``forceEscalation`` is **DANGEROUS**! With a ``true`` value, it forces the WebServer to release the priviledge from the currenr privileged user to the issuing user. This key is thought in order to avoid another bugged client to always to answer "no" with the service "Authorize escalation". This parameter is simply ignored until a client is answering "no" with the service "Authorize escalation" for more that 2 minutes. After that time every new request with this parameter set will be evaluated.
When the procedure is started a message will be sent to the notification channel identified by: "com.tridas.escalation. "token" ".
of the current priviledge user.
Answers data:
```
#!json
{
result: "procedureinitiated|procedureAlreadystarted|WAFOU|WAFOUFEE|escalationCompleted|youAreAlreadyPriviledged",
currentPriviledgedName: "[name of the current privileged user]",
currentEscalatingName: "[name of the current escalating user]",
message: "[other information eg The procedure is started by you wait, The user XX has already started the procedure, ]",
timestamp: "[time stamp of the begining of the procedure]",
secondsToForceEnabling:"seconds",
}
```
Answers meaning:
* **procedureinitiated**: You are the initializer of the escalation procedure, if all will end fine you will become a privileged user.
* **procedureAlreadystarted**: the procedure is on going by another user you need to wait.
* **WAFOU**: (Waiting Answer From Other User) you have already asked to become a privileged user and now you need to wait that it complete. The maximum time of completion could be 2 minutes or 5 minutes depending on the behaviour of the other users.
* **WAFOUFEE**: (Waiting Answer From Other User, Force Escalation Enabled) the privileged user is continually answering "no" so from now the parameter "forceEscalation" is evaluated.
* **escalationCompleted**: There wasn't any privileged user so now you have automaticcaly became the new priviledged user
* **youAreAlreadyPriviledged**: You are escalating on yourself, nothing will be done.
-
* **"Will I losing the privilege"?**
This command is provided in order to know if someone has started the "Escalation procedure". When the procedure is started this is the way to know who has started the procedure. If this service answer with a "yes" answer you need to answer with the service "Authorize escalation".
POST data:
```
#!json
{
command: "imlosingprivilege",
authToken: "[previously received token]"
}
```
Answers data:
```
#!json
{
result: "true|false",
desc: "[some usefull description eg. User XX want to became privileged, contact answer service]"
}
```
** NOTE FOR MATTEO FAVARO **
**Explain the websocket subscription in order to receive the messege of escalation procedure in progress**
**WHEN YOU HAVE FINISHED TO IMPLEMENT**
* **"Authorize escalation"**
When "Will I losing the privilege" answers with a "yes" you need to contact this service within 2 minutes. If no contact will be received from the WebServer, it will suppose that the answer i "yes". If the current privileged user continually answer "no" for 5 minutes, the WebServer will give to the requesting user the possibility to force the privilege acquisition.
POST data:
```
#!json
{
command: "authorizeescalation",
authorize: "[yes|no]",
authToken: "[previously received token]"
}
```
Answers data:
```
#!json
{
result: "ok",
}
```
* **"Release Privilege"**
This command explicitly release the privilege acquired.
POST data:
```
#!json
{
command: "releaseprivilege",
authToken: "[previously received token]"
}
```
Answers data:
```
#!json
{
result: "ok",
}
```
# Escalation procedure #
**add the notification information to the wiki**
In this paragraph we explain in which order and how to contact the provided "escalation" command in order to achieve the privilege to issuing commands to the Tridas system.
1. [OPTIONAL but USEFUL depending on dev implementation] before to contact the **``command``** service and issue a command is a good practice contact the **``escalate``** service with the ``amiprivileged`` command.
a. If a "yes" answer is replied you are still privileged and you can send commands and control the data acquisition.
b. If a "no" is replied continue on step 2
2. probably you want to escalate and gain the power to control the Tridas, concerning this you need to call the **``escalate``** service with the ``iwouldliketoescalate`` command. Now it is implementation depending, you can keep polling this service and evaluate the answer or you can keep polling the service **``escalate``** service with the ``amiprivileged`` command. It is the same. There are two things to keep in mind:
a. the other user has 2 minutes for answering: if this time expires and no answer has been given you will get the privilege automatically. In other hand the user can answer with a no and you can discover this contacting the the service **``escalate``** service with the ``amiprivileged`` command. ( at the moment we are evaluating a web socket implementation, in order to avoid the polling system).
b. if he doesn't want to release its power for 2 times the system give you the ability to force the procedure.
3. When someone is privileged, he must keep polling the service the service **``escalate``** service with the ``imlosingprivilege`` command.
4. If you discover that you are losing the priviledge you need to contact the service **``escalate``** service with the ``authorizeescalation`` command.
5. normally is a good practice release the privilege at the end of your purpose contacting the service **``escalate``** service with the ``releaseprivilege`` command.
\ No newline at end of file