Prefix replacement of the old application-nested module path in go.mod and every import. No identifier, string, table, migration ID, config key or comment changes.
76 lines
2.1 KiB
Go
76 lines
2.1 KiB
Go
package classes
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"git.golem15.com/golem15/sm-user-plugin/models"
|
|
"git.golem15.com/golem15/summercms/modules/backpack"
|
|
"git.golem15.com/golem15/summercms/modules/bouncer"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
var _ bouncer.UserProvider = GormUsers{}
|
|
|
|
// GormUsers loads JWT principals from the users table.
|
|
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 models.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
|
|
}
|
|
principal := &bouncer.Principal{ID: row.ID, MustChangePassword: row.MustChangePassword}
|
|
if row.PreferredLocale != nil {
|
|
principal.PreferredLocale = *row.PreferredLocale
|
|
}
|
|
if row.TokensValidAfter != nil {
|
|
principal.TokensValidAfter = *row.TokensValidAfter
|
|
}
|
|
return principal, nil
|
|
}
|
|
|
|
// LookupByEmail returns the user row, including a soft-deleted one.
|
|
// A missing email is (nil, nil).
|
|
func LookupByEmail(ctx context.Context, db *gorm.DB, email string) (*models.User, error) {
|
|
if db == nil {
|
|
return nil, fmt.Errorf("golem15.user: gorm handle is missing")
|
|
}
|
|
var row models.User
|
|
err := db.WithContext(ctx).Unscoped().Where("email = ?", email).Take(&row).Error
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return nil, nil
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &row, nil
|
|
}
|
|
|
|
// JWTSecret reads golem15.user.jwt.secret and fails loudly when it is empty.
|
|
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
|
|
}
|