[MM-37984] Allow Desktop App to authenticate via external providers outside of the app on supported servers (#24140)

* [MM-37984] Allow Desktop App to authenticate via external providers outside of the app on supported servers

* PR feedback

* Add support for mattermost-dev protocol for development use

* Update server/channels/db/migrations/postgres/000110_create_desktop_tokens.up.sql

* Fix silly typo

* Update server/channels/db/migrations/postgres/000110_create_desktop_tokens.up.sql

* Remove storage of client token, only validate it on the client

* Update migrations

* Add concurrently create index

* Remove CONCURRENTLY for now

* Fix issue with changing history

* Remove old migration

* Use idempotent statement to drop old index

* Remove reference to old table
Этот коммит содержится в:
Devin Binnie
2023-08-30 11:21:43 -04:00
коммит произвёл GitHub
родитель 105fa4a195
Коммит a3b194581f
41 изменённых файлов: 1569 добавлений и 24 удалений

Просмотреть файл

@@ -11,6 +11,7 @@ import (
"net/url"
"path/filepath"
"strings"
"time"
"github.com/mattermost/mattermost/server/public/model"
"github.com/mattermost/mattermost/server/public/shared/i18n"
@@ -344,6 +345,34 @@ 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 != "" {
serverToken, serverTokenErr := c.App.GenerateAndSaveDesktopToken(time.Now().Unix(), user)
if serverTokenErr != nil {
serverTokenErr.Translate(c.AppContext.T)
c.LogErrorByCode(serverTokenErr)
renderError(serverTokenErr)
return
}
queryString := map[string]string{
"client_token": desktopToken,
"server_token": *serverToken,
}
if val, ok := props["redirect_to"]; ok {
queryString["redirect_to"] = val
}
if strings.HasPrefix(desktopToken, "dev-") {
queryString["isDesktopDev"] = "true"
}
redirectURL = utils.AppendQueryParamsToURL(c.GetSiteURLHeader()+"/login/desktop", queryString)
}
}
w.Header().Set("Content-Type", "text/html; charset=utf-8")
@@ -358,6 +387,7 @@ 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 redirectURL != "" && !utils.IsValidWebAuthRedirectURL(c.App.Config(), redirectURL) {
c.Err = model.NewAppError("loginWithOAuth", "api.invalid_redirect_url", nil, "", http.StatusBadRequest)
@@ -370,7 +400,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
@@ -399,7 +429,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
@@ -427,7 +457,9 @@ 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")
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,11 @@ func loginWithSaml(c *Context, w http.ResponseWriter, r *http.Request) {
relayProps["redirect_to"] = redirectURL
}
desktopToken := r.URL.Query().Get("desktop_token")
if desktopToken != "" {
relayProps["desktop_token"] = desktopToken
}
relayProps[model.UserAuthServiceIsMobile] = strconv.FormatBool(isMobile)
if len(relayProps) > 0 {
@@ -185,6 +191,30 @@ func completeSaml(c *Context, w http.ResponseWriter, r *http.Request) {
c.App.AttachSessionCookies(c.AppContext, w, r)
desktopToken := relayProps["desktop_token"]
if desktopToken != "" {
serverToken, serverTokenErr := c.App.GenerateAndSaveDesktopToken(time.Now().Unix(), user)
if serverTokenErr != nil {
handleError(serverTokenErr)
return
}
queryString := map[string]string{
"client_token": desktopToken,
"server_token": *serverToken,
}
if val, ok := relayProps["redirect_to"]; ok {
queryString["redirect_to"] = val
}
if strings.HasPrefix(desktopToken, "dev-") {
queryString["isDesktopDev"] = "true"
}
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