[MM-37984] Allow Desktop App to authenticate via external providers outside of the app on supported servers (#23795)
* WIP * Add rate limiting for desktop token API * Missing mocks * Style fixes * Update snapshots * Maybe use an actual redirect link :P * Refactoring for tests * Add tests for server * Fix lint issue * Fix tests * Fix lint * Add front-end screen component * Component logic * Style changes * Quick style fix * Lint fixes * Initial PR feedback * Enable logging into the browser as well when completing the login process * Refactor to push more logic to the other component * Remove unnecessary helper code * Fix i18n --------- Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
5e3c03a0a8
Коммит
abdf4e58c3
@@ -10,6 +10,7 @@ import (
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/public/shared/i18n"
|
||||
@@ -343,6 +344,29 @@ func completeOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
} else { // For web
|
||||
c.App.AttachSessionCookies(c.AppContext, w, r)
|
||||
}
|
||||
|
||||
desktopToken := ""
|
||||
if val, ok := props["desktop_token"]; ok {
|
||||
desktopToken = val
|
||||
}
|
||||
|
||||
if desktopToken != "" {
|
||||
desktopTokenErr := c.App.AuthenticateDesktopToken(desktopToken, time.Now().Add(-model.DesktopTokenTTL).Unix(), user)
|
||||
if desktopTokenErr != nil {
|
||||
desktopTokenErr.Translate(c.AppContext.T)
|
||||
c.LogErrorByCode(desktopTokenErr)
|
||||
renderError(desktopTokenErr)
|
||||
return
|
||||
}
|
||||
|
||||
queryString := map[string]string{
|
||||
"desktopAuthComplete": "true",
|
||||
}
|
||||
if val, ok := props["redirect_to"]; ok {
|
||||
queryString["redirect_to"] = val
|
||||
}
|
||||
redirectURL = utils.AppendQueryParamsToURL(c.GetSiteURLHeader()+"/login/desktop", queryString)
|
||||
}
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
@@ -357,6 +381,15 @@ func loginWithOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
loginHint := r.URL.Query().Get("login_hint")
|
||||
redirectURL := r.URL.Query().Get("redirect_to")
|
||||
desktopToken := r.URL.Query().Get("desktop_token")
|
||||
if desktopToken != "" {
|
||||
desktopTokenErr := c.App.CreateDesktopToken(desktopToken, time.Now().Unix())
|
||||
|
||||
if desktopTokenErr != nil {
|
||||
c.Err = desktopTokenErr
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if redirectURL != "" && !utils.IsValidWebAuthRedirectURL(c.App.Config(), redirectURL) {
|
||||
c.Err = model.NewAppError("loginWithOAuth", "api.invalid_redirect_url", nil, "", http.StatusBadRequest)
|
||||
@@ -369,7 +402,7 @@ func loginWithOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
authURL, err := c.App.GetOAuthLoginEndpoint(w, r, c.Params.Service, teamId, model.OAuthActionLogin, redirectURL, loginHint, false)
|
||||
authURL, err := c.App.GetOAuthLoginEndpoint(w, r, c.Params.Service, teamId, model.OAuthActionLogin, redirectURL, loginHint, false, desktopToken)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
@@ -398,7 +431,7 @@ func mobileLoginWithOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
authURL, err := c.App.GetOAuthLoginEndpoint(w, r, c.Params.Service, teamId, model.OAuthActionMobile, redirectURL, "", true)
|
||||
authURL, err := c.App.GetOAuthLoginEndpoint(w, r, c.Params.Service, teamId, model.OAuthActionMobile, redirectURL, "", true, "")
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
@@ -426,7 +459,17 @@ func signupWithOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
authURL, err := c.App.GetOAuthSignupEndpoint(w, r, c.Params.Service, teamId)
|
||||
desktopToken := r.URL.Query().Get("desktop_token")
|
||||
if desktopToken != "" {
|
||||
desktopTokenErr := c.App.CreateDesktopToken(desktopToken, time.Now().Unix())
|
||||
|
||||
if desktopTokenErr != nil {
|
||||
c.Err = desktopTokenErr
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
authURL, err := c.App.GetOAuthSignupEndpoint(w, r, c.Params.Service, teamId, desktopToken)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
@@ -59,6 +60,16 @@ func loginWithSaml(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
relayProps["redirect_to"] = redirectURL
|
||||
}
|
||||
|
||||
desktopToken := r.URL.Query().Get("desktop_token")
|
||||
if desktopToken != "" {
|
||||
desktopTokenErr := c.App.CreateDesktopToken(desktopToken, time.Now().Unix())
|
||||
if desktopTokenErr != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
relayProps["desktop_token"] = desktopToken
|
||||
}
|
||||
|
||||
relayProps[model.UserAuthServiceIsMobile] = strconv.FormatBool(isMobile)
|
||||
|
||||
if len(relayProps) > 0 {
|
||||
@@ -185,6 +196,26 @@ func completeSaml(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
c.App.AttachSessionCookies(c.AppContext, w, r)
|
||||
|
||||
desktopToken := relayProps["desktop_token"]
|
||||
if desktopToken != "" {
|
||||
desktopTokenErr := c.App.AuthenticateDesktopToken(desktopToken, time.Now().Add(-model.DesktopTokenTTL).Unix(), user)
|
||||
if desktopTokenErr != nil {
|
||||
handleError(desktopTokenErr)
|
||||
return
|
||||
}
|
||||
|
||||
queryString := map[string]string{
|
||||
"desktopAuthComplete": "true",
|
||||
}
|
||||
if val, ok := relayProps["redirect_to"]; ok {
|
||||
queryString["redirect_to"] = val
|
||||
}
|
||||
|
||||
redirectURL = utils.AppendQueryParamsToURL(c.GetSiteURLHeader()+"/login/desktop", queryString)
|
||||
http.Redirect(w, r, redirectURL, http.StatusFound)
|
||||
return
|
||||
}
|
||||
|
||||
if hasRedirectURL {
|
||||
if isMobile {
|
||||
// Mobile clients with redirect url support
|
||||
|
||||
Ссылка в новой задаче
Block a user