From f6bdc5c2b362db99bd9517f42795bdaba1049ce4 Mon Sep 17 00:00:00 2001 From: Chaim Lev Ari Date: Wed, 16 Jan 2019 17:01:38 +0200 Subject: [PATCH] refactor(auth): move oauth handler code to its own file --- api/http/handler/auth/authenticate.go | 54 ----------------- api/http/handler/auth/authenticate_oauth.go | 64 +++++++++++++++++++++ 2 files changed, 64 insertions(+), 54 deletions(-) create mode 100644 api/http/handler/auth/authenticate_oauth.go diff --git a/api/http/handler/auth/authenticate.go b/api/http/handler/auth/authenticate.go index a0fbf7c51..8183c2f7b 100644 --- a/api/http/handler/auth/authenticate.go +++ b/api/http/handler/auth/authenticate.go @@ -93,60 +93,6 @@ func (handler *Handler) authenticateLDAP(w http.ResponseWriter, user *portainer. return handler.writeToken(w, user) } -func (handler *Handler) authenticateOAuth(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { - var payload oauthPayload - err := request.DecodeAndValidateJSONPayload(r, &payload) - if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} - } - - settings, err := handler.SettingsService.Settings() - if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve settings from the database", err} - } - - if settings.AuthenticationMethod != 3 { - return &httperror.HandlerError{http.StatusForbidden, "OAuth authentication is not being used", err} - } - - token, err := handler.OAuthService.GetAccessToken(payload.Code, &settings.OAuthSettings) - if err != nil { - log.Printf("[DEBUG] - Failed retrieving access token: %v", err) - return &httperror.HandlerError{http.StatusUnprocessableEntity, "Invalid access token", portainer.ErrUnauthorized} - } - - username, err := handler.OAuthService.GetUsername(token, &settings.OAuthSettings) - if err != nil { - log.Printf("[DEBUG] - Failed acquiring username: %v", err) - return &httperror.HandlerError{http.StatusForbidden, "Unable to acquire username", portainer.ErrUnauthorized} - } - - u, err := handler.UserService.UserByUsername(username) - if err != nil && err != portainer.ErrObjectNotFound { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve a user with the specified username from the database", err} - } - - if u == nil && !settings.OAuthSettings.OAuthAutoCreateUsers { - return &httperror.HandlerError{http.StatusForbidden, "Unregistered account", portainer.ErrUnauthorized} - } - - if u == nil { - user := &portainer.User{ - Username: username, - Role: portainer.StandardUserRole, - } - - err = handler.UserService.CreateUser(user) - if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist user inside the database", err} - } - - return handler.writeToken(w, user) - } - - return handler.writeToken(w, u) -} - func (handler *Handler) authenticateInternal(w http.ResponseWriter, user *portainer.User, password string) *httperror.HandlerError { err := handler.CryptoService.CompareHashAndData(user.Password, password) if err != nil { diff --git a/api/http/handler/auth/authenticate_oauth.go b/api/http/handler/auth/authenticate_oauth.go new file mode 100644 index 000000000..58319b9df --- /dev/null +++ b/api/http/handler/auth/authenticate_oauth.go @@ -0,0 +1,64 @@ +package auth + +import ( + "log" + "net/http" + + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/portainer" +) + +func (handler *Handler) authenticateOAuth(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { + var payload oauthPayload + err := request.DecodeAndValidateJSONPayload(r, &payload) + if err != nil { + return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + } + + settings, err := handler.SettingsService.Settings() + if err != nil { + return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve settings from the database", err} + } + + if settings.AuthenticationMethod != 3 { + return &httperror.HandlerError{http.StatusForbidden, "OAuth authentication is not being used", err} + } + + token, err := handler.OAuthService.GetAccessToken(payload.Code, &settings.OAuthSettings) + if err != nil { + log.Printf("[DEBUG] - Failed retrieving access token: %v", err) + return &httperror.HandlerError{http.StatusUnprocessableEntity, "Invalid access token", portainer.ErrUnauthorized} + } + + username, err := handler.OAuthService.GetUsername(token, &settings.OAuthSettings) + if err != nil { + log.Printf("[DEBUG] - Failed acquiring username: %v", err) + return &httperror.HandlerError{http.StatusForbidden, "Unable to acquire username", portainer.ErrUnauthorized} + } + + u, err := handler.UserService.UserByUsername(username) + if err != nil && err != portainer.ErrObjectNotFound { + return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve a user with the specified username from the database", err} + } + + if u == nil && !settings.OAuthSettings.OAuthAutoCreateUsers { + return &httperror.HandlerError{http.StatusForbidden, "Unregistered account", portainer.ErrUnauthorized} + } + + if u == nil { + user := &portainer.User{ + Username: username, + Role: portainer.StandardUserRole, + } + + err = handler.UserService.CreateUser(user) + if err != nil { + return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist user inside the database", err} + } + + return handler.writeToken(w, user) + } + + return handler.writeToken(w, u) +}