mirror of
https://github.com/steveiliop56/tinyauth.git
synced 2026-05-27 14:40:14 +00:00
refactor: simplify error handling in oidc authorize handler (#907)
This commit is contained in:
@@ -16,6 +16,15 @@ import (
|
|||||||
"github.com/tinyauthapp/tinyauth/internal/utils/logger"
|
"github.com/tinyauthapp/tinyauth/internal/utils/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type authorizeErrorParams struct {
|
||||||
|
err error
|
||||||
|
reason string
|
||||||
|
reasonPublic string
|
||||||
|
callback string
|
||||||
|
callbackError string
|
||||||
|
state string
|
||||||
|
}
|
||||||
|
|
||||||
type OIDCController struct {
|
type OIDCController struct {
|
||||||
log *logger.Logger
|
log *logger.Logger
|
||||||
oidc *service.OIDCService
|
oidc *service.OIDCService
|
||||||
@@ -119,34 +128,55 @@ func (controller *OIDCController) GetClientInfo(c *gin.Context) {
|
|||||||
|
|
||||||
func (controller *OIDCController) Authorize(c *gin.Context) {
|
func (controller *OIDCController) Authorize(c *gin.Context) {
|
||||||
if controller.oidc == nil {
|
if controller.oidc == nil {
|
||||||
controller.authorizeError(c, errors.New("err_oidc_not_configured"), "OIDC not configured", "This instance is not configured for OIDC", "", "", "")
|
controller.authorizeError(c, authorizeErrorParams{
|
||||||
|
err: errors.New("err_oidc_not_configured"),
|
||||||
|
reason: "OIDC not configured",
|
||||||
|
reasonPublic: "This instance is not configured for OIDC",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
userContext, err := new(model.UserContext).NewFromGin(c)
|
userContext, err := new(model.UserContext).NewFromGin(c)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
controller.authorizeError(c, err, "Failed to get user context", "User is not logged in or the session is invalid", "", "", "")
|
controller.authorizeError(c, authorizeErrorParams{
|
||||||
|
err: err,
|
||||||
|
reason: "Failed to get user context",
|
||||||
|
reasonPublic: "User is not logged in or the session is invalid",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !userContext.Authenticated {
|
if !userContext.Authenticated {
|
||||||
controller.authorizeError(c, errors.New("err user not logged in"), "User not logged in", "The user is not logged in", "", "", "")
|
controller.authorizeError(c, authorizeErrorParams{
|
||||||
|
err: errors.New("err user not logged in"),
|
||||||
|
reason: "User not logged in",
|
||||||
|
reasonPublic: "The user is not logged in",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var req service.AuthorizeRequest
|
var req service.AuthorizeRequest
|
||||||
|
|
||||||
err = c.BindJSON(&req)
|
err = c.Bind(&req)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
controller.authorizeError(c, err, "Failed to bind JSON", "The client provided an invalid authorization request", "", "", "")
|
controller.authorizeError(c, authorizeErrorParams{
|
||||||
|
err: err,
|
||||||
|
reason: "Failed to bind JSON",
|
||||||
|
reasonPublic: "The client provided an invalid authorization request",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
client, ok := controller.oidc.GetClient(req.ClientID)
|
client, ok := controller.oidc.GetClient(req.ClientID)
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
controller.authorizeError(c, fmt.Errorf("client not found: %s", req.ClientID), "Client not found", "The client ID is invalid", "", "", "")
|
controller.authorizeError(c, authorizeErrorParams{
|
||||||
|
err: fmt.Errorf("client not found: %s", req.ClientID),
|
||||||
|
reason: "Client not found",
|
||||||
|
reasonPublic: "The client ID is invalid",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,10 +185,21 @@ func (controller *OIDCController) Authorize(c *gin.Context) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
controller.log.App.Warn().Err(err).Msg("Failed to validate authorize params")
|
controller.log.App.Warn().Err(err).Msg("Failed to validate authorize params")
|
||||||
if err.Error() != "invalid_request_uri" {
|
if err.Error() != "invalid_request_uri" {
|
||||||
controller.authorizeError(c, err, "Failed validate authorize params", "Invalid request parameters", req.RedirectURI, err.Error(), req.State)
|
controller.authorizeError(c, authorizeErrorParams{
|
||||||
|
err: err,
|
||||||
|
reason: "Failed validate authorize params",
|
||||||
|
reasonPublic: "Invalid request parameters",
|
||||||
|
callback: req.RedirectURI,
|
||||||
|
callbackError: err.Error(),
|
||||||
|
state: req.State,
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
controller.authorizeError(c, err, "Redirect URI not trusted", "The provided redirect URI is not trusted", "", "", "")
|
controller.authorizeError(c, authorizeErrorParams{
|
||||||
|
err: err,
|
||||||
|
reason: "Redirect URI not trusted",
|
||||||
|
reasonPublic: "The provided redirect URI is not trusted",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,14 +210,28 @@ func (controller *OIDCController) Authorize(c *gin.Context) {
|
|||||||
// Before storing the code, delete old session
|
// Before storing the code, delete old session
|
||||||
err = controller.oidc.DeleteOldSession(c, sub)
|
err = controller.oidc.DeleteOldSession(c, sub)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
controller.authorizeError(c, err, "Failed to delete old sessions", "Failed to delete old sessions", req.RedirectURI, "server_error", req.State)
|
controller.authorizeError(c, authorizeErrorParams{
|
||||||
|
err: err,
|
||||||
|
reason: "Failed to delete old sessions",
|
||||||
|
reasonPublic: "Failed to delete old sessions",
|
||||||
|
callback: req.RedirectURI,
|
||||||
|
callbackError: "server_error",
|
||||||
|
state: req.State,
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = controller.oidc.StoreCode(c, sub, code, req)
|
err = controller.oidc.StoreCode(c, sub, code, req)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
controller.authorizeError(c, err, "Failed to store code", "Failed to store code", req.RedirectURI, "server_error", req.State)
|
controller.authorizeError(c, authorizeErrorParams{
|
||||||
|
err: err,
|
||||||
|
reason: "Failed to store code",
|
||||||
|
reasonPublic: "Failed to store code",
|
||||||
|
callback: req.RedirectURI,
|
||||||
|
callbackError: "server_error",
|
||||||
|
state: req.State,
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,7 +241,14 @@ func (controller *OIDCController) Authorize(c *gin.Context) {
|
|||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
controller.log.App.Error().Err(err).Msg("Failed to store user info")
|
controller.log.App.Error().Err(err).Msg("Failed to store user info")
|
||||||
controller.authorizeError(c, err, "Failed to store user info", "Failed to store user info", req.RedirectURI, "server_error", req.State)
|
controller.authorizeError(c, authorizeErrorParams{
|
||||||
|
err: err,
|
||||||
|
reason: "Failed to store user info",
|
||||||
|
reasonPublic: "Failed to store user info",
|
||||||
|
callback: req.RedirectURI,
|
||||||
|
callbackError: "server_error",
|
||||||
|
state: req.State,
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -197,7 +259,14 @@ func (controller *OIDCController) Authorize(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
controller.authorizeError(c, err, "Failed to build query", "Failed to build query", req.RedirectURI, "server_error", req.State)
|
controller.authorizeError(c, authorizeErrorParams{
|
||||||
|
err: err,
|
||||||
|
reason: "Failed to build query",
|
||||||
|
reasonPublic: "Failed to build query",
|
||||||
|
callback: req.RedirectURI,
|
||||||
|
callbackError: "server_error",
|
||||||
|
state: req.State,
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -478,20 +547,20 @@ func (controller *OIDCController) Userinfo(c *gin.Context) {
|
|||||||
c.JSON(200, controller.oidc.CompileUserinfo(user, entry.Scope))
|
c.JSON(200, controller.oidc.CompileUserinfo(user, entry.Scope))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (controller *OIDCController) authorizeError(c *gin.Context, err error, reason string, reasonUser string, callback string, callbackError string, state string) {
|
func (controller *OIDCController) authorizeError(c *gin.Context, params authorizeErrorParams) {
|
||||||
controller.log.App.Warn().Err(err).Str("reason", reason).Msg("Authorization error")
|
controller.log.App.Error().Err(params.err).Str("reason", params.reason).Msg("Authorization error")
|
||||||
|
|
||||||
if callback != "" {
|
if params.callback != "" {
|
||||||
errorQueries := CallbackError{
|
errorQueries := CallbackError{
|
||||||
Error: callbackError,
|
Error: params.callbackError,
|
||||||
}
|
}
|
||||||
|
|
||||||
if reasonUser != "" {
|
if params.reasonPublic != "" {
|
||||||
errorQueries.ErrorDescription = reasonUser
|
errorQueries.ErrorDescription = params.reasonPublic
|
||||||
}
|
}
|
||||||
|
|
||||||
if state != "" {
|
if params.state != "" {
|
||||||
errorQueries.State = state
|
errorQueries.State = params.state
|
||||||
}
|
}
|
||||||
|
|
||||||
queries, err := query.Values(errorQueries)
|
queries, err := query.Values(errorQueries)
|
||||||
@@ -503,13 +572,13 @@ func (controller *OIDCController) authorizeError(c *gin.Context, err error, reas
|
|||||||
|
|
||||||
c.JSON(200, gin.H{
|
c.JSON(200, gin.H{
|
||||||
"status": 200,
|
"status": 200,
|
||||||
"redirect_uri": fmt.Sprintf("%s?%s", callback, queries.Encode()),
|
"redirect_uri": fmt.Sprintf("%s?%s", params.callback, queries.Encode()),
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
errorQueries := ErrorScreen{
|
errorQueries := ErrorScreen{
|
||||||
Error: reasonUser,
|
Error: params.reasonPublic,
|
||||||
}
|
}
|
||||||
|
|
||||||
queries, err := query.Values(errorQueries)
|
queries, err := query.Values(errorQueries)
|
||||||
|
|||||||
Reference in New Issue
Block a user