summaryrefslogtreecommitdiff
path: root/internal/db/data_validation.go
blob: 1883dc01feba66f95319c4a2a53e1e995932b5e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package db

import (
	"context"
	"database/sql"
	"log/slog"
)

const (
	PublicUserSignupKey = "ACCEPT_PUBLIC_USERS"
	EnforceHttpsKey     = "ENFORCE_HTTPS"
	MaxUsersKey         = "MAX_USERS"
)

var settingValidations = [...]struct {
	key        string // key to look for in the settings
	defaultVal string // Default value to init if not set
}{
	{ // Only admins can create users when false
		PublicUserSignupKey,
		"FALSE",
	},
	{ // If something like traefik manages https, this can be set to
		// false. But there MUST be https in your stack otherwise
		// credentials are sent in the clear
		EnforceHttpsKey,
		"TRUE",
	},
	{ // Safeguard to avoid account creation spamming.
		// An admin can still create users over the limit
		MaxUsersKey,
		"25",
	},
}

func ValidateSettings(ctx context.Context, db *sql.DB) error {
	valTx, err := db.PrepareContext(ctx, "SELECT value FROM Settings WHERE key=?")
	if err != nil {
		return err
	}
	defer valTx.Close()

	newTx, err := db.PrepareContext(ctx, "INSERT INTO Settings (key, value) VALUES (?, ?)")
	if err != nil {
		return err
	}
	defer newTx.Close()

	for _, s := range settingValidations {
		var val string
		err := valTx.QueryRowContext(ctx, s.key).Scan(&val)
		if err != nil {
			return err
		}
		if val == "" {
			slog.WarnContext(ctx, "Missing configuration, setting the default",
				"setting", s.key,
				"value", s.defaultVal,
			)
			_, err := newTx.ExecContext(ctx, s.key, s.defaultVal)
			if err != nil {
				return err
			}
		}
	}
	return nil
}