279 lines
12 KiB
Markdown
279 lines
12 KiB
Markdown
# StuVe IT Tools Backend
|
|
|
|
## Übersicht
|
|
|
|
Als Backend für die StuVe IT Tools wird [Pocketbase](https://pocketbase.io)
|
|
verwendet. Pocketbase ist ein self-hosted Backend-as-a-Service, der auf SQLite basiert.
|
|
|
|
## Was ist Pocketbase?
|
|
|
|
Implementiert ist Pocketbase in Golang und kann dort auch einfach als
|
|
Library eingebunden werden und so [erweitert](https://pocketbase.io/docs/go-overview/) werden.
|
|
Dies wurde in diesem Projekt auch gemacht, um die Authentifizierung
|
|
um eine LDAP Authentifizierung zu erweitern.
|
|
|
|
Aus diesem Grund handelt es sich bei diesem Projekt nicht um
|
|
einen Fork von Pocketbase, sondern um eine Library, die Pocketbase
|
|
erweitert.
|
|
|
|
Pocketbase selbst bietet folgende Features:
|
|
|
|
- Datenbank
|
|
- Als Datenbank verwendet Pocketbase SQLite
|
|
- Authentifizierung
|
|
- Pocketbase bietet sogenannte "Auth-Collections" an, die eine
|
|
Authentifizierung über E-Mail und Passwort ermöglichen.
|
|
- Es ist allerdings möglich dieses Mechanismus zu erweitern was in
|
|
diesem Projekt auch gemacht wurde. (siehe unten)
|
|
- File Storage
|
|
- Pocketbase bietet einen File Storage an, der allerdings nur
|
|
Dateien bis 5B unterstützt.
|
|
- Achtung: Per Default sind alle Dateien öffentlich zugänglich.
|
|
- E-Mail Versand (limitiert aber in Golang erweiterbar)
|
|
- Pocketbase sendet per Default nur System E-Mails, zb Passwort
|
|
vergessen.
|
|
- Über Golang ist es allerdings möglich den E-Mailversand zu
|
|
erweitern. Dies ist in **Planung**.
|
|
- Realtime Events (Websockets)
|
|
- Pocketbase bietet einen Realtime Event Service an, der über
|
|
Websockets funktioniert. Dabei können auf alle Datenbank Events (Insert,
|
|
Update, Delete) reagiert werden.
|
|
- JavaScript SDK
|
|
- Pocketbase bietet ein JavaScript SDK an, das alle Features von
|
|
Pocketbase unterstützt.
|
|
|
|
## Admin UI
|
|
|
|
Pocketbase bietet eine Admin UI an, die unter `https://<pocketbase-url>/_/` erreichbar ist.
|
|
Der Login hierzu ist im SysPass unter *Pocketbase* zu finden.
|
|
|
|
In der Admin UI können Tabellen erstellt, bearbeitet und gelöscht werden.
|
|
Außerdem können die API Rules bearbeitet werden, die festlegen, welche
|
|
Funktionen für die einzelnen Tabellen und User erlaubt sind.
|
|
|
|
## Entwickeln
|
|
|
|
```bash
|
|
git clone https://git.stuve.uni-ulm.de/StuVe-IT/stuve-it-backend.git
|
|
cd stuve-it-backend
|
|
go run main/main.go serve # --debug=0 for no debug output
|
|
```
|
|
|
|
## Installation
|
|
|
|
Das Projekt kann mittels Docker installiert werden.
|
|
Durch die Gitlab CI/CD Pipeline wird bei jedem Push auf `main` ein neues Docker
|
|
Image erstellt. Dieses muss dann nur noch auf dem Server deployt werden.
|
|
|
|
## Projekt Struktur
|
|
|
|
Die einzelnen custom go Packages sind weiter unten beschrieben.
|
|
|
|
```
|
|
├── Dockefile # Dockerfile für die Entwicklung
|
|
├── .dockerignore # Dateien die nicht in den Docker Container kopiert werden sollen
|
|
├── .gitignore # Dateien die nicht in Git gepusht werden sollen
|
|
├── go.mod # Go Module Datei (Go's Package Manager)
|
|
├── main # Main Package (App Entry Point)
|
|
│ └── main.go # Main Funktion
|
|
├── logger # Custom Logger Package
|
|
│ └── main.go # Logger Funktionen
|
|
├── ldapSync # LDAP Sync Package
|
|
│ ├── main.go # LDAP Sync Entry Point
|
|
│ ├── db.go # Datenbank Funktionen (Insert Users, Groups, ...)
|
|
│ ├── models.go # Structs für LDAP User und Group
|
|
│ ├── tables.go # Erstellt die benötigten Tabellen in der Datenbank (Users, Groups, Logs)
|
|
│ └── ldapSync.go # Sync Funktionen (Sync Users, Groups, ...)
|
|
├── ldapLogin # LDAP Login Package
|
|
│ └── main.go # Login Funktionen (Login Route)
|
|
└── qrApi # QR API Package
|
|
└── main.go # Api Route
|
|
```
|
|
|
|
## Custom Packages
|
|
|
|
Damit Pocketbase mit der StuVe IT Tools Infrastruktur funktioniert,
|
|
wurden einige Packages erstellt, die Pocketbase erweitern.
|
|
|
|
### Logger
|
|
|
|
Das Logger Package ist ein custom Logger, der die Log-Nachrichten
|
|
farblich in die Konsole schreibt.
|
|
Diese Package ist sehr minimal gehalten und bietet nur die
|
|
Funktionen `Success`, `Info` und `Error` an.
|
|
|
|
#### Beispiel
|
|
|
|
```go
|
|
package main
|
|
|
|
import "git.stuve.uni-ulm.de/StuVe-IT/stuve-it-backend/logger"
|
|
|
|
func main() {
|
|
logger.LogInfoF("Info Message")
|
|
logger.LogErrorF("Warn Message")
|
|
logger.LogErrorF("Error Message")
|
|
}
|
|
```
|
|
|
|
### QR API
|
|
|
|
Das QR API Package ist ein einfaches Package, das eine API Route
|
|
zum Generieren von QR-Codes in SVG anbietet.
|
|
|
|
#### API Route
|
|
|
|
Das Package bietet die Route `GET /api/qr/v1` an, welche die folgenden
|
|
Parameter als json entgegennimmt:
|
|
|
|
| Parameter | Datentyp | Beschreibung |
|
|
|-------------------|-------------|------------------------------------------------------------------------------------------------|
|
|
| `data` | string | Der Text, der im QR-Code codiert werden soll (**required**) |
|
|
| `ecc` | string-enum | Der Error Correction Level des QR-Codes (`L`, `M` - default, `Q`, `H`) |
|
|
| `scale` | int | Der Scale des QR-Codes (default `1`) |
|
|
| `border` | int | Der Border des QR-Codes (default `1`), eine Border Uni ist die Größe von einem QR-Code 'pixel' |
|
|
| `color` | hex-string | Die Farbe des QR-Codes (default `#000000`) |
|
|
| `colorBackground` | hex-string | Die Hintergrundfarbe des QR-Codes (default `#FFFFFF`) |
|
|
|
|
#### Beispiel
|
|
|
|
```bash
|
|
curl -X GET https://it.stuve.uni-ulm.de/api/qr/v1 -d '{"data": "https://stuve.uni-ulm.de"}'
|
|
```
|
|
|
|
### LDAP Sync
|
|
|
|
Dieses Package ist das umfangreichste Package und synchronisiert
|
|
die LDAP Datenbank mit der Pocketbase Datenbank.
|
|
|
|
Dabei werden alle LDAP User und Gruppen in die Pocketbase Datenbank
|
|
kopiert.
|
|
|
|
Dieses Package erfordert, dass alle Gruppen und User das Attribut `objectGUID` haben. Dies ist in der Regel bei Windows
|
|
ADs der Fall.
|
|
|
|
#### LDAP Attribute
|
|
|
|
Die folgenden LDAP Attribute werden in der Pocketbase Datenbank gespeichert.
|
|
|
|
##### User
|
|
|
|
| Attribut | Pocketbase Name | Beschreibung |
|
|
|----------------|--------------------------------------------|-------------------------------------------------------------------|
|
|
| objectGUID | id | Eindeutige ID des Users (nur die ersten 15 Zeichen werden genutzt |
|
|
| givenName | givenName | Vorname des Users |
|
|
| sn | sn | Nachname des Users |
|
|
| mail | email | E-Mail des Users |
|
|
| memberOf | memberOf (in Pocketbase eine SQL Relation) | Gruppenzugehörigkeit des Users |
|
|
| accountExpires | accountExpires (in Pocketbase UTC) | Account Ablaufdatum |
|
|
| dn | dn | Distinguished Name des Users |
|
|
| cn | cn & username | Common Name des Users |
|
|
|
|
##### Group
|
|
|
|
| Attribut | Pocketbase Name | Beschreibung |
|
|
|-------------|--------------------------------------------|--------------------------------------------------------------------|
|
|
| objectGUID | id | Eindeutige ID der Gruppe (nur die ersten 15 Zeichen werden genutzt |
|
|
| cn | cn | Common Name der Gruppe |
|
|
| dn | dn | Distinguished Name der Gruppe |
|
|
| description | description | Beschreibung der Gruppe |
|
|
| memberOf | memberOf (in Pocketbase eine SQL Relation) | Gruppenzugehörigkeit der Gruppe |
|
|
|
|
#### Konfiguration
|
|
|
|
Das Package benötigt folgende ENV Variablen:
|
|
|
|
- `LDAP_URL`: LDAP Server URL (e.g. `ldap://ldap.stuve.uni-ulm.de`)
|
|
- `LDAP_BIND_DN`: LDAP Bind DN (zum Lesen der LDAP Datenbank, admin user)
|
|
- `LDAP_BIND_PASSWORD`: LDAP Bind Password (das Passwort des admin users)
|
|
- `LDAP_USER_BASE_DN`: LDAP User Base DN (hier werden alle User gesucht,
|
|
e.g. `ou=useraccounts,ou=user,dc=stuve,dc=uni-ulm,dc=de`)
|
|
- `LDAP_USER_FILTER`: LDAP User Filter (e.g. `(|(objectCategory=person)(objectClass=user))`)
|
|
- `LDAP_GROUP_BASE_DN`: LDAP Group Base DN (hier werden alle Gruppen gesucht,
|
|
e.g. `ou=groups,ou=user,dc=stuve,dc=uni-ulm,dc=de`)
|
|
- `LDAP_GROUP_FILTER`: LDAP Group Filter (e.g. `(objectClass=group)`)
|
|
- `LDAP_SUNC_SCHEDULE`: LDAP Sync Schedule (e.g. `*/1 * * * *` für minütliches Syncen)
|
|
(siehe [Cron](https://en.wikipedia.org/wiki/Cron))
|
|
|
|
#### Tabellen
|
|
|
|
Das Package erstellt folgende Tabellen in der Pocketbase Datenbank:
|
|
|
|
- `ldap_users`: Alle LDAP User ([auth-Collection](https://pocketbase.io/docs/collections/#auth-collection))
|
|
- `ldap_groups`: Alle LDAP Gruppen
|
|
- `ldap_sync_logs`: Alle LDAP Sync Logs (wann wurde was synchronisiert)
|
|
|
|
Die Tabellen werden automatisch erstellt, wenn das Programm gestartet wird und sie noch nicht existieren.
|
|
|
|
#### Sync
|
|
|
|
Das Package synchronisiert die LDAP Datenbank mit der Pocketbase Datenbank.
|
|
|
|
Dabei werden alle LDAP User und Gruppen in die Pocketbase Datenbank
|
|
kopiert. Es werden `memberOf` ldap Attribute verwendet, um die
|
|
Gruppenzugehörigkeit zu bestimmen und in SQL Relationen umzuwandeln.
|
|
|
|
Beim ersten synchronisieren kann es sein, dass eine `memberOf` Gruppe
|
|
noch nicht existiert. In diesem Fall wird die Beziehung erst beim
|
|
nächsten Sync erstellt. Falls eine `memberOf` Gruppe nicht gefunden wird,
|
|
wird dies in der Konsole geloggt.
|
|
|
|
Für jede Synchronisation wird ein Log-in der `ldap_sync_logs` Tabelle
|
|
erstellt.
|
|
|
|
Sowohl für die ldap_users als auch für die ldap_groups Tabelle wird
|
|
unter den API Rules das bearbeiten und löschen deaktiviert, da diese
|
|
Tabellen nur synchronisiert werden und nicht manuell bearbeitet werden
|
|
sollen.
|
|
Dadruch können sie nur über das LDAP Sync Package (und die Admin UI) bearbeitet werden.
|
|
|
|
#### User Sync
|
|
|
|
Damit man sich später auch als Nutzer anmelden kann, werden die
|
|
User in einer `auth` Collection gespeichert. Allerdings werden
|
|
natürlich nicht die LDAP Passwörter synchronisiert.
|
|
|
|
Aus diesem Grund muss auch jede Auth-Methode unter Options im Admin UI
|
|
für diese Collection deaktiviert werden (Username, E-Mail, OAuth2).
|
|
|
|
Mehr dazu unter dem LDAP Login Package.
|
|
|
|
#### DB Util
|
|
|
|
In der `db.go` Datei sind alle Datenbank Funktionen implementiert.
|
|
Hier gibt es Methoden um User oder Groups zu finden, die dabei automatisch
|
|
die Beziehungen zu anderen Tabellen laden (`memberOf`).
|
|
|
|
### LDAP Login
|
|
|
|
Dieses Package ist für die Authentifizierung zuständig.
|
|
Es implementiert eine LDAP Authentifizierung, die Pocketbase
|
|
um eine LDAP Authentifizierung erweitert.
|
|
|
|
#### Konfiguration
|
|
|
|
Das Package benötigt folgende ENV Variablen:
|
|
|
|
- `LDAP_URL`: LDAP Server URL (e.g. `ldap://ldap.stuve.uni-ulm.de`)
|
|
|
|
#### Mechanismus
|
|
|
|
Dieses Package für der Api die folgende Route hinzu:
|
|
|
|
`POST /api/ldap/login`
|
|
|
|
Diese Route nimmt die Parameter `username` und `password` als json Body entgegen:
|
|
|
|
```json
|
|
{
|
|
"username": "username",
|
|
"password": "password"
|
|
}
|
|
```
|
|
|
|
Das Passwort wird mit dem LDAP Server abgeglichen und nach einer
|
|
erfolgreichen Authentifizierung ein Token und das ldap_user Modell
|
|
zurückgegeben. Die `memberOf` Beziehungen werden dabei automatisch geladen.
|
|
Das Passwort wird nicht in der Datenbank gespeichert.
|
|
|
|
Diese Response ist identisch mit der standard Pocketbase Authentifizierung (z.B. AuthWithPassword). |