rin
Публичный Open-source lightweight git hosting.
auth_test.go · 101 строка · 2.7 KB
Raw
1 package auth
2
3 import (
4 "context"
5 "path/filepath"
6 "strings"
7 "testing"
8
9 "polar/internal/db"
10 )
11
12 func TestPasswordHashAndVerify(t *testing.T) {
13 if _, err := HashPassword("short"); err == nil {
14 t.Fatalf("expected error for short password")
15 }
16
17 hash, err := HashPassword("correct-horse-battery-staple")
18 if err != nil {
19 t.Fatalf("HashPassword failed: %v", err)
20 }
21 if !strings.HasPrefix(hash, "$argon2id$") {
22 t.Fatalf("expected argon2id PHC format, got %q", hash)
23 }
24
25 ok, err := VerifyPassword("correct-horse-battery-staple", hash)
26 if err != nil || !ok {
27 t.Fatalf("VerifyPassword failed for valid password: %v", err)
28 }
29
30 ok, err = VerifyPassword("wrong-password", hash)
31 if err != nil || ok {
32 t.Fatalf("VerifyPassword should return false for wrong password")
33 }
34 }
35
36 func TestSessionsAndTokens(t *testing.T) {
37 ctx := context.Background()
38 database, err := db.Open(ctx, filepath.Join(t.TempDir(), "auth.db"), true)
39 if err != nil {
40 t.Fatalf("open db: %v", err)
41 }
42 defer database.Close()
43
44 _, err = database.ExecContext(ctx, `INSERT INTO users (id, username, email, password_hash, is_admin) VALUES (1, 'alice', 'alice@example.com', 'hash', 1)`)
45 if err != nil {
46 t.Fatalf("insert test user: %v", err)
47 }
48
49 svc := NewService(database)
50
51 sess, err := svc.CreateSession(ctx, 1)
52 if err != nil {
53 t.Fatalf("CreateSession failed: %v", err)
54 }
55 if len(sess.ID) != 64 || len(sess.CSRFToken) < 32 {
56 t.Fatalf("unexpected session ID or CSRF token length")
57 }
58
59 loaded, err := svc.GetSession(ctx, sess.ID)
60 if err != nil || loaded.UserID != 1 {
61 t.Fatalf("GetSession failed: %v", err)
62 }
63
64 if err := svc.DeleteSession(ctx, sess.ID); err != nil {
65 t.Fatalf("DeleteSession failed: %v", err)
66 }
67 if _, err := svc.GetSession(ctx, sess.ID); err == nil {
68 t.Fatalf("expected error after session deletion")
69 }
70
71 rawToken, tok, err := svc.CreateToken(ctx, 1, "Laptop CLI")
72 if err != nil {
73 t.Fatalf("CreateToken failed: %v", err)
74 }
75 if !strings.HasPrefix(rawToken, "polar_") {
76 t.Fatalf("expected polar_ prefix, got %q", rawToken)
77 }
78 if tok.Name != "Laptop CLI" {
79 t.Fatalf("unexpected token name: %q", tok.Name)
80 }
81
82 uid, err := svc.VerifyToken(ctx, rawToken)
83 if err != nil || uid != 1 {
84 t.Fatalf("VerifyToken failed: uid=%d err=%v", uid, err)
85 }
86
87 tokens, err := svc.ListTokens(ctx, 1)
88 if err != nil || len(tokens) != 1 {
89 t.Fatalf("ListTokens failed: len=%d err=%v", len(tokens), err)
90 }
91 if tokens[0].LastUsedAt == nil {
92 t.Fatalf("expected LastUsedAt to be updated after VerifyToken")
93 }
94
95 if err := svc.RevokeToken(ctx, 1, tok.ID); err != nil {
96 t.Fatalf("RevokeToken failed: %v", err)
97 }
98 if _, err := svc.VerifyToken(ctx, rawToken); err == nil {
99 t.Fatalf("expected error for revoked token")
100 }
101 }
102