github.com/turgay/mattermost-server@v5.3.2-0.20181002173352-2945e8a2b0ce+incompatible/api4/oauth.go (about)

     1  // Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package api4
     5  
     6  import (
     7  	"net/http"
     8  	"net/url"
     9  	"path/filepath"
    10  	"strings"
    11  
    12  	"github.com/mattermost/mattermost-server/app"
    13  	"github.com/mattermost/mattermost-server/mlog"
    14  	"github.com/mattermost/mattermost-server/model"
    15  	"github.com/mattermost/mattermost-server/utils"
    16  )
    17  
    18  func (api *API) InitOAuth() {
    19  	api.BaseRoutes.OAuthApps.Handle("", api.ApiSessionRequired(createOAuthApp)).Methods("POST")
    20  	api.BaseRoutes.OAuthApp.Handle("", api.ApiSessionRequired(updateOAuthApp)).Methods("PUT")
    21  	api.BaseRoutes.OAuthApps.Handle("", api.ApiSessionRequired(getOAuthApps)).Methods("GET")
    22  	api.BaseRoutes.OAuthApp.Handle("", api.ApiSessionRequired(getOAuthApp)).Methods("GET")
    23  	api.BaseRoutes.OAuthApp.Handle("/info", api.ApiSessionRequired(getOAuthAppInfo)).Methods("GET")
    24  	api.BaseRoutes.OAuthApp.Handle("", api.ApiSessionRequired(deleteOAuthApp)).Methods("DELETE")
    25  	api.BaseRoutes.OAuthApp.Handle("/regen_secret", api.ApiSessionRequired(regenerateOAuthAppSecret)).Methods("POST")
    26  
    27  	api.BaseRoutes.User.Handle("/oauth/apps/authorized", api.ApiSessionRequired(getAuthorizedOAuthApps)).Methods("GET")
    28  
    29  	// API version independent OAuth 2.0 as a service provider endpoints
    30  	api.BaseRoutes.Root.Handle("/oauth/authorize", api.ApiHandlerTrustRequester(authorizeOAuthPage)).Methods("GET")
    31  	api.BaseRoutes.Root.Handle("/oauth/authorize", api.ApiSessionRequired(authorizeOAuthApp)).Methods("POST")
    32  	api.BaseRoutes.Root.Handle("/oauth/deauthorize", api.ApiSessionRequired(deauthorizeOAuthApp)).Methods("POST")
    33  	api.BaseRoutes.Root.Handle("/oauth/access_token", api.ApiHandlerTrustRequester(getAccessToken)).Methods("POST")
    34  
    35  	// API version independent OAuth as a client endpoints
    36  	api.BaseRoutes.Root.Handle("/oauth/{service:[A-Za-z0-9]+}/complete", api.ApiHandler(completeOAuth)).Methods("GET")
    37  	api.BaseRoutes.Root.Handle("/oauth/{service:[A-Za-z0-9]+}/login", api.ApiHandler(loginWithOAuth)).Methods("GET")
    38  	api.BaseRoutes.Root.Handle("/oauth/{service:[A-Za-z0-9]+}/mobile_login", api.ApiHandler(mobileLoginWithOAuth)).Methods("GET")
    39  	api.BaseRoutes.Root.Handle("/oauth/{service:[A-Za-z0-9]+}/signup", api.ApiHandler(signupWithOAuth)).Methods("GET")
    40  
    41  	// Old endpoints for backwards compatibility, needed to not break SSO for any old setups
    42  	api.BaseRoutes.Root.Handle("/api/v3/oauth/{service:[A-Za-z0-9]+}/complete", api.ApiHandler(completeOAuth)).Methods("GET")
    43  	api.BaseRoutes.Root.Handle("/signup/{service:[A-Za-z0-9]+}/complete", api.ApiHandler(completeOAuth)).Methods("GET")
    44  	api.BaseRoutes.Root.Handle("/login/{service:[A-Za-z0-9]+}/complete", api.ApiHandler(completeOAuth)).Methods("GET")
    45  }
    46  
    47  func createOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) {
    48  	oauthApp := model.OAuthAppFromJson(r.Body)
    49  
    50  	if oauthApp == nil {
    51  		c.SetInvalidParam("oauth_app")
    52  		return
    53  	}
    54  
    55  	if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_OAUTH) {
    56  		c.SetPermissionError(model.PERMISSION_MANAGE_OAUTH)
    57  		return
    58  	}
    59  
    60  	if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
    61  		oauthApp.IsTrusted = false
    62  	}
    63  
    64  	oauthApp.CreatorId = c.Session.UserId
    65  
    66  	rapp, err := c.App.CreateOAuthApp(oauthApp)
    67  	if err != nil {
    68  		c.Err = err
    69  		return
    70  	}
    71  
    72  	c.LogAudit("client_id=" + rapp.Id)
    73  	w.WriteHeader(http.StatusCreated)
    74  	w.Write([]byte(rapp.ToJson()))
    75  }
    76  
    77  func updateOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) {
    78  	c.RequireAppId()
    79  	if c.Err != nil {
    80  		return
    81  	}
    82  
    83  	if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_OAUTH) {
    84  		c.SetPermissionError(model.PERMISSION_MANAGE_OAUTH)
    85  		return
    86  	}
    87  
    88  	oauthApp := model.OAuthAppFromJson(r.Body)
    89  	if oauthApp == nil {
    90  		c.SetInvalidParam("oauth_app")
    91  		return
    92  	}
    93  
    94  	// The app being updated in the payload must be the same one as indicated in the URL.
    95  	if oauthApp.Id != c.Params.AppId {
    96  		c.SetInvalidParam("app_id")
    97  		return
    98  	}
    99  
   100  	c.LogAudit("attempt")
   101  
   102  	oldOauthApp, err := c.App.GetOAuthApp(c.Params.AppId)
   103  	if err != nil {
   104  		c.Err = err
   105  		return
   106  	}
   107  
   108  	if c.Session.UserId != oldOauthApp.CreatorId && !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH) {
   109  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH)
   110  		return
   111  	}
   112  
   113  	updatedOauthApp, err := c.App.UpdateOauthApp(oldOauthApp, oauthApp)
   114  	if err != nil {
   115  		c.Err = err
   116  		return
   117  	}
   118  
   119  	c.LogAudit("success")
   120  
   121  	w.Write([]byte(updatedOauthApp.ToJson()))
   122  }
   123  
   124  func getOAuthApps(c *Context, w http.ResponseWriter, r *http.Request) {
   125  	if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_OAUTH) {
   126  		c.Err = model.NewAppError("getOAuthApps", "api.command.admin_only.app_error", nil, "", http.StatusForbidden)
   127  		return
   128  	}
   129  
   130  	var apps []*model.OAuthApp
   131  	var err *model.AppError
   132  	if c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH) {
   133  		apps, err = c.App.GetOAuthApps(c.Params.Page, c.Params.PerPage)
   134  	} else if c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_OAUTH) {
   135  		apps, err = c.App.GetOAuthAppsByCreator(c.Session.UserId, c.Params.Page, c.Params.PerPage)
   136  	} else {
   137  		c.SetPermissionError(model.PERMISSION_MANAGE_OAUTH)
   138  		return
   139  	}
   140  
   141  	if err != nil {
   142  		c.Err = err
   143  		return
   144  	}
   145  
   146  	w.Write([]byte(model.OAuthAppListToJson(apps)))
   147  }
   148  
   149  func getOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) {
   150  	c.RequireAppId()
   151  	if c.Err != nil {
   152  		return
   153  	}
   154  
   155  	if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_OAUTH) {
   156  		c.SetPermissionError(model.PERMISSION_MANAGE_OAUTH)
   157  		return
   158  	}
   159  
   160  	oauthApp, err := c.App.GetOAuthApp(c.Params.AppId)
   161  	if err != nil {
   162  		c.Err = err
   163  		return
   164  	}
   165  
   166  	if oauthApp.CreatorId != c.Session.UserId && !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH) {
   167  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH)
   168  		return
   169  	}
   170  
   171  	w.Write([]byte(oauthApp.ToJson()))
   172  }
   173  
   174  func getOAuthAppInfo(c *Context, w http.ResponseWriter, r *http.Request) {
   175  	c.RequireAppId()
   176  	if c.Err != nil {
   177  		return
   178  	}
   179  
   180  	oauthApp, err := c.App.GetOAuthApp(c.Params.AppId)
   181  	if err != nil {
   182  		c.Err = err
   183  		return
   184  	}
   185  
   186  	oauthApp.Sanitize()
   187  	w.Write([]byte(oauthApp.ToJson()))
   188  }
   189  
   190  func deleteOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) {
   191  	c.RequireAppId()
   192  	if c.Err != nil {
   193  		return
   194  	}
   195  
   196  	c.LogAudit("attempt")
   197  
   198  	if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_OAUTH) {
   199  		c.SetPermissionError(model.PERMISSION_MANAGE_OAUTH)
   200  		return
   201  	}
   202  
   203  	oauthApp, err := c.App.GetOAuthApp(c.Params.AppId)
   204  	if err != nil {
   205  		c.Err = err
   206  		return
   207  	}
   208  
   209  	if c.Session.UserId != oauthApp.CreatorId && !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH) {
   210  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH)
   211  		return
   212  	}
   213  
   214  	err = c.App.DeleteOAuthApp(oauthApp.Id)
   215  	if err != nil {
   216  		c.Err = err
   217  		return
   218  	}
   219  
   220  	c.LogAudit("success")
   221  	ReturnStatusOK(w)
   222  }
   223  
   224  func regenerateOAuthAppSecret(c *Context, w http.ResponseWriter, r *http.Request) {
   225  	c.RequireAppId()
   226  	if c.Err != nil {
   227  		return
   228  	}
   229  
   230  	if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_OAUTH) {
   231  		c.SetPermissionError(model.PERMISSION_MANAGE_OAUTH)
   232  		return
   233  	}
   234  
   235  	oauthApp, err := c.App.GetOAuthApp(c.Params.AppId)
   236  	if err != nil {
   237  		c.Err = err
   238  		return
   239  	}
   240  
   241  	if oauthApp.CreatorId != c.Session.UserId && !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH) {
   242  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH)
   243  		return
   244  	}
   245  
   246  	oauthApp, err = c.App.RegenerateOAuthAppSecret(oauthApp)
   247  	if err != nil {
   248  		c.Err = err
   249  		return
   250  	}
   251  
   252  	c.LogAudit("success")
   253  	w.Write([]byte(oauthApp.ToJson()))
   254  }
   255  
   256  func getAuthorizedOAuthApps(c *Context, w http.ResponseWriter, r *http.Request) {
   257  	c.RequireUserId()
   258  	if c.Err != nil {
   259  		return
   260  	}
   261  
   262  	if !c.App.SessionHasPermissionToUser(c.Session, c.Params.UserId) {
   263  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
   264  		return
   265  	}
   266  
   267  	apps, err := c.App.GetAuthorizedAppsForUser(c.Params.UserId, c.Params.Page, c.Params.PerPage)
   268  	if err != nil {
   269  		c.Err = err
   270  		return
   271  	}
   272  
   273  	w.Write([]byte(model.OAuthAppListToJson(apps)))
   274  }
   275  
   276  func authorizeOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) {
   277  	authRequest := model.AuthorizeRequestFromJson(r.Body)
   278  	if authRequest == nil {
   279  		c.SetInvalidParam("authorize_request")
   280  	}
   281  
   282  	if err := authRequest.IsValid(); err != nil {
   283  		c.Err = err
   284  		return
   285  	}
   286  
   287  	if c.Session.IsOAuth {
   288  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
   289  		c.Err.DetailedError += ", attempted access by oauth app"
   290  		return
   291  	}
   292  
   293  	c.LogAudit("attempt")
   294  
   295  	redirectUrl, err := c.App.AllowOAuthAppAccessToUser(c.Session.UserId, authRequest)
   296  
   297  	if err != nil {
   298  		c.Err = err
   299  		return
   300  	}
   301  
   302  	c.LogAudit("")
   303  
   304  	w.Write([]byte(model.MapToJson(map[string]string{"redirect": redirectUrl})))
   305  }
   306  
   307  func deauthorizeOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) {
   308  	requestData := model.MapFromJson(r.Body)
   309  	clientId := requestData["client_id"]
   310  
   311  	if len(clientId) != 26 {
   312  		c.SetInvalidParam("client_id")
   313  		return
   314  	}
   315  
   316  	err := c.App.DeauthorizeOAuthAppForUser(c.Session.UserId, clientId)
   317  	if err != nil {
   318  		c.Err = err
   319  		return
   320  	}
   321  
   322  	c.LogAudit("success")
   323  	ReturnStatusOK(w)
   324  }
   325  
   326  func authorizeOAuthPage(c *Context, w http.ResponseWriter, r *http.Request) {
   327  	if !c.App.Config().ServiceSettings.EnableOAuthServiceProvider {
   328  		err := model.NewAppError("authorizeOAuth", "api.oauth.authorize_oauth.disabled.app_error", nil, "", http.StatusNotImplemented)
   329  		utils.RenderWebAppError(c.App.Config(), w, r, err, c.App.AsymmetricSigningKey())
   330  		return
   331  	}
   332  
   333  	authRequest := &model.AuthorizeRequest{
   334  		ResponseType: r.URL.Query().Get("response_type"),
   335  		ClientId:     r.URL.Query().Get("client_id"),
   336  		RedirectUri:  r.URL.Query().Get("redirect_uri"),
   337  		Scope:        r.URL.Query().Get("scope"),
   338  		State:        r.URL.Query().Get("state"),
   339  	}
   340  
   341  	loginHint := r.URL.Query().Get("login_hint")
   342  
   343  	if err := authRequest.IsValid(); err != nil {
   344  		utils.RenderWebAppError(c.App.Config(), w, r, err, c.App.AsymmetricSigningKey())
   345  		return
   346  	}
   347  
   348  	oauthApp, err := c.App.GetOAuthApp(authRequest.ClientId)
   349  	if err != nil {
   350  		utils.RenderWebAppError(c.App.Config(), w, r, err, c.App.AsymmetricSigningKey())
   351  		return
   352  	}
   353  
   354  	// here we should check if the user is logged in
   355  	if len(c.Session.UserId) == 0 {
   356  		if loginHint == model.USER_AUTH_SERVICE_SAML {
   357  			http.Redirect(w, r, c.GetSiteURLHeader()+"/login/sso/saml?redirect_to="+url.QueryEscape(r.RequestURI), http.StatusFound)
   358  		} else {
   359  			http.Redirect(w, r, c.GetSiteURLHeader()+"/login?redirect_to="+url.QueryEscape(r.RequestURI), http.StatusFound)
   360  		}
   361  		return
   362  	}
   363  
   364  	if !oauthApp.IsValidRedirectURL(authRequest.RedirectUri) {
   365  		err := model.NewAppError("authorizeOAuthPage", "api.oauth.allow_oauth.redirect_callback.app_error", nil, "", http.StatusBadRequest)
   366  		utils.RenderWebAppError(c.App.Config(), w, r, err, c.App.AsymmetricSigningKey())
   367  		return
   368  	}
   369  
   370  	isAuthorized := false
   371  
   372  	if _, err := c.App.GetPreferenceByCategoryAndNameForUser(c.Session.UserId, model.PREFERENCE_CATEGORY_AUTHORIZED_OAUTH_APP, authRequest.ClientId); err == nil {
   373  		// when we support scopes we should check if the scopes match
   374  		isAuthorized = true
   375  	}
   376  
   377  	// Automatically allow if the app is trusted
   378  	if oauthApp.IsTrusted || isAuthorized {
   379  		redirectUrl, err := c.App.AllowOAuthAppAccessToUser(c.Session.UserId, authRequest)
   380  
   381  		if err != nil {
   382  			utils.RenderWebAppError(c.App.Config(), w, r, err, c.App.AsymmetricSigningKey())
   383  			return
   384  		}
   385  
   386  		http.Redirect(w, r, redirectUrl, http.StatusFound)
   387  		return
   388  	}
   389  
   390  	w.Header().Set("X-Frame-Options", "SAMEORIGIN")
   391  	w.Header().Set("Content-Security-Policy", "frame-ancestors 'self'")
   392  	w.Header().Set("Content-Type", "text/html; charset=utf-8")
   393  	w.Header().Set("Cache-Control", "no-cache, max-age=31556926, public")
   394  
   395  	staticDir, _ := utils.FindDir(model.CLIENT_DIR)
   396  	http.ServeFile(w, r, filepath.Join(staticDir, "root.html"))
   397  }
   398  
   399  func getAccessToken(c *Context, w http.ResponseWriter, r *http.Request) {
   400  	r.ParseForm()
   401  
   402  	code := r.FormValue("code")
   403  	refreshToken := r.FormValue("refresh_token")
   404  
   405  	grantType := r.FormValue("grant_type")
   406  	switch grantType {
   407  	case model.ACCESS_TOKEN_GRANT_TYPE:
   408  		if len(code) == 0 {
   409  			c.Err = model.NewAppError("getAccessToken", "api.oauth.get_access_token.missing_code.app_error", nil, "", http.StatusBadRequest)
   410  			return
   411  		}
   412  	case model.REFRESH_TOKEN_GRANT_TYPE:
   413  		if len(refreshToken) == 0 {
   414  			c.Err = model.NewAppError("getAccessToken", "api.oauth.get_access_token.missing_refresh_token.app_error", nil, "", http.StatusBadRequest)
   415  			return
   416  		}
   417  	default:
   418  		c.Err = model.NewAppError("getAccessToken", "api.oauth.get_access_token.bad_grant.app_error", nil, "", http.StatusBadRequest)
   419  		return
   420  	}
   421  
   422  	clientId := r.FormValue("client_id")
   423  	if len(clientId) != 26 {
   424  		c.Err = model.NewAppError("getAccessToken", "api.oauth.get_access_token.bad_client_id.app_error", nil, "", http.StatusBadRequest)
   425  		return
   426  	}
   427  
   428  	secret := r.FormValue("client_secret")
   429  	if len(secret) == 0 {
   430  		c.Err = model.NewAppError("getAccessToken", "api.oauth.get_access_token.bad_client_secret.app_error", nil, "", http.StatusBadRequest)
   431  		return
   432  	}
   433  
   434  	redirectUri := r.FormValue("redirect_uri")
   435  
   436  	c.LogAudit("attempt")
   437  
   438  	accessRsp, err := c.App.GetOAuthAccessTokenForCodeFlow(clientId, grantType, redirectUri, code, secret, refreshToken)
   439  	if err != nil {
   440  		c.Err = err
   441  		return
   442  	}
   443  
   444  	w.Header().Set("Content-Type", "application/json")
   445  	w.Header().Set("Cache-Control", "no-store")
   446  	w.Header().Set("Pragma", "no-cache")
   447  
   448  	c.LogAudit("success")
   449  
   450  	w.Write([]byte(accessRsp.ToJson()))
   451  }
   452  
   453  func completeOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
   454  	c.RequireService()
   455  	if c.Err != nil {
   456  		return
   457  	}
   458  
   459  	service := c.Params.Service
   460  
   461  	oauthError := r.URL.Query().Get("error")
   462  	if oauthError == "access_denied" {
   463  		utils.RenderWebError(c.App.Config(), w, r, http.StatusTemporaryRedirect, url.Values{
   464  			"type":    []string{"oauth_access_denied"},
   465  			"service": []string{strings.Title(service)},
   466  		}, c.App.AsymmetricSigningKey())
   467  		return
   468  	}
   469  
   470  	code := r.URL.Query().Get("code")
   471  	if len(code) == 0 {
   472  		utils.RenderWebError(c.App.Config(), w, r, http.StatusTemporaryRedirect, url.Values{
   473  			"type":    []string{"oauth_missing_code"},
   474  			"service": []string{strings.Title(service)},
   475  		}, c.App.AsymmetricSigningKey())
   476  		return
   477  	}
   478  
   479  	state := r.URL.Query().Get("state")
   480  
   481  	uri := c.GetSiteURLHeader() + "/signup/" + service + "/complete"
   482  
   483  	body, teamId, props, err := c.App.AuthorizeOAuthUser(w, r, service, code, state, uri)
   484  
   485  	action := ""
   486  	if props != nil {
   487  		action = props["action"]
   488  	}
   489  
   490  	if err != nil {
   491  		err.Translate(c.T)
   492  		mlog.Error(err.Error())
   493  		if action == model.OAUTH_ACTION_MOBILE {
   494  			w.Write([]byte(err.ToJson()))
   495  		} else {
   496  			utils.RenderWebAppError(c.App.Config(), w, r, err, c.App.AsymmetricSigningKey())
   497  		}
   498  		return
   499  	}
   500  
   501  	user, err := c.App.CompleteOAuth(service, body, teamId, props)
   502  	if err != nil {
   503  		err.Translate(c.T)
   504  		mlog.Error(err.Error())
   505  		if action == model.OAUTH_ACTION_MOBILE {
   506  			w.Write([]byte(err.ToJson()))
   507  		} else {
   508  			utils.RenderWebAppError(c.App.Config(), w, r, err, c.App.AsymmetricSigningKey())
   509  		}
   510  		return
   511  	}
   512  
   513  	var redirectUrl string
   514  	if action == model.OAUTH_ACTION_EMAIL_TO_SSO {
   515  		redirectUrl = c.GetSiteURLHeader() + "/login?extra=signin_change"
   516  	} else if action == model.OAUTH_ACTION_SSO_TO_EMAIL {
   517  
   518  		redirectUrl = app.GetProtocol(r) + "://" + r.Host + "/claim?email=" + url.QueryEscape(props["email"])
   519  	} else {
   520  		session, err := c.App.DoLogin(w, r, user, "")
   521  		if err != nil {
   522  			err.Translate(c.T)
   523  			c.Err = err
   524  			if action == model.OAUTH_ACTION_MOBILE {
   525  				w.Write([]byte(err.ToJson()))
   526  			}
   527  			return
   528  		}
   529  
   530  		c.Session = *session
   531  
   532  		redirectUrl = c.GetSiteURLHeader()
   533  	}
   534  
   535  	if action == model.OAUTH_ACTION_MOBILE {
   536  		ReturnStatusOK(w)
   537  		return
   538  	}
   539  
   540  	http.Redirect(w, r, redirectUrl, http.StatusTemporaryRedirect)
   541  }
   542  
   543  func loginWithOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
   544  	c.RequireService()
   545  	if c.Err != nil {
   546  		return
   547  	}
   548  
   549  	loginHint := r.URL.Query().Get("login_hint")
   550  	redirectTo := r.URL.Query().Get("redirect_to")
   551  
   552  	teamId, err := c.App.GetTeamIdFromQuery(r.URL.Query())
   553  	if err != nil {
   554  		c.Err = err
   555  		return
   556  	}
   557  
   558  	authUrl, err := c.App.GetOAuthLoginEndpoint(w, r, c.Params.Service, teamId, model.OAUTH_ACTION_LOGIN, redirectTo, loginHint)
   559  	if err != nil {
   560  		c.Err = err
   561  		return
   562  	}
   563  
   564  	http.Redirect(w, r, authUrl, http.StatusFound)
   565  }
   566  
   567  func mobileLoginWithOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
   568  	c.RequireService()
   569  	if c.Err != nil {
   570  		return
   571  	}
   572  
   573  	teamId, err := c.App.GetTeamIdFromQuery(r.URL.Query())
   574  	if err != nil {
   575  		c.Err = err
   576  		return
   577  	}
   578  
   579  	authUrl, err := c.App.GetOAuthLoginEndpoint(w, r, c.Params.Service, teamId, model.OAUTH_ACTION_MOBILE, "", "")
   580  	if err != nil {
   581  		c.Err = err
   582  		return
   583  	}
   584  
   585  	http.Redirect(w, r, authUrl, http.StatusFound)
   586  }
   587  
   588  func signupWithOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
   589  	c.RequireService()
   590  	if c.Err != nil {
   591  		return
   592  	}
   593  
   594  	if !*c.App.Config().TeamSettings.EnableUserCreation {
   595  		utils.RenderWebError(c.App.Config(), w, r, http.StatusBadRequest, url.Values{
   596  			"message": []string{utils.T("api.oauth.singup_with_oauth.disabled.app_error")},
   597  		}, c.App.AsymmetricSigningKey())
   598  		return
   599  	}
   600  
   601  	teamId, err := c.App.GetTeamIdFromQuery(r.URL.Query())
   602  	if err != nil {
   603  		c.Err = err
   604  		return
   605  	}
   606  
   607  	authUrl, err := c.App.GetOAuthSignupEndpoint(w, r, c.Params.Service, teamId)
   608  	if err != nil {
   609  		c.Err = err
   610  		return
   611  	}
   612  
   613  	http.Redirect(w, r, authUrl, http.StatusFound)
   614  }