Files
volumen/internal/tokens/tokens_test.go
T
petrbalvin f8ed33df83
Test / test (push) Successful in 7m5s
Release / gates (push) Successful in 7m28s
Release / build (amd64, freebsd) (push) Successful in 2m52s
Release / build (amd64, linux) (push) Successful in 2m46s
Release / build (arm64, freebsd) (push) Successful in 2m22s
Release / build (arm64, linux) (push) Successful in 2m38s
Release / build (loong64, linux) (push) Successful in 2m7s
Release / build (riscv64, linux) (push) Successful in 2m17s
Release / release (push) Successful in 1m0s
Initial commit
Assisted-by: GLM 5.3
2026-09-29 10:03:32 +02:00

167 lines
4.2 KiB
Go

// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
package tokens
import (
"errors"
"os"
"path/filepath"
"strings"
"testing"
)
func TestCreateAndAuthenticate(t *testing.T) {
path := filepath.Join(t.TempDir(), "tokens.toml")
s := New(path)
record, raw, err := s.Create("ci", nil)
if err != nil {
t.Fatalf("Create: %v", err)
}
if record == nil || raw == "" {
t.Fatal("Create failed")
}
if !strings.HasPrefix(raw, TokenPrefix) {
t.Fatalf("raw = %q", raw)
}
if record.TokenHash == raw {
t.Fatal("raw token persisted")
}
found := s.Authenticate(raw)
if found == nil || found.Name != "ci" {
t.Fatalf("Authenticate = %v", found)
}
if !found.HasScope("write") {
t.Fatal("unrestricted token should grant every scope")
}
if s.Authenticate("vol_wrong") != nil {
t.Fatal("wrong token authenticated")
}
if s.Authenticate("not-our-prefix") != nil {
t.Fatal("foreign prefix authenticated")
}
info, err := os.Stat(path)
if err != nil {
t.Fatalf("stat: %v", err)
}
if info.Mode().Perm() != 0o600 {
t.Fatalf("mode = %v", info.Mode().Perm())
}
rawFile, err := os.ReadFile(path)
if err != nil {
t.Fatalf("read: %v", err)
}
if strings.Contains(string(rawFile), raw) {
t.Fatal("raw token leaked into the file")
}
}
func TestCreateScopes(t *testing.T) {
s := New(filepath.Join(t.TempDir(), "tokens.toml"))
record, _, err := s.Create("scoped", []string{"write", "bogus", "delete"})
if err != nil {
t.Fatalf("Create: %v", err)
}
if record == nil {
t.Fatal("Create failed")
}
if len(record.Scopes) != 2 || record.Scopes[0] != "write" || record.Scopes[1] != "delete" {
t.Fatalf("scopes = %v", record.Scopes)
}
if record.HasScope("read") {
t.Fatal("read scope granted")
}
if !record.HasScope("write") {
t.Fatal("write scope missing")
}
// An explicit list that names no valid scope must be refused, not
// turned into an unrestricted token.
if _, _, err := s.Create("invalid-only", []string{"bogus"}); !errors.Is(err, ErrNoValidScope) {
t.Fatalf("err = %v, want ErrNoValidScope", err)
}
}
func TestCreateRejectsDuplicatesAndEmpty(t *testing.T) {
s := New(filepath.Join(t.TempDir(), "tokens.toml"))
if record, _, err := s.Create("dup", nil); err != nil || record == nil {
t.Fatalf("first Create: %v, %v", record, err)
}
if record, _, err := s.Create("dup", nil); err == nil || record != nil {
t.Fatal("duplicate name accepted")
}
if record, _, err := s.Create(" ", nil); err == nil || record != nil {
t.Fatal("empty name accepted")
}
}
func TestPersistedAcrossReopen(t *testing.T) {
path := filepath.Join(t.TempDir(), "tokens.toml")
s := New(path)
_, raw, err := s.Create("ci", []string{"write"})
if err != nil {
t.Fatalf("Create: %v", err)
}
reopened := New(path)
if len(reopened.All()) != 1 {
t.Fatalf("tokens = %v", reopened.All())
}
if reopened.Authenticate(raw) == nil {
t.Fatal("token lost across reopen")
}
}
func TestTouchRefreshesOncePerDay(t *testing.T) {
s := New(filepath.Join(t.TempDir(), "tokens.toml"))
record, _, err := s.Create("ci", nil)
if err != nil {
t.Fatalf("Create: %v", err)
}
s.Touch("ci")
after := s.All()[0]
if after.LastUsed == "" {
t.Fatal("last_used not set")
}
s.Touch("ci")
again := s.All()[0]
if again.LastUsed != after.LastUsed {
t.Fatal("last_used updated twice in one day")
}
s.Touch("missing")
if record.Created == "" {
t.Fatal("created missing")
}
}
func TestRevoke(t *testing.T) {
s := New(filepath.Join(t.TempDir(), "tokens.toml"))
s.Create("one", nil)
if !s.Revoke("one") {
t.Fatal("Revoke failed")
}
if s.Revoke("one") {
t.Fatal("Revoke succeeded twice")
}
if len(s.All()) != 0 {
t.Fatalf("tokens = %v", s.All())
}
}
func TestUnreadableFileYieldsNoTokens(t *testing.T) {
path := filepath.Join(t.TempDir(), "tokens.toml")
if err := os.WriteFile(path, []byte("broken = = ="), 0o600); err != nil {
t.Fatalf("write: %v", err)
}
if got := New(path).All(); got != nil {
t.Fatalf("tokens = %v, want none", got)
}
}
func TestMissingFileYieldsNoTokens(t *testing.T) {
if got := New(filepath.Join(t.TempDir(), "nope.toml")).All(); got != nil {
t.Fatalf("tokens = %v, want none", got)
}
}