You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
3.7 KiB
106 lines
3.7 KiB
// Package cashu defines interfaces for the Cashu access token system. |
|
// Implement these interfaces to integrate with your authorization backend. |
|
package cashu |
|
|
|
import ( |
|
"context" |
|
) |
|
|
|
// AuthzChecker determines if a pubkey is authorized for a given scope. |
|
// Implement this interface to integrate with your access control system. |
|
type AuthzChecker interface { |
|
// CheckAuthorization returns nil if the pubkey is authorized for the scope, |
|
// or an error describing why authorization failed. |
|
// |
|
// Parameters: |
|
// - ctx: Context for cancellation and timeouts |
|
// - pubkey: User's Nostr pubkey (32 bytes) |
|
// - scope: Token scope (e.g., "relay", "nip46", "api") |
|
// - remoteAddr: Client's remote address (for IP-based checks) |
|
// |
|
// The implementation should check if the user has sufficient permissions |
|
// for the requested scope. This is called during token issuance. |
|
CheckAuthorization(ctx context.Context, pubkey []byte, scope string, remoteAddr string) error |
|
} |
|
|
|
// ReauthorizationChecker is an optional extension of AuthzChecker that |
|
// supports re-checking authorization during token verification. |
|
// This enables "stateless revocation" - tokens become invalid immediately |
|
// when the user is removed from the access list. |
|
type ReauthorizationChecker interface { |
|
AuthzChecker |
|
|
|
// ReauthorizationEnabled returns true if authorization should be |
|
// re-checked on every token verification. |
|
ReauthorizationEnabled() bool |
|
} |
|
|
|
// ClaimValidator validates custom claims in tokens. |
|
// Implement this for application-specific claim validation. |
|
type ClaimValidator interface { |
|
// ValidateClaims validates custom claims embedded in a token. |
|
// Returns nil if claims are valid, error otherwise. |
|
ValidateClaims(claims map[string]any) error |
|
} |
|
|
|
// KindPermissionChecker validates event kind permissions. |
|
// This is typically implemented by the token itself, but can be |
|
// extended for additional validation logic. |
|
type KindPermissionChecker interface { |
|
// IsKindPermitted returns true if the given event kind is allowed. |
|
IsKindPermitted(kind int) bool |
|
|
|
// HasWritePermission returns true if any kinds are permitted. |
|
HasWritePermission() bool |
|
} |
|
|
|
// Common error types that implementations may return. |
|
type AuthzError struct { |
|
Code string |
|
Message string |
|
} |
|
|
|
func (e *AuthzError) Error() string { |
|
return e.Message |
|
} |
|
|
|
// Predefined authorization error codes. |
|
const ( |
|
ErrCodeNotAuthorized = "not_authorized" |
|
ErrCodeBanned = "banned" |
|
ErrCodeBlocked = "blocked" |
|
ErrCodeInvalidScope = "invalid_scope" |
|
ErrCodeRateLimited = "rate_limited" |
|
ErrCodeInsufficientAccess = "insufficient_access" |
|
) |
|
|
|
// NewAuthzError creates a new authorization error. |
|
func NewAuthzError(code, message string) *AuthzError { |
|
return &AuthzError{Code: code, Message: message} |
|
} |
|
|
|
// Common authorization errors. |
|
var ( |
|
ErrNotAuthorized = NewAuthzError(ErrCodeNotAuthorized, "not authorized for this scope") |
|
ErrBanned = NewAuthzError(ErrCodeBanned, "user is banned") |
|
ErrBlocked = NewAuthzError(ErrCodeBlocked, "IP address is blocked") |
|
ErrInvalidScope = NewAuthzError(ErrCodeInvalidScope, "invalid scope requested") |
|
) |
|
|
|
// AllowAllChecker is a simple implementation that allows all requests. |
|
// Useful for testing or open relays. |
|
type AllowAllChecker struct{} |
|
|
|
// CheckAuthorization always returns nil (allowed). |
|
func (AllowAllChecker) CheckAuthorization(ctx context.Context, pubkey []byte, scope string, remoteAddr string) error { |
|
return nil |
|
} |
|
|
|
// DenyAllChecker is a simple implementation that denies all requests. |
|
// Useful for testing or temporarily disabling token issuance. |
|
type DenyAllChecker struct{} |
|
|
|
// CheckAuthorization always returns ErrNotAuthorized. |
|
func (DenyAllChecker) CheckAuthorization(ctx context.Context, pubkey []byte, scope string, remoteAddr string) error { |
|
return ErrNotAuthorized |
|
}
|
|
|