diff --git a/clientapi/routing/consent_tracking.go b/clientapi/routing/consent_tracking.go index c3075e15b..a71402edd 100644 --- a/clientapi/routing/consent_tracking.go +++ b/clientapi/routing/consent_tracking.go @@ -22,7 +22,6 @@ import ( "encoding/hex" "fmt" "net/http" - "net/url" appserviceAPI "github.com/matrix-org/dendrite/appservice/api" "github.com/matrix-org/dendrite/clientapi/jsonerror" @@ -156,7 +155,7 @@ func sendServerNoticeForConsent(userAPI userapi.UserInternalAPI, rsAPI api.Rooms continue } userID := fmt.Sprintf("@%s:%s", localpart, cfgClient.Matrix.ServerName) - data["ConsentURL"], err = buildConsentURI(cfgClient, userID) + data["ConsentURL"], err = consentOpts.ConsentURL(userID) if err != nil { logrus.WithError(err).WithField("userID", userID).Error("unable to construct consentURI") continue @@ -199,24 +198,6 @@ func sendServerNoticeForConsent(userAPI userapi.UserInternalAPI, rsAPI api.Rooms } } -func buildConsentURI(cfgClient *config.ClientAPI, userID string) (string, error) { - consentOpts := cfgClient.Matrix.UserConsentOptions - - mac := hmac.New(sha256.New, []byte(consentOpts.FormSecret)) - _, err := mac.Write([]byte(userID)) - if err != nil { - return "", err - } - userMAC := mac.Sum(nil) - - params := url.Values{} - params.Add("u", userID) - params.Add("h", string(userMAC)) - params.Add("v", consentOpts.Version) - - return fmt.Sprintf("%s/_matrix/client/consent?%s", cfgClient.Matrix.UserConsentOptions.BaseURL, params.Encode()), nil -} - func validHMAC(username, userHMAC, secret string) (bool, error) { mac := hmac.New(sha256.New, []byte(secret)) _, err := mac.Write([]byte(username)) diff --git a/internal/httputil/httpapi.go b/internal/httputil/httpapi.go index 9716c4974..4433f524e 100644 --- a/internal/httputil/httpapi.go +++ b/internal/httputil/httpapi.go @@ -17,15 +17,11 @@ package httputil import ( "bytes" "context" - "crypto/hmac" - "crypto/sha256" - "encoding/hex" "fmt" "io" "net/http" "net/http/httptest" "net/http/httputil" - "net/url" "os" "strings" "sync" @@ -138,7 +134,7 @@ func checkConsent(ctx context.Context, userID string, userAPI userapi.UserIntern // user hasn't accepted any policy, block access. if userConsentCfg.Version != res.PolicyVersion { - uri, err := getConsentURL(userID, userConsentCfg) + uri, err := userConsentCfg.ConsentURL(userID) if err != nil { return &util.JSONResponse{ Code: http.StatusInternalServerError, @@ -166,23 +162,6 @@ func checkConsent(ctx context.Context, userID string, userAPI userapi.UserIntern return nil } -// getConsentURL constructs the URL shown to users to accept the TOS -func getConsentURL(userID string, config config.UserConsentOptions) (string, error) { - mac := hmac.New(sha256.New, []byte(config.FormSecret)) - _, err := mac.Write([]byte(userID)) - if err != nil { - return "", err - } - hmac := hex.EncodeToString(mac.Sum(nil)) - - params := url.Values{} - params.Add("u", userID) - params.Add("h", string(hmac)) - params.Add("v", config.Version) - - return fmt.Sprintf("%s/_matrix/client/consent?%s", config.BaseURL, params.Encode()), nil -} - // MakeExternalAPI turns a util.JSONRequestHandler function into an http.Handler. // This is used for APIs that are called from the internet. func MakeExternalAPI(metricsName string, f func(*http.Request) util.JSONResponse) http.Handler { diff --git a/setup/config/config_global.go b/setup/config/config_global.go index 25ea91d43..883784e30 100644 --- a/setup/config/config_global.go +++ b/setup/config/config_global.go @@ -1,9 +1,13 @@ package config import ( + "crypto/hmac" + "crypto/sha256" + "encoding/hex" "fmt" "html/template" "math/rand" + "net/url" "path/filepath" textTemplate "text/template" "time" @@ -324,6 +328,23 @@ func (c *UserConsentOptions) Verify(configErrors *ConfigErrors, isMonolith bool) } } +// ConsentURL constructs the URL shown to users to accept the TOS +func (c *UserConsentOptions) ConsentURL(userID string) (string, error) { + mac := hmac.New(sha256.New, []byte(c.FormSecret)) + _, err := mac.Write([]byte(userID)) + if err != nil { + return "", err + } + userMAC := hex.EncodeToString(mac.Sum(nil)) + + params := url.Values{} + params.Add("u", userID) + params.Add("h", userMAC) + params.Add("v", c.Version) + + return fmt.Sprintf("%s/_matrix/client/consent?%s", c.BaseURL, params.Encode()), nil +} + // PresenceOptions defines possible configurations for presence events. type PresenceOptions struct { // Whether inbound presence events are allowed