mirror of https://github.com/h44z/wg-portal.git
				
				
				
			improve logging of OAuth login issues, decrease auth-code exchange timeout (#451)
This commit is contained in:
		
							parent
							
								
									61d8aa6589
								
							
						
					
					
						commit
						e3b65ca337
					
				|  | @ -57,6 +57,52 @@ | |||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "/auth/login/{provider}/callback": { | ||||
|             "get": { | ||||
|                 "produces": [ | ||||
|                     "application/json" | ||||
|                 ], | ||||
|                 "tags": [ | ||||
|                     "Authentication" | ||||
|                 ], | ||||
|                 "summary": "Handle the OAuth callback.", | ||||
|                 "operationId": "auth_handleOauthCallbackGet", | ||||
|                 "responses": { | ||||
|                     "200": { | ||||
|                         "description": "OK", | ||||
|                         "schema": { | ||||
|                             "type": "array", | ||||
|                             "items": { | ||||
|                                 "$ref": "#/definitions/model.LoginProviderInfo" | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "/auth/login/{provider}/init": { | ||||
|             "get": { | ||||
|                 "produces": [ | ||||
|                     "application/json" | ||||
|                 ], | ||||
|                 "tags": [ | ||||
|                     "Authentication" | ||||
|                 ], | ||||
|                 "summary": "Initiate the OAuth login flow.", | ||||
|                 "operationId": "auth_handleOauthInitiateGet", | ||||
|                 "responses": { | ||||
|                     "200": { | ||||
|                         "description": "OK", | ||||
|                         "schema": { | ||||
|                             "type": "array", | ||||
|                             "items": { | ||||
|                                 "$ref": "#/definitions/model.LoginProviderInfo" | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "/auth/logout": { | ||||
|             "post": { | ||||
|                 "produces": [ | ||||
|  | @ -275,52 +321,6 @@ | |||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "/auth/{provider}/callback": { | ||||
|             "get": { | ||||
|                 "produces": [ | ||||
|                     "application/json" | ||||
|                 ], | ||||
|                 "tags": [ | ||||
|                     "Authentication" | ||||
|                 ], | ||||
|                 "summary": "Handle the OAuth callback.", | ||||
|                 "operationId": "auth_handleOauthCallbackGet", | ||||
|                 "responses": { | ||||
|                     "200": { | ||||
|                         "description": "OK", | ||||
|                         "schema": { | ||||
|                             "type": "array", | ||||
|                             "items": { | ||||
|                                 "$ref": "#/definitions/model.LoginProviderInfo" | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "/auth/{provider}/init": { | ||||
|             "get": { | ||||
|                 "produces": [ | ||||
|                     "application/json" | ||||
|                 ], | ||||
|                 "tags": [ | ||||
|                     "Authentication" | ||||
|                 ], | ||||
|                 "summary": "Initiate the OAuth login flow.", | ||||
|                 "operationId": "auth_handleOauthInitiateGet", | ||||
|                 "responses": { | ||||
|                     "200": { | ||||
|                         "description": "OK", | ||||
|                         "schema": { | ||||
|                             "type": "array", | ||||
|                             "items": { | ||||
|                                 "$ref": "#/definitions/model.LoginProviderInfo" | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "/config/frontend.js": { | ||||
|             "get": { | ||||
|                 "produces": [ | ||||
|  | @ -2234,6 +2234,9 @@ | |||
|                 "MailLinkOnly": { | ||||
|                     "type": "boolean" | ||||
|                 }, | ||||
|                 "MinPasswordLength": { | ||||
|                     "type": "integer" | ||||
|                 }, | ||||
|                 "PersistentConfigSupported": { | ||||
|                     "type": "boolean" | ||||
|                 }, | ||||
|  |  | |||
|  | @ -383,6 +383,8 @@ definitions: | |||
|         type: boolean | ||||
|       MailLinkOnly: | ||||
|         type: boolean | ||||
|       MinPasswordLength: | ||||
|         type: integer | ||||
|       PersistentConfigSupported: | ||||
|         type: boolean | ||||
|       SelfProvisioning: | ||||
|  | @ -472,7 +474,22 @@ paths: | |||
|       summary: Get all available audit entries. Ordered by timestamp. | ||||
|       tags: | ||||
|       - Audit | ||||
|   /auth/{provider}/callback: | ||||
|   /auth/login: | ||||
|     post: | ||||
|       operationId: auth_handleLoginPost | ||||
|       produces: | ||||
|       - application/json | ||||
|       responses: | ||||
|         "200": | ||||
|           description: OK | ||||
|           schema: | ||||
|             items: | ||||
|               $ref: '#/definitions/model.LoginProviderInfo' | ||||
|             type: array | ||||
|       summary: Get all available external login providers. | ||||
|       tags: | ||||
|       - Authentication | ||||
|   /auth/login/{provider}/callback: | ||||
|     get: | ||||
|       operationId: auth_handleOauthCallbackGet | ||||
|       produces: | ||||
|  | @ -487,7 +504,7 @@ paths: | |||
|       summary: Handle the OAuth callback. | ||||
|       tags: | ||||
|       - Authentication | ||||
|   /auth/{provider}/init: | ||||
|   /auth/login/{provider}/init: | ||||
|     get: | ||||
|       operationId: auth_handleOauthInitiateGet | ||||
|       produces: | ||||
|  | @ -502,21 +519,6 @@ paths: | |||
|       summary: Initiate the OAuth login flow. | ||||
|       tags: | ||||
|       - Authentication | ||||
|   /auth/login: | ||||
|     post: | ||||
|       operationId: auth_handleLoginPost | ||||
|       produces: | ||||
|       - application/json | ||||
|       responses: | ||||
|         "200": | ||||
|           description: OK | ||||
|           schema: | ||||
|             items: | ||||
|               $ref: '#/definitions/model.LoginProviderInfo' | ||||
|             type: array | ||||
|       summary: Get all available external login providers. | ||||
|       tags: | ||||
|       - Authentication | ||||
|   /auth/logout: | ||||
|     post: | ||||
|       operationId: auth_handleLogoutPost | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ package handlers | |||
| 
 | ||||
| import ( | ||||
| 	"context" | ||||
| 	"log/slog" | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
| 	"strconv" | ||||
|  | @ -189,7 +190,7 @@ func (e AuthEndpoint) handleSessionInfoGet() http.HandlerFunc { | |||
| // @Summary Initiate the OAuth login flow.
 | ||||
| // @Produce json
 | ||||
| // @Success 200 {object} []model.LoginProviderInfo
 | ||||
| // @Router /auth/{provider}/init [get]
 | ||||
| // @Router /auth/login/{provider}/init [get]
 | ||||
| func (e AuthEndpoint) handleOauthInitiateGet() http.HandlerFunc { | ||||
| 	return func(w http.ResponseWriter, r *http.Request) { | ||||
| 		currentSession := e.session.GetData(r.Context()) | ||||
|  | @ -234,6 +235,8 @@ func (e AuthEndpoint) handleOauthInitiateGet() http.HandlerFunc { | |||
| 
 | ||||
| 		authCodeUrl, state, nonce, err := e.authService.OauthLoginStep1(context.Background(), provider) | ||||
| 		if err != nil { | ||||
| 			slog.Debug("failed to create oauth auth code URL", | ||||
| 				"provider", provider, "error", err) | ||||
| 			if autoRedirect && e.isValidReturnUrl(returnTo) { | ||||
| 				redirectToReturn() | ||||
| 			} else { | ||||
|  | @ -268,7 +271,7 @@ func (e AuthEndpoint) handleOauthInitiateGet() http.HandlerFunc { | |||
| // @Summary Handle the OAuth callback.
 | ||||
| // @Produce json
 | ||||
| // @Success 200 {object} []model.LoginProviderInfo
 | ||||
| // @Router /auth/{provider}/callback [get]
 | ||||
| // @Router /auth/login/{provider}/callback [get]
 | ||||
| func (e AuthEndpoint) handleOauthCallbackGet() http.HandlerFunc { | ||||
| 	return func(w http.ResponseWriter, r *http.Request) { | ||||
| 		currentSession := e.session.GetData(r.Context()) | ||||
|  | @ -306,6 +309,8 @@ func (e AuthEndpoint) handleOauthCallbackGet() http.HandlerFunc { | |||
| 		oauthState := request.Query(r, "state") | ||||
| 
 | ||||
| 		if provider != currentSession.OauthProvider { | ||||
| 			slog.Debug("invalid oauth provider in callback", | ||||
| 				"expected", currentSession.OauthProvider, "got", provider, "state", oauthState) | ||||
| 			if returnUrl != nil && e.isValidReturnUrl(returnUrl.String()) { | ||||
| 				redirectToReturn() | ||||
| 			} else { | ||||
|  | @ -315,6 +320,8 @@ func (e AuthEndpoint) handleOauthCallbackGet() http.HandlerFunc { | |||
| 			return | ||||
| 		} | ||||
| 		if oauthState != currentSession.OauthState { | ||||
| 			slog.Debug("invalid oauth state in callback", | ||||
| 				"expected", currentSession.OauthState, "got", oauthState, "provider", provider) | ||||
| 			if returnUrl != nil && e.isValidReturnUrl(returnUrl.String()) { | ||||
| 				redirectToReturn() | ||||
| 			} else { | ||||
|  | @ -324,11 +331,13 @@ func (e AuthEndpoint) handleOauthCallbackGet() http.HandlerFunc { | |||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		loginCtx, cancel := context.WithTimeout(context.Background(), 1000*time.Second) | ||||
| 		loginCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second) // avoid long waits
 | ||||
| 		user, err := e.authService.OauthLoginStep2(loginCtx, provider, currentSession.OauthNonce, | ||||
| 			oauthCode) | ||||
| 		cancel() | ||||
| 		if err != nil { | ||||
| 			slog.Debug("failed to process oauth code", | ||||
| 				"provider", provider, "state", oauthState, "error", err) | ||||
| 			if returnUrl != nil && e.isValidReturnUrl(returnUrl.String()) { | ||||
| 				redirectToReturn() | ||||
| 			} else { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue