refactor to improve database operability in hwsauth

This commit is contained in:
2026-01-11 23:00:50 +11:00
parent ae4094d426
commit 4c5af63ea2
17 changed files with 582 additions and 96 deletions

View File

@@ -14,13 +14,30 @@ func getNil[T Model]() T {
return result
}
// Model represents an authenticated user model.
// User types must implement this interface to be used with the authenticator.
type Model interface {
ID() int
GetID() int // Returns the unique identifier for the user
}
// ContextLoader is a function type that loads a model from a context.
// Deprecated: Use CurrentModel method instead.
type ContextLoader[T Model] func(ctx context.Context) T
type LoadFunc[T Model] func(tx DBTransaction, id int) (T, error)
// LoadFunc is a function type that loads a user model from the database.
// It receives a context for cancellation, a transaction for database operations,
// and the user ID to load.
//
// Example:
//
// loadUser := func(ctx context.Context, tx *sql.Tx, id int) (User, error) {
// var user User
// err := tx.QueryRowContext(ctx,
// "SELECT id, username, email FROM users WHERE id = $1", id).
// Scan(&user.ID, &user.Username, &user.Email)
// return user, err
// }
type LoadFunc[T Model, TX DBTransaction] func(ctx context.Context, tx TX, id int) (T, error)
// Return a new context with the user added in
func setAuthenticatedModel[T Model](ctx context.Context, m authenticatedModel[T]) context.Context {
@@ -43,15 +60,26 @@ func getAuthorizedModel[T Model](ctx context.Context) (model authenticatedModel[
return model, true
}
func (auth *Authenticator[T]) CurrentModel(ctx context.Context) T {
auth.logger.Debug().Any("context", ctx).Msg("")
// CurrentModel retrieves the authenticated user from the request context.
// Returns a zero-value T if no user is authenticated or context is nil.
//
// Example:
//
// func handler(w http.ResponseWriter, r *http.Request) {
// user := auth.CurrentModel(r.Context())
// if user.ID() == 0 {
// http.Error(w, "Not authenticated", http.StatusUnauthorized)
// return
// }
// fmt.Fprintf(w, "Hello, %s!", user.Username)
// }
func (auth *Authenticator[T, TX]) CurrentModel(ctx context.Context) T {
if ctx == nil {
return getNil[T]()
}
model, ok := getAuthorizedModel[T](ctx)
if !ok {
result := getNil[T]()
auth.logger.Debug().Any("model", result).Msg("")
return result
}
return model.model