Remove name prefix in apikeys (#1167)

This commit is contained in:
Zoe Roux 2025-11-19 23:29:31 +01:00 committed by GitHub
parent a115c83cba
commit 18b2ae2c5f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 46 additions and 51 deletions

View File

@ -4,10 +4,9 @@ import (
"context"
"crypto/rand"
"encoding/base64"
"fmt"
"maps"
"net/http"
"strings"
"slices"
"time"
"github.com/golang-jwt/jwt/v5"
@ -45,7 +44,7 @@ func MapDbKey(key *dbc.Apikey) ApiKeyWToken {
CreatedAt: key.CreatedAt,
LastUsed: key.LastUsed,
},
Token: fmt.Sprintf("%s-%s", key.Name, key.Token),
Token: key.Token,
}
}
@ -75,7 +74,10 @@ func (h *Handler) CreateApiKey(c echo.Context) error {
return err
}
if _, conflict := h.config.EnvApiKeys[req.Name]; conflict {
conflict := slices.ContainsFunc(h.config.EnvApiKeys, func(k ApiKeyWToken) bool {
return k.Name == req.Name
})
if conflict {
return echo.NewHTTPError(409, "An env apikey is already defined with the same name")
}
@ -174,17 +176,15 @@ func (h *Handler) ListApiKey(c echo.Context) error {
}
func (h *Handler) createApiJwt(apikey string) (string, error) {
info := strings.SplitN(apikey, "-", 2)
if len(info) != 2 {
return "", echo.NewHTTPError(http.StatusForbidden, "Invalid api key format")
var key *ApiKeyWToken
for _, k := range h.config.EnvApiKeys {
if k.Token == apikey {
key = &k
break
}
key, fromEnv := h.config.EnvApiKeys[info[0]]
if !fromEnv {
dbKey, err := h.db.GetApiKey(context.Background(), dbc.GetApiKeyParams{
Name: info[0],
Token: info[1],
})
}
if key == nil {
dbKey, err := h.db.GetApiKey(context.Background(), apikey)
if err == pgx.ErrNoRows {
return "", echo.NewHTTPError(http.StatusForbidden, "Invalid api key")
} else if err != nil {
@ -195,7 +195,8 @@ func (h *Handler) createApiJwt(apikey string) (string, error) {
h.db.TouchApiKey(context.Background(), dbKey.Pk)
}()
key = MapDbKey(&dbKey)
found := MapDbKey(&dbKey)
key = &found
}
claims := maps.Clone(key.Claims)

View File

@ -12,6 +12,7 @@ import (
"fmt"
"maps"
"os"
"slices"
"strings"
"time"
@ -31,7 +32,7 @@ type Configuration struct {
GuestClaims jwt.MapClaims
ProtectedClaims []string
ExpirationDelay time.Duration
EnvApiKeys map[string]ApiKeyWToken
EnvApiKeys []ApiKeyWToken
}
var DefaultConfig = Configuration{
@ -39,7 +40,7 @@ var DefaultConfig = Configuration{
FirstUserClaims: make(jwt.MapClaims),
ProtectedClaims: []string{"permissions"},
ExpirationDelay: 30 * 24 * time.Hour,
EnvApiKeys: make(map[string]ApiKeyWToken),
EnvApiKeys: make([]ApiKeyWToken, 0),
}
func LoadConfiguration(db *dbc.Queries) (*Configuration, error) {
@ -137,14 +138,14 @@ func LoadConfiguration(db *dbc.Queries) (*Configuration, error) {
}
name = strings.ToLower(name)
ret.EnvApiKeys[name] = ApiKeyWToken{
ret.EnvApiKeys = append(ret.EnvApiKeys, ApiKeyWToken{
ApiKey: ApiKey{
Id: uuid.New(),
Name: name,
Claims: claims,
},
Token: v[1],
}
})
}
apikeys, err := db.ListApiKeys(context.Background())
@ -152,7 +153,10 @@ func LoadConfiguration(db *dbc.Queries) (*Configuration, error) {
return nil, err
}
for _, key := range apikeys {
if _, defined := ret.EnvApiKeys[key.Name]; defined {
dup := slices.ContainsFunc(ret.EnvApiKeys, func(k ApiKeyWToken) bool {
return k.Name == key.Name
})
if dup {
return nil, fmt.Errorf(
"an api key with the name %s is already defined in database. Can't specify a new one via env var",
key.Name,

View File

@ -76,17 +76,11 @@ select
from
keibi.apikeys
where
name = $1
and token = $2
token = $1
`
type GetApiKeyParams struct {
Name string `json:"name"`
Token string `json:"token"`
}
func (q *Queries) GetApiKey(ctx context.Context, arg GetApiKeyParams) (Apikey, error) {
row := q.db.QueryRow(ctx, getApiKey, arg.Name, arg.Token)
func (q *Queries) GetApiKey(ctx context.Context, token string) (Apikey, error) {
row := q.db.QueryRow(ctx, getApiKey, token)
var i Apikey
err := row.Scan(
&i.Pk,

View File

@ -4,8 +4,7 @@ select
from
keibi.apikeys
where
name = $1
and token = $2;
token = $1;
-- name: TouchApiKey :exec
update

View File

@ -11,7 +11,7 @@ HTTP 401
POST {{host}}/keys
# this is created from the gh workflow file's env var
X-API-KEY: hurl-1234apikey
X-API-KEY: 1234apikey
{
"name": "dryflower",
"claims": {
@ -32,7 +32,7 @@ jwt: jsonpath "$.token"
# Duplicates email
POST {{host}}/keys
X-API-KEY: hurl-1234apikey
X-API-KEY: 1234apikey
{
"name": "dryflower",
"claims": {
@ -57,5 +57,5 @@ Authorization: Bearer {{jwt}}
HTTP 403
DELETE {{host}}/keys/{{id}}
X-API-KEY: hurl-1234apikey
X-API-KEY: 1234apikey
HTTP 200

View File

@ -1,6 +1,6 @@
POST {{host}}/keys
# this is created from the gh workflow file's env var
X-API-KEY: hurl-1234apikey
X-API-KEY: 1234apikey
{
"name": "dryflower",
"claims": {
@ -32,5 +32,5 @@ jsonpath "$.items[0].claims.permissions" contains "apikeys.read"
# Clean api key
DELETE {{host}}/keys/{{id}}
X-API-KEY: hurl-1234apikey
X-API-KEY: 1234apikey
HTTP 200

View File

@ -62,13 +62,11 @@ spec:
value: "http://{{ include "kyoo.auth.fullname" . }}:4568/.well-known/jwks.json"
- name: JWT_ISSUER
value: {{ .Values.kyoo.address | quote }}
- name: HELPERVAR_APIKEY
- name: KYOO_APIKEY
valueFrom:
secretKeyRef:
key: {{ .Values.kyoo.auth.apikeys.scanner.apikeyKey }}
name: {{ .Values.kyoo.auth.apikeys.scanner.existingSecret }}
- name: KYOO_APIKEY
value: "scanner-$(HELPERVAR_APIKEY)"
- name: THEMOVIEDB_API_ACCESS_TOKEN
valueFrom:
secretKeyRef:

View File

@ -115,7 +115,6 @@ kyoo:
extra: []
# - name: example
# existingSecret: bigsecret
## value of the apieky should be $name-$apikey
# apikeyKey: example_apikey
# claims: '{"permissions": ["core.read"]}'

View File

@ -121,7 +121,7 @@ services:
# Use this env var once we use mTLS for auth
# - KYOO_URL=${KYOO_URL:-http://api:3567/api}
- KYOO_URL=${KYOO_URL:-http://traefik:8901/api}
- KYOO_APIKEY=scanner-$KEIBI_APIKEY_SCANNER
- KYOO_APIKEY=$KEIBI_APIKEY_SCANNER
- JWKS_URL=http://auth:4568/.well-known/jwks.json
- JWT_ISSUER=${PUBLIC_URL}
volumes:

View File

@ -78,7 +78,7 @@ services:
# Use this env var once we use mTLS for auth
# - KYOO_URL=${KYOO_URL:-http://api:3567/api}
- KYOO_URL=${KYOO_URL:-http://traefik:8901/api}
- KYOO_APIKEY=scanner-$KEIBI_APIKEY_SCANNER
- KYOO_APIKEY=$KEIBI_APIKEY_SCANNER
- JWKS_URL=http://auth:4568/.well-known/jwks.json
- JWT_ISSUER=${PUBLIC_URL}
volumes:

View File

@ -11,7 +11,7 @@ LIBRARY_IGNORE_PATTERN=".*/[dD]ownloads?/.*"
THEMOVIEDB_API_ACCESS_TOKEN=""
KYOO_URL="http://api:3567/api"
KYOO_APIKEY=scanner-$KEIBI_APIKEY_SCANNER
KYOO_APIKEY=$KEIBI_APIKEY_SCANNER
JWKS_URL="http://auth:4568/.well-known/jwks.json"
JWT_ISSUER=$PUBLIC_URL