fix(auth): allow API token to perform write/execute operations (#1486)
Some checks failed
CI / Check for spelling errors (push) Has been cancelled
CI / Go Linter (push) Has been cancelled
CI / Test on ${{ matrix.os }} (ubuntu-latest) (push) Has been cancelled

Issue #1478 

* **Bug Fixes**
* API tokens now grant admin privileges in builtin authentication mode,
enabling write, execute, and delete operations.

* **Tests**
* New test coverage verifying API token authentication in builtin mode
allows admin-level create, start, and delete actions.
This commit is contained in:
Yota Hamada 2025-12-15 20:11:20 +09:00 committed by GitHub
parent cb83c59a6d
commit 5d6e50df04
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 53 additions and 1 deletions

View File

@ -184,6 +184,49 @@ func TestAuth_BuiltinModeWithAPIToken(t *testing.T) {
ExpectStatus(http.StatusOK).Send(t)
}
// TestAuth_BuiltinModeWithAPIToken_WriteExecute tests that API token can perform
// write and execute operations in builtin mode (regression test for issue #1478)
func TestAuth_BuiltinModeWithAPIToken_WriteExecute(t *testing.T) {
t.Parallel()
server := test.SetupServer(t, test.WithConfigMutator(func(cfg *config.Config) {
cfg.Server.Auth.Mode = config.AuthModeBuiltin
cfg.Server.Auth.Builtin.Admin.Username = "admin"
cfg.Server.Auth.Builtin.Admin.Password = "adminpass"
cfg.Server.Auth.Builtin.Token.Secret = "jwt-secret-key"
cfg.Server.Auth.Builtin.Token.TTL = 24 * time.Hour
// Also configure API token
cfg.Server.Auth.Token.Value = "my-api-token"
}))
spec := `
steps:
- name: test
command: echo hello
`
// Without auth - write should fail
server.Client().Post("/api/v2/dags", api.CreateNewDAGJSONRequestBody{
Name: "api_token_test_dag",
Spec: &spec,
}).ExpectStatus(http.StatusUnauthorized).Send(t)
// Test write operation (create DAG) with API token - this was failing before the fix
server.Client().Post("/api/v2/dags", api.CreateNewDAGJSONRequestBody{
Name: "api_token_test_dag",
Spec: &spec,
}).WithBearerToken("my-api-token").ExpectStatus(http.StatusCreated).Send(t)
// Test execute operation (start DAG) with API token - this was also failing
server.Client().Post("/api/v2/dags/api_token_test_dag/start", api.ExecuteDAGJSONRequestBody{}).
WithBearerToken("my-api-token").
ExpectStatus(http.StatusOK).Send(t)
// Test delete operation with API token
server.Client().Delete("/api/v2/dags/api_token_test_dag").
WithBearerToken("my-api-token").
ExpectStatus(http.StatusNoContent).Send(t)
}
// TestAuth_BuiltinModeIgnoresBasicAuth tests that basic auth is ignored in builtin mode
func TestAuth_BuiltinModeIgnoresBasicAuth(t *testing.T) {
t.Parallel()

View File

@ -86,7 +86,16 @@ func Middleware(opts Options) func(next http.Handler) http.Handler {
// Try API token authentication if enabled
if opts.APITokenEnabled && checkAPIToken(r, opts.APIToken) {
next.ServeHTTP(w, r)
// API token grants full admin access
// Inject a synthetic admin user so that permission checks (requireWrite,
// requireExecute, requireAdmin) work correctly in builtin auth mode
adminUser := &auth.User{
ID: "api-token",
Username: "api-token",
Role: auth.RoleAdmin,
}
ctx := auth.WithUser(r.Context(), adminUser)
next.ServeHTTP(w, r.WithContext(ctx))
return
}