mirror of
https://github.com/absmach/magistrala.git
synced 2026-06-23 04:10:28 +00:00
9c2608659f
Signed-off-by: Felix Gateru <felix.gateru@gmail.com> Signed-off-by: nyagamunene <stevenyaga2014@gmail.com> Co-authored-by: nyagamunene <stevenyaga2014@gmail.com>
127 lines
3.1 KiB
Go
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
|
|
}
|