Files
Felix Gateru 9c2608659f SMQ-1672 - Revoke refresh token (#3241)
Signed-off-by: Felix Gateru <felix.gateru@gmail.com>
Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
Co-authored-by: nyagamunene <stevenyaga2014@gmail.com>
2026-03-03 15:22:28 +01:00

127 lines
3.1 KiB
Go

// Copyright (c) Abstract Machines
// SPDX-License-Identifier: Apache-2.0
package auth
import (
"context"
"errors"
"fmt"
"time"
)
// ErrKeyExpired indicates that the Key is expired.
var ErrKeyExpired = errors.New("use of expired key")
type Token struct {
AccessToken string // AccessToken contains the security credentials for a login session and identifies the client.
RefreshToken string // RefreshToken is a credential artifact that OAuth can use to get a new access token without client interaction.
AccessType string // AccessType is the specific type of access token issued. It can be Bearer, Client or Basic.
}
type KeyType uint32
const (
// AccessKey is temporary User key received on successful login.
AccessKey KeyType = iota
// RefreshKey is a temporary User key used to generate a new access key.
RefreshKey
// RecoveryKey represents a key for resseting password.
RecoveryKey
// APIKey enables the one to act on behalf of the user.
APIKey
// PersonalAccessToken represents token generated by user for automation.
PersonalAccessToken
// InvitationKey is a key for inviting new users.
InvitationKey
)
func (kt KeyType) Validate() bool {
return AccessKey <= kt && kt <= InvitationKey
}
func (kt KeyType) String() string {
switch kt {
case AccessKey:
return "access"
case RefreshKey:
return "refresh"
case RecoveryKey:
return "recovery"
case APIKey:
return "API"
case PersonalAccessToken:
return "pat"
default:
return "unknown"
}
}
type Role uint32
const (
UserRole Role = iota + 1
AdminRole
)
func (r Role) String() string {
switch r {
case UserRole:
return "user"
case AdminRole:
return "admin"
default:
return "unknown"
}
}
func (r Role) Validate() bool {
return UserRole <= r && r <= AdminRole
}
// Key represents API key.
type Key struct {
ID string `json:"id,omitempty"`
Type KeyType `json:"type,omitempty"`
Issuer string `json:"issuer,omitempty"`
Subject string `json:"subject,omitempty"` // user ID
Role Role `json:"role,omitempty"`
IssuedAt time.Time `json:"issued_at,omitempty"`
ExpiresAt time.Time `json:"expires_at,omitempty"`
Verified bool `json:"verified,omitempty"`
Description string `json:"description,omitempty"` // Optional description for refresh tokens
}
func (key Key) String() string {
return fmt.Sprintf(`{
id: %s,
type: %s,
issuer_id: %s,
subject: %s,
role: %s,
iat: %v,
eat: %v
}`, key.ID, key.Type, key.Issuer, key.Subject, key.Role, key.IssuedAt, key.ExpiresAt)
}
// Expired verifies if the key is expired.
func (key Key) Expired() bool {
if key.Type == APIKey && key.ExpiresAt.IsZero() {
return false
}
return key.ExpiresAt.UTC().Before(time.Now().UTC())
}
// KeyRepository specifies Key persistence API.
type KeyRepository interface {
// Save persists the Key. A non-nil error is returned to indicate
// operation failure
Save(ctx context.Context, key Key) (id string, err error)
// Retrieve retrieves Key by its unique identifier.
Retrieve(ctx context.Context, issuer string, id string) (key Key, err error)
// Remove removes Key with provided ID.
Remove(ctx context.Context, issuer string, id string) error
}