feat: own shared user API tokens
This commit is contained in:
50
models/api_token.go
Normal file
50
models/api_token.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
"git.golem15.com/golem15/summercms/modules/lagoon"
|
||||
)
|
||||
|
||||
// APIToken is a personal or OAuth access token owned by golem15.user. The
|
||||
// clear-text secret is returned once and never persisted.
|
||||
type APIToken struct {
|
||||
ID uint `gorm:"column:id;primaryKey"`
|
||||
UserID uint `gorm:"column:user_id"`
|
||||
Name *string `gorm:"column:name"`
|
||||
TokenHash string `gorm:"column:token_hash" json:"-"`
|
||||
Scopes lagoon.Jsonable[[]string] `gorm:"column:scopes"`
|
||||
CollectionIDs lagoon.Jsonable[[]uint] `gorm:"column:collection_ids"`
|
||||
ExpiresAt *time.Time `gorm:"column:expires_at"`
|
||||
RevokedAt *time.Time `gorm:"column:revoked_at"`
|
||||
LastUsedAt *time.Time `gorm:"column:last_used_at"`
|
||||
LastUsedIP *string `gorm:"column:last_used_ip"`
|
||||
OAuthClientID *string `gorm:"column:oauth_client_id"`
|
||||
CreatedAt time.Time `gorm:"column:created_at"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at"`
|
||||
}
|
||||
|
||||
func (APIToken) TableName() string { return "user_api_tokens" }
|
||||
|
||||
func (APIToken) Fillable() []string {
|
||||
return []string{
|
||||
"user_id", "name", "token_hash", "scopes", "collection_ids",
|
||||
"expires_at", "revoked_at", "last_used_at", "last_used_ip", "oauth_client_id",
|
||||
}
|
||||
}
|
||||
|
||||
func (APIToken) Hidden() []string { return []string{"token_hash"} }
|
||||
|
||||
// HasScope reports whether this token explicitly carries scope.
|
||||
func (t APIToken) HasScope(scope string) bool { return slices.Contains(t.Scopes.Get(), scope) }
|
||||
|
||||
// IsUsableAt is false after revocation or expiry.
|
||||
func (t APIToken) IsUsableAt(now time.Time) bool {
|
||||
return t.RevokedAt == nil && (t.ExpiresAt == nil || t.ExpiresAt.After(now))
|
||||
}
|
||||
|
||||
// IsUsable checks usability at the current time.
|
||||
func (t APIToken) IsUsable() bool { return t.IsUsableAt(time.Now()) }
|
||||
|
||||
func init() { Register(APIToken{}) }
|
||||
Reference in New Issue
Block a user