Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion internal/handlers/authorize.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,15 @@ func (h *AuthorizeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return
}

// Check if there's an error scenario configured for the authorize endpoint
// Check if there's an error scenario configured for the authorize endpoint.
// If an error scenario is configured and enabled for this endpoint, we return
// an OAuth2 error response by redirecting to the redirect_uri with error parameters
// instead of proceeding with the normal authorization code flow.
//
// The error response follows the OAuth2 specification (RFC 6749 Section 4.1.2.1):
// - error: OAuth2 error code (e.g., "access_denied", "invalid_scope")
// - error_description: Human-readable error description (optional)
// - state: The state parameter from the original request (if provided)
if errorScenario, exists := h.Store.GetErrorScenario("authorize"); exists {
// Redirect to the provided redirect URI with error parameters
redirectURL, err := url.Parse(redirectURI)
Expand Down
37 changes: 37 additions & 0 deletions internal/handlers/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,24 @@ type ConfigRequest struct {
}

// ErrorScenario defines an error condition to simulate
//
// When an error scenario is configured for an endpoint, that endpoint will return
// an OAuth2 error response instead of proceeding with the normal authentication flow.
//
// The Enabled field uses a pointer to bool (*bool) to distinguish between three states:
// - nil (field not provided in JSON): defaults to true - error scenario is enabled
// - true (explicitly set): error scenario is enabled
// - false (explicitly set): error scenario is disabled
//
// This allows clients to:
// 1. Enable an error by just providing endpoint and error fields
// 2. Explicitly enable with "enabled": true
// 3. Disable a previously configured error with "enabled": false
//
// Example usage:
// Enable error (implicit): {"endpoint": "authorize", "error": "access_denied"}
// Enable error (explicit): {"endpoint": "authorize", "error": "access_denied", "enabled": true}
// Disable error: {"endpoint": "authorize", "enabled": false}
type ErrorScenario struct {
Enabled *bool `json:"enabled,omitempty"` // Whether the error scenario is enabled (defaults to true if not specified)
Endpoint string `json:"endpoint"` // Which endpoint should return an error (authorize, token, userinfo)
Expand Down Expand Up @@ -85,6 +103,10 @@ func (h *ConfigHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Store error scenario if provided
if config.ErrorScenario != nil {
h.storeErrorScenario(*config.ErrorScenario)
log.Printf("Configured error scenario: endpoint=%s, error=%s, enabled=%v",
config.ErrorScenario.Endpoint,
config.ErrorScenario.Error,
config.ErrorScenario.Enabled)
}

// Return success response
Expand All @@ -108,6 +130,18 @@ func (h *ConfigHandler) storeTokenConfig(tokenConfig map[string]interface{}) {
}

// storeErrorScenario saves error scenario configuration to the store
//
// This function handles the defaulting logic for the Enabled field:
// - If scenario.Enabled is nil (not provided in JSON), it defaults to true
// - If scenario.Enabled is not nil, it uses the explicit value (true or false)
//
// The function also determines the appropriate HTTP status code based on the
// OAuth2 error code and creates a types.ErrorScenario that is stored in the store.
//
// Note: The store only maintains ONE error scenario at a time. If multiple error
// scenarios are configured for different endpoints, the last one configured will
// overwrite any previous configurations. This is by design for simplicity in a
// mock server context.
func (h *ConfigHandler) storeErrorScenario(scenario ErrorScenario) {
// Default enabled to true when an error scenario is being configured
// If Enabled is nil (not provided), default to true
Expand All @@ -126,6 +160,9 @@ func (h *ConfigHandler) storeErrorScenario(scenario ErrorScenario) {
Description: scenario.ErrorDescription,
}

log.Printf("Storing error scenario: endpoint=%s, error=%s, enabled=%t, status_code=%d",
storeScenario.Endpoint, storeScenario.ErrorCode, storeScenario.Enabled, storeScenario.StatusCode)

// Store the error scenario in the store
h.store.StoreErrorScenario(storeScenario)
}
Expand Down
Loading
Loading