diff --git a/dendrite-config.yaml b/dendrite-config.yaml index c537bd1ef..b137ff478 100644 --- a/dendrite-config.yaml +++ b/dendrite-config.yaml @@ -86,7 +86,7 @@ global: enabled: false # The base URL this homeserver will serve clients on, e.g. https://matrix.org base_url: http://localhost - # Randomly generated string to be used to calculate the HMAC + # Randomly generated string (e.g. by using "pwgen -sy 32") to be used to calculate the HMAC form_secret: "superSecretRandomlyGeneratedSecret" # Require consent when user registers for the first time require_at_registration: false diff --git a/docs/templates/privacy/1.0.gohtml b/docs/templates/privacy/1.0.gohtml index 8704ff2e2..6e866cff2 100644 --- a/docs/templates/privacy/1.0.gohtml +++ b/docs/templates/privacy/1.0.gohtml @@ -12,13 +12,13 @@
Please give your consent to keep using this homeserver.
- {{ if not .PublicVersion }} + {{ if not .ReadOnly }} {{ end }} {{ end }} diff --git a/internal/httputil/httpapi.go b/internal/httputil/httpapi.go index 910d92876..ba8f67cf4 100644 --- a/internal/httputil/httpapi.go +++ b/internal/httputil/httpapi.go @@ -25,6 +25,7 @@ import ( "net/http" "net/http/httptest" "net/http/httputil" + "net/url" "os" "strings" "sync" @@ -119,14 +120,14 @@ func MakeAuthAPI( } func checkConsent(ctx context.Context, userID string, userAPI userapi.UserInternalAPI, userConsentCfg config.UserConsentOptions) *util.JSONResponse { - localPart, _, err := gomatrixserverlib.SplitID('@', userID) + localpart, _, err := gomatrixserverlib.SplitID('@', userID) if err != nil { return nil } // check which version of the policy the user accepted res := &userapi.QueryPolicyVersionResponse{} err = userAPI.QueryPolicyVersion(ctx, &userapi.QueryPolicyVersionRequest{ - Localpart: localPart, + Localpart: localpart, }, res) if err != nil { return &util.JSONResponse{ @@ -166,18 +167,20 @@ func checkConsent(ctx context.Context, userID string, userAPI userapi.UserIntern } // getConsentURL constructs the URL shown to users to accept the TOS -func getConsentURL(username string, config config.UserConsentOptions) (string, error) { +func getConsentURL(userID string, config config.UserConsentOptions) (string, error) { mac := hmac.New(sha256.New, []byte(config.FormSecret)) - _, err := mac.Write([]byte(username)) + _, err := mac.Write([]byte(userID)) if err != nil { return "", err } hmac := hex.EncodeToString(mac.Sum(nil)) - return fmt.Sprintf( - "%s/_matrix/client/consent?u=%s&h=%s&v=%s", - config.BaseURL, username, hmac, config.Version, - ), 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. diff --git a/mediaapi/routing/routing.go b/mediaapi/routing/routing.go index 4e37a8bb5..ff4d31501 100644 --- a/mediaapi/routing/routing.go +++ b/mediaapi/routing/routing.go @@ -59,14 +59,14 @@ func Setup( PathToResult: map[string]*types.ThumbnailGenerationResult{}, } - uploadHandler := httputil.MakeAuthAPI("upload", userAPI, cfg.Matrix.UserConsentOptions, false, func(req *http.Request, dev *userapi.Device) util.JSONResponse { + uploadHandler := httputil.MakeAuthAPI("upload", userAPI, func(req *http.Request, dev *userapi.Device) util.JSONResponse { if r := rateLimits.Limit(req); r != nil { return *r } return Upload(req, cfg, dev, db, activeThumbnailGeneration) }) - configHandler := httputil.MakeAuthAPI("config", userAPI, cfg.Matrix.UserConsentOptions, false, func(req *http.Request, device *userapi.Device) util.JSONResponse { + configHandler := httputil.MakeAuthAPI("config", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse { if r := rateLimits.Limit(req); r != nil { return *r } diff --git a/setup/config/config_global.go b/setup/config/config_global.go index 19eec8be4..098d278a8 100644 --- a/setup/config/config_global.go +++ b/setup/config/config_global.go @@ -275,7 +275,6 @@ func (c *UserConsentOptions) Defaults() { c.PolicyName = "Privacy Policy" c.Version = "1.0" c.TemplateDir = "./templates/privacy" - c.BaseURL = "http://localhost" } func (c *UserConsentOptions) Verify(configErrors *ConfigErrors, isMonolith bool) { @@ -284,6 +283,7 @@ func (c *UserConsentOptions) Verify(configErrors *ConfigErrors, isMonolith bool) checkNotEmpty(configErrors, "version", c.Version) checkNotEmpty(configErrors, "policy_name", c.PolicyName) checkNotEmpty(configErrors, "form_secret", c.FormSecret) + checkNotEmpty(configErrors, "base_url", c.BaseURL) if len(*configErrors) > 0 { return } diff --git a/setup/config/config_global_test.go b/setup/config/config_global_test.go index a3ede2d59..ab61514ad 100644 --- a/setup/config/config_global_test.go +++ b/setup/config/config_global_test.go @@ -82,6 +82,8 @@ func TestUserConsentOptions_Verify(t *testing.T) { TemplateDir: "./testdata/privacy", Version: "1.0", PolicyName: "Privacy policy", + FormSecret: "helloWorld", + BaseURL: "http://localhost", }, args: struct { configErrors *ConfigErrors @@ -93,6 +95,9 @@ func TestUserConsentOptions_Verify(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { c := &UserConsentOptions{ + Enabled: true, + BaseURL: tt.fields.BaseURL, + FormSecret: tt.fields.FormSecret, RequireAtRegistration: tt.fields.RequireAtRegistration, PolicyName: tt.fields.PolicyName, Version: tt.fields.Version, @@ -102,7 +107,7 @@ func TestUserConsentOptions_Verify(t *testing.T) { BlockEventsError: tt.fields.BlockEventsError, } c.Verify(tt.args.configErrors, tt.args.isMonolith) - if tt.wantErr && tt.args.configErrors == nil { + if !tt.wantErr && len(*tt.args.configErrors) > 0 { t.Errorf("expected no errors, got '%+v'", tt.args.configErrors) } }) diff --git a/setup/config/testdata/privacy/1.0.gohtml b/setup/config/testdata/privacy/1.0.gohtml index 12602fada..6e866cff2 100644 --- a/setup/config/testdata/privacy/1.0.gohtml +++ b/setup/config/testdata/privacy/1.0.gohtml @@ -1,26 +1,26 @@ -- Your base already belong to us. -
++ You have already given your consent. +
{{ else }} -- All your base are belong to us. -
-{{ if not .PublicVersion }} - - -{{ end }} ++ Please give your consent to keep using this homeserver. +
+ {{ if not .ReadOnly }} + + + {{ end }} {{ end }} \ No newline at end of file diff --git a/setup/mscs/msc2836/msc2836.go b/setup/mscs/msc2836/msc2836.go index 7678dcb86..29c781a88 100644 --- a/setup/mscs/msc2836/msc2836.go +++ b/setup/mscs/msc2836/msc2836.go @@ -126,7 +126,7 @@ func Enable( }) base.PublicClientAPIMux.Handle("/unstable/event_relationships", - httputil.MakeAuthAPI("eventRelationships", userAPI, base.Cfg.Global.UserConsentOptions, false, eventRelationshipHandler(db, rsAPI, fsAPI)), + httputil.MakeAuthAPI("eventRelationships", userAPI, eventRelationshipHandler(db, rsAPI, fsAPI)), ).Methods(http.MethodPost, http.MethodOptions) base.PublicFederationAPIMux.Handle("/unstable/event_relationships", httputil.MakeExternalAPI(