From b825d8f9d0d37ee683b7cc097b3c0a4e0bfafcf8 Mon Sep 17 00:00:00 2001 From: Tom Thornton Date: Fri, 8 May 2026 17:22:49 +0100 Subject: [PATCH 1/4] Added support for AWS Cognito OAuth2 provider --- routers/web/auth/oauth.go | 10 ++- .../auth/source/oauth2/providers_cognito.go | 68 +++++++++++++++++++ web_src/js/features/admin/common.ts | 1 + 3 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 services/auth/source/oauth2/providers_cognito.go diff --git a/routers/web/auth/oauth.go b/routers/web/auth/oauth.go index 8645aedbdeeac..ef122629d9974 100644 --- a/routers/web/auth/oauth.go +++ b/routers/web/auth/oauth.go @@ -539,7 +539,15 @@ func buildOIDCEndSessionURL(ctx *context.Context, doer *user_model.User) string // https://openid.net/specs/openid-connect-rpinitiated-1_0.html#RPLogout params := endSessionURL.Query() params.Set("client_id", oauth2Cfg.ClientID) - params.Set("post_logout_redirect_uri", httplib.GuessCurrentAppURL(ctx)) + + // AWS Cognito uses "logout_uri" instead of the standard "post_logout_redirect_uri" + redirectURI := httplib.GuessCurrentAppURL(ctx) + if oauth2Cfg.Provider == "cognito" { + params.Set("logout_uri", redirectURI) + } else { + params.Set("post_logout_redirect_uri", redirectURI) + } + endSessionURL.RawQuery = params.Encode() return endSessionURL.String() } diff --git a/services/auth/source/oauth2/providers_cognito.go b/services/auth/source/oauth2/providers_cognito.go new file mode 100644 index 0000000000000..ed499e093fdf5 --- /dev/null +++ b/services/auth/source/oauth2/providers_cognito.go @@ -0,0 +1,68 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package oauth2 + +import ( + "html/template" + + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/svg" + + "github.com/markbates/goth" + "github.com/markbates/goth/providers/openidConnect" +) + +// CognitoProvider is a GothProvider for AWS Cognito +type CognitoProvider struct{} + +func (c *CognitoProvider) SupportSSHPublicKey() bool { + return true +} + +// Name provides the technical name for this provider +func (c *CognitoProvider) Name() string { + return "cognito" +} + +// DisplayName returns the friendly name for this provider +func (c *CognitoProvider) DisplayName() string { + return "AWS Cognito" +} + +// IconHTML returns icon HTML for this provider +func (c *CognitoProvider) IconHTML(size int) template.HTML { + return svg.RenderHTML("gitea-openid", size) +} + +// CreateGothProvider creates a GothProvider from this Provider +func (c *CognitoProvider) CreateGothProvider(providerName, callbackURL string, source *Source) (goth.Provider, error) { + scopes := setting.OAuth2Client.OpenIDConnectScopes + if len(scopes) == 0 { + scopes = append(scopes, source.Scopes...) + } + + provider, err := openidConnect.New(source.ClientID, source.ClientSecret, callbackURL, source.OpenIDConnectAutoDiscoveryURL, scopes...) + if err != nil { + log.Warn("Failed to create AWS Cognito Provider with name '%s' with url '%s': %v", providerName, source.OpenIDConnectAutoDiscoveryURL, err) + return nil, err + } + if source.ExternalIDClaim != "" { + // UserIdClaims is a fallback list; goth returns the first non-empty matching claim. + // A single entry is sufficient because the admin explicitly chooses one claim (e.g. "sub" for Cognito). + provider.UserIdClaims = []string{source.ExternalIDClaim} + } + return provider, nil +} + +// CustomURLSettings returns the custom url settings for this provider +func (c *CognitoProvider) CustomURLSettings() *CustomURLSettings { + return nil +} + +var _ GothProvider = &CognitoProvider{} + +func init() { + RegisterGothProvider(&CognitoProvider{}) +} diff --git a/web_src/js/features/admin/common.ts b/web_src/js/features/admin/common.ts index f0c0f5bee6909..734c7915e0572 100644 --- a/web_src/js/features/admin/common.ts +++ b/web_src/js/features/admin/common.ts @@ -86,6 +86,7 @@ function initAdminAuthentication() { const provider = document.querySelector('#oauth2_provider')!.value; switch (provider) { case 'openidConnect': + case 'cognito': document.querySelector('.open_id_connect_auto_discovery_url input')!.setAttribute('required', 'required'); showElem('.open_id_connect_auto_discovery_url'); showElem('.open_id_connect_external_id_claim'); From 94a0bc348525e9469404809344e40b9339b42413 Mon Sep 17 00:00:00 2001 From: Tom Thornton Date: Fri, 8 May 2026 17:46:37 +0100 Subject: [PATCH 2/4] refactored to reduce duplication --- .../auth/source/oauth2/providers_cognito.go | 49 ++----------------- 1 file changed, 3 insertions(+), 46 deletions(-) diff --git a/services/auth/source/oauth2/providers_cognito.go b/services/auth/source/oauth2/providers_cognito.go index ed499e093fdf5..5b064ce979ab4 100644 --- a/services/auth/source/oauth2/providers_cognito.go +++ b/services/auth/source/oauth2/providers_cognito.go @@ -3,22 +3,9 @@ package oauth2 -import ( - "html/template" - - "code.gitea.io/gitea/modules/log" - "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/svg" - - "github.com/markbates/goth" - "github.com/markbates/goth/providers/openidConnect" -) - -// CognitoProvider is a GothProvider for AWS Cognito -type CognitoProvider struct{} - -func (c *CognitoProvider) SupportSSHPublicKey() bool { - return true +// CognitoProvider is a GothProvider for AWS Cognito (based on OpenID Connect) +type CognitoProvider struct { + OpenIDProvider } // Name provides the technical name for this provider @@ -31,36 +18,6 @@ func (c *CognitoProvider) DisplayName() string { return "AWS Cognito" } -// IconHTML returns icon HTML for this provider -func (c *CognitoProvider) IconHTML(size int) template.HTML { - return svg.RenderHTML("gitea-openid", size) -} - -// CreateGothProvider creates a GothProvider from this Provider -func (c *CognitoProvider) CreateGothProvider(providerName, callbackURL string, source *Source) (goth.Provider, error) { - scopes := setting.OAuth2Client.OpenIDConnectScopes - if len(scopes) == 0 { - scopes = append(scopes, source.Scopes...) - } - - provider, err := openidConnect.New(source.ClientID, source.ClientSecret, callbackURL, source.OpenIDConnectAutoDiscoveryURL, scopes...) - if err != nil { - log.Warn("Failed to create AWS Cognito Provider with name '%s' with url '%s': %v", providerName, source.OpenIDConnectAutoDiscoveryURL, err) - return nil, err - } - if source.ExternalIDClaim != "" { - // UserIdClaims is a fallback list; goth returns the first non-empty matching claim. - // A single entry is sufficient because the admin explicitly chooses one claim (e.g. "sub" for Cognito). - provider.UserIdClaims = []string{source.ExternalIDClaim} - } - return provider, nil -} - -// CustomURLSettings returns the custom url settings for this provider -func (c *CognitoProvider) CustomURLSettings() *CustomURLSettings { - return nil -} - var _ GothProvider = &CognitoProvider{} func init() { From b314fc97baa0f5d1c53f7014c0927f58774ce261 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sun, 10 May 2026 20:45:34 +0800 Subject: [PATCH 3/4] use const --- routers/web/auth/oauth.go | 2 +- .../source/oauth2/providers_awscognito.go | 27 +++++++++++++++++++ .../auth/source/oauth2/providers_cognito.go | 25 ----------------- web_src/js/features/admin/common.ts | 2 +- 4 files changed, 29 insertions(+), 27 deletions(-) create mode 100644 services/auth/source/oauth2/providers_awscognito.go delete mode 100644 services/auth/source/oauth2/providers_cognito.go diff --git a/routers/web/auth/oauth.go b/routers/web/auth/oauth.go index ef122629d9974..f7983559c01af 100644 --- a/routers/web/auth/oauth.go +++ b/routers/web/auth/oauth.go @@ -542,7 +542,7 @@ func buildOIDCEndSessionURL(ctx *context.Context, doer *user_model.User) string // AWS Cognito uses "logout_uri" instead of the standard "post_logout_redirect_uri" redirectURI := httplib.GuessCurrentAppURL(ctx) - if oauth2Cfg.Provider == "cognito" { + if oauth2Cfg.Provider == oauth2.ProviderNameAwsCognito { params.Set("logout_uri", redirectURI) } else { params.Set("post_logout_redirect_uri", redirectURI) diff --git a/services/auth/source/oauth2/providers_awscognito.go b/services/auth/source/oauth2/providers_awscognito.go new file mode 100644 index 0000000000000..835dd37a66558 --- /dev/null +++ b/services/auth/source/oauth2/providers_awscognito.go @@ -0,0 +1,27 @@ +// Copyright 2026 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package oauth2 + +const ProviderNameAwsCognito = "aws-cognito" + +// AwsCognitoProvider is a GothProvider for AWS Cognito (based on OpenID Connect) +type AwsCognitoProvider struct { + OpenIDProvider +} + +// Name provides the technical name for this provider +func (c *AwsCognitoProvider) Name() string { + return ProviderNameAwsCognito +} + +// DisplayName returns the friendly name for this provider +func (c *AwsCognitoProvider) DisplayName() string { + return "AWS Cognito" +} + +var _ GothProvider = &AwsCognitoProvider{} + +func init() { + RegisterGothProvider(&AwsCognitoProvider{}) +} diff --git a/services/auth/source/oauth2/providers_cognito.go b/services/auth/source/oauth2/providers_cognito.go deleted file mode 100644 index 5b064ce979ab4..0000000000000 --- a/services/auth/source/oauth2/providers_cognito.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2025 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package oauth2 - -// CognitoProvider is a GothProvider for AWS Cognito (based on OpenID Connect) -type CognitoProvider struct { - OpenIDProvider -} - -// Name provides the technical name for this provider -func (c *CognitoProvider) Name() string { - return "cognito" -} - -// DisplayName returns the friendly name for this provider -func (c *CognitoProvider) DisplayName() string { - return "AWS Cognito" -} - -var _ GothProvider = &CognitoProvider{} - -func init() { - RegisterGothProvider(&CognitoProvider{}) -} diff --git a/web_src/js/features/admin/common.ts b/web_src/js/features/admin/common.ts index 734c7915e0572..5753aad2b2cf5 100644 --- a/web_src/js/features/admin/common.ts +++ b/web_src/js/features/admin/common.ts @@ -86,7 +86,7 @@ function initAdminAuthentication() { const provider = document.querySelector('#oauth2_provider')!.value; switch (provider) { case 'openidConnect': - case 'cognito': + case 'aws-cognito': document.querySelector('.open_id_connect_auto_discovery_url input')!.setAttribute('required', 'required'); showElem('.open_id_connect_auto_discovery_url'); showElem('.open_id_connect_external_id_claim'); From 8dc71e8d54c96a437a17b1b10c43609d4b8e3a67 Mon Sep 17 00:00:00 2001 From: Tom Thornton Date: Mon, 11 May 2026 09:28:25 +0100 Subject: [PATCH 4/4] Moved cognito provider into custom providers --- .../source/oauth2/providers_awscognito.go | 27 ------------------- .../auth/source/oauth2/providers_custom.go | 21 +++++++++++++++ 2 files changed, 21 insertions(+), 27 deletions(-) delete mode 100644 services/auth/source/oauth2/providers_awscognito.go diff --git a/services/auth/source/oauth2/providers_awscognito.go b/services/auth/source/oauth2/providers_awscognito.go deleted file mode 100644 index 835dd37a66558..0000000000000 --- a/services/auth/source/oauth2/providers_awscognito.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2026 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package oauth2 - -const ProviderNameAwsCognito = "aws-cognito" - -// AwsCognitoProvider is a GothProvider for AWS Cognito (based on OpenID Connect) -type AwsCognitoProvider struct { - OpenIDProvider -} - -// Name provides the technical name for this provider -func (c *AwsCognitoProvider) Name() string { - return ProviderNameAwsCognito -} - -// DisplayName returns the friendly name for this provider -func (c *AwsCognitoProvider) DisplayName() string { - return "AWS Cognito" -} - -var _ GothProvider = &AwsCognitoProvider{} - -func init() { - RegisterGothProvider(&AwsCognitoProvider{}) -} diff --git a/services/auth/source/oauth2/providers_custom.go b/services/auth/source/oauth2/providers_custom.go index 65cf538ad7386..6a4098dda6ba6 100644 --- a/services/auth/source/oauth2/providers_custom.go +++ b/services/auth/source/oauth2/providers_custom.go @@ -120,4 +120,25 @@ func init() { }), nil }, )) + + RegisterGothProvider(&AwsCognitoProvider{}) } + +const ProviderNameAwsCognito = "aws-cognito" + +// AwsCognitoProvider is a GothProvider for AWS Cognito (based on OpenID Connect) +type AwsCognitoProvider struct { + OpenIDProvider +} + +// Name provides the technical name for this provider +func (c *AwsCognitoProvider) Name() string { + return ProviderNameAwsCognito +} + +// DisplayName returns the friendly name for this provider +func (c *AwsCognitoProvider) DisplayName() string { + return "AWS Cognito" +} + +var _ GothProvider = &AwsCognitoProvider{}