Release: v0.1.0-alpha
Release Docker Image / Build & Push Docker Image (release) Failing after 1m30s

This commit is contained in:
2026-04-05 16:56:16 +02:00
parent 23ff731579
commit fd13e67aef
89 changed files with 18786 additions and 0 deletions
+178
View File
@@ -0,0 +1,178 @@
// Keywarden - Centralized SSH Key Management and Deployment
// Copyright (C) 2026 Patrick Asmus (scriptos)
// SPDX-License-Identifier: AGPL-3.0-or-later
//go:build integration
package database
import (
"os"
"path/filepath"
"testing"
)
func TestNewDatabase(t *testing.T) {
tmpDir := t.TempDir()
dbPath := filepath.Join(tmpDir, "test.db")
db, err := New(dbPath)
if err != nil {
t.Fatalf("New() failed: %v", err)
}
defer db.Close()
// Verify file was created
if _, err := os.Stat(dbPath); os.IsNotExist(err) {
t.Fatal("Database file was not created")
}
}
func TestMigrationsCreateTables(t *testing.T) {
tmpDir := t.TempDir()
db, err := New(filepath.Join(tmpDir, "test.db"))
if err != nil {
t.Fatalf("New() failed: %v", err)
}
defer db.Close()
tables := []string{"users", "ssh_keys", "servers", "key_deployments", "audit_log", "settings", "_migrations"}
for _, table := range tables {
var count int
err := db.QueryRow(`SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name=?`, table).Scan(&count)
if err != nil {
t.Fatalf("Failed to check table %s: %v", table, err)
}
if count == 0 {
t.Fatalf("Table %q was not created", table)
}
}
}
func TestMigrationsIdempotent(t *testing.T) {
tmpDir := t.TempDir()
dbPath := filepath.Join(tmpDir, "test.db")
// Run migrations twice (opening creates + migrates)
db1, err := New(dbPath)
if err != nil {
t.Fatalf("New() first call failed: %v", err)
}
db1.Close()
db2, err := New(dbPath)
if err != nil {
t.Fatalf("New() second call failed (migrations should be idempotent): %v", err)
}
defer db2.Close()
}
func TestAlterMigrationsTracked(t *testing.T) {
tmpDir := t.TempDir()
db, err := New(filepath.Join(tmpDir, "test.db"))
if err != nil {
t.Fatalf("New() failed: %v", err)
}
defer db.Close()
// Check that alter migrations are tracked
expectedMigrations := []string{"add_mfa_enabled", "add_mfa_secret", "add_is_master_key"}
for _, name := range expectedMigrations {
var count int
err := db.QueryRow(`SELECT COUNT(*) FROM _migrations WHERE name = ?`, name).Scan(&count)
if err != nil {
t.Fatalf("Failed to check migration %s: %v", name, err)
}
if count == 0 {
t.Fatalf("Migration %q was not tracked", name)
}
}
}
func TestInsertAndQueryUser(t *testing.T) {
tmpDir := t.TempDir()
db, err := New(filepath.Join(tmpDir, "test.db"))
if err != nil {
t.Fatalf("New() failed: %v", err)
}
defer db.Close()
result, err := db.Exec(
`INSERT INTO users (username, email, password_hash, role) VALUES (?, ?, ?, ?)`,
"testuser", "test@example.com", "hash123", "user",
)
if err != nil {
t.Fatalf("Insert user failed: %v", err)
}
id, _ := result.LastInsertId()
if id == 0 {
t.Fatal("Expected non-zero insert ID")
}
var username string
err = db.QueryRow(`SELECT username FROM users WHERE id = ?`, id).Scan(&username)
if err != nil {
t.Fatalf("Query user failed: %v", err)
}
if username != "testuser" {
t.Fatalf("Expected username 'testuser', got %q", username)
}
}
func TestSSHKeyWithMasterFlag(t *testing.T) {
tmpDir := t.TempDir()
db, err := New(filepath.Join(tmpDir, "test.db"))
if err != nil {
t.Fatalf("New() failed: %v", err)
}
defer db.Close()
// Create a user first
db.Exec(`INSERT INTO users (username, email, password_hash, role) VALUES (?, ?, ?, ?)`,
"testuser", "test@example.com", "hash", "user")
// Insert a master key
_, err = db.Exec(
`INSERT INTO ssh_keys (user_id, name, key_type, bits, fingerprint, public_key, private_key_enc, is_master)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
1, "Master Key", "ed25519", 256, "SHA256:test", "pubkey", "encpriv", 1,
)
if err != nil {
t.Fatalf("Insert master key failed: %v", err)
}
// Verify is_master flag
var isMaster int
err = db.QueryRow(`SELECT is_master FROM ssh_keys WHERE user_id = 1 AND is_master = 1`).Scan(&isMaster)
if err != nil {
t.Fatalf("Query master key failed: %v", err)
}
if isMaster != 1 {
t.Fatalf("Expected is_master=1, got %d", isMaster)
}
}
func TestForeignKeyCascade(t *testing.T) {
tmpDir := t.TempDir()
db, err := New(filepath.Join(tmpDir, "test.db"))
if err != nil {
t.Fatalf("New() failed: %v", err)
}
defer db.Close()
// Insert user and key
db.Exec(`INSERT INTO users (username, email, password_hash, role) VALUES (?, ?, ?, ?)`,
"testuser", "test@example.com", "hash", "user")
db.Exec(`INSERT INTO ssh_keys (user_id, name, key_type, bits, fingerprint, public_key, private_key_enc)
VALUES (?, ?, ?, ?, ?, ?, ?)`, 1, "Test", "ed25519", 256, "fp", "pub", "priv")
// Delete user — key should cascade
db.Exec(`DELETE FROM users WHERE id = 1`)
var count int
db.QueryRow(`SELECT COUNT(*) FROM ssh_keys WHERE user_id = 1`).Scan(&count)
if count != 0 {
t.Fatalf("Expected 0 keys after user deletion (cascade), got %d", count)
}
}