Deduplicate constructing consent URL

This commit is contained in:
Till Faelligen 2022-05-04 14:40:25 +02:00
parent bddf8ed3ac
commit 88612ddd0c
3 changed files with 23 additions and 42 deletions

View file

@ -22,7 +22,6 @@ import (
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"net/http" "net/http"
"net/url"
appserviceAPI "github.com/matrix-org/dendrite/appservice/api" appserviceAPI "github.com/matrix-org/dendrite/appservice/api"
"github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/jsonerror"
@ -156,7 +155,7 @@ func sendServerNoticeForConsent(userAPI userapi.UserInternalAPI, rsAPI api.Rooms
continue continue
} }
userID := fmt.Sprintf("@%s:%s", localpart, cfgClient.Matrix.ServerName) userID := fmt.Sprintf("@%s:%s", localpart, cfgClient.Matrix.ServerName)
data["ConsentURL"], err = buildConsentURI(cfgClient, userID) data["ConsentURL"], err = consentOpts.ConsentURL(userID)
if err != nil { if err != nil {
logrus.WithError(err).WithField("userID", userID).Error("unable to construct consentURI") logrus.WithError(err).WithField("userID", userID).Error("unable to construct consentURI")
continue 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) { func validHMAC(username, userHMAC, secret string) (bool, error) {
mac := hmac.New(sha256.New, []byte(secret)) mac := hmac.New(sha256.New, []byte(secret))
_, err := mac.Write([]byte(username)) _, err := mac.Write([]byte(username))

View file

@ -17,15 +17,11 @@ package httputil
import ( import (
"bytes" "bytes"
"context" "context"
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"net/http/httputil" "net/http/httputil"
"net/url"
"os" "os"
"strings" "strings"
"sync" "sync"
@ -138,7 +134,7 @@ func checkConsent(ctx context.Context, userID string, userAPI userapi.UserIntern
// user hasn't accepted any policy, block access. // user hasn't accepted any policy, block access.
if userConsentCfg.Version != res.PolicyVersion { if userConsentCfg.Version != res.PolicyVersion {
uri, err := getConsentURL(userID, userConsentCfg) uri, err := userConsentCfg.ConsentURL(userID)
if err != nil { if err != nil {
return &util.JSONResponse{ return &util.JSONResponse{
Code: http.StatusInternalServerError, Code: http.StatusInternalServerError,
@ -166,23 +162,6 @@ func checkConsent(ctx context.Context, userID string, userAPI userapi.UserIntern
return nil 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. // MakeExternalAPI turns a util.JSONRequestHandler function into an http.Handler.
// This is used for APIs that are called from the internet. // This is used for APIs that are called from the internet.
func MakeExternalAPI(metricsName string, f func(*http.Request) util.JSONResponse) http.Handler { func MakeExternalAPI(metricsName string, f func(*http.Request) util.JSONResponse) http.Handler {

View file

@ -1,9 +1,13 @@
package config package config
import ( import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt" "fmt"
"html/template" "html/template"
"math/rand" "math/rand"
"net/url"
"path/filepath" "path/filepath"
textTemplate "text/template" textTemplate "text/template"
"time" "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. // PresenceOptions defines possible configurations for presence events.
type PresenceOptions struct { type PresenceOptions struct {
// Whether inbound presence events are allowed // Whether inbound presence events are allowed