summaryrefslogtreecommitdiffstats
path: root/app/oauth.go
diff options
context:
space:
mode:
authorJoram Wilander <jwawilander@gmail.com>2018-07-27 17:35:43 -0400
committerElias Nahum <nahumhbl@gmail.com>2018-07-27 17:35:43 -0400
commit6ac82d5171769bf8d543cb6c017d29c0a4c81621 (patch)
tree945a5d1511b1eb4048bfaa4ea59777886713d797 /app/oauth.go
parent441c8741c1738e93258b861d92e4f7293203918a (diff)
downloadchat-6ac82d5171769bf8d543cb6c017d29c0a4c81621.tar.gz
chat-6ac82d5171769bf8d543cb6c017d29c0a4c81621.tar.bz2
chat-6ac82d5171769bf8d543cb6c017d29c0a4c81621.zip
Implement OAuth2 implicit grant flow (#9178)
Diffstat (limited to 'app/oauth.go')
-rw-r--r--app/oauth.go73
1 files changed, 66 insertions, 7 deletions
diff --git a/app/oauth.go b/app/oauth.go
index 80fe4342e..af8bca050 100644
--- a/app/oauth.go
+++ b/app/oauth.go
@@ -11,6 +11,7 @@ import (
"io/ioutil"
"net/http"
"net/url"
+ "strconv"
"strings"
"time"
@@ -108,6 +109,33 @@ func (a *App) GetOAuthAppsByCreator(userId string, page, perPage int) ([]*model.
}
}
+func (a *App) GetOAuthImplicitRedirect(userId string, authRequest *model.AuthorizeRequest) (string, *model.AppError) {
+ session, err := a.GetOAuthAccessTokenForImplicitFlow(userId, authRequest)
+ if err != nil {
+ return "", err
+ }
+
+ values := &url.Values{}
+ values.Add("access_token", session.Token)
+ values.Add("token_type", "bearer")
+ values.Add("expires_in", strconv.FormatInt((session.ExpiresAt-model.GetMillis())/1000, 10))
+ values.Add("scope", authRequest.Scope)
+ values.Add("state", authRequest.State)
+
+ return fmt.Sprintf("%s#%s", authRequest.RedirectUri, values.Encode()), nil
+}
+
+func (a *App) GetOAuthCodeRedirect(userId string, authRequest *model.AuthorizeRequest) (string, *model.AppError) {
+ authData := &model.AuthData{UserId: userId, ClientId: authRequest.ClientId, CreateAt: model.GetMillis(), RedirectUri: authRequest.RedirectUri, State: authRequest.State, Scope: authRequest.Scope}
+ authData.Code = model.NewId() + model.NewId()
+
+ if result := <-a.Srv.Store.OAuth().SaveAuthData(authData); result.Err != nil {
+ return authRequest.RedirectUri + "?error=server_error&state=" + authRequest.State, nil
+ }
+
+ return authRequest.RedirectUri + "?code=" + url.QueryEscape(authData.Code) + "&state=" + url.QueryEscape(authData.State), nil
+}
+
func (a *App) AllowOAuthAppAccessToUser(userId string, authRequest *model.AuthorizeRequest) (string, *model.AppError) {
if !a.Config().ServiceSettings.EnableOAuthServiceProvider {
return "", model.NewAppError("AllowOAuthAppAccessToUser", "api.oauth.allow_oauth.turn_off.app_error", nil, "", http.StatusNotImplemented)
@@ -128,12 +156,22 @@ func (a *App) AllowOAuthAppAccessToUser(userId string, authRequest *model.Author
return "", model.NewAppError("AllowOAuthAppAccessToUser", "api.oauth.allow_oauth.redirect_callback.app_error", nil, "", http.StatusBadRequest)
}
- if authRequest.ResponseType != model.AUTHCODE_RESPONSE_TYPE {
+ var redirectURI string
+ var err *model.AppError
+
+ switch authRequest.ResponseType {
+ case model.AUTHCODE_RESPONSE_TYPE:
+ redirectURI, err = a.GetOAuthCodeRedirect(userId, authRequest)
+ case model.IMPLICIT_RESPONSE_TYPE:
+ redirectURI, err = a.GetOAuthImplicitRedirect(userId, authRequest)
+ default:
return authRequest.RedirectUri + "?error=unsupported_response_type&state=" + authRequest.State, nil
}
- authData := &model.AuthData{UserId: userId, ClientId: authRequest.ClientId, CreateAt: model.GetMillis(), RedirectUri: authRequest.RedirectUri, State: authRequest.State, Scope: authRequest.Scope}
- authData.Code = model.NewId() + model.NewId()
+ if err != nil {
+ mlog.Error(err.Error())
+ return authRequest.RedirectUri + "?error=server_error&state=" + authRequest.State, nil
+ }
// this saves the OAuth2 app as authorized
authorizedApp := model.Preference{
@@ -144,17 +182,38 @@ func (a *App) AllowOAuthAppAccessToUser(userId string, authRequest *model.Author
}
if result := <-a.Srv.Store.Preference().Save(&model.Preferences{authorizedApp}); result.Err != nil {
+ mlog.Error(result.Err.Error())
return authRequest.RedirectUri + "?error=server_error&state=" + authRequest.State, nil
}
- if result := <-a.Srv.Store.OAuth().SaveAuthData(authData); result.Err != nil {
- return authRequest.RedirectUri + "?error=server_error&state=" + authRequest.State, nil
+ return redirectURI, nil
+}
+
+func (a *App) GetOAuthAccessTokenForImplicitFlow(userId string, authRequest *model.AuthorizeRequest) (*model.Session, *model.AppError) {
+ if !a.Config().ServiceSettings.EnableOAuthServiceProvider {
+ return nil, model.NewAppError("GetOAuthAccessToken", "api.oauth.get_access_token.disabled.app_error", nil, "", http.StatusNotImplemented)
}
- return authRequest.RedirectUri + "?code=" + url.QueryEscape(authData.Code) + "&state=" + url.QueryEscape(authData.State), nil
+ var oauthApp *model.OAuthApp
+ oauthApp, err := a.GetOAuthApp(authRequest.ClientId)
+ if err != nil {
+ return nil, model.NewAppError("GetOAuthAccessToken", "api.oauth.get_access_token.credentials.app_error", nil, "", http.StatusNotFound)
+ }
+
+ user, err := a.GetUser(userId)
+ if err != nil {
+ return nil, err
+ }
+
+ session, err := a.newSession(oauthApp.Name, user)
+ if err != nil {
+ return nil, err
+ }
+
+ return session, nil
}
-func (a *App) GetOAuthAccessToken(clientId, grantType, redirectUri, code, secret, refreshToken string) (*model.AccessResponse, *model.AppError) {
+func (a *App) GetOAuthAccessTokenForCodeFlow(clientId, grantType, redirectUri, code, secret, refreshToken string) (*model.AccessResponse, *model.AppError) {
if !a.Config().ServiceSettings.EnableOAuthServiceProvider {
return nil, model.NewAppError("GetOAuthAccessToken", "api.oauth.get_access_token.disabled.app_error", nil, "", http.StatusNotImplemented)
}