Add audit and snapshots tables to SQLite migrations; enhance audit_events table handling in migrations.go. Refactor admin routes in router.go for improved organization and clarity.

This commit is contained in:
2025-12-13 18:17:36 +00:00
parent ad464c828a
commit 999bfa1026
2 changed files with 34 additions and 15 deletions

View File

@@ -64,21 +64,23 @@ func RegisterRoutes(r *chi.Mux, app *App) {
r.With(RequirePermission(app, "iscsi.portal.create")).Post("/api/iscsi/add_portal", app.AddISCSIPortalHandler)
r.With(RequirePermission(app, "iscsi.initiator.create")).Post("/api/iscsi/add_initiator", app.AddISCSIInitiatorHandler)
// Admin routes
r.Route("/admin", func(r chi.Router) {
// Admin routes - users
r.Route("/admin/users", func(r chi.Router) {
r.Use(RequirePermission(app, "users.manage"))
r.Get("/users", app.UsersHandler)
r.Get("/hx/users", app.HXUsersHandler)
r.Post("/users/create", app.CreateUserHandler)
r.Post("/users/{id}/delete", app.DeleteUserHandler)
r.Post("/users/{id}/roles", app.UpdateUserRolesHandler)
r.Get("/", app.UsersHandler)
r.Get("/hx", app.HXUsersHandler)
r.Post("/create", app.CreateUserHandler)
r.Post("/{id}/delete", app.DeleteUserHandler)
r.Post("/{id}/roles", app.UpdateUserRolesHandler)
})
// Admin routes - roles
r.Route("/admin/roles", func(r chi.Router) {
r.Use(RequirePermission(app, "roles.manage"))
r.Get("/roles", app.RolesHandler)
r.Get("/hx/roles", app.HXRolesHandler)
r.Post("/roles/create", app.CreateRoleHandler)
r.Post("/roles/{id}/delete", app.DeleteRoleHandler)
r.Post("/roles/{id}/permissions", app.UpdateRolePermissionsHandler)
r.Get("/", app.RolesHandler)
r.Get("/hx", app.HXRolesHandler)
r.Post("/create", app.CreateRoleHandler)
r.Post("/{id}/delete", app.DeleteRoleHandler)
r.Post("/{id}/permissions", app.UpdateRolePermissionsHandler)
})
r.Get("/static/*", StaticHandler)

View File

@@ -4,6 +4,7 @@ import (
"context"
"database/sql"
"log"
"strings"
"github.com/example/storage-appliance/internal/auth"
)
@@ -27,6 +28,10 @@ func MigrateAndSeed(ctx context.Context, db *sql.DB) error {
`CREATE TABLE IF NOT EXISTS iscsi_portals (id TEXT PRIMARY KEY, target_id TEXT NOT NULL, address TEXT NOT NULL, port INTEGER DEFAULT 3260, created_at DATETIME DEFAULT CURRENT_TIMESTAMP);`,
`CREATE TABLE IF NOT EXISTS iscsi_initiators (id TEXT PRIMARY KEY, target_id TEXT NOT NULL, initiator_iqn TEXT NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP);`,
`CREATE TABLE IF NOT EXISTS iscsi_luns (id TEXT PRIMARY KEY, target_id TEXT NOT NULL, lun_id INTEGER NOT NULL, zvol TEXT NOT NULL, size INTEGER, blocksize INTEGER, mapped INTEGER DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP);`,
// Audit and snapshots tables
`CREATE TABLE IF NOT EXISTS audit_events (id TEXT PRIMARY KEY, ts DATETIME DEFAULT CURRENT_TIMESTAMP, user_id TEXT, action TEXT, resource_type TEXT, resource_id TEXT, success INTEGER DEFAULT 1, details TEXT, actor TEXT, resource TEXT, payload_hash TEXT, result TEXT, client_ip TEXT);`,
`CREATE TABLE IF NOT EXISTS datasets (name TEXT PRIMARY KEY, pool TEXT, type TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP);`,
`CREATE TABLE IF NOT EXISTS snapshots (id TEXT PRIMARY KEY, dataset TEXT, name TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP);`,
// RBAC tables
`CREATE TABLE IF NOT EXISTS roles (id TEXT PRIMARY KEY, name TEXT NOT NULL UNIQUE, description TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP);`,
`CREATE TABLE IF NOT EXISTS permissions (id TEXT PRIMARY KEY, name TEXT NOT NULL UNIQUE, description TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP);`,
@@ -44,6 +49,7 @@ func MigrateAndSeed(ctx context.Context, db *sql.DB) error {
}
// Enhance audit_events table if needed (add missing columns)
// Note: audit_events table is now created with all columns above, but this handles upgrades
enhanceAuditTable(ctx, tx)
// Seed default roles and permissions
@@ -78,6 +84,14 @@ func MigrateAndSeed(ctx context.Context, db *sql.DB) error {
}
func enhanceAuditTable(ctx context.Context, tx *sql.Tx) {
// Check if table exists first
var tableExists int
err := tx.QueryRowContext(ctx, `SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='audit_events'`).Scan(&tableExists)
if err != nil || tableExists == 0 {
// Table doesn't exist, it will be created above with all columns
return
}
// Check if columns exist and add them if missing
// SQLite doesn't support IF NOT EXISTS for ALTER TABLE, so we'll try-catch
columns := []struct {
@@ -94,8 +108,11 @@ func enhanceAuditTable(ctx context.Context, tx *sql.Tx) {
for _, col := range columns {
_, err := tx.ExecContext(ctx, col.stmt)
if err != nil {
// Column might already exist, ignore error
log.Printf("Note: %s column may already exist: %v", col.name, err)
// Column might already exist, ignore error silently
// Only log if it's not a "duplicate column" error
if !strings.Contains(err.Error(), "duplicate column") && !strings.Contains(err.Error(), "no such table") {
log.Printf("Note: %s column may already exist: %v", col.name, err)
}
}
}
}