From 19f4300ad05a57e2a7a2f3ef0a3acbac8f30a435 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 2 Dec 2024 22:44:47 +0100 Subject: [PATCH] Allow to enable Proof Key for Code Exachange (PKCE) (#271) * Allow to enable Proof Key for Code Exachange (PKCE) Wires usePkceWithAuthorizationCodeGrant OAuth2 option of the Swagger UI to the options interface * Changes according to maintainers review --------- Co-authored-by: Mario Gruber --- README.md | 1 + swagger.go | 16 +++++++++++++++- swagger_test.go | 13 +++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9c20ddd..8f268d4 100644 --- a/README.md +++ b/README.md @@ -204,3 +204,4 @@ func main() { | InstanceName | string | "swagger" | The instance name of the swagger document. If multiple different swagger instances should be deployed on one gin router, ensure that each instance has a unique name (use the _--instanceName_ parameter to generate swagger documents with _swag init_). | | PersistAuthorization | bool | false | If set to true, it persists authorization data and it would not be lost on browser close/refresh. | | Oauth2DefaultClientID | string | "" | If set, it's used to prepopulate the _client_id_ field of the OAuth2 Authorization dialog. | +| Oauth2UsePkce | bool | false | If set to true, it enables Proof Key for Code Exchange to enhance security for OAuth public clients. | \ No newline at end of file diff --git a/swagger.go b/swagger.go index 9206c78..7e0e414 100644 --- a/swagger.go +++ b/swagger.go @@ -24,6 +24,7 @@ type swaggerConfig struct { DeepLinking bool PersistAuthorization bool Oauth2DefaultClientID string + Oauth2UsePkce bool } // Config stores ginSwagger configuration variables. @@ -37,6 +38,7 @@ type Config struct { DeepLinking bool PersistAuthorization bool Oauth2DefaultClientID string + Oauth2UsePkce bool } func (config Config) toSwaggerConfig() swaggerConfig { @@ -51,6 +53,7 @@ func (config Config) toSwaggerConfig() swaggerConfig { Title: config.Title, PersistAuthorization: config.PersistAuthorization, Oauth2DefaultClientID: config.Oauth2DefaultClientID, + Oauth2UsePkce: config.Oauth2UsePkce, } } @@ -106,6 +109,15 @@ func Oauth2DefaultClientID(oauth2DefaultClientID string) func(*Config) { } } +// Oauth2UsePkce enables Proof Key for Code Exchange. +// Corresponds to the usePkceWithAuthorizationCodeGrant property of the Swagger UI +// and applies only to accessCode (Authorization Code) flows. +func Oauth2UsePkce(usePkce bool) func(*Config) { + return func(c *Config) { + c.Oauth2UsePkce = usePkce + } +} + // WrapHandler wraps `http.Handler` into `gin.HandlerFunc`. func WrapHandler(handler *webdav.Handler, options ...func(*Config)) gin.HandlerFunc { var config = Config{ @@ -117,6 +129,7 @@ func WrapHandler(handler *webdav.Handler, options ...func(*Config)) gin.HandlerF DeepLinking: true, PersistAuthorization: false, Oauth2DefaultClientID: "", + Oauth2UsePkce: false, } for _, c := range options { @@ -273,7 +286,8 @@ window.onload = function() { const defaultClientId = "{{.Oauth2DefaultClientID}}"; if (defaultClientId) { ui.initOAuth({ - clientId: defaultClientId + clientId: defaultClientId, + usePkceWithAuthorizationCodeGrant: {{.Oauth2UsePkce}} }) } diff --git a/swagger_test.go b/swagger_test.go index a7a825b..85c5cb7 100644 --- a/swagger_test.go +++ b/swagger_test.go @@ -254,3 +254,16 @@ func TestOauth2DefaultClientID(t *testing.T) { configFunc(&cfg) assert.Equal(t, "", cfg.Oauth2DefaultClientID) } + +func TestOauth2UsePkce(t *testing.T) { + var cfg Config + assert.Equal(t, false, cfg.Oauth2UsePkce) + + configFunc := Oauth2UsePkce(true) + configFunc(&cfg) + assert.Equal(t, true, cfg.Oauth2UsePkce) + + configFunc = Oauth2UsePkce(false) + configFunc(&cfg) + assert.Equal(t, false, cfg.Oauth2UsePkce) +}