Files
sm-user-plugin/classes/authorizer.go
Jakub Zych c0770294a5 feat(19-04): user authorizer, user.Deleting and handle backfill
Register lighthouse user:{id} if the namespace is free, fire user.Deleting before unscoped delete, and backfill missing handles.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-17 21:53:21 +02:00

50 lines
1.5 KiB
Go

package classes
import (
"context"
"log/slog"
"strings"
"git.golem15.com/golem15/summercms/modules/backpack"
"git.golem15.com/golem15/summercms/modules/lighthouse"
)
// AuthorizeUser is the lighthouse authorizer for the user namespace
// (D-17, T-19-10). It allows only user:{id} for that user. ChannelID is
// the two-segment reader (segment 1 is the id). A second presence: prefix
// or extra segments are denied.
func AuthorizeUser() lighthouse.AuthorizerFunc {
return func(_ context.Context, userID uint, channel string) lighthouse.Result {
name := strings.TrimPrefix(channel, "presence:")
if strings.HasPrefix(name, "presence:") {
return lighthouse.Denied("invalid user channel")
}
parts := strings.Split(name, ":")
if len(parts) != 2 || parts[0] != "user" {
return lighthouse.Denied("invalid user channel")
}
if userID == 0 || lighthouse.ChannelID(name) != int64(userID) {
return lighthouse.Denied("not that user")
}
return lighthouse.Allowed(nil)
}
}
// RegisterUserAuthorizer registers the user namespace if it is free. A
// missing lighthouse service is skipped so Boot stays additive on hosts
// that never mount realtime.
func RegisterUserAuthorizer(app *backpack.App) error {
svc, err := lighthouse.From(app)
if err != nil {
slog.Default().Warn("golem15.user: lighthouse unavailable; user authorizer not registered", "err", err)
return nil
}
if svc == nil || svc.Registry() == nil {
return nil
}
if _, ok := svc.Registry().Get("user"); ok {
return nil
}
return svc.Registry().Register("user", AuthorizeUser())
}