From abce1998065644089c639d78f62b9f70be990599 Mon Sep 17 00:00:00 2001 From: Tommie Gannert Date: Sat, 2 Oct 2021 11:13:15 +0200 Subject: [PATCH] Adds a better /pushrules/ GET response. Still static, but hopefully passes Element Android push checks, which requires ".m.rule.master": https://github.com/matrix-org/matrix-android-sdk2/blob/develop/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/RuleIds.kt --- clientapi/routing/routing.go | 32 +- userapi/storage/accounts/common/pushrules.go | 345 +++++++++++++++++++ userapi/storage/accounts/postgres/storage.go | 15 +- 3 files changed, 371 insertions(+), 21 deletions(-) create mode 100644 userapi/storage/accounts/common/pushrules.go diff --git a/clientapi/routing/routing.go b/clientapi/routing/routing.go index 90f60f98b9..a7e29bcd0f 100644 --- a/clientapi/routing/routing.go +++ b/clientapi/routing/routing.go @@ -15,7 +15,6 @@ package routing import ( - "encoding/json" "net/http" "strings" @@ -531,20 +530,29 @@ func Setup( ).Methods(http.MethodGet, http.MethodPost, http.MethodOptions) r0mux.Handle("/pushrules/", - httputil.MakeExternalAPI("push_rules", func(req *http.Request) util.JSONResponse { + httputil.MakeAuthAPI("push_rules", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse { + const pushRulesType = "m.push_rules" + // TODO: Implement push rules API - res := json.RawMessage(`{ - "global": { - "content": [], - "override": [], - "room": [], - "sender": [], - "underride": [] - } - }`) + dataReq := userapi.QueryAccountDataRequest{ + UserID: device.UserID, + DataType: pushRulesType, + } + var dataRes userapi.QueryAccountDataResponse + if err := userAPI.QueryAccountData(req.Context(), &dataReq, &dataRes); err != nil { + util.GetLogger(req.Context()).WithError(err).Error("userAPI.QueryAccountData failed") + return util.ErrorResponse(err) + } + data, ok := dataRes.GlobalAccountData[pushRulesType] + if !ok { + return util.JSONResponse{ + Code: http.StatusNotFound, + JSON: jsonerror.NotFound("data not found"), + } + } return util.JSONResponse{ Code: http.StatusOK, - JSON: &res, + JSON: data, } }), ).Methods(http.MethodGet, http.MethodOptions) diff --git a/userapi/storage/accounts/common/pushrules.go b/userapi/storage/accounts/common/pushrules.go new file mode 100644 index 0000000000..a3fea0b151 --- /dev/null +++ b/userapi/storage/accounts/common/pushrules.go @@ -0,0 +1,345 @@ +package common + +import ( + "encoding/json" + "strings" + "text/template" +) + +func DefaultPushRules(userID, serverName string) (json.RawMessage, error) { + var sb strings.Builder + if err := pushRulesTmpl.Execute(&sb, map[string]string{"UserID": userID, "ServerName": serverName}); err != nil { + return nil, err + } + return json.RawMessage(sb.String()), nil +} + +// pushRulesTmpl is a simple value of m.push_rules. It was +// snapshotted from a default Element Web account on matrix.org. +var pushRulesTmpl = template.Must(template.New("").Parse(`{ + "device" : {}, + "global" : { + "content" : [ + { + "actions" : [ + "notify", + { + "set_tweak" : "sound", + "value" : "default" + }, + { + "set_tweak" : "highlight" + } + ], + "default" : true, + "enabled" : true, + "pattern" : "{{.Device.UserID}}", + "rule_id" : ".m.rule.contains_user_name" + } + ], + "override" : [ + { + "actions" : [ + "dont_notify" + ], + "conditions" : [], + "default" : true, + "enabled" : false, + "rule_id" : ".m.rule.master" + }, + { + "actions" : [ + "dont_notify" + ], + "conditions" : [ + { + "key" : "content.msgtype", + "kind" : "event_match", + "pattern" : "m.notice" + } + ], + "default" : true, + "enabled" : true, + "rule_id" : ".m.rule.suppress_notices" + }, + { + "actions" : [ + "notify", + { + "set_tweak" : "sound", + "value" : "default" + }, + { + "set_tweak" : "highlight", + "value" : false + } + ], + "conditions" : [ + { + "key" : "type", + "kind" : "event_match", + "pattern" : "m.room.member" + }, + { + "key" : "content.membership", + "kind" : "event_match", + "pattern" : "invite" + }, + { + "key" : "state_key", + "kind" : "event_match", + "pattern" : "@{{.Device.UserID}}:{{.ServerName}}" + } + ], + "default" : true, + "enabled" : true, + "rule_id" : ".m.rule.invite_for_me" + }, + { + "actions" : [ + "dont_notify" + ], + "conditions" : [ + { + "key" : "type", + "kind" : "event_match", + "pattern" : "m.room.member" + } + ], + "default" : true, + "enabled" : true, + "rule_id" : ".m.rule.member_event" + }, + { + "actions" : [ + "notify", + { + "set_tweak" : "sound", + "value" : "default" + }, + { + "set_tweak" : "highlight" + } + ], + "conditions" : [ + { + "kind" : "contains_display_name" + } + ], + "default" : true, + "enabled" : true, + "rule_id" : ".m.rule.contains_display_name" + }, + { + "actions" : [ + "notify", + { + "set_tweak" : "highlight", + "value" : true + } + ], + "conditions" : [ + { + "key" : "content.body", + "kind" : "event_match", + "pattern" : "@room" + }, + { + "key" : "room", + "kind" : "sender_notification_permission" + } + ], + "default" : true, + "enabled" : true, + "rule_id" : ".m.rule.roomnotif" + }, + { + "actions" : [ + "notify", + { + "set_tweak" : "highlight", + "value" : true + } + ], + "conditions" : [ + { + "key" : "type", + "kind" : "event_match", + "pattern" : "m.room.tombstone" + }, + { + "key" : "state_key", + "kind" : "event_match", + "pattern" : "" + } + ], + "default" : true, + "enabled" : true, + "rule_id" : ".m.rule.tombstone" + }, + { + "actions" : [ + "dont_notify" + ], + "conditions" : [ + { + "key" : "type", + "kind" : "event_match", + "pattern" : "m.reaction" + } + ], + "default" : true, + "enabled" : true, + "rule_id" : ".m.rule.reaction" + } + ], + "room" : [], + "sender" : [], + "underride" : [ + { + "actions" : [ + "notify", + { + "set_tweak" : "sound", + "value" : "ring" + }, + { + "set_tweak" : "highlight", + "value" : false + } + ], + "conditions" : [ + { + "key" : "type", + "kind" : "event_match", + "pattern" : "m.call.invite" + } + ], + "default" : true, + "enabled" : true, + "rule_id" : ".m.rule.call" + }, + { + "actions" : [ + "notify", + { + "set_tweak" : "sound", + "value" : "default" + }, + { + "set_tweak" : "highlight", + "value" : false + } + ], + "conditions" : [ + { + "is" : "2", + "kind" : "room_member_count" + }, + { + "key" : "type", + "kind" : "event_match", + "pattern" : "m.room.message" + } + ], + "default" : true, + "enabled" : true, + "rule_id" : ".m.rule.room_one_to_one" + }, + { + "actions" : [ + "notify", + { + "set_tweak" : "sound", + "value" : "default" + }, + { + "set_tweak" : "highlight", + "value" : false + } + ], + "conditions" : [ + { + "is" : "2", + "kind" : "room_member_count" + }, + { + "key" : "type", + "kind" : "event_match", + "pattern" : "m.room.encrypted" + } + ], + "default" : true, + "enabled" : true, + "rule_id" : ".m.rule.encrypted_room_one_to_one" + }, + { + "actions" : [ + "notify", + { + "set_tweak" : "highlight", + "value" : false + } + ], + "conditions" : [ + { + "key" : "type", + "kind" : "event_match", + "pattern" : "m.room.message" + } + ], + "default" : true, + "enabled" : true, + "rule_id" : ".m.rule.message" + }, + { + "actions" : [ + "notify", + { + "set_tweak" : "highlight", + "value" : false + } + ], + "conditions" : [ + { + "key" : "type", + "kind" : "event_match", + "pattern" : "m.room.encrypted" + } + ], + "default" : true, + "enabled" : true, + "rule_id" : ".m.rule.encrypted" + }, + { + "actions" : [ + "notify", + { + "set_tweak" : "highlight", + "value" : false + } + ], + "conditions" : [ + { + "key" : "type", + "kind" : "event_match", + "pattern" : "im.vector.modular.widgets" + }, + { + "key" : "content.type", + "kind" : "event_match", + "pattern" : "jitsi" + }, + { + "key" : "state_key", + "kind" : "event_match", + "pattern" : "*" + } + ], + "default" : true, + "enabled" : true, + "rule_id" : ".im.vector.jitsi" + } + ] + } +}`)) diff --git a/userapi/storage/accounts/postgres/storage.go b/userapi/storage/accounts/postgres/storage.go index 2f8290623f..7a12635e9b 100644 --- a/userapi/storage/accounts/postgres/storage.go +++ b/userapi/storage/accounts/postgres/storage.go @@ -27,6 +27,7 @@ import ( "github.com/matrix-org/dendrite/internal/sqlutil" "github.com/matrix-org/dendrite/setup/config" "github.com/matrix-org/dendrite/userapi/api" + "github.com/matrix-org/dendrite/userapi/storage/accounts/common" "github.com/matrix-org/dendrite/userapi/storage/accounts/postgres/deltas" "github.com/matrix-org/gomatrixserverlib" "golang.org/x/crypto/bcrypt" @@ -206,15 +207,11 @@ func (d *Database) createAccount( if err = d.profiles.insertProfile(ctx, txn, localpart); err != nil { return nil, err } - if err = d.accountDatas.insertAccountData(ctx, txn, localpart, "", "m.push_rules", json.RawMessage(`{ - "global": { - "content": [], - "override": [], - "room": [], - "sender": [], - "underride": [] - } - }`)); err != nil { + pr, err := common.DefaultPushRules(localpart, string(d.serverName)) + if err != nil { + return nil, err + } + if err = d.accountDatas.insertAccountData(ctx, txn, localpart, "", "m.push_rules", pr); err != nil { return nil, err } return account, nil