2023-10-26 20:34:59 +00:00
|
|
|
# StuVe IT Tools Backend
|
|
|
|
|
|
|
|
## Übersicht
|
|
|
|
|
|
|
|
Als Backend für die StuVe IT Tools wird [Pocketbase](https://pocketbase.io)
|
2024-03-27 14:36:45 +00:00
|
|
|
verwendet. Pocketbase ist ein self-hosted Backend-as-a-Service, der auf SQLite basiert.
|
2023-10-26 20:34:59 +00:00
|
|
|
|
|
|
|
## 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.
|
|
|
|
|
2023-11-20 15:32:32 +00:00
|
|
|
## 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.
|
|
|
|
|
2023-10-26 20:34:59 +00:00
|
|
|
## Entwickeln
|
|
|
|
|
2023-11-20 15:32:32 +00:00
|
|
|
```bash
|
2024-03-27 15:00:59 +00:00
|
|
|
git clone https://git.stuve.uni-ulm.de/stuve-it/stuve-it-backend.git
|
2024-03-27 14:36:45 +00:00
|
|
|
cd stuve-it-backend
|
|
|
|
go run main/main.go serve # --debug=0 for no debug output
|
2023-11-20 15:32:32 +00:00
|
|
|
```
|
2023-10-26 20:34:59 +00:00
|
|
|
|
|
|
|
## Installation
|
|
|
|
|
2023-11-20 15:32:32 +00:00
|
|
|
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.
|
2023-10-26 20:34:59 +00:00
|
|
|
|
|
|
|
## 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, ...)
|
2024-03-27 16:57:58 +00:00
|
|
|
├── ldapApi # LDAP API Package
|
|
|
|
│ └── main.go # Api Route
|
2024-03-27 14:36:45 +00:00
|
|
|
└── qrApi # QR API Package
|
|
|
|
└── main.go # Api Route
|
2023-10-26 20:34:59 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
## 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
|
2024-03-27 14:36:45 +00:00
|
|
|
Funktionen `Success`, `Info` und `Error` an.
|
|
|
|
|
|
|
|
#### Beispiel
|
|
|
|
|
|
|
|
```go
|
|
|
|
package main
|
|
|
|
|
2024-03-27 15:00:59 +00:00
|
|
|
import "git.stuve.uni-ulm.de/stuve-it/stuve-it-backend/logger"
|
2024-03-27 14:36:45 +00:00
|
|
|
|
|
|
|
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
|
2024-03-27 18:43:54 +00:00
|
|
|
Parameter als query string entgegennimmt:
|
2024-03-27 14:36:45 +00:00
|
|
|
|
|
|
|
| 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
|
2024-03-27 18:43:54 +00:00
|
|
|
curl -X GET https://it.stuve.uni-ulm.de/api/qr/v1?data=stuve.uni-ulm.de
|
2024-03-27 14:36:45 +00:00
|
|
|
```
|
2023-10-26 20:34:59 +00:00
|
|
|
|
2024-03-27 16:57:58 +00:00
|
|
|
### LDAP API
|
|
|
|
|
|
|
|
Im LDAP API Package sind zwei API Routen implementiert:
|
|
|
|
|
|
|
|
- LDAP Login: `POST /api/ldap/login`
|
|
|
|
- LDAP Search: `GET /api/ldap/search`
|
|
|
|
|
|
|
|
#### LDAP Login
|
|
|
|
|
|
|
|
Dieses Package implementiert eine LDAP Authentifizierung, die Pocketbase um eine LDAP Authentifizierung erweitert.
|
|
|
|
|
|
|
|
Das Package bietet die Route `POST /api/ldap/login` an, welche die folgenden
|
|
|
|
Parameter als json entgegennimmt:
|
|
|
|
|
|
|
|
| Parameter | Datentyp | Beschreibung |
|
|
|
|
|------------|----------|-------------------------------------------------------|
|
|
|
|
| `username` | string | Der Benutzername des LDAP Users (`cn`) (**required**) |
|
|
|
|
| `password` | string | Das Passwort des LDAP Users (**required**) |
|
|
|
|
|
|
|
|
##### Konfiguration
|
|
|
|
|
|
|
|
Das Package benötigt folgende ENV Variablen:
|
|
|
|
|
|
|
|
- `LDAP_URL`: LDAP Server URL (e.g. `ldap://ldap.stuve.uni-ulm.de`)
|
|
|
|
|
|
|
|
##### Mechanismus
|
|
|
|
|
|
|
|
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).
|
|
|
|
|
|
|
|
##### Beispiel
|
|
|
|
|
|
|
|
```bash
|
|
|
|
curl -X POST https://it.stuve.uni-ulm.de/api/ldap/login -d '{"username": "vorname.nachname", "password": "*******"}'
|
|
|
|
```
|
|
|
|
|
|
|
|
#### LDAP Search
|
|
|
|
|
|
|
|
Dieses Package implementiert eine LDAP Suche, die Pocketbase um eine LDAP Suche erweitert.
|
|
|
|
Damit kann per HTTP Request die LDAP Datenbank durchsucht werden.
|
|
|
|
|
|
|
|
Das Package bietet die Route `GET /api/ldap/search` an, welche die folgenden
|
|
|
|
Parameter als json entgegennimmt:
|
|
|
|
|
|
|
|
| Parameter | Datentyp | Beschreibung |
|
|
|
|
|--------------|----------|-------------------------------------------------------------------------------------------------------------|
|
|
|
|
| `baseDN` | string | Die Base DN, in der gesucht werden soll (**required**) |
|
|
|
|
| `filter` | string | Der Filter, nach dem gesucht werden soll (**required**) |
|
|
|
|
| `attributes` | []string | Die Attribute, die zurückgegeben werden sollen, bei einem leeren Array werden alle Attribute zurückgegeben. |
|
|
|
|
|
|
|
|
##### 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_ADMIN_GROUP_DN`: LDAP Admin Group DN (Gruppe, die Admin Rechte hat)
|
|
|
|
|
|
|
|
##### Mechanismus
|
|
|
|
|
|
|
|
Die Route führt eine LDAP Suche durch und gibt die gefundenen LDAP
|
|
|
|
Objekte zurück. Dabei wird die Suche mit dem `LDAP_BIND_DN` durchgeführt.
|
|
|
|
|
|
|
|
Es wird überprüft, ob der User der das GET Request schickt in der `LDAP_ADMIN_GROUP_DN` Gruppe ist.
|
|
|
|
|
|
|
|
##### Beispiel
|
|
|
|
|
|
|
|
```bash
|
|
|
|
curl -X GET https://it.stuve.uni-ulm.de/api/ldap/search -d '{"baseDN": "ou=useraccounts,ou=user,dc=stuve,dc=uni-ulm,dc=de", "filter": "(cn=vorname.nachname)"}'
|
|
|
|
```
|
|
|
|
|
2024-03-27 17:18:43 +00:00
|
|
|
Als return wir ein JSON Objekt nach folgendem Schema zurückgegeben:
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
|
|
|
"Entries": [
|
|
|
|
{
|
|
|
|
"DN": "CN=vorname.nachname,OU=UserAccounts,OU=User,DC=stuve,DC=uni-ulm,DC=de",
|
|
|
|
"Attributes": [
|
|
|
|
{
|
|
|
|
"Name": "cn",
|
|
|
|
"Values": [
|
|
|
|
"vorname.nachname"
|
|
|
|
],
|
|
|
|
"ByteValues": [
|
|
|
|
"xxxxxxxxxxxxxxx"
|
|
|
|
]
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"Referrals": [],
|
|
|
|
"Controls": []
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
Json Schemata:
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
|
|
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
|
|
"type": "object",
|
|
|
|
"properties": {
|
|
|
|
"Entries": {
|
|
|
|
"type": "array",
|
|
|
|
"items": {
|
|
|
|
"type": "object",
|
|
|
|
"properties": {
|
|
|
|
"DN": {
|
|
|
|
"type": "string"
|
|
|
|
},
|
|
|
|
"Attributes": {
|
|
|
|
"type": "array",
|
|
|
|
"items": {
|
|
|
|
"type": "object",
|
|
|
|
"properties": {
|
|
|
|
"Name": {
|
|
|
|
"type": "string"
|
|
|
|
},
|
|
|
|
"Values": {
|
|
|
|
"type": "array",
|
|
|
|
"items": {
|
|
|
|
"type": "string"
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"ByteValues": {
|
|
|
|
"type": "array",
|
|
|
|
"items": {
|
|
|
|
"type": "string"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"required": ["Name", "Values", "ByteValues"]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"required": ["DN", "Attributes"]
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"Referrals": {
|
|
|
|
"type": "array",
|
|
|
|
"items": {}
|
|
|
|
},
|
|
|
|
"Controls": {
|
|
|
|
"type": "array",
|
|
|
|
"items": {}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"required": ["Entries", "Referrals", "Controls"]
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2023-10-26 20:34:59 +00:00
|
|
|
### 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.
|
|
|
|
|
2024-03-27 14:36:45 +00:00
|
|
|
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 |
|
|
|
|
|
2023-10-26 20:34:59 +00:00
|
|
|
#### 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))`)
|
2024-03-27 16:57:58 +00:00
|
|
|
- `LDAP_ADMIN_GROUP_DN`: LDAP Admin Group DN (Gruppe, die Admin Rechte hat)
|
2023-10-26 20:34:59 +00:00
|
|
|
- `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.
|
|
|
|
|
2024-03-27 14:36:45 +00:00
|
|
|
Für jede Synchronisation wird ein Log-in der `ldap_sync_logs` Tabelle
|
2023-10-26 20:34:59 +00:00
|
|
|
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.
|
|
|
|
|
2023-11-20 15:32:32 +00:00
|
|
|
#### 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
|
2024-03-27 16:57:58 +00:00
|
|
|
die Beziehungen zu anderen Tabellen laden (`memberOf`).
|