Skip to content
Snippets Groups Projects
Unverified Commit fe3cc85d authored by Marco Emilio "sphakka" Poleggi's avatar Marco Emilio "sphakka" Poleggi
Browse files

README: added data schemas and test instructions

parent cee2baf4
No related branches found
No related tags found
No related merge requests found
README.html
......@@ -52,9 +52,9 @@ Buttons: 4, named as the routes above.
### Back-end
:construction: Session management subsystem written in Python/FlaskGunicorn/???
:construction: Session management subsystem written in Python/Flask
:hammer_and_wrench: This part requires some development by the students.
:tools: This part requires some development by the students.
### Storage
......@@ -62,22 +62,110 @@ Buttons: 4, named as the routes above.
:construction: S3-like object storage composed of 1 buckets with two directories: one for
*enrollment* data, one for *session* data.
Objects shall be written as JSON data based on the following proposed schema.
#### Enrollment objects
An enrollment object:
* is named after the user e-mail
* is unique in the system
* is created when a new user subscribes to the system via the `enroll` function
* is never updated (assume that users' passwords cannot be changed)
* is deleted when a subscribed (== existing) user unsubscribes from the
system via the `unenroll` function
Minimum schema (you're free to extend it):
``` json
{
"title": "Enrollment",
"type": "object",
"properties": {
"password": {
"type": "string",
"description": "The user's password."
},
"timestamp": {
"description": "The UNIX epoch time of object's creation",
"type": "integer",
"minimum": 0
}
}
}
```
Example data for object named `foo@bar.com`:
``` json
{
"password": "SECRET",
"timestamp": 1733330967
}
```
#### Session objects
A session object:
* is named after the user e-mail
* is unique in the system -- multiple sessions are not permitted
* is created at the first user's connection to the system via the `login`
function
* is never updated
* is deleted when a logged-in user disconnects from the system via the
`logout` function
Minimum schema (you're free to extend it):
``` json
{
"title": "Session",
"type": "object",
"properties": {
"client": {
"description": "The client host's IPv4 address",
"type": "string",
"format": "ipv4"
},
"timestamp": {
"description": "The UNIX epoch time of object's creation",
"type": "integer",
"minimum": 0
}
}
}
```
Example data for object named `foo@bar.com`:
``` json
{
"timestamp": 1733330967
}
```
### Workflows
The following workflows correspond to the front-end routes discussed above.
The following workflows correspond to the application "routes" discussed
above. Additional information is provided in the boilerplate files. All
involved data are in JSON format.
Conventions:
* KEYWORDS are capitalized.
* **Actors** are in boldface.
* 'CONSTANTS' are capitalized and single-quoted.
* *data* items are lower-case and italicized.
* all times are represented as [UNIX epoch
timestamps](https://en.wikipedia.org/wiki/Unix_time)
:bulb: This is a fake SSO ;-) For the sake of simplicity:
:bulb: For the sake of simplicity:
* Sessions never expire.
* No cookies are stored at the client.
* The e-mail address is used as authentication token.
All operations are *stateless*: apart from enrollment and session data,
nothing else is recorded by the back-end.
#### Enroll
......@@ -90,7 +178,7 @@ A new user subscribes to the system via the `enroll` function:
- IF user exists THEN returns 'KO:ALREADY_ENROLLED'
- ELSE
1. Writes enrollment data to storage
2. Returns 'OK' to the front-end
2. Returns 'OK:ENROLLED' to the front-end
4. **Front-end** receives response from the back-end and shows it to the user.
......@@ -102,10 +190,10 @@ An enrolled unsubscribes from the system with the `unenroll` function:
front-end.
2. **Front-end** sends enrollment data to the back-end.
3. **Back-end** verifies enrollment data:
- IF user does not exists THEN returns 'KO:NO_SUCH_USER'
- IF user does not exists THEN returns 'KO:NO\_SUCH\_USER'
- ELSE
1. Removes enrollment data and any active sessions from the storage
2. Returns 'OK' to the front-end
2. Returns 'OK:UNENROLLED' to the front-end
4. **Front-end** receives response from the back-end and shows it to the user.
......@@ -116,22 +204,22 @@ An enrolled user authenticates to the system with the `login` function:
1. **User** provides *e-mail* via the the front-end.
2. **Front-end** sends *e-mail* to the back-end.
3. **Back-end** verifies the *e-mail*:
- IF user does not exists THEN returns 'KO:NO_SUCH_USER'
- IF user does not exists THEN returns 'KO:NO\_SUCH\_USER'
- ELSE verifies sessions:
1. IF an active session exists THEN returns 'OK'
2. ELSE returns 'NEED_PASSWORD'.
1. IF an active session exists THEN returns 'OK:SESSION_EXISTS'
2. ELSE returns 'OK:NEED_PASSWORD'.
4. **Front-end** receives first response from the back-end:
- IF response == 'NEED_PASSWORD' THEN
- IF response == 'OK:NEED_PASSWORD' THEN
1. Prompts the user for their *password*.
2. **User** provides *password*.
3. **Front-end** sends *e-mail* and *password* to the back-end.
4. **Back-end** verifies the *password*:
- IF *password* matches THEN
1. Writes session to storage.
2. Returns 'OK' to the front-end.
1. Writes a new session to storage.
2. Returns 'OK:LOGGED_IN' to the front-end.
- ELSE returns 'KO:WRONG_PASSWORD' to the front-end.
- ELSE shows 'OK' response to the user and terminates.
5. **Front-end** receives second response 'OK/KO' from the back-end and
- ELSE shows other response to the user and terminates.
5. **Front-end** receives second response from the back-end and
shows it to the user.
......@@ -142,12 +230,12 @@ An enrolled user deauthenticates to the system with the `logout` function:
1. **User** provides *e-mail* via the the front-end.
2. **Front-end** sends *e-mail* to the back-end.
3. **Back-end** verifies the *e-mail*:
- IF user does not exists THEN returns 'KO'
- IF user does not exists THEN returns 'KO:NO\_SUCH\_USER'
- ELSE verifies sessions:
- IF an active session exists THEN
1. Removes session from storage.
2. Returns 'OK'.
- ELSE returns 'KO'.
2. Returns 'OK:LOGGED_OUT'.
- ELSE returns 'KO:NO\_ACTIVE\_SESSION'.
4. **Front-end** receives response from the back-end and shows it to the user.
......@@ -186,18 +274,53 @@ whenever its image is updated.
## Tasks
:construction: **To be finalized**
You shall:
0. Fork this repository.
1. Complete the Python back-end file(s) in folder `Application/back-end.py`.
2. Rebuild the application Docker image, and store it :question: somewhere --
**(TO-DO: We should provide instructions. Build on the student's
workstation?)**.
3. Complete the `Terraform/main.tf` recipe to handle the provisioning of the S3 storage
bucket.
4. Complete the `Ansible/deploy.yml` playbook to handle:
- exposure of the application portal IP (e.g., load-balancer IP) to the
2. Rebuild the application Docker image, and store it (somewhere) --
**(:question: TO-DO - We should provide instructions + Dockerfile:
- Build image on the student's workstation
- What's better: push to Dockerhub vs to scp to VM + import?
)**. This task shall be automated via Ansible -- see below.
3. Complete your Terraform files from the version you developed in
[Lab-Terraform](https://gitedu.hesge.ch/lsds/teaching/bachelor/cloud-and-deployment/lab-terraform/-/blob/main/SwitchEngines/README.md)
up to Task #8. Your recipe shall handle only the provisioning of the VM
plus an S3 storage bucket -- no KinD/Kubectl package installation. Commit
your recipe files (included Cloud-init) and in directory `Terraform/`.
4. Complete your Ansible playbook, starting from the version you developed in
[Lab-Ansible](https://gitedu.hesge.ch/lsds/teaching/bachelor/cloud-and-deployment/lab-ansible)
Task #10, to:
- expose the application portal IP (e.g., load-balancer IP) to the
Internet via `socat` or other mechanism of your choice;
- :question: **(TO-DO: What's better? Local or registry [Helm/Docker])?**
transfer/download of the application image to your VM instance.
Tests: :construction: **TO-DO**
- :question: **(TO-DO: What's better? Local or registry [Docker])?**
rebuild and transfer/download the application image to your VM instance.
Commit these files in directory `Ansible/`.
### Tests
The following tests shall be passed by your implementation:
* Starting with a non-provisioned infrastructure:
1. Terraform apply shall provision a bare-bone VM and an S3 bucket
2. Ansible-playbook shall install KinD/Kubectl and deploy your
load-balanced application
3. Your application shall be reachable on port 80 (or another of your
choice) from any host outside the Cloud network.
* Once your application is installed, you shall exercise all the branch
conditions described by the above workflows:
1. Enroll a new user: shall succeed
2. Enroll an existing: user shall fail
3. Unenroll a new user: shall fail
4. Unenroll an existing user: shall succeed
5. Login an enrolled user: shall succeed and ask for the password
* with a valid password: shall succeed
* with an invalid password: shall fail
6. Login a non-enrolled user: shall fail
7. Logout a non-enrolled user: shall fail
8. Logout an enrolled user
* with an active session: shall succeed
* without an active session: shall fail
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment