DeleteClientConfiguration returns an http.HandlerFunc that handles DELETE /oauth2/clients/{client_id}
(db database.Store, auditor *audit.Auditor, logger slog.Logger)
| 357 | |
| 358 | // DeleteClientConfiguration returns an http.HandlerFunc that handles DELETE /oauth2/clients/{client_id} |
| 359 | func DeleteClientConfiguration(db database.Store, auditor *audit.Auditor, logger slog.Logger) http.HandlerFunc { |
| 360 | return func(rw http.ResponseWriter, r *http.Request) { |
| 361 | ctx := r.Context() |
| 362 | aReq, commitAudit := audit.InitRequest[database.OAuth2ProviderApp](rw, &audit.RequestParams{ |
| 363 | Audit: *auditor, |
| 364 | Log: logger, |
| 365 | Request: r, |
| 366 | Action: database.AuditActionDelete, |
| 367 | }) |
| 368 | defer commitAudit() |
| 369 | |
| 370 | // Extract client ID from URL path |
| 371 | clientIDStr := chi.URLParam(r, "client_id") |
| 372 | clientID, err := uuid.Parse(clientIDStr) |
| 373 | if err != nil { |
| 374 | writeOAuth2RegistrationError(ctx, rw, http.StatusBadRequest, |
| 375 | "invalid_client_metadata", "Invalid client ID format") |
| 376 | return |
| 377 | } |
| 378 | |
| 379 | // Get existing app to verify it exists and is dynamically registered |
| 380 | //nolint:gocritic // OAuth2 system context — RFC 7592 client configuration endpoint |
| 381 | existingApp, err := db.GetOAuth2ProviderAppByClientID(dbauthz.AsSystemOAuth2(ctx), clientID) |
| 382 | if err == nil { |
| 383 | aReq.Old = existingApp |
| 384 | } |
| 385 | if err != nil { |
| 386 | if xerrors.Is(err, sql.ErrNoRows) { |
| 387 | writeOAuth2RegistrationError(ctx, rw, http.StatusUnauthorized, |
| 388 | "invalid_token", "Client not found") |
| 389 | } else { |
| 390 | writeOAuth2RegistrationError(ctx, rw, http.StatusInternalServerError, |
| 391 | "server_error", "Failed to retrieve client") |
| 392 | } |
| 393 | return |
| 394 | } |
| 395 | |
| 396 | // Check if client was dynamically registered |
| 397 | if !existingApp.DynamicallyRegistered.Bool { |
| 398 | writeOAuth2RegistrationError(ctx, rw, http.StatusForbidden, |
| 399 | "invalid_token", "Client was not dynamically registered") |
| 400 | return |
| 401 | } |
| 402 | |
| 403 | // Delete the client and all associated data (tokens, secrets, etc.) |
| 404 | //nolint:gocritic // OAuth2 system context — RFC 7592 client configuration endpoint |
| 405 | err = db.DeleteOAuth2ProviderAppByClientID(dbauthz.AsSystemOAuth2(ctx), clientID) |
| 406 | if err != nil { |
| 407 | writeOAuth2RegistrationError(ctx, rw, http.StatusInternalServerError, |
| 408 | "server_error", "Failed to delete client") |
| 409 | return |
| 410 | } |
| 411 | |
| 412 | // Note: audit data already set above with aReq.Old = existingApp |
| 413 | |
| 414 | // Return 204 No Content as per RFC 7592 |
| 415 | rw.WriteHeader(http.StatusNoContent) |
| 416 | } |
no test coverage detected