feat: add API token authentication (closes #87)
- Add api_tokens table migration (007) - Add APIToken model with CRUD operations - Generate tokens with upaas_ prefix + 32 hex chars - Store SHA-256 hash of tokens (not plaintext) - Update APISessionAuth middleware to check Bearer tokens - Add POST/GET/DELETE /api/v1/tokens endpoints - Token creation returns plaintext once; list never exposes it - Expired and revoked tokens are rejected - Tests for creation, listing, deletion, bearer auth, revocation
This commit is contained in:
@@ -176,6 +176,13 @@ func HashWebhookSecret(secret string) string {
|
||||
return hex.EncodeToString(sum[:])
|
||||
}
|
||||
|
||||
// HashAPIToken returns the hex-encoded SHA-256 hash of an API token.
|
||||
func HashAPIToken(token string) string {
|
||||
sum := sha256.Sum256([]byte(token))
|
||||
|
||||
return hex.EncodeToString(sum[:])
|
||||
}
|
||||
|
||||
func (d *Database) backfillWebhookSecretHashes(ctx context.Context) error {
|
||||
rows, err := d.database.QueryContext(ctx,
|
||||
"SELECT id, webhook_secret FROM apps WHERE webhook_secret_hash = '' AND webhook_secret != ''")
|
||||
|
||||
12
internal/database/migrations/007_add_api_tokens.sql
Normal file
12
internal/database/migrations/007_add_api_tokens.sql
Normal file
@@ -0,0 +1,12 @@
|
||||
CREATE TABLE IF NOT EXISTS api_tokens (
|
||||
id TEXT PRIMARY KEY,
|
||||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
name TEXT NOT NULL,
|
||||
token_hash TEXT NOT NULL,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
expires_at DATETIME,
|
||||
last_used_at DATETIME
|
||||
);
|
||||
|
||||
CREATE INDEX idx_api_tokens_user_id ON api_tokens(user_id);
|
||||
CREATE INDEX idx_api_tokens_token_hash ON api_tokens(token_hash);
|
||||
Reference in New Issue
Block a user