aboutsummaryrefslogtreecommitdiff
path: root/userapi/internal
diff options
context:
space:
mode:
Diffstat (limited to 'userapi/internal')
-rw-r--r--userapi/internal/api.go171
1 files changed, 169 insertions, 2 deletions
diff --git a/userapi/internal/api.go b/userapi/internal/api.go
index f54cc613..7a42fc60 100644
--- a/userapi/internal/api.go
+++ b/userapi/internal/api.go
@@ -20,6 +20,8 @@ import (
"encoding/json"
"errors"
"fmt"
+ "strconv"
+ "time"
"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util"
@@ -27,16 +29,22 @@ import (
"github.com/matrix-org/dendrite/appservice/types"
"github.com/matrix-org/dendrite/clientapi/userutil"
+ "github.com/matrix-org/dendrite/internal/pushrules"
"github.com/matrix-org/dendrite/internal/sqlutil"
keyapi "github.com/matrix-org/dendrite/keyserver/api"
"github.com/matrix-org/dendrite/setup/config"
"github.com/matrix-org/dendrite/userapi/api"
+ "github.com/matrix-org/dendrite/userapi/producers"
"github.com/matrix-org/dendrite/userapi/storage"
+ "github.com/matrix-org/dendrite/userapi/storage/tables"
)
type UserInternalAPI struct {
- DB storage.Database
- ServerName gomatrixserverlib.ServerName
+ DB storage.Database
+ SyncProducer *producers.SyncAPI
+
+ DisableTLSValidation bool
+ ServerName gomatrixserverlib.ServerName
// AppServices is the list of all registered AS
AppServices []config.ApplicationService
KeyAPI keyapi.KeyInternalAPI
@@ -595,3 +603,162 @@ func (a *UserInternalAPI) QueryKeyBackup(ctx context.Context, req *api.QueryKeyB
}
res.Keys = result
}
+
+func (a *UserInternalAPI) QueryNotifications(ctx context.Context, req *api.QueryNotificationsRequest, res *api.QueryNotificationsResponse) error {
+ if req.Limit == 0 || req.Limit > 1000 {
+ req.Limit = 1000
+ }
+
+ var fromID int64
+ var err error
+ if req.From != "" {
+ fromID, err = strconv.ParseInt(req.From, 10, 64)
+ if err != nil {
+ return fmt.Errorf("QueryNotifications: parsing 'from': %w", err)
+ }
+ }
+ var filter tables.NotificationFilter = tables.AllNotifications
+ if req.Only == "highlight" {
+ filter = tables.HighlightNotifications
+ }
+ notifs, lastID, err := a.DB.GetNotifications(ctx, req.Localpart, fromID, req.Limit, filter)
+ if err != nil {
+ return err
+ }
+ if notifs == nil {
+ // This ensures empty is JSON-encoded as [] instead of null.
+ notifs = []*api.Notification{}
+ }
+ res.Notifications = notifs
+ if lastID >= 0 {
+ res.NextToken = strconv.FormatInt(lastID+1, 10)
+ }
+ return nil
+}
+
+func (a *UserInternalAPI) PerformPusherSet(ctx context.Context, req *api.PerformPusherSetRequest, res *struct{}) error {
+ util.GetLogger(ctx).WithFields(logrus.Fields{
+ "localpart": req.Localpart,
+ "pushkey": req.Pusher.PushKey,
+ "display_name": req.Pusher.AppDisplayName,
+ }).Info("PerformPusherCreation")
+ if !req.Append {
+ err := a.DB.RemovePushers(ctx, req.Pusher.AppID, req.Pusher.PushKey)
+ if err != nil {
+ return err
+ }
+ }
+ if req.Pusher.Kind == "" {
+ return a.DB.RemovePusher(ctx, req.Pusher.AppID, req.Pusher.PushKey, req.Localpart)
+ }
+ if req.Pusher.PushKeyTS == 0 {
+ req.Pusher.PushKeyTS = gomatrixserverlib.AsTimestamp(time.Now())
+ }
+ return a.DB.UpsertPusher(ctx, req.Pusher, req.Localpart)
+}
+
+func (a *UserInternalAPI) PerformPusherDeletion(ctx context.Context, req *api.PerformPusherDeletionRequest, res *struct{}) error {
+ pushers, err := a.DB.GetPushers(ctx, req.Localpart)
+ if err != nil {
+ return err
+ }
+ for i := range pushers {
+ logrus.Warnf("pusher session: %d, req session: %d", pushers[i].SessionID, req.SessionID)
+ if pushers[i].SessionID != req.SessionID {
+ err := a.DB.RemovePusher(ctx, pushers[i].AppID, pushers[i].PushKey, req.Localpart)
+ if err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
+
+func (a *UserInternalAPI) QueryPushers(ctx context.Context, req *api.QueryPushersRequest, res *api.QueryPushersResponse) error {
+ var err error
+ res.Pushers, err = a.DB.GetPushers(ctx, req.Localpart)
+ return err
+}
+
+func (a *UserInternalAPI) PerformPushRulesPut(
+ ctx context.Context,
+ req *api.PerformPushRulesPutRequest,
+ _ *struct{},
+) error {
+ bs, err := json.Marshal(&req.RuleSets)
+ if err != nil {
+ return err
+ }
+ userReq := api.InputAccountDataRequest{
+ UserID: req.UserID,
+ DataType: pushRulesAccountDataType,
+ AccountData: json.RawMessage(bs),
+ }
+ var userRes api.InputAccountDataResponse // empty
+ if err := a.InputAccountData(ctx, &userReq, &userRes); err != nil {
+ return err
+ }
+
+ if err := a.SyncProducer.SendAccountData(req.UserID, "" /* roomID */, pushRulesAccountDataType); err != nil {
+ util.GetLogger(ctx).WithError(err).Errorf("syncProducer.SendData failed")
+ }
+
+ return nil
+}
+
+func (a *UserInternalAPI) QueryPushRules(ctx context.Context, req *api.QueryPushRulesRequest, res *api.QueryPushRulesResponse) error {
+ userReq := api.QueryAccountDataRequest{
+ UserID: req.UserID,
+ DataType: pushRulesAccountDataType,
+ }
+ var userRes api.QueryAccountDataResponse
+ if err := a.QueryAccountData(ctx, &userReq, &userRes); err != nil {
+ return err
+ }
+ bs, ok := userRes.GlobalAccountData[pushRulesAccountDataType]
+ if ok {
+ // Legacy Dendrite users will have completely empty push rules, so we should
+ // detect that situation and set some defaults.
+ var rules struct {
+ G struct {
+ Content []json.RawMessage `json:"content"`
+ Override []json.RawMessage `json:"override"`
+ Room []json.RawMessage `json:"room"`
+ Sender []json.RawMessage `json:"sender"`
+ Underride []json.RawMessage `json:"underride"`
+ } `json:"global"`
+ }
+ if err := json.Unmarshal([]byte(bs), &rules); err == nil {
+ count := len(rules.G.Content) + len(rules.G.Override) +
+ len(rules.G.Room) + len(rules.G.Sender) + len(rules.G.Underride)
+ ok = count > 0
+ }
+ }
+ if !ok {
+ // If we didn't find any default push rules then we should just generate some
+ // fresh ones.
+ localpart, _, err := gomatrixserverlib.SplitID('@', req.UserID)
+ if err != nil {
+ return fmt.Errorf("failed to split user ID %q for push rules", req.UserID)
+ }
+ pushRuleSets := pushrules.DefaultAccountRuleSets(localpart, a.ServerName)
+ prbs, err := json.Marshal(pushRuleSets)
+ if err != nil {
+ return fmt.Errorf("failed to marshal default push rules: %w", err)
+ }
+ if err := a.DB.SaveAccountData(ctx, localpart, "", pushRulesAccountDataType, json.RawMessage(prbs)); err != nil {
+ return fmt.Errorf("failed to save default push rules: %w", err)
+ }
+ res.RuleSets = pushRuleSets
+ return nil
+ }
+ var data pushrules.AccountRuleSets
+ if err := json.Unmarshal([]byte(bs), &data); err != nil {
+ util.GetLogger(ctx).WithError(err).Error("json.Unmarshal of push rules failed")
+ return err
+ }
+ res.RuleSets = &data
+ return nil
+}
+
+const pushRulesAccountDataType = "m.push_rules"