[MM-65015] Restore Mobile redirection on oauth login (#33626) (#33633)

Этот коммит содержится в:
Mattermost Build
2025-08-07 20:47:01 +03:00
коммит произвёл GitHub
родитель 540f4c1145
Коммит e14175eb65
3 изменённых файлов: 21 добавлений и 6 удалений

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

@@ -11,6 +11,7 @@ import (
"net/url"
"path"
"path/filepath"
"slices"
"strings"
"time"
@@ -22,6 +23,10 @@ import (
"github.com/mattermost/mattermost/server/v8/channels/utils/fileutils"
)
const (
callbackHost = "callback"
)
func (w *Web) InitOAuth() {
// API version independent OAuth 2.0 as a service provider endpoints
w.MainRouter.Handle("/oauth/authorize", w.APIHandlerTrustRequester(authorizeOAuthPage)).Methods(http.MethodGet)
@@ -315,7 +320,7 @@ func completeOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
hasRedirectURL = redirectURL != ""
}
}
redirectURL = fullyQualifiedRedirectURL(c.GetSiteURLHeader(), redirectURL)
redirectURL = fullyQualifiedRedirectURL(c.GetSiteURLHeader(), redirectURL, c.App.Config().NativeAppSettings.AppCustomURLSchemes)
renderError := func(err *model.AppError) {
if isMobile && hasRedirectURL {
@@ -535,7 +540,7 @@ func signupWithOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, authURL, http.StatusFound)
}
func fullyQualifiedRedirectURL(siteURLPrefix, targetURL string) string {
func fullyQualifiedRedirectURL(siteURLPrefix, targetURL string, otherValidSchemes []string) string {
parsed, err := url.Parse(targetURL)
if err != nil {
return siteURLPrefix
@@ -544,8 +549,15 @@ func fullyQualifiedRedirectURL(siteURLPrefix, targetURL string) string {
if err != nil {
return siteURLPrefix
}
// Check if the targetURL is a valid URL and is within the siteURLPrefix
// mobile access
if slices.Contains(otherValidSchemes, fmt.Sprintf("%v://", parsed.Scheme)) &&
parsed.Host == callbackHost &&
parsed.Path == "" &&
parsed.RawQuery == "" &&
parsed.Fragment == "" {
return targetURL
}
// Check if the targetURL is valid and within the siteURLPrefix, excluding native app schemes like mmauth://
sameScheme := parsed.Scheme == prefixParsed.Scheme
sameHost := parsed.Host == prefixParsed.Host
safePath := strings.HasPrefix(path.Clean(parsed.Path), path.Clean(prefixParsed.Path))

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

@@ -861,6 +861,7 @@ func (th *TestHelper) AddPermissionToRole(permission string, roleName string) {
func TestFullyQualifiedRedirectURL(t *testing.T) {
const siteURL = "https://xxx.yyy/mm"
for target, expected := range map[string]string{
"": siteURL,
"/": siteURL + "/",
@@ -881,9 +882,11 @@ func TestFullyQualifiedRedirectURL(t *testing.T) {
"https://xxx.yyy/mm/some-path#section": siteURL + "/some-path#section",
"https://xxx.yyy/mm/../malicious-path": siteURL,
":foo": siteURL,
"mmauth://callback": "mmauth://callback",
"mmauth://xxx.yyy/mm": siteURL, // invalid mobile URL (wrong host)
} {
t.Run(target, func(t *testing.T) {
require.Equal(t, expected, fullyQualifiedRedirectURL(siteURL, target))
require.Equal(t, expected, fullyQualifiedRedirectURL(siteURL, target, []string{"mmauth://"}))
})
}
}

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

@@ -117,7 +117,7 @@ func completeSaml(c *Context, w http.ResponseWriter, r *http.Request) {
redirectURL = val
hasRedirectURL = val != ""
}
redirectURL = fullyQualifiedRedirectURL(c.GetSiteURLHeader(), redirectURL)
redirectURL = fullyQualifiedRedirectURL(c.GetSiteURLHeader(), redirectURL, c.App.Config().NativeAppSettings.AppCustomURLSchemes)
handleError := func(err *model.AppError) {
if isMobile && hasRedirectURL {