Adds documentation to IT3 - less branches

This commit is contained in:
Gabriel Matte 2024-11-27 14:47:54 -05:00
parent 6883774ed4
commit 2176edf7d0
23 changed files with 1392 additions and 2 deletions

31
.github/workflows/create-docs.yml vendored Normal file
View file

@ -0,0 +1,31 @@
name: Creates docs and deploy to gh-pages
on:
workflow_call:
workflow_dispatch:
push:
branches: [ main ]
jobs:
build:
name: Deploy docs
runs-on: ubuntu-latest
steps:
- name: Checkout main
uses: actions/checkout@v2
- name: Setup Python
uses: actions/setup-python@v5
- name: Install dependencies
working-directory: ./documentation
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Build docs
working-directory: ./documentation
run: mkdocs build --verbose --clean
- name: Push docs to gh-pages
working-directory: ./documentation
run: python deploy.py

4
.gitignore vendored
View file

@ -73,7 +73,7 @@ web_modules/
.yarn-integrity
# dotenv environment variable files
.env
server/.env
.env.development.local
.env.test.local
.env.production.local
@ -130,4 +130,4 @@ dist
.pnp.*
db-backup/
deployments
.venv

1
documentation/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
site

2
documentation/deploy.py Normal file
View file

@ -0,0 +1,2 @@
from ghp_import import ghp_import
ghp_import('site', push=True, force=True)

View file

@ -0,0 +1,12 @@
## À Propos
Ce projet utilise Node.js Express pour créer un backend simple pour l'application.
## Routes API
Vous pouvez consulter toutes les routes utilisables du backend ici
* User : https://documenter.getpostman.com/view/32663805/2sA2rCU28v#e942a4f4-321c-465b-bf88-e6c1f1d6f6c8
* Quiz : https://documenter.getpostman.com/view/32663805/2sA2rCU28v#732d980b-02fd-4807-b5bc-72725098b9b0
* Folders : https://documenter.getpostman.com/view/32663805/2sA2rCU28v#49ecd432-ccfc-4c8a-8390-b3962f0d5fd7
* Images : https://documenter.getpostman.com/view/32663805/2sA2rCU28v#58382180-d6f0-492d-80c3-e09de1c368b8

View file

@ -0,0 +1,372 @@
# Authentification
## Introduction
Le but du module d'authentification est de pouvoir facilement faire des blocks de code permettant une authentification personalisée. Il est possible de le faire grâce a cette architecture. Pour la première version de cette fonctionalitée, l'introduction de OICD et de OAuth sont priorisé ainsi que la migration du module d'authentification simple.
## Déconstruction simple de la structure
La structure est la suivante :
Le AuthManager s'occupe de centraliser les requetes d'authentifications. Ce qui veux dire d'initialiser les autres modules et d'être la source de véritée dans au sujet de l'authentification. Les modules sont automatiquement chargé par l'utilisation de variables d'environment.
Le module s'occupe de creer les routes nécéssaires pour son fonctionnement et de créer les utilisateurs. Ces modules vont appeller le AuthManager afin de confirmer leurs actions avec le login/register de celui-ci
Dans le cas de modules plus complexe, tels que le module Passport, la chaine peut être prolongée afin de maintenir centralisée les actions. Chaque connecteur de PassportJs est initialisé par le module de PassportJs.
## Besoins exprimés
Modularité et généricité :
- Le système d'authentification doit être adaptable à diverses configurations, notamment pour répondre aux exigences spécifiques des différentes universités ou institutions.
Utilisation de différentes méthodes d'authentification :
- L'application doit permettre de gérer plusieurs fournisseurs d'authentification (SSO, LDAP, OAuth, etc.) de manière centralisée et flexible.
Facilité de configuration :
- Le système doit permettre une configuration simple et flexible, adaptée à différents environnements (développement, production, etc.).
Gestion des permissions :
- Il doit être possible de définir et de mapper facilement les permissions et les rôles des utilisateurs pour sécuriser laccès aux différentes fonctionnalités de lapplication.
Maintien de la connexion :
- Le système doit garantir la persistance de la connexion pendant toute la durée de l'utilisation de l'application (exemple : quiz), avec la possibilité de se reconnecter sans perte de données en cas de déconnexion temporaire.
## Recis utilisateurs pris en comptes
- En tant qu'utilisateur de projet FOSS, je veux que le module d'authentifcation soit modulaire et générique afin de l'adapter a mes besoins.
- En tant qu'administrateur, je veux que les droits des utilisateurs soient inférés par l'authentificateur de l'établissement.
- En tant qu'administrateur, je veux que la configuration des authentificateur soit simple
- En tant qu'administrateur, je veux configurer les connections a partir de variables d'env ou fichier de config.
- En tant qu'utilisateur, je veux que ma connexion soit stable.
- En tant qu'utilisateur, je veux pouvoir me reconnecter a une salle s'il y arrive un problème de connexion.
## Diagrammes
### Structure
```plantuml
@startuml
package Backend {
class AuthManager{
+IAuthModule[] auths
#userInfos
-load()
-registerAuths()
+showAuths()
+authStatus()
+logIn(UserInfos)
+register(UserInfos)
+logOut()
}
interface IAuthModule{
+registerAuth()
+authenticate()
+register()
+showAuth()
}
class SimpleFormAuthModule{
}
class PassportAuthModule{
IPassportProviderDefinition[] providers
}
Interface IPassportProviderDefinition{
+name
+type
}
class OAuthPassportProvider{
+clientId
+clientSecret
+configUrl
+authorizeUrl
+tokenUrl
+userinfoUrl
+logoutUrl
+JWKSUrl
}
IAuthModule <|-- SimpleFormAuthModule
IAuthModule <|-- PassportAuthModule
IPassportProviderDefinition <|-- OAuthPassportProvider
AuthManager -> IAuthModule
PassportAuthModule -> IPassportProviderDefinition
}
package Frontend{
class AuthDrawer{
+IAuthVisual[] getAuthsVisual()
+drawAuths()
}
Interface IAuthVisual{
+draw()
}
class FormVisual{
+FormInput[] formInputs
}
interface FormInput{
+name
+label
+type
+value
}
AuthDrawer -> IAuthVisual
IAuthVisual <|-- FormVisual
FormVisual -> FormInput
}
@enduml
```
### Explication des communications : Passport Js
```plantuml
@startuml
box "Frontend"
participant User
Participant App
end box
box "Backend"
participant PassportAuthModule
participant Db
participant AuthManager
end box
box "Auth Server"
participant AuthServer
end box
User -> App : Get auth page
App -> User : auth page
User -> App : click OAuth button
App -> User : redirect to OAuth
User -> AuthServer: Login
AuthServer -> User: Redirect to Auth endpoint with token
User -> PassportAuthModule: Authenticate with token
PassportAuthModule -> AuthServer: get user info
AuthServer -> PassportAuthModule: userInfo
alt login
PassportAuthModule -> Db : fetch local userInfo
Db->PassportAuthModule: userInfo
PassportAuthModule -> PassportAuthModule: Merge userInfo definition
PassportAuthModule -> Db : update user profile
Db->PassportAuthModule: userInfo
end
alt register
PassportAuthModule -> Db : fetch local userInfo
Db->PassportAuthModule: null
PassportAuthModule -> Db : create user profile
Db->PassportAuthModule: userInfo
end
PassportAuthModule -> AuthManager : login(userInfos)
AuthManager -> User: Give refresh token + Redirect to page
User -> App: get /
App -> User: Show Authenticated /
@enduml
```
### Explication des communications : SimpleAuth
```plantuml
@startuml
box "Frontend"
participant User
Participant App
end box
box "Backend"
participant SimpleAuthModule
participant Db
participant AuthManager
end box
User -> App : Get auth page
App -> User : auth page
alt Login
User -> App : Send Login/Pass
App -> SimpleAuthModule: Send login/pass
SimpleAuthModule -> Db: get user info
Db->SimpleAuthModule: user info
SimpleAuthModule -> SimpleAuthModule: Validate Hash
end
alt register
User -> App : Send Username + Password + Email
App -> SimpleAuthModule: Send Username + Password + Email
SimpleAuthModule -> Db: get user info
Db -> SimpleAuthModule : null
SimpleAuthModule -> Db: put user info
end
SimpleAuthModule -> AuthManager: userInfo
AuthManager -> User: Give refresh token + Redirect to page
User -> App: get /
App -> User: Show Authenticated /
@enduml
```
### Comment les boutons sont affichés
```plantuml
@startuml
box "FrontEnd"
participant User
Participant FrontEnd
Participant AuthDrawer
end box
box "BackEnd"
participant API
participant AuthManager
participant Db
participant IAuthModule
end box
API -> API : load global configurations
create AuthManager
API -> AuthManager : instanciate with auth configurations
create IAuthModule
AuthManager -> IAuthModule : instanciate array
loop For each auth in auths
AuthManager -> IAuthModule : register
IAuthModule -> API : register routes
API -> IAuthModule : route registration confirmation
IAuthModule -> AuthManager : module registration confirmation
end
User -> FrontEnd : get login page
alt already logged in
FrontEnd -> User: redirected to authenticated page
end
FrontEnd -> AuthDrawer : get auth visual
AuthDrawer -> API : get auth form data
API -> AuthManager : get auth form data
loop For each auth in auths
AuthManager -> IAuthModule : get form data
IAuthModule -> AuthManager : form data
end
AuthManager -> API : auth fom data
API -> AuthDrawer : auth form data
AuthDrawer -> AuthDrawer : make auth html
AuthDrawer -> FrontEnd : auth HTML
FrontEnd -> User : show auth page
@enduml
```
### Comment les sessions sont conservées
```plantuml
@startuml
box "Frontend"
participant User
Participant App
end box
box "Backend"
participant AuthManager
participant IAuthModules
end box
App -> AuthManager : send refresh token
AuthManager -> IAuthModules: ForEach check if logged
IAuthModules -> AuthManager: is authenticated ?
alt one logged in
AuthManager -> App : send new token
end
alt all logged out
AuthManager -> App : send error
App -> App : destroy token
App -> User : redirect to login page
end
@enduml
```
## Configuration des variables d'environnement
Example de configuration du fichier : `server/auth_config.json` :
```json
{
"auth": {
"passportjs": // Module
[
{
"gmatte": { // Nom du sous-module Passport
"type": "oauth", // type
"OAUTH_AUTHORIZATION_URL": "https://auth.gmatte.xyz/application/o/authorize/",
"OAUTH_TOKEN_URL": "https://auth.gmatte.xyz/application/o/token/",
"OAUTH_USERINFO_URL": "https://auth.gmatte.xyz/application/o/userinfo/",
"OAUTH_CLIENT_ID": "--redacted--",
"OAUTH_CLIENT_SECRET": "--Redacted--",
"OAUTH_ADD_SCOPE": "groups", // scopes supplémentaire nécéssaire pour le pivot
"OAUTH_ROLE_TEACHER_VALUE": "groups_evaluetonsavoir-prof", // valeur de pivot afin de définir un enseignant
"OAUTH_ROLE_STUDENT_VALUE": "groups_evaluetonsavoir" // valeur de pivot afin de définir un étudiant
}
},
{
"etsmtl":{
"type":"oidc",
"OIDC_CONFIG_URL":"https://login.microsoftonline.com/70aae3b7-9f3b-484d-8f95-49e8fbb783c0/v2.0/.well-known/openid-configuration",
"OIDC_CLIENT_ID": "--redacted--",
"OIDC_CLIENT_SECRET": "--redacted--",
"OIDC_ADD_SCOPE": "",
"OIDC_ROLE_TEACHER_VALUE": "groups_evaluetonsavoir-prof",
"OIDC_ROLE_STUDENT_VALUE": "groups_evaluetonsavoir"
}
}
],
"simpleauth":{}
}
}
```

View file

@ -0,0 +1,11 @@
# Type de base de données
La base de données est une mongoDB
# Collections disponibles
* Files : Ceci est la collection qui contient les différents quiz et leurs questions.
* Folders : Ceci est la collection qui contient les dossiers qui servent à la gestion des différents quiz
* Images : C'est dans cette collection que sont stockées les images utilisées dans les quiz
* Users : Cette collection est utilisée pour la gestion des utilisateurs
# Information sur la création
Lors du démarrage du projet, la base de données est créée automatiquement.

View file

@ -0,0 +1,39 @@
# KaTeX
KaTeX est le module qui s'occupe de formater les formules mathématiques selon la configuration donnée.
Les formules entourées de $$ s'afficheront centrées sur leur propre ligne
`.replace(/\$\$(.*?)\$\$/g, (_, inner) => katex.renderToString(inner, { displayMode: true }))`
alors que les formules entourées de $ s'afficheront sur la même ligne
`.replace(/\$(.*?)\$/g, (_, inner) => katex.renderToString(inner, { displayMode: false }))`
La configuration du formatage peut être trouvée dans le fichier TextType.ts situé dans le dossier EvalueTonSavoir/client/src/components/GiftTemplate/templates
C'est aussi dans ce fichier que le format markdown est pris en charge.
## Éditeur de quiz
Pour l'affichage dans l'éditeur de quiz, on peut retrouver la classe TextType être appliquée sur différents éléments du dossier templates, par exemple la classe Numerical.ts.
On peut voir ici que le TextType est appliqué sur le contenu de la question:
```typescript
<p style="${ParagraphStyle(state.theme)}">${TextType({text: stem })}</p>
```
Selon ce qui avait été écrit dans la question, la classe s'occupera de formatter les bonnes sections.
## Affichage de questions
Le module React-latex était utilisé pour le formatage des questions durant un quiz, mais cela a apporté le problème de disparité d'affichage entre la création et l'affichage des questions avec des formules mathématiques.
Les classes affichant les questions durant un quiz peuvent utiliser ce format, mais avec une manipulation de plus.
Les variables contenant la question doivent d'abord avoir un type TextFormat pour pouvoir faire appel à la classe qui s'occupe du format sous le module KaTeX.
Puis, étant sur un environnement React, il faut utiliser la propriété dangerouslySetInnerHTML pour afficher la question correctement.
`<div dangerouslySetInnerHTML={{ __html: TextType({text: questionContent}) }} />
`
Ce type de manipulation peut être utilisé dans d'autre environnement React si on veut éviter d'utiliser React-latex.

View file

@ -0,0 +1,54 @@
# Example de Quiz
```gift
//-----------------------------------------//
// Examples from gift/format.php.
//-----------------------------------------//
Who's buried in Grant's tomb?{~Grant ~Jefferson =no one}
Grant is {~buried =entombed ~living} in Grant's tomb.
Grant is buried in Grant's tomb.{FALSE}
Who's buried in Grant's tomb?{=no one =nobody}
When was Ulysses S. Grant born?{#1822:5}
Match the following countries with their corresponding capitals. {
=Canada -> Ottawa
=Italy -> Rome
=Japan -> Tokyo
=India -> New Delhi
####It's good to know the capitals
}
//-----------------------------------------//
// More complicated examples.
//-----------------------------------------//
::Grant's Tomb::Grant is {
~buried#No one is buried there.
=entombed#Right answer!
~living#We hope not!
} in Grant's tomb.
Difficult multiple choice question.{
~wrong answer #comment on wrong answer
~%50%half credit answer #comment on answer
=full credit answer #well done!}
::Jesus' hometown (Short answer ex.):: Jesus Christ was from {
=Nazareth#Yes! That's right!
=%75%Nazereth#Right, but misspelled.
=%25%Bethlehem#He was born here, but not raised here.
}.
//this comment will be ignored by the filter
::Numerical example::
When was Ulysses S. Grant born? {#
=1822:0 #Correct! 100% credit
=%50%1822:2 #He was born in 1822.
You get 50% credit for being close.
}
```

View file

@ -0,0 +1,146 @@
{
"openapi": "3.0.2",
"info": {
"title": "Room API"
},
"servers":[
{
"url": "http://localhost",
"description": "Via Docker"
},
{
"url": "http://localhost:3000",
"description": "Via npm"
}
],
"security": [
{
"bearerAuth": []
}
],
"paths": {
"/api/room": {
"get": {
"summary": "Get all rooms",
"description": "Returns a list of rooms",
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Room"
}
}
}
}
}
}
},
"post": {
"summary": "Create a new room",
"description": "Creates a new room, returns the created room",
"responses": {
"200": {
"description": "Created",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Room"
}
}
}
}
}
}
},
"/api/room/{roomId}": {
"get": {
"summary": "Get a room by id",
"description": "Returns a room by id",
"parameters": [
{
"name": "roomId",
"in": "path",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Room"
}
}
}
}
}
},
"delete": {
"summary": "Delete a room by id",
"description": "Deletes a room by id",
"parameters": [
{
"name": "roomId",
"in": "path",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "OK"
}
}
}
}
},
"components": {
"securitySchemes": {
"bearerAuth": {
"type": "http",
"scheme": "bearer",
"bearerFormat": "JWT"
}
},
"schemas": {
"Room": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"default": "autoincrement"
},
"name": {
"type": "string"
},
"host": {
"type": "string"
},
"nbStudents": {
"type": "integer",
"default": 0
},
"mustBeCleaned": {
"type": "boolean",
"default": false
}
},
"required": [
"id",
"name",
"host"
]
}
}
}
}

View file

@ -0,0 +1,185 @@
# Salles de Quiz
## Introduction
Les salles de quiz ont été extraites dans leur propre container afin de limiter les dégats liés soit a une surutilisation d'une salle ou une attaque sur le logiciel.
En éffet, le découplement permet a un quiz de:
- Survivre même si le backend est non-fonctionnel
- Mourir sans entrainer toute l'application avec elle
- Créer/Supprimer des salles automatiquement dépendant de la demande
Pour éffectuer ceci il faut éffectuer une petite gymnastique. Il y a une route dans l'api servant à gerer les salles. Lorsqu'un utilisateur demande le socket d'une salle : "/api/rooms/{id}/socket", la requette rebondit sur le proxy Nginx. Celui-ci contacte le backend afin d'obtenir l'addresse de l'ordinateur auquel envoyer la requette et redirige le socket vers ce pc.
## Déconstruction simple de la structure
Un module supplémnetaire a été ajouté à la structure : Rooms.
L'objet `room` est la définition d'une salle de façon minimaliste, cette définission est aggrandie avec l'information récotlé du "provider".
Le `provider` est le système gérant les différentes salles. Dans l'implémentation éffectuée, il s'agit de docker.
Lorsque l'api des salles est instantié, celui-ci est lié avec un "provider", définissant comment les salles seront créées.
L'api des salles permet de les ajouter, les supprimer, et les consulter les salles.
L'api lance deux "jobs":
- Une vérification de l'état de santé des salles. Celle-ci roule tous les 10 secondes et met a jour les salles.
- Une suppression des salles. Celle-ci roule tous les 30 secondes et supprimme automatiquement les salles ayant la mention de suppression.
## Besoins exprimés
Fiabilite :
- Nous voulons s'assurer qu'il soit possible d'avoir un grand nombre d'élèves présent sans qu'il y ait des problèmes de déconnexions
- Nous voulons que le temps de réponse soit bas
- Nous voulons que le système soit capable de fonctionner de facon indépendante
## Recis utilisateurs pris en comptes
- En tant qu'enseignant, je veux que tous mes élèves soient capable de se connecter a la salle de classe rapidement
- En tant qu'enseignant, je veux que la salle de quiz puisse survivre des pannes liées aux autres modules de l'aplication
- En tant qu'administrateur, je veux que les salles soient indépendantes et qui ne touche pas aux performances des autres salles
- En tant qu'administrateur, je veux que les salles puissent être hébergées séparément du projet
## Diagrammes
### Structure
```plantuml
@startuml
class Room{
+id
+name
+host
+nbStudents
+mustBeCleaned
}
class RoomRepository {
+get(id)
+create(room)
+delete(id)
+update(room,id)
+getAll()
}
class RoomController {
+setupRoom(options)
+deleteRoom(roomId)
+listRooms()
+getRoomStatus(roomId)
+updateRoom(room,roomId)
}
class RoomRouter{
+ / : GET
+ /:id : GET
+ / : POST
+ /:id : PUT
+ /:id : DELETE
}
class BaseRoomProvider {
+createRoom(roomid,options)
+deleteRoom(roomId)
+getRoomInfo(roomId)
+getRoomStatus(roomId)
+listRooms()
-cleanup()
-syncInstantiatedRooms()
#updateRoomInfos()
}
class DockerRoomProvider
circle Dockerode
Room - RoomRepository
BaseRoomProvider o-- RoomRepository
DockerRoomProvider --|> BaseRoomProvider
DockerRoomProvider - Dockerode
Dockerode o-- QuizRoom
RoomController o-- BaseRoomProvider
RoomRouter o-- RoomController
class QuizRoom{
+/health: GET
+create-room()
+join-room()
+next-question()
+launch-student-mode()
+end-quiz()
+submit-answers()
-disconnect()
}
@enduml
```
Remarque: Les signatures de fonctions semblent un peu partout car il y a des fonctions de classes standard, des appels HTTPS et des appels de sockets dans le même diagramme.
### Diagramme de séquence démontrant les communications
```plantuml
@startuml
actor Teacher
actor Student
entity Nginx
entity Frontend
entity Api
entity Docker
entity Database
group Quiz Creation
Teacher -> Frontend : Create a quizroom
Frontend -> Api : Create a quizroom
Api -> Docker : Create a quizroom
Docker -> QuizRoom **
QuizRoom -> Docker : creation successful
Docker -> Api : Creation Successful
loop every seconds until healthy or 30s:
Api -> QuizRoom : Checking Health via /health
QuizRoom -> Api : Doesn't answer, answer healthy or unhealthy
end
Api -> Database : Create Room
Database -> Api : Room created
Api -> Teacher : Route to room socket
end
group Quiz Joining:
Teacher -> Nginx : Join Room
Nginx -> Api : Get room infos from id
Api -> Nginx : Ip:port of room
Nginx -> QuizRoom: Give teacher's connexion
Student -> Frontend: Join Room X
Frontend -> Nginx : Join Room X
Nginx -> Api : Get room infos from id
Api -> Nginx : Ip:port of room
Nginx -> QuizRoom: Give student's connexion
QuizRoom -> QuizRoom : Give Quiz ... (Multiple actions)
Student -> QuizRoom: Disconnect
Teacher -> QuizRoom: Disconect
end
group QuizManagement (Every 10 seconds)
Api -> QuizRoom : Checking number of people in the room
QuizRoom -> Api : Number of people (0) or Unhealthy
Api -> Database : Mark room to deletion
end
group Quiz Deletion (Every 30 seconds)
Api -> Database : Give all rooms marked for deletion
Database -> Api : rooms
Api -> Docker : delete rooms
Docker -> QuizRoom : delete
Docker -> Api : Deleted
end
@enduml
```
## API
<swagger-ui src="salle-de-quiz-swagger.json"/>

View file

@ -0,0 +1,61 @@
## Prérequis
- Assurez-vous d'avoir Node JS installé en téléchargeant la dernière version depuis [https://nodejs.org/en](https://nodejs.org/en).
- Ensuite, assurez-vous d'avoir accès à un serveur MongoDB de développement
> Pour plus d'informations sur la base de données, veuillez consulter la documentation [[ici|Base-de-données]]
- Cloner le projet avec la commande suivante :
```
git clone https://github.com/ets-cfuhrman-pfe/EvalueTonSavoir.git
```
## Étape 1 - démarrage du backend
1. Naviguez vers le répertoire du projet en utilisant la commande suivante :
```
cd .\EvalueTonSavoir\server\
```
2. Assurez-vous de créer le fichier .env et d'y ajouter les paramètres appropriés. Vous pouvez vous inspirer du fichier .env.example pour connaître les paramètres nécessaires.
[[Voir ici la documentation des configurations|Configurations]]
3. Installez les dépendances avec la commande suivante :
```
npm install
```
4. Démarrez le serveur en utilisant la commande suivante :
```
npm run dev
```
5. Ouvrez votre navigateur et accédez à l'URL indiquée dans la console (par exemple, http://localhost:4400).
## Étape 2 - Démarrage du frontend
1. Naviguez vers le répertoire du projet en utilisant la commande suivante :
```
cd .\EvalueTonSavoir\client\
```
> [!WARNING]
> Assurez-vous que le backend est en cours d'exécution avant de démarrer le frontend. \
> Notez également l'URL du serveur pour le fichier `.env`.
2. Assurez-vous de créer le fichier .env et d'y ajouter les paramètres appropriés. Vous pouvez vous inspirer du fichier .env.example pour connaître les paramètres nécessaires.
[[Voir ici la documentation des configurations|Configurations]]
3. Installez les dépendances avec la commande suivante :
```
npm install
```
4. Démarrez le frontend avec la commande suivante :
```
npm run dev
```
5. Ouvrez votre navigateur et accédez à l'URL indiquée dans la console (par exemple, http://localhost:5173/).

View file

@ -0,0 +1,195 @@
## Introduction
Nous avons choisi d'exécuter les composantes de cette application avec Docker, car cela simplifie le processus de gestion des processus d'application.
Voici un diagramme de déploiement expliquant la relation des composantes et comment les images Docker sont créées et déployées dans un serveur.
```plantuml
@startuml
[Navigateur moderne (Windows/Android)] as Navigateur
[MongoDB] as MongoDB
Navigateur -> "docker-compose.yml"
[Docker] as Docker
"docker-compose.yml" -> [evaluetonSavoir-backend (Express, Javscript)]
[evaluetonSavoir-backend (Express, Javscript)] -> API_REST
[evaluetonSavoir-backend (Express, Javscript)] -> SOCKET_SALLE
[evaluetonSavoir-routeur (nginx)] as routeur
API_REST -> routeur
SOCKET_SALLE -> routeur
[evaluetonSavoir-frontend (Vue + TypeScript React)] as frontend
routeur -> frontend
[Docker hub] as DockerHub
[image-evaluetonSavoir-backend] -> DockerHub
[image-evaluetonSavoir-routeur] -> DockerHub
[image-evaluetonSavoir-frontend] -> DockerHub
[GitHub] as GitHub
"backend-deploy.yml" <- GitHub
"routeur-deploy.yml" <- GitHub
"frontend-deploy.yml" <- GitHub
Navigateur <--> evalsa.etsmtl.ca : chargée à partir des pages web
@enduml
```
## Prérequis
Les STI nous a fourni un serveur avec les spécifications suivantes :
- Ubuntu 22.04 LTS
- CPU : 4 cœurs
- RAM : 8 Go
- HDD : 100 Go
- Certificat SSL
Les STI ont déjà effectué la configuration initiale de la machine selon leurs normes de mise en place d'un serveur pour assurer la bonne maintenance et sécurité au sein de leur infrastructure. Cette configuration inclut un utilisateur non root.
Vous aurez également besoin d'un compte Docker Hub, ou vous pouvez simplement créer une PR sur le projet principal et elle sera déployée automatiquement.
## Étape 1 - Installation de Docker
Connectez-vous avec les informations d'identification de l'ETS :
```
ssh <email>@<IP>
```
Tout d'abord, mettez à jour votre liste existante de packages :
```
sudo apt update
```
Ensuite, installez quelques packages prérequis qui permettent à apt d'utiliser des packages via HTTPS :
> [!WARNING]
> Si vous voyez l'erreur suivante, ARRÊTEZ. Contactez les STI pour résoudre le problème. \
> `Waiting for cache lock: Could not get lock /var/lib/dpkg/lock-frontend. It is held by process 10703 (apt)`
```
sudo apt install apt-transport-https ca-certificates curl software-properties-common
```
Ajoutez la clé GPG du référentiel Docker officiel à votre système :
```
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
```
Ajoutez le référentiel Docker aux sources APT :
```
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
```
Mettez à jour à nouveau votre liste existante de packages pour que l'ajout soit reconnu :
```
sudo apt update
```
Assurez-vous que vous vous apprêtez à installer à partir du référentiel Docker plutôt que du référentiel Ubuntu par défaut :
```
apt-cache policy docker-ce
```
Vous verrez une sortie comme celle-ci, bien que le numéro de version pour Docker puisse être différent :
```Output
docker-ce:
Installed: (none)
Candidate: 5:26.0.0-1~ubuntu.22.04~jammy
Version table:
5:26.0.0-1~ubuntu.22.04~jammy 500
500 https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
5:25.0.5-1~ubuntu.22.04~jammy 500
500 https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
...
```
Installez Docker :
```
sudo apt install docker-ce
```
Vérifiez que Docker fonctionne :
```
sudo systemctl status docker
```
La sortie devrait être similaire à ce qui suit, montrant que le service est actif et en cours d'exécution :
```Output
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2024-04-05 13:20:12 EDT; 1min 24s ago
TriggeredBy: ● docker.socket
Docs: https://docs.docker.com
Main PID: 19389 (dockerd)
Tasks: 10
Memory: 28.7M
CPU: 172ms
CGroup: /system.slice/docker.service
└─19389 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
...
```
> [!NOTE]
> Si Docker ne roule pas, p.ex. vous voyez :
> ```
> ○ docker.service - Docker Application Container Engine
> Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
> Active: inactive (dead)
> ```
> Vous devez démarrer Docker :
> ```
> sudo systemctl start docker
> ```
## Étape 2 - Installation de Docker Compose
Créez un répertoire d'installation Docker Compose :
```
mkdir -p ~/.docker/cli-plugins/
```
Obtenez Docker Compose :
```
curl -SL https://github.com/docker/compose/releases/download/v2.26.1/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose
```
Ensuite, définissez les permissions correctes pour que la commande docker compose soit exécutable :
```
chmod +x ~/.docker/cli-plugins/docker-compose
```
Pour vérifier que l'installation a réussi, vous pouvez exécuter :
```
docker compose version
```
## Étape 3 - Ajouter notre projet
Commencez par créer un nouveau répertoire dans votre dossier personnel :
```
mkdir ~/EvalueTonSavoir
```
Puis déplacez-vous dans le répertoire :
```
cd ~/EvalueTonSavoir
```
Créez un fichier `docker-compose.yaml` à partir du dépôt GitHub :
```
curl -SL https://raw.githubusercontent.com/ets-cfuhrman-pfe/EvalueTonSavoir/main/docker-compose.yaml -o docker-compose.yaml
```
> [!NOTE]
> Avant de continuer, veuillez noter qu'il est crucial de mettre à jour les variables d'environnement dans le script, car les valeurs actuelles sont des modèles génériques. Assurez-vous de personnaliser ces variables selon les besoins spécifiques de votre environnement avant d'exécuter le script.
Avec le fichier docker-compose.yml en place, vous pouvez maintenant exécuter Docker Compose pour démarrer votre environnement :
```
sudo docker compose up -d
```
Vérifiez que les services fonctionne :
```
sudo docker ps -a
```
## Conclusion
Félicitations ! Vous avez maintenant avec succès configuré et lancé EvalueTonSavoir sur votre serveur, prêt à être utilisé.

View file

@ -0,0 +1,23 @@
# A propos
## Lancer la documentation
Pour lancer la documentation, il faut installer python et entrer dans le dossier documentation.
Il faut ensuite installer les dépendances avec `pip install -r requirements.txt`.
Pour lancer le mode développement il faut executer `python -m mkdocs serve`
Afin d'accellerer le déploiement et ne pas être touché par des érreurs de "rate-limiting", il est préférable d'utiliser une image docker de plantuml. Pour cela, il faut utiliser la commande suivante : `docker run -d --name plantuml -p 8080:8080 plantuml/plantuml-server:tomcat`
## Deploiement
Le code est automatiquement déployé par la github-action `create-docs.yaml`
Celle-ci ouvre le repo et fait les memes étapes que "lancer la documentation".
Il y a une différence, elle utilise `build` au lieu de `serve` pour ensuite publier avec l'outil [`ghp-import`](https://github.com/c-w/ghp-import).
La page est poussée sur la branche [`gh-pages`](https://github.com/ets-cfuhrman-pfe/EvalueTonSavoir/tree/gh-pages) et ensuite publié en tant que [gh-page](https://pages.github.com/)
## Themes et Plugins
Si vous ajoutez des plugins, veuillez mettre a jour le fichier `requirements.txt`.
La documentation utilise [MkDocs](https://www.mkdocs.org/) avec [le theme matérial]((https://squidfunk.github.io/mkdocs-material/)). Il y a bien des fonctionalitées tel que les code-blocks qui peuvent être activés.
Vous pouvez avoir accès a la documentation ici : [https://squidfunk.github.io/mkdocs-material/reference/code-blocks/](https://squidfunk.github.io/mkdocs-material/reference/code-blocks/)
## Autre méthode de lancement (virtuel)
Si vous avez un probleme avec votre environement et vous avez besoin d'un environement virtuel, il s'agit de faire `python -m venv .venv` dans le dossier document et d'activer cet environemment avec le fichier activate (changeant depedant de votre invite de commande) : `.venv\script\activate`
vous pouvez ensuite continuer les autres étapes.

View file

@ -0,0 +1,21 @@
## À Propos
Ce projet représente une interface utilisateur React pour notre application.
## GIFT text format render (code source)
Le code original a été développé pour créer une extension VS afin de prendre en charge le format de texte GIFT.
Le code peut être trouvé ici: [https://codesandbox.io/s/gift-templates-iny09](https://codesandbox.io/s/gift-templates-iny09)
Nous avons décidé de réutiliser ce code car il fournit un aperçu proche de ce à quoi ressemblent les quiz dans Moodle. Ce qui est une plateforme bien connue à l'École de technologie supérieure (ÉTS).
Pour réutiliser le code, nous avons dû installer les packages NPM suivants:
- [katex](https://www.npmjs.com/package/katex) : Une bibliothèque JavaScript rapide et facile à utiliser pour le rendu mathématique TeX sur le web.
- [marked](https://www.npmjs.com/package/marked) : Un analyseur syntaxique et un compilateur de markdown. Construit pour la vitesse.
- [nanoid](https://www.npmjs.com/package/nanoid) : Un générateur d'identifiants de chaîne unique, sécurisé, convivial pour les URL et minuscule (108 octets) pour JavaScript.
- [gift-pegjs](https://www.npmjs.com/package/gift-pegjs) : Un analyseur GIFT pour JavaScript utilisant PEG.js.
- [@types/katex](https://www.npmjs.com/package/@types/katex) : Définitions TypeScript pour katex.
- [@types/marked](https://www.npmjs.com/package/@types/marked) : Définitions TypeScript pour marked.
- [@types/nanoid](https://www.npmjs.com/package/@types/nanoid) : Définitions TypeScript pour nanoid.

View file

@ -0,0 +1,78 @@
# Structure haut niveau
## But du projet
ÉvalueTonSavoir a été créer dû aux gros coûts des versions entreprises des logiciels similaires tels que Socrative et Kahoot. Le bût principal est dêtre capable davoir une plateforme auto-hébergée et bien intégrée dans les systèmes déjà présents des établissements scolaire.
## Requis
Le but du projet étant un outils gratuis/libre afin d'améliorer l'apprentissage, celui-ci a les bûts suivants :
- Permettre aux personnels enseignant de créer des tests
- Permettre aux enseignant de collecter les résultats des tests
- Permettre aux étudiants de prendre ces tests
- Permettre aux étudiants d'avoir une rétroaction
Afin de limiter le niveau de difficulté d'intégration du personnel enseignant:
- L'utilisation du format [`GIFT`](https://docs.moodle.org/405/en/GIFT_format) déja présent dans moodle doit être utilisé
- Le personnel et les étudiants doivent être capable de s'authentifier avec le portail de l'école
- Le démarage du quiz doit se faire de facon rapide et éfficace.
Afin de faciliter le déploiement de masse :
- Le logiciel doit être facile a déployer sur des machines locales
- Le logiciel doit être facile a déployer sur le cloud
- Le logiciel doit s'interconnecter à l'infrastructure présente
- Le logiciel doit être performant et fiable
## Architecture actuelle
```plantuml
@startuml
package Proxy{
component Nginx
}
package App{
component Frontend
component Backend
database MongoDb
}
cloud Provider{
component QuizRoom
}
Nginx --down-> Backend
Nginx --down-> Frontend
Nginx --down-> Provider
Backend --right-> MongoDb
Backend --up-> Nginx
Frontend --up-> Nginx
@enduml
```
### Details techniques
Le tableau ci-dessus est simplifié grandement car toutes les composantes sont individuelles. Ce qui veux dire qu'une toutes les parties pouraient être déployé sur un serveur différent et tout de même fonctionner, permettant de distribuer la charge de travail facilement.
Le proxy Nginx permet de camoufler la séparation du backend et frontend en réunissant les deux parties sous la même url. Il a aussi la tache de diriger les appels de sockets vers leurs machine interne dans le provider.
Le frontend déssert la partie visuel de l'application.
Le backend s'occupe de tous les services tel quel :
- La gestion des utilisateurs
- La gestion des quizs
- La gestion des médias
- La gestion des salles
### Liens vers détails supplémentaires
- [Gestion de l'authentification](./backend/auth.md)
- [Gestion de la salle de Quiz](./backend/salle-de-quiz.md)

View file

@ -0,0 +1,23 @@
# A propos
EvalueTonSavoir est une plateforme open source et auto-hébergée qui poursuit le développement du code provenant de [https://github.com/ETS-PFE004-Plateforme-sondage-minitest](https://github.com/ETS-PFE004-Plateforme-sondage-minitest). Cette plateforme minimaliste est conçue comme un outil d'apprentissage et d'enseignement, offrant une solution simple et efficace pour la création de quiz utilisant le format GIFT, similaire à Moodle.
## Fonctionnalités clés
* Open Source et Auto-hébergé : Possédez et contrôlez vos données en déployant la plateforme sur votre propre infrastructure.
* Compatibilité GIFT : Créez des quiz facilement en utilisant le format GIFT, permettant une intégration transparente avec d'autres systèmes d'apprentissage.
* Minimaliste et Efficace : Une approche bare bones pour garantir la simplicité et la facilité d'utilisation, mettant l'accent sur l'essentiel de l'apprentissage.
## Contribution
Actuellement, il n'y a pas de modèle établi pour les contributions. Si vous constatez quelque chose de manquant ou si vous pensez qu'une amélioration est possible, n'hésitez pas à ouvrir un issue et/ou une PR)
## Liens utiles
* [Dépôt d'origine Frontend](https://github.com/ETS-PFE004-Plateforme-sondage-minitest/ETS-PFE004-EvalueTonSavoir-Frontend)
* [Dépôt d'origine Backend](https://github.com/ETS-PFE004-Plateforme-sondage-minitest/ETS-PFE004-EvalueTonSavoir-Backend)
* [Documentation (Wiki)](https://github.com/ets-cfuhrman-pfe/EvalueTonSavoir/wiki)
## License
EvalueTonSavoir is open-sourced and licensed under the [MIT License](/LICENSE).

View file

@ -0,0 +1,10 @@
document$.subscribe(({ body }) => {
renderMathInElement(body, {
delimiters: [
{ left: "$$", right: "$$", display: true },
{ left: "$", right: "$", display: false },
{ left: "\\(", right: "\\)", display: false },
{ left: "\\[", right: "\\]", display: true }
],
})
})

View file

@ -0,0 +1,25 @@
> [!NOTE]
> Chaque projet contient un fichier `.env.example` fournissant des exemples de configuration. Assurez-vous de consulter ce fichier pour vous inspirer des paramètres nécessaires à votre configuration.
> [!NOTE]
> Ce sont toutes les options de configuration. N'hésitez pas à ouvrir une PR si vous en voyez qui manquent.
## Options de Configuration Backend
| Variable d'Environnement | Description | Exemple | Optionnel |
|---|---|---|---|
| `PORT` | Le port sur lequel l'application fonctionne | 4400 | non|
| `MONGO_URI` | La chaîne de connexion pour se connecter à la base de données mongodb | `mongodb://localhost:27017` or `mongodb://127.0.0.1:27017` (the former can cause trouble on Windows depending on hosts files) | non|
| `MONGO_DATABASE` | Le nom souhaité pour la base de données | evaluetonsavoir | non|
| `EMAIL_SERVICE` | Le service utilisé pour les e-mails | gmail | non|
| `SENDER_EMAIL` | L'adresse e-mail utilisée pour l'envoi | monadresse@gmail.com | non|
| `EMAIL_PSW` | Le mot de passe de l'adresse e-mail | 'monmotdepasse' | non|
| `JWT_SECRET` | Le secret utilisé pour la gestion des JWT | monsecretJWT | non|
| `FRONTEND_URL` | URL du frontend, y compris le port | http://localhost:5173 | non|
## Options de Configuration Frontend
| Variable d'Environnement | Description | Exemple | Optionnel |
|---|---|---|---|
| `VITE_BACKEND_URL` | URL du backend, y compris le port | http://localhost:4400 | non|
| `VITE_AZURE_BACKEND_URL` | URL du backend, y compris le port | http://localhost:4400 | non|

View file

@ -0,0 +1,13 @@
# Déploiement
Les méthodes recommandées de déploiement sont via Ansible et Opentofu.
Ansible est utilisés afin de faire un déploiement sur un serveur local, opentofu sur le cloud.
## Ansible
Le déploiement avec ansible est un déploiement simplifié.
Il vous suffis d'avoir un ordinateur linux/mac ou pouvant faire exécuter [WSL2](https://learn.microsoft.com/en-us/windows/wsl/install) dans le cas de windows. Il faut ensuite utiliser le gestionnaire de paquet (souvent apt) afin d'installer le paquet `ansible-core`, d'autres méthodes sont indiquées dans la [documentation officielle de ansible](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html). Une fois le tout fais, vous pouvez telécharger [les fichiers nécéssaire](https://github.com/ets-cfuhrman-pfe/EvalueTonSavoir/ansible) et lancer la commande `ansible-playbook -i inventory.ini deploy.yml`
## OpenTofu
Le déploiement avec OpenTofu est un peu plus complexe mais il permet d'héberger la solution sur votre cloud préféré.
Il suffit [d'installer OpenTofu](https://opentofu.org/docs/intro/install/) et de téléchgarger [les fichiers nécéssaires](https://github.com/ets-cfuhrman-pfe/EvalueTonSavoir/opentofu). Un Readme est inclus afin d'organiser votre grape de serveurs.

80
documentation/mkdocs.yml Normal file
View file

@ -0,0 +1,80 @@
site_name: EvalueTonSavoir
repo_url: https://github.com/ets-cfuhrman-pfe/EvalueTonSavoir
edit_uri: edit/main/documentation/docs
theme:
language: fr
icon:
repo: fontawesome/brands/github
name: material
palette:
# Palette toggle for light mode
- media: "(prefers-color-scheme: light)"
scheme: default
primary: deep purple
accent: purple
toggle:
icon: material/brightness-7
name: Mode sombre
# Palette toggle for dark mode
- media: "(prefers-color-scheme: dark)"
scheme: slate
primary: deep purple
accent: purple
toggle:
icon: material/brightness-4
name: Mode clair
features:
- content.code.copy
- content.code.select
- content.code.annotate
- navigation.instant
- navigation.instant.progress
- navigation.tracking
- content.action.edit
highlightjs: true
hljs_languages:
- javascript
- typescript
- css
- react
- yaml
- latex
- katex
- gift
use_directory_urls: false
plugins:
- search
- offline
- plantuml:
default: https://www.plantuml.com/plantuml/ # default
puml_url: http://localhost:8080/plantuml # dev
puml_keyword: plantuml
theme:
light: material/deep-purple-light
dark: material/deep-purple-dark
- swagger-ui-tag:
docExpansion: "list"
tryItOutEnabled: false
markdown_extensions:
- pymdownx.highlight:
anchor_linenums: true
line_spans: __span
pygments_lang_class: true
- pymdownx.inlinehilite
- pymdownx.snippets
- pymdownx.superfences
- pymdownx.arithmatex:
generic: true
extra_javascript:
- javascripts/katex.js
- https://unpkg.com/katex@0/dist/katex.min.js
- https://unpkg.com/katex@0/dist/contrib/auto-render.min.js
extra_css:
- https://unpkg.com/katex@0/dist/katex.min.css

View file

@ -0,0 +1 @@
3.12

View file

@ -0,0 +1,7 @@
mkdocs
mkdocs[i18n]
mkdocs_puml
mkdocs-material
Pygments
ghp-import
mkdocs-swagger-ui-tag