README.md 14 KB
Newer Older
Alexis POYEN's avatar
Alexis POYEN committed
1
2
# SDK - GO

Alexis POYEN's avatar
Alexis POYEN committed
3
4
[![Quality Gate Status](https://sonarqube.forge.grandlyon.com/api/project_badges/measure?project=sdk-go&metric=alert_status)](https://sonarqube.forge.grandlyon.com/dashboard?id=sdk-go) [![Security Rating](https://sonarqube.forge.grandlyon.com/api/project_badges/measure?project=sdk-go&metric=security_rating)](https://sonarqube.forge.grandlyon.com/dashboard?id=sdk-go) [![Technical Debt](https://sonarqube.forge.grandlyon.com/api/project_badges/measure?project=sdk-go&metric=sqale_index)](https://sonarqube.forge.grandlyon.com/dashboard?id=sdk-go) [![Vulnerabilities](https://sonarqube.forge.grandlyon.com/api/project_badges/measure?project=sdk-go&metric=vulnerabilities)](https://sonarqube.forge.grandlyon.com/dashboard?id=sdk-go)

Alexis POYEN's avatar
Alexis POYEN committed
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Ce dépôt est un kit de développement en [GO](https://golang.org/) basé sur l'ORM [GORM](https://gorm.io/) qui permet facilement de créer et déployer des applications sous forme conteneurisée.

Le kit comprends une démonstration de ce qui peut être fait en simulant une application bancaire simplifiée développée en JavaScript et avec le framework CSS [Bulma](https://bulma.io/)

## Fonctionnalités

Les principales fonctionnalités :

- serveur d'API : basé sur le modèle de donnée définit dans l'ORM GORM
- serveur WEB : fournit à l'utilisateur l'application front-end (projet from scratch ou framework)
- authentification : permet à l'utilisateur de se connecter avec un compte local à l'application ou à partir d'un fournisseur d'identité OAuth2, de manière transparante
- gestion des droits : différents rôles peuvent être définit dans l'application et les API protégées par ces rôles
- gestion du cookie de session utilisateur chiffré entre le navigateur et le serveur

19
20
21
22
23
## Démarrage pour tests / dev

## Identifiants de démonstration

Trois comptes de démonstrations permettent de tester le kit avec trois profils différent : `admin` (rôle d'administrateur), `banker` (rôle de banquier), et `dupond` (rôle de client). Ces trois comptes ont pour mot de passe `password`
Alexis POYEN's avatar
Alexis POYEN committed
24
25

### Avec VS Code
26

Alexis POYEN's avatar
Alexis POYEN committed
27
28
29
30
> Il est nécessaire d'avoir un environnement de développement GO installé et opérationnel sur le poste.

Télécharger le dépot

Alexis POYEN's avatar
Alexis POYEN committed
31
```sh
32
git clone https://forge.grandlyon.com/systemes-dinformation/project-template/sdk-go.git
Alexis POYEN's avatar
Alexis POYEN committed
33
34
35
36
```

Ouvrir le dépôt avec VS Code puis dans l'onglet `Debug`, démarrer le projet avec `Debug SDK-GO with Mock OAuth2`

37
38
La démo est accessible avec l'url https://sdk-go.127.0.0.1.nip.io:1443

Alexis POYEN's avatar
Alexis POYEN committed
39
### Avec Docker
40

Alexis POYEN's avatar
Alexis POYEN committed
41
42
43
44
Installer sur le poste [Docker](https://docs.docker.com/get-docker/) et [docker-compose](https://docs.docker.com/compose/install/)

Télécharger le dépot

Alexis POYEN's avatar
Alexis POYEN committed
45
```sh
Alexis POYEN's avatar
Alexis POYEN committed
46
git clone https://forge.grandlyon.com/systemes-dinformation/project-template/sdk-go.git
Alexis POYEN's avatar
Alexis POYEN committed
47
48
49
50
51
52
53
54
55
cd sdk-go
```

Dans le fichier docker-compose.yml décommenter la ligne `command: -debug` (ATTENTION : cette ligne doit être commentée lors d'un passage en prod et ne sert que pour tester ou débuger l'application)

```sh
docker-compose up -d
```

56
57
La démo est accessible avec l'url https://sdk-go.127.0.0.1.nip.io

Alexis POYEN's avatar
Alexis POYEN committed
58
59
## Architecture

60
61
### Arborescence fichier

Alexis POYEN's avatar
Alexis POYEN committed
62
63
64
- `./data` contient les bases de données locales sqlite, users.db pour les utilisateurs et test.db pour le modèle de donnée
- `./dev-certificates` contient les fichiers nécessaires pour servir l'application en HTTPS durant le développement.
- `./internal` contient les paquets nécessaires au développement de l'application
Alexis POYEN's avatar
Alexis POYEN committed
65
66
  - `./auth` contient la gestion des utilisateurs et des droits sur l'application
  - `./mocks` permet de mocker l'API d'authentification pour passer les tests
67
  - `./models` permet de définir le modèle de données et les API qui seront servies par le back-end
Alexis POYEN's avatar
Alexis POYEN committed
68
  - `./rootmux` contient le fichier `rootmux.go` qui permet de servir les APIs, de gérer l'authentification, de servir le site web et la gestion des cookies utilisateurs. Le répertoire contient également tous les tests d'intégration sur les APIs.
Alexis POYEN's avatar
Alexis POYEN committed
69
- `./miscellaneous/keycloack` contient un environnement Keycloack qui peut être utilisé pour déployer un environnement OAuth2
70
- `./pkg` contient les différents package génériques qui permettent de gérer les logs applicatifs, de créer les fonctiones de tests, la gestion des tokens...
Alexis POYEN's avatar
Alexis POYEN committed
71
72
- `./web` est le répertoire où est stockée l'application front-end et publié par le serveur back-end.

73
### Utilisateurs et droits
Alexis POYEN's avatar
Doc V1    
Alexis POYEN committed
74
75
76
77
78
79
**Utilisateurs techniques**
Les utilisateurs techniques permettent de s'authentifier à l'application et d'accéder aux API en fonction du rôle de l'utilisateur qui définit alors ses droits.
La source de création et d'authentification des utilisateurs technique est double. Elle peut soit provenir directement de la base de donnée locale d'utilisateurs de l'application (./data/users.db) ou d'un fournisseur d'identité avec le protocole OAuth2.

Dans le cas d'une connexion avec OAuth2, l'utilisateur est crée dans la base locale d'utilisateurs avec son identifiant OAuth2 qui permet de faire le lien avec l'utilisateur technique. Dans le cas d'une connexion avec OAuth2, l'utilisateur doit obligatoirement faire parti d'un groupe applicatif autorisé (cf variable d'envrionnement ADMIN_GROUP et CLIENT_GROUP) Un rôle différent est attribué automatiquement à l'utilisateur en fonction de son groupe.

Alexis POYEN's avatar
Alexis POYEN committed
80
> ATTENTION : le rôle "ADMIN" est obligatoire dans l'application car permet de gérer les utilisateurs et leurs droits. Sans celui-ci et sans utilisateurs ayant ce rôle dans la base, il est impossible de créer de nouveaux utilisateurs !
Alexis POYEN's avatar
Doc V1    
Alexis POYEN committed
81
82
83

**Utilisateurs applicatif**
Les utilisateurs applicatifs sont facultatifs, ils permettent d'affecter des données à un utilisateur (ex : un client peut possèder un ou plusieurs comptes) Les utilisateurs applicatifs sont créé dans la base locale de données (./data/test.db) avec l'identifiant de l'utilisateur technique qui permet de faire la jointure entre un utilisateur applicatif et un utilisateur technique.
84
85
86

### Tests

Alexis POYEN's avatar
Doc V1    
Alexis POYEN committed
87
88
89
90
91
92
93
94
**Tests unitaires**
Les tests unitaires sont définis dans le répertoire de chaque paquet (ex : `auth-test.go` dans le package `auth`)

**Tests d'intégration**
Les tests d'intégration  sont dans le répertoire `./rootmux`. 
Les tests métiers (ex : mettre à jour le montant sur le compte bancaire d'un client lorsqu'il effectue une opération) sont définis dans le fichier `rootmux_test.go`.  
Les tests concernant les droits et les réponses attendues par utilisateur (ex : un banquier n'a accès qu'aux clients qui lui sont rattachés et pas aux autres) sont écrits dans des fichiers différent par type de droits différent (ex : `banker_test.go` pour tester les droits des banquiers)

Nicolas PERNOUD's avatar
Nicolas PERNOUD committed
95
## Démarrer un projet à partir du SDK
96
97
98
99
100
101
102
103
104
105

Il faut forker le dépôt SDK-GO

### Nettoyage des fichiers

Supprimer le répertoire pkg. Ceci permet d'utiliser les dépendances `pkg` du dépôt SDK-GO directement et de bénéficier des mises à jour apportée sur ces packages.

Supprimer les fichiers `admin_test.go`, `banker_test.go` et `client_test.go` qui sont spécifiques à l'application de démonstration. Toutefois ces tests peuvent être adaptés à votre application pour tester les droits d'accès en fonction des rôles des utilisateurs.

Si vous souhaitez partir de l'interface web du kit, supprimer simplement les répertoires `web/components/bankerPage` et `web/components/clientPage` qui sont spécifiques à la démo.  
Alexis POYEN's avatar
Doc V1    
Alexis POYEN committed
106
Sinon supprimer tout le contenu du répertoire `web` pour repartir de zéro, il faudra alors redévelopper l'interface de gestion des utilisateurs.
107
108
109
110
111

### Nommage de l'application

> ATTENTION : ne pas faire un chercher -> remplacer de `SDK-GO` par `<nom du projet>`, le fork du projet doit continuer d'inclure certaines dépendances vers le projet SDK-GO afin de bénéficier de ces dernières mises à jour et de toutes ces fonctionnalités.

Alexis POYEN's avatar
Alexis POYEN committed
112
Pour remplacer les mentions "SDK-GO" par le nom du projet, ces éléments sont nécéssaires :
113
114
115

- nom-du-projet : le nom donné au projet
- nom-du-dépôt : le nom du projet tel qu'il apparaît dans l'url sur la forge
Nicolas PERNOUD's avatar
Nicolas PERNOUD committed
116
- hostname-du-projet : l'url attribué au projet (dans le cadre du développement il est intéressant de garder une adresse .nip.io)
117
118
119
120
121
122
123
124

Dans le fichier `.env` modifier la variable `HOSTNAME=sdk-go.127.0.0.1.nip.io` => `HOSTNAME=<hostname-du-projet>.127.0.0.1.nip.io`

Dans le fichier `docker-compose.yml` remplacer `sdk-go-container:` par `<nom-du-projet>-container:` et `image: sdk-go` par `image : <nom-du-projet>`

Dans le fichier `main.go` remplacer

```go
Nicolas PERNOUD's avatar
Nicolas PERNOUD committed
125
126
"forge.grandlyon.com/systemes-dinformation/project-template/sdk-go/internal/mocks" => "forge.grandlyon.com/<chemin-du-dépôt>/<nom-du-dépôt>/internal/mocks"
"forge.grandlyon.com/systemes-dinformation/project-template/sdk-go/internal/rootmux" => "forge.grandlyon.com/<chemin-du-dépôt>/<nom-du-dépôt/internal/rootmux"
127
128
129
130
131
132
133
```

Dans le fichier `dev_certificates/domains.ext` remplacer `DNS.4 = sdk-go.127.0.0.1.nip.io:1443` => `DNS.4 = <hostname-du-projet>.127.0.0.1.nip.io:1443`

Dans le fichier `internal/models/models.go`, remplacer :

```go
Nicolas PERNOUD's avatar
Nicolas PERNOUD committed
134
"forge.grandlyon.com/systemes-dinformation/project-template/sdk-go/internal/auth" => "forge.grandlyon.com/<chemin-du-dépôt>/<nom-du-dépôt>/internal/auth"
135
136
137
138
139
```

Dans le fichier `internal/rootmux/rootmux_test.go` remplacer :

```go
Nicolas PERNOUD's avatar
Nicolas PERNOUD committed
140
141
"forge.grandlyon.com/systemes-dinformation/project-template/sdk-go/internal/auth" => "forge.grandlyon.com/<chemin-du-dépôt>/<nom-du-dépôt>o/internal/auth"
"forge.grandlyon.com/systemes-dinformation/project-template/sdk-go/internal/mocks" => "forge.grandlyon.com/<chemin-du-dépôt>/<nom-du-dépôt>/internal/mocks"
142
143
144
145
146
```

Dans le fichier `internal/rootmux/rootmux.go`, remplacer :

```go
Nicolas PERNOUD's avatar
Nicolas PERNOUD committed
147
148
"forge.grandlyon.com/systemes-dinformation/project-template/sdk-go/internal/auth" => "forge.grandlyon.com/<chemin-du-dépôt>/<nom-du-dépôt>/internal/auth"
"forge.grandlyon.com/systemes-dinformation/project-template/sdk-go/internal/models" => "forge.grandlyon.com/<chemin-du-dépôt>/<nom-du-dépôt>/internal/models"
149
150
```

Nicolas PERNOUD's avatar
Nicolas PERNOUD committed
151
Dans le fichier `web/index.html` remplacer `<title>SDK-GO</title>` => `<title><nom-du-projet></title>` et `https://forge.grandlyon.com/systemes-dinformation/project-template/sdk-go` => `https://forge.grandlyon.com/<chemin-du-dépôt>/<nom-du-dépot>`
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168

Dans le fichier `web/assets/brand/brand.js`, remplacer :

```javascript
export const windowTitle = "SDK-GO"; => export const windowTitle = "<nom-du-projet>";
export const navTitle = "SDK-GO"; => export const navTitle = "<nom-du-projet>";
```

Dans le fichier `web/assets/brand/manifest.js`, remplacer :

```javascript
"name": "SDK-GO" => "name": "<nom-du-projet>",,
"short_name": "SDK-GO" => "short_name": "<nom-du-projet>",,
```

### Définition du modèle

Alexis POYEN's avatar
Doc V1    
Alexis POYEN committed
169
C'est dans le fichier `models.go` que doit être définit le modèle de donnée de l'application et les réponses aux API.
Alexis POYEN's avatar
Alexis POYEN committed
170

Alexis POYEN's avatar
Alexis POYEN committed
171
172
173
174
175
176
177
178
179
> Ce qui suit sont des recommandations :

Créer un fichier par objet du modèle en suivant la structure des fichiers `bankers.go` ou `client.go`

Dans le répertoire `./rootmux` écrire les tests métiers (ex : mettre à jour le montant sur le compte bancaire d'un client lorsqu'il effectue une opération) dans le fichier `rootmux_test.go`.  
Les tests concernant les droits et les réponses attendues par utilisateur (ex : un banquier n'a accès qu'aux client qui lui sont rattachés et pas aux autres) peuvent être écrit dans des fichiers différent par type de droits différent (ex : `banker_test.go` pour tester les droits des banquiers)

### Création de rôles

Alexis POYEN's avatar
Alexis POYEN committed
180
> ATTENTION : le rôle "ADMIN" est obligatoire dans l'application car permet de gérer les utilisateurs et leurs droits. Sans celui-ci et sans utilisateurs ayant ce rôle dans la base, il est impossible de créer de nouveaux utilisateurs !
Alexis POYEN's avatar
Alexis POYEN committed
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216

En mode InMemory (utilisateurs dans la bases locales) L'API de gestion des utilisateurs suit ce format :

```json
{ "login": "UserTest", "password": "password", "role": "CLIENT" }
```

Il suffit donc de remplacer "CLIENT" par n'importe quelle valeur pour créer un nouveau rôle

> Si vous utilisez l'interface web du SDK pour la gestion des utilisateurs, pour définir les rôles possibles il faut modifier les options dans le menu `select` du fichier `./web/components/users/handleUser.js`
>
> ```html
> <select name="role" id="users-modal-role">
>   <option value="CLIENT">Client</option>
>   <option value="BANKER">Banquier</option>
>   <option value="ADMIN">Administrateur</option>
> </select>
> ```

**Rôles à partir d'OAuth2**
Pour définir des rôles automatiquement à partir d'une connexion OAuth2 et un groupe applicatif donné il faut dans la fonction `addUserInMemory` du fichier `./internal/auth/oauth2.go` rajouter la condition qui permet d'identifier le groupe applicatif de l'utilisateur et de lui donner le rôle qui correspond

```go
if userRole != "" && (userRole == os.Getenv("ADMIN_GROUP")) {
    user.Role = "ADMIN"
    user.IsAdmin = true
    break
} else if userRole != "" && (userRole == os.Getenv("CLIENT_GROUP")) {
    user.Role = "CLIENT"
    user.IsAdmin = false
    break
} else {
    return user, errors.New("user not in an app group")
}
```

Alexis POYEN's avatar
Alexis POYEN committed
217
218
219
220
221
222
223
224
225
226
227
Un utilisateur qui n'est pas dans un groupe applicatif autorisé ne pourra pas accèder à l'application

### Design

Pour modifier le design de l'application sans en altérer le code source,  récupérer le répertoire `miscellaneous/bulma` en local.

Modifier les règles SCSS pour les adapter à vos besoins. ([doc Bulma](https://bulma.io/documentation/))

Dans le répertoire `miscellaneous/bulma`  exécuter la commande `npm run build-perso` (nécessite npm d'installer sur le poste) pour construire le fichier minifié CSS prenant en compte la personnalisation. 

Placer ensuite ce fichier à côté du fichier `docker-compose.yml` et décommenter la ligne appropriée dans le fichier `docker-compose.yml` puis exécuter la commande `docker-compose up -d` pour lancer le conteneur.
Alexis POYEN's avatar
Alexis POYEN committed
228

Alexis POYEN's avatar
Alexis POYEN committed
229
230
231
232
233
234
## Contribution

Un bug découvert ? Une demande d'amélioration ? Une contribution à la dcoumentation ?

Utilisé le système d'issue pour expliquer votre découverte ou votre poposition.

Alexis POYEN's avatar
Alexis POYEN committed
235
Vous voulez contribuez directement au code ?
Alexis POYEN's avatar
Alexis POYEN committed
236

Alexis POYEN's avatar
Alexis POYEN committed
237
Créer une issue pour expliquer votre contribution, créer une branche à partir de cette issue, développer votre fonctionnalité sur la branche et faite une merge request.