package user import ( "context" "errors" "fmt" "strings" "git.golem15.com/golem15/summercms/backpack" "git.golem15.com/golem15/summercms/bouncer" "gorm.io/gorm" ) // User is the minimal users row the JWT guard loads. type User struct { ID uint `gorm:"column:id;primaryKey"` Email string `gorm:"column:email"` Password string `gorm:"column:password"` MustChangePassword bool `gorm:"column:must_change_password"` } func (User) TableName() string { return "users" } type gormUsers struct { app *backpack.App } func (g gormUsers) FindByID(ctx context.Context, id uint) (*bouncer.Principal, error) { if g.app == nil { return nil, fmt.Errorf("golem15.user: app is nil") } gdb, ok := g.app.Lookup[*gorm.DB]() if !ok || gdb == nil { return nil, fmt.Errorf("golem15.user: gorm handle is missing") } var row User err := gdb.WithContext(ctx).Where("id = ?", id).Take(&row).Error if errors.Is(err, gorm.ErrRecordNotFound) { return nil, nil } if err != nil { return nil, err } return &bouncer.Principal{ID: row.ID, MustChangePassword: row.MustChangePassword}, nil } func jwtSecret(app *backpack.App) (string, error) { if app == nil || app.Config == nil { return "", fmt.Errorf("golem15.user: jwt.secret is empty (set SUMMER_GOLEM15__USER__JWT__SECRET)") } secret := strings.TrimSpace(app.Config.String("golem15.user.jwt.secret")) if secret == "" { return "", fmt.Errorf("golem15.user: jwt.secret is empty (set SUMMER_GOLEM15__USER__JWT__SECRET)") } return secret, nil }