122 lines
3.7 KiB
Go
122 lines
3.7 KiB
Go
package db
|
|
|
|
import "database/sql"
|
|
import "time"
|
|
|
|
import "codit/internal/models"
|
|
import "codit/internal/util"
|
|
|
|
func (s *Store) CreatePrincipalAPIKey(principalID string, name string, tokenHash string, prefix string, expiresAt int64) (models.PrincipalAPIKey, error) {
|
|
var key models.PrincipalAPIKey
|
|
var err error
|
|
var now time.Time
|
|
var nowUnix int64
|
|
var id string
|
|
|
|
id, err = util.NewID()
|
|
if err != nil {
|
|
return key, err
|
|
}
|
|
now = time.Now().UTC()
|
|
nowUnix = now.Unix()
|
|
key = models.PrincipalAPIKey{
|
|
ID: id,
|
|
PrincipalID: principalID,
|
|
Name: name,
|
|
Prefix: prefix,
|
|
CreatedAt: nowUnix,
|
|
LastUsedAt: 0,
|
|
ExpiresAt: expiresAt,
|
|
Disabled: false,
|
|
}
|
|
_, err = s.Exec(`INSERT INTO principal_api_keys (public_id, principal_id, name, token_hash, token_prefix, created_at, last_used_at, expires_at, disabled)
|
|
VALUES (?, (SELECT id FROM service_principals WHERE public_id = ?), ?, ?, ?, ?, ?, ?, ?)`,
|
|
key.ID, key.PrincipalID, key.Name, tokenHash, key.Prefix, key.CreatedAt, key.LastUsedAt, key.ExpiresAt, key.Disabled)
|
|
return key, err
|
|
}
|
|
|
|
func (s *Store) ListPrincipalAPIKeys(principalID string) ([]models.PrincipalAPIKey, error) {
|
|
var rows *sql.Rows
|
|
var err error
|
|
var keys []models.PrincipalAPIKey
|
|
var key models.PrincipalAPIKey
|
|
|
|
rows, err = s.Query(`SELECT k.public_id, p.public_id, k.name, k.token_prefix, k.created_at, k.last_used_at, k.expires_at, k.disabled
|
|
FROM principal_api_keys k
|
|
JOIN service_principals p ON p.id = k.principal_id
|
|
WHERE p.public_id = ?
|
|
ORDER BY k.created_at DESC`, principalID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
for rows.Next() {
|
|
err = rows.Scan(&key.ID, &key.PrincipalID, &key.Name, &key.Prefix, &key.CreatedAt, &key.LastUsedAt, &key.ExpiresAt, &key.Disabled)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
keys = append(keys, key)
|
|
}
|
|
return keys, rows.Err()
|
|
}
|
|
|
|
func (s *Store) DeletePrincipalAPIKey(principalID string, id string) error {
|
|
var err error
|
|
|
|
_, err = s.Exec(`DELETE FROM principal_api_keys WHERE public_id = ? AND principal_id = (SELECT id FROM service_principals WHERE public_id = ?)`, id, principalID)
|
|
return err
|
|
}
|
|
|
|
func (s *Store) SetPrincipalAPIKeyDisabled(principalID string, id string, disabled bool) error {
|
|
var err error
|
|
|
|
_, err = s.Exec(`UPDATE principal_api_keys SET disabled = ? WHERE public_id = ? AND principal_id = (SELECT id FROM service_principals WHERE public_id = ?)`, disabled, id, principalID)
|
|
return err
|
|
}
|
|
|
|
func (s *Store) GetPrincipalByAPIKeyHash(tokenHash string) (models.ServicePrincipal, error) {
|
|
var principal models.ServicePrincipal
|
|
var tx *sql.Tx
|
|
var owned bool
|
|
var row *sql.Row
|
|
var keyID int64
|
|
var now time.Time
|
|
var nowUnix int64
|
|
var currentUnix int64
|
|
var err error
|
|
|
|
tx, owned, err = s.begin()
|
|
if err != nil {
|
|
return principal, err
|
|
}
|
|
now = time.Now().UTC()
|
|
currentUnix = now.Unix()
|
|
row = tx.QueryRow(`
|
|
SELECT p.public_id, p.name, p.description, p.is_admin, p.disabled, p.created_at, p.updated_at, k.id
|
|
FROM principal_api_keys k
|
|
JOIN service_principals p ON p.id = k.principal_id
|
|
WHERE k.token_hash = ?
|
|
AND p.disabled = 0
|
|
AND k.disabled = 0
|
|
AND (k.expires_at = 0 OR k.expires_at > ?)
|
|
LIMIT 1
|
|
`, tokenHash, currentUnix)
|
|
err = row.Scan(&principal.ID, &principal.Name, &principal.Description, &principal.IsAdmin, &principal.Disabled, &principal.CreatedAt, &principal.UpdatedAt, &keyID)
|
|
if err != nil {
|
|
rollbackIfOwned(tx, owned)
|
|
return principal, err
|
|
}
|
|
now = time.Now().UTC()
|
|
nowUnix = now.Unix()
|
|
_, err = tx.Exec(`UPDATE principal_api_keys SET last_used_at = ? WHERE id = ?`, nowUnix, keyID)
|
|
if err != nil {
|
|
rollbackIfOwned(tx, owned)
|
|
return principal, err
|
|
}
|
|
err = commitIfOwned(tx, owned)
|
|
if err != nil {
|
|
return principal, err
|
|
}
|
|
return principal, nil
|
|
}
|