mirror of
https://github.com/jsiebens/ionscale.git
synced 2026-03-31 15:07:49 +01:00
5ad89ff02f
Signed-off-by: Johan Siebens <johan.siebens@gmail.com>
110 lines
2.3 KiB
Go
110 lines
2.3 KiB
Go
package domain
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"github.com/jsiebens/ionscale/internal/util"
|
|
"golang.org/x/crypto/bcrypt"
|
|
"gorm.io/gorm"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
func CreateAuthKey(tailnet *Tailnet, user *User, ephemeral bool, tags Tags, expiresAt *time.Time) (string, *AuthKey) {
|
|
key := util.RandStringBytes(12)
|
|
pwd := util.RandStringBytes(22)
|
|
value := fmt.Sprintf("%s_%s", key, pwd)
|
|
|
|
hash, err := bcrypt.GenerateFromPassword([]byte(pwd), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return value, &AuthKey{
|
|
ID: util.NextID(),
|
|
Key: key,
|
|
Hash: string(hash),
|
|
Ephemeral: ephemeral,
|
|
Tags: tags,
|
|
CreatedAt: time.Now().UTC(),
|
|
ExpiresAt: expiresAt,
|
|
|
|
TailnetID: tailnet.ID,
|
|
UserID: user.ID,
|
|
}
|
|
}
|
|
|
|
type AuthKey struct {
|
|
ID uint64 `gorm:"primary_key;autoIncrement:false"`
|
|
Key string `gorm:"type:varchar(64);unique_index"`
|
|
Hash string
|
|
Ephemeral bool
|
|
Tags Tags
|
|
|
|
CreatedAt time.Time
|
|
ExpiresAt *time.Time
|
|
|
|
TailnetID uint64
|
|
Tailnet Tailnet
|
|
|
|
UserID uint64
|
|
User User
|
|
}
|
|
|
|
func (r *repository) SaveAuthKey(ctx context.Context, key *AuthKey) error {
|
|
tx := r.withContext(ctx).Save(key)
|
|
|
|
if tx.Error != nil {
|
|
return tx.Error
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (r *repository) DeleteAuthKey(ctx context.Context, id uint64) (bool, error) {
|
|
tx := r.withContext(ctx).Delete(&AuthKey{}, id)
|
|
return tx.RowsAffected == 1, tx.Error
|
|
}
|
|
|
|
func (r *repository) ListAuthKeys(ctx context.Context, tailnetID uint64) ([]AuthKey, error) {
|
|
var authKeys = []AuthKey{}
|
|
tx := (r.withContext(ctx).
|
|
Preload("User").
|
|
Preload("Tailnet")).
|
|
Where("tailnet_id = ?", tailnetID).
|
|
Find(&authKeys)
|
|
if tx.Error != nil {
|
|
return nil, tx.Error
|
|
}
|
|
return authKeys, nil
|
|
}
|
|
|
|
func (r *repository) LoadAuthKey(ctx context.Context, key string) (*AuthKey, error) {
|
|
split := strings.Split(key, "_")
|
|
if len(split) != 2 {
|
|
return nil, nil
|
|
}
|
|
|
|
var m AuthKey
|
|
tx := r.withContext(ctx).Preload("User").Preload("Tailnet").First(&m, "key = ?", split[0])
|
|
|
|
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
|
|
return nil, nil
|
|
}
|
|
|
|
if tx.Error != nil {
|
|
return nil, tx.Error
|
|
}
|
|
|
|
if err := bcrypt.CompareHashAndPassword([]byte(m.Hash), []byte(split[1])); err != nil {
|
|
return nil, nil
|
|
}
|
|
|
|
if !m.ExpiresAt.IsZero() && m.ExpiresAt.Before(time.Now()) {
|
|
return nil, nil
|
|
}
|
|
|
|
return &m, nil
|
|
}
|