From b51811875797863e8f4b4a1cf8a2f24a7c65e077 Mon Sep 17 00:00:00 2001
From: Travis Ralston <travpc@gmail.com>
Date: Sun, 21 Mar 2021 21:29:22 -0600
Subject: [PATCH] Fix handling of guest accounts (MSC3069)

---
 CHANGELOG.md         | 4 ++++
 api/auth.go          | 3 +++
 api/responses.go     | 4 ++++
 common/errorcodes.go | 1 +
 matrix/auth.go       | 4 ++++
 matrix/matrix.go     | 4 +++-
 matrix/responses.go  | 3 ++-
 7 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index bf3d1c96..5f159987 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 
 ## [Unreleased]
 
+### Fixed
+
+* Handle guest accounts properly. Previously they were still declined, though by coincidence.
+
 ## [1.2.5] - March 17th, 2021
 
 ### Added
diff --git a/api/auth.go b/api/auth.go
index 2c26bc70..584f3317 100644
--- a/api/auth.go
+++ b/api/auth.go
@@ -39,6 +39,9 @@ func AccessTokenRequiredRoute(next func(r *http.Request, rctx rcontext.RequestCo
 		appserviceUserId := util.GetAppserviceUserIdFromRequest(r)
 		userId, err := auth_cache.GetUserId(rctx, accessToken, appserviceUserId)
 		if err != nil || userId == "" {
+			if err == matrix.ErrGuestToken {
+				return GuestAuthFailed()
+			}
 			if err != nil && err != matrix.ErrInvalidToken {
 				sentry.CaptureException(err)
 				rctx.Log.Error("Error verifying token (fatal): ", err)
diff --git a/api/responses.go b/api/responses.go
index d032ce80..93d2c39c 100644
--- a/api/responses.go
+++ b/api/responses.go
@@ -46,6 +46,10 @@ func AuthFailed() *ErrorResponse {
 	return &ErrorResponse{common.ErrCodeUnknownToken, "Authentication Failed", common.ErrCodeUnknownToken}
 }
 
+func GuestAuthFailed() *ErrorResponse {
+	return &ErrorResponse{common.ErrCodeNoGuests, "Guests cannot use this endpoint", common.ErrCodeNoGuests}
+}
+
 func BadRequest(message string) *ErrorResponse {
 	return &ErrorResponse{common.ErrCodeUnknown, message, common.ErrCodeBadRequest}
 }
diff --git a/common/errorcodes.go b/common/errorcodes.go
index 8deb6494..599b32c9 100644
--- a/common/errorcodes.go
+++ b/common/errorcodes.go
@@ -5,6 +5,7 @@ const ErrCodeHostNotFound = "M_HOST_NOT_FOUND"
 const ErrCodeHostBlacklisted = "M_HOST_BLACKLISTED"
 const ErrCodeNotFound = "M_NOT_FOUND"
 const ErrCodeUnknownToken = "M_UNKNOWN_TOKEN"
+const ErrCodeNoGuests = "M_GUEST_ACCESS_FORBIDDEN"
 const ErrCodeMissingToken = "M_MISSING_TOKEN"
 const ErrCodeMediaTooLarge = "M_MEDIA_TOO_LARGE"
 const ErrCodeMediaTooSmall = "M_MEDIA_TOO_SMALL"
diff --git a/matrix/auth.go b/matrix/auth.go
index 96f0704a..ca397c8e 100644
--- a/matrix/auth.go
+++ b/matrix/auth.go
@@ -10,6 +10,7 @@ import (
 )
 
 var ErrInvalidToken = errors.New("Missing or invalid access token")
+var ErrGuestToken = errors.New("Token belongs to a guest")
 
 func doBreakerRequest(ctx rcontext.RequestContext, serverName string, accessToken string, appserviceUserId string, ipAddr string, method string, path string, resp interface{}) error {
 	if accessToken == "" {
@@ -53,6 +54,9 @@ func GetUserIdFromToken(ctx rcontext.RequestContext, serverName string, accessTo
 	if err != nil {
 		return "", err
 	}
+	if response.IsGuest {
+		return "", ErrGuestToken
+	}
 	return response.UserId, nil
 }
 
diff --git a/matrix/matrix.go b/matrix/matrix.go
index 7a278afd..4abf21d8 100644
--- a/matrix/matrix.go
+++ b/matrix/matrix.go
@@ -36,9 +36,11 @@ func filterError(err error) (error, error) {
 
 	// Unknown token errors should be filtered out explicitly to ensure we don't break on bad requests
 	if httpErr, ok := err.(*errorResponse); ok {
+		// We send back our own version of errors to ensure we can filter them out elsewhere
 		if httpErr.ErrorCode == common.ErrCodeUnknownToken {
-			// We send back our own version of 'unknown token' to ensure we can filter it out elsewhere
 			return nil, ErrInvalidToken
+		} else if httpErr.ErrorCode == common.ErrCodeNoGuests {
+			return nil, ErrGuestToken
 		}
 	}
 
diff --git a/matrix/responses.go b/matrix/responses.go
index 3efb078b..3d93cf21 100644
--- a/matrix/responses.go
+++ b/matrix/responses.go
@@ -8,7 +8,8 @@ type emptyResponse struct {
 }
 
 type userIdResponse struct {
-	UserId string `json:"user_id"`
+	UserId  string `json:"user_id"`
+	IsGuest bool   `json:"org.matrix.msc3069.is_guest"`
 }
 
 type whoisResponse struct {
-- 
GitLab