Skip to content

Commit 67be486

Browse files
author
root
committed
fix test backend
1 parent e054922 commit 67be486

50 files changed

Lines changed: 1574 additions & 997 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

backend/domain/certs/hooks.go

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -155,16 +155,27 @@ func RegisterHooks(app *pocketbase.PocketBase) {
155155
}
156156

157157
func validatePrivateKeySecretRef(app core.App, secretID, userID string) error {
158+
return validatePrivateKeySecretRefWith(secretID, userID,
159+
func(secretID, userID string) error {
160+
return secrets.ValidateRef(app, secretID, userID)
161+
},
162+
func(secretID string) (*core.Record, error) {
163+
return app.FindRecordById("secrets", secretID)
164+
},
165+
)
166+
}
167+
168+
func validatePrivateKeySecretRefWith(secretID, userID string, validateRef func(string, string) error, findSecret func(string) (*core.Record, error)) error {
158169
secretID = strings.TrimSpace(secretID)
159170
if secretID == "" {
160171
return nil
161172
}
162173

163-
if err := secrets.ValidateRef(app, secretID, userID); err != nil {
174+
if err := validateRef(secretID, userID); err != nil {
164175
return fmt.Errorf("invalid private key secret")
165176
}
166177

167-
rec, err := app.FindRecordById("secrets", secretID)
178+
rec, err := findSecret(secretID)
168179
if err != nil {
169180
return fmt.Errorf("invalid private key secret")
170181
}
@@ -201,21 +212,20 @@ func runExpirySweepLoop(app core.App, stop <-chan struct{}) {
201212
}
202213

203214
func expireDueCertificates(app core.App) error {
204-
now := time.Now().UTC().Format(time.RFC3339)
215+
now := time.Now().UTC()
205216
records, err := app.FindRecordsByFilter(
206217
"certificates",
207-
"status = 'active' && expires_at != '' && expires_at <= {:now}",
218+
"status = 'active' && expires_at != ''",
208219
"",
209220
200,
210221
0,
211-
map[string]any{"now": now},
222+
nil,
212223
)
213224
if err != nil {
214225
return err
215226
}
216227

217-
for _, record := range records {
218-
record.Set("status", "expired")
228+
for _, record := range markExpiredCertificates(records, now) {
219229
if saveErr := app.Save(record); saveErr != nil {
220230
log.Printf("[WARN] certs: failed to mark certificate %s expired: %v", record.Id, saveErr)
221231
}
@@ -224,6 +234,33 @@ func expireDueCertificates(app core.App) error {
224234
return nil
225235
}
226236

237+
func markExpiredCertificates(records []*core.Record, now time.Time) []*core.Record {
238+
expired := make([]*core.Record, 0, len(records))
239+
for _, record := range records {
240+
if !certificateShouldExpire(record, now) {
241+
continue
242+
}
243+
record.Set("status", "expired")
244+
expired = append(expired, record)
245+
}
246+
return expired
247+
}
248+
249+
func certificateShouldExpire(record *core.Record, now time.Time) bool {
250+
if record == nil || record.GetString("status") != "active" {
251+
return false
252+
}
253+
expiresAt := strings.TrimSpace(record.GetString("expires_at"))
254+
if expiresAt == "" {
255+
return false
256+
}
257+
parsed, err := time.Parse(time.RFC3339, expiresAt)
258+
if err != nil {
259+
return false
260+
}
261+
return !parsed.After(now)
262+
}
263+
227264
// checkAndExpire updates status to "expired" if expires_at is in the past
228265
// and status is still "active". The save is async to avoid blocking the response.
229266
func actorID(auth *core.Record) string {

backend/domain/certs/hooks_expiry_test.go

Lines changed: 13 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,61 +5,42 @@ import (
55
"time"
66

77
"github.com/pocketbase/pocketbase/core"
8-
"github.com/pocketbase/pocketbase/tests"
9-
10-
_ "github.com/websoft9/appos/backend/infra/migrations"
118
)
129

1310
func TestExpireDueCertificates(t *testing.T) {
14-
app, err := tests.NewTestApp()
15-
if err != nil {
16-
t.Fatal(err)
17-
}
18-
defer app.Cleanup()
19-
20-
col, err := app.FindCollectionByNameOrId("certificates")
21-
if err != nil {
22-
t.Fatal(err)
23-
}
11+
col := core.NewBaseCollection("certificates")
12+
now := time.Now().UTC()
2413

2514
newCert := func(name, status string, expiresAt time.Time) *core.Record {
2615
rec := core.NewRecord(col)
16+
rec.Id = name
2717
rec.Set("name", name)
2818
rec.Set("domain", "test.example.com")
2919
rec.Set("kind", "self_signed")
3020
rec.Set("status", status)
3121
if !expiresAt.IsZero() {
3222
rec.Set("expires_at", expiresAt.UTC().Format(time.RFC3339))
3323
}
34-
if err := app.Save(rec); err != nil {
35-
t.Fatalf("save certificate %s: %v", name, err)
36-
}
3724
return rec
3825
}
3926

40-
expiredActive := newCert("expired-active", "active", time.Now().Add(-2*time.Hour))
41-
futureActive := newCert("future-active", "active", time.Now().Add(48*time.Hour))
42-
alreadyExpired := newCert("already-expired", "expired", time.Now().Add(-24*time.Hour))
27+
expiredActive := newCert("expired-active", "active", now.Add(-2*time.Hour))
28+
futureActive := newCert("future-active", "active", now.Add(48*time.Hour))
29+
alreadyExpired := newCert("already-expired", "expired", now.Add(-24*time.Hour))
4330
noExpires := newCert("no-expires", "active", time.Time{})
4431

45-
if err := expireDueCertificates(app); err != nil {
46-
t.Fatalf("expireDueCertificates returned error: %v", err)
47-
}
32+
markExpiredCertificates([]*core.Record{expiredActive, futureActive, alreadyExpired, noExpires}, now)
4833

49-
assertStatus := func(id, want string) {
34+
assertStatus := func(rec *core.Record, want string) {
5035
t.Helper()
51-
rec, findErr := app.FindRecordById("certificates", id)
52-
if findErr != nil {
53-
t.Fatalf("find certificate %s: %v", id, findErr)
54-
}
5536
got := rec.GetString("status")
5637
if got != want {
57-
t.Fatalf("status mismatch for %s: want %q, got %q", id, want, got)
38+
t.Fatalf("status mismatch for %s: want %q, got %q", rec.Id, want, got)
5839
}
5940
}
6041

61-
assertStatus(expiredActive.Id, "expired")
62-
assertStatus(futureActive.Id, "active")
63-
assertStatus(alreadyExpired.Id, "expired")
64-
assertStatus(noExpires.Id, "active")
42+
assertStatus(expiredActive, "expired")
43+
assertStatus(futureActive, "active")
44+
assertStatus(alreadyExpired, "expired")
45+
assertStatus(noExpires, "active")
6546
}

backend/domain/certs/hooks_test.go

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,47 @@
11
package certs
22

33
import (
4+
"errors"
45
"testing"
56

67
"github.com/pocketbase/pocketbase/core"
7-
"github.com/pocketbase/pocketbase/tests"
8-
9-
_ "github.com/websoft9/appos/backend/infra/migrations"
108
)
119

1210
func TestValidatePrivateKeySecretRef(t *testing.T) {
13-
app, err := tests.NewTestApp()
14-
if err != nil {
15-
t.Fatal(err)
16-
}
17-
defer app.Cleanup()
11+
secretCol := core.NewBaseCollection("secrets")
1812

19-
secretCol, err := app.FindCollectionByNameOrId("secrets")
20-
if err != nil {
21-
t.Fatal(err)
22-
}
23-
24-
newSecret := func(name, templateID, scope, createdBy, status string) string {
13+
newSecret := func(name, templateID, status string) *core.Record {
2514
t.Helper()
2615
rec := core.NewRecord(secretCol)
16+
rec.Id = name
2717
rec.Set("name", name)
2818
rec.Set("template_id", templateID)
29-
rec.Set("scope", scope)
30-
rec.Set("created_by", createdBy)
3119
rec.Set("status", status)
32-
if err := app.Save(rec); err != nil {
33-
t.Fatalf("save secret %s: %v", name, err)
34-
}
35-
return rec.Id
20+
return rec
3621
}
3722

3823
t.Run("allows empty relation", func(t *testing.T) {
39-
if err := validatePrivateKeySecretRef(app, "", "user-1"); err != nil {
24+
if err := validatePrivateKeySecretRefWith("", "user-1", func(string, string) error { return nil }, func(string) (*core.Record, error) {
25+
return nil, nil
26+
}); err != nil {
4027
t.Fatalf("expected nil error, got %v", err)
4128
}
4229
})
4330

4431
t.Run("accepts accessible tls private key secret", func(t *testing.T) {
45-
secretID := newSecret("tls-key", "tls_private_key", "global", "owner-1", "active")
46-
if err := validatePrivateKeySecretRef(app, secretID, "user-1"); err != nil {
32+
secret := newSecret("tls-key", "tls_private_key", "active")
33+
if err := validatePrivateKeySecretRefWith(secret.Id, "user-1", func(string, string) error { return nil }, func(string) (*core.Record, error) {
34+
return secret, nil
35+
}); err != nil {
4736
t.Fatalf("expected nil error, got %v", err)
4837
}
4938
})
5039

5140
t.Run("rejects non tls-private-key secret", func(t *testing.T) {
52-
secretID := newSecret("token", "single_value", "global", "owner-1", "active")
53-
err := validatePrivateKeySecretRef(app, secretID, "user-1")
41+
secret := newSecret("token", "single_value", "active")
42+
err := validatePrivateKeySecretRefWith(secret.Id, "user-1", func(string, string) error { return nil }, func(string) (*core.Record, error) {
43+
return secret, nil
44+
})
5445
if err == nil {
5546
t.Fatal("expected error for non-tls-private-key secret")
5647
}
@@ -60,8 +51,12 @@ func TestValidatePrivateKeySecretRef(t *testing.T) {
6051
})
6152

6253
t.Run("rejects inaccessible private secret", func(t *testing.T) {
63-
secretID := newSecret("private-tls-key", "tls_private_key", "user_private", "owner-1", "active")
64-
err := validatePrivateKeySecretRef(app, secretID, "other-user")
54+
secret := newSecret("private-tls-key", "tls_private_key", "active")
55+
err := validatePrivateKeySecretRefWith(secret.Id, "other-user", func(string, string) error {
56+
return errors.New("denied")
57+
}, func(string) (*core.Record, error) {
58+
return secret, nil
59+
})
6560
if err == nil {
6661
t.Fatal("expected error for inaccessible secret")
6762
}

backend/domain/certs/resolve.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,22 @@ var (
2828
//
2929
// callerID is used only for audit/logging; pass "" for system calls.
3030
func ResolveCertificate(app core.App, certID string, callerID string) (*CertMaterial, error) {
31+
return resolveCertificateWith(certID, callerID,
32+
func(certID string) (*core.Record, error) {
33+
return app.FindRecordById("certificates", certID)
34+
},
35+
func(secretID, callerID string) (*secrets.ResolveResult, error) {
36+
return secrets.Resolve(app, secretID, callerID)
37+
},
38+
)
39+
}
40+
41+
func resolveCertificateWith(certID string, callerID string, findCertificate func(string) (*core.Record, error), resolveSecret func(string, string) (*secrets.ResolveResult, error)) (*CertMaterial, error) {
3142
if strings.TrimSpace(callerID) == "" {
3243
callerID = secrets.CreatedSourceSystem
3344
}
3445

35-
record, err := app.FindRecordById("certificates", certID)
46+
record, err := findCertificate(certID)
3647
if err != nil {
3748
if errors.Is(err, sql.ErrNoRows) {
3849
return nil, ErrCertNotFound
@@ -52,7 +63,7 @@ func ResolveCertificate(app core.App, certID string, callerID string) (*CertMate
5263
keyPEM := ""
5364
secretID := getPrivateKeySecretID(record)
5465
if secretID != "" {
55-
result, err := secrets.Resolve(app, secretID, callerID)
66+
result, err := resolveSecret(secretID, callerID)
5667
if err != nil {
5768
return nil, fmt.Errorf("resolving private key secret: %w", err)
5869
}

0 commit comments

Comments
 (0)