Rework filter methods

This commit is contained in:
nxshock 2019-08-05 19:39:28 +05:00
parent f3ded3e660
commit 330f362e54
7 changed files with 98 additions and 46 deletions

View File

@ -2,9 +2,9 @@ package internal
import ( import (
"github.com/signaller-matrix/signaller/internal/models" "github.com/signaller-matrix/signaller/internal/models"
"github.com/signaller-matrix/signaller/internal/models/common"
"github.com/signaller-matrix/signaller/internal/models/createroom" "github.com/signaller-matrix/signaller/internal/models/createroom"
"github.com/signaller-matrix/signaller/internal/models/devices" "github.com/signaller-matrix/signaller/internal/models/devices"
"github.com/signaller-matrix/signaller/internal/models/filter"
"github.com/signaller-matrix/signaller/internal/models/rooms" "github.com/signaller-matrix/signaller/internal/models/rooms"
"github.com/signaller-matrix/signaller/internal/models/sync" "github.com/signaller-matrix/signaller/internal/models/sync"
) )
@ -51,6 +51,6 @@ type User interface {
LogoutAll() LogoutAll()
JoinRoom(Room) models.ApiError JoinRoom(Room) models.ApiError
Invite(Room, User) models.ApiError Invite(Room, User) models.ApiError
AddFilter(filterID string, filter common.Filter) AddFilter(filterID string, filterReq filter.Request)
GetFilterByID(filterID string) *common.Filter GetFilterByID(filterID string) *filter.Request
} }

View File

@ -7,11 +7,10 @@ import (
"strings" "strings"
"sync" "sync"
"github.com/signaller-matrix/signaller/internal/models/common"
"github.com/signaller-matrix/signaller/internal" "github.com/signaller-matrix/signaller/internal"
"github.com/signaller-matrix/signaller/internal/models" "github.com/signaller-matrix/signaller/internal/models"
"github.com/signaller-matrix/signaller/internal/models/createroom" "github.com/signaller-matrix/signaller/internal/models/createroom"
"github.com/signaller-matrix/signaller/internal/models/filter"
mSync "github.com/signaller-matrix/signaller/internal/models/sync" mSync "github.com/signaller-matrix/signaller/internal/models/sync"
) )
@ -55,7 +54,7 @@ func (backend *Backend) Register(username, password, device string) (user intern
password: password, password: password,
Tokens: make(map[string]Token), Tokens: make(map[string]Token),
backend: backend, backend: backend,
filters: make(map[string]common.Filter)} filters: make(map[string]filter.Request)}
backend.data[username] = user backend.data[username] = user

View File

@ -3,10 +3,12 @@ package memory
import ( import (
"testing" "testing"
"github.com/signaller-matrix/signaller/internal"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func TestTokenGenerator(t *testing.T) { func TestTokenGenerator(t *testing.T) {
token := newToken(defaultTokenSize) token := internal.RandomString(defaultTokenSize)
assert.Len(t, token, defaultTokenSize*2) assert.Len(t, token, defaultTokenSize*2)
} }

View File

@ -6,9 +6,9 @@ import (
"github.com/signaller-matrix/signaller/internal" "github.com/signaller-matrix/signaller/internal"
"github.com/signaller-matrix/signaller/internal/models" "github.com/signaller-matrix/signaller/internal/models"
"github.com/signaller-matrix/signaller/internal/models/common"
"github.com/signaller-matrix/signaller/internal/models/createroom" "github.com/signaller-matrix/signaller/internal/models/createroom"
"github.com/signaller-matrix/signaller/internal/models/devices" "github.com/signaller-matrix/signaller/internal/models/devices"
"github.com/signaller-matrix/signaller/internal/models/filter"
"github.com/signaller-matrix/signaller/internal/models/rooms" "github.com/signaller-matrix/signaller/internal/models/rooms"
) )
@ -16,7 +16,7 @@ type User struct {
name string name string
password string password string
Tokens map[string]Token Tokens map[string]Token
filters map[string]common.Filter filters map[string]filter.Request
backend *Backend backend *Backend
@ -278,13 +278,20 @@ func (user *User) JoinRoom(room internal.Room) models.ApiError {
return nil return nil
} }
func (user *User) AddFilter(filterID string, filter common.Filter) { func (user *User) AddFilter(filterID string, filterReq filter.Request) {
user.filters[filterID] = filter user.mutex.Lock()
defer user.mutex.Unlock()
user.filters[filterID] = filterReq
} }
func (user *User) GetFilterByID(filterID string) *common.Filter { func (user *User) GetFilterByID(filterID string) *filter.Request {
if val, ok := user.filters[filterID]; ok { user.mutex.RLock()
return &val defer user.mutex.RUnlock()
if filterReq, ok := user.filters[filterID]; ok {
return &filterReq
} }
return nil return nil
} }

View File

@ -14,6 +14,7 @@ import (
"github.com/signaller-matrix/signaller/internal/models/capabilities" "github.com/signaller-matrix/signaller/internal/models/capabilities"
"github.com/signaller-matrix/signaller/internal/models/common" "github.com/signaller-matrix/signaller/internal/models/common"
"github.com/signaller-matrix/signaller/internal/models/devices" "github.com/signaller-matrix/signaller/internal/models/devices"
"github.com/signaller-matrix/signaller/internal/models/filter"
"github.com/signaller-matrix/signaller/internal/models/joinedrooms" "github.com/signaller-matrix/signaller/internal/models/joinedrooms"
"github.com/signaller-matrix/signaller/internal/models/listroom" "github.com/signaller-matrix/signaller/internal/models/listroom"
"github.com/signaller-matrix/signaller/internal/models/login" "github.com/signaller-matrix/signaller/internal/models/login"
@ -323,6 +324,7 @@ func CapabilitiesHandler(w http.ResponseWriter, r *http.Request) {
sendJsonResponse(w, http.StatusOK, response) sendJsonResponse(w, http.StatusOK, response)
} }
//
func AddFilterHandler(w http.ResponseWriter, r *http.Request) { func AddFilterHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost { if r.Method != http.MethodPost {
errorResponse(w, models.M_UNKNOWN, http.StatusBadRequest, "wrong method: "+r.Method) errorResponse(w, models.M_UNKNOWN, http.StatusBadRequest, "wrong method: "+r.Method)
@ -341,15 +343,19 @@ func AddFilterHandler(w http.ResponseWriter, r *http.Request) {
return return
} }
var request common.Filter var request filter.Request
getRequest(r, &request) err := getRequest(r, &request)
if err != nil {
errorResponse(w, models.M_BAD_JSON, http.StatusBadRequest, err.Error())
return
}
filterID := RandomString(12) filterID := RandomString(12)
user.AddFilter(filterID, request) user.AddFilter(filterID, request)
sendJsonResponse(w, http.StatusOK, map[string]interface{}{ response := filter.Response{FilterID: filterID}
"filter_id": filterID,
}) sendJsonResponse(w, http.StatusOK, response)
} }
func GetFilterHandler(w http.ResponseWriter, r *http.Request) { func GetFilterHandler(w http.ResponseWriter, r *http.Request) {
@ -373,6 +379,7 @@ func GetFilterHandler(w http.ResponseWriter, r *http.Request) {
filter := user.GetFilterByID(mux.Vars(r)["filterID"]) filter := user.GetFilterByID(mux.Vars(r)["filterID"])
if filter == nil { if filter == nil {
errorResponse(w, models.M_INVALID_PARAM, http.StatusNotFound, "") errorResponse(w, models.M_INVALID_PARAM, http.StatusNotFound, "")
return
} }
sendJsonResponse(w, http.StatusOK, filter) sendJsonResponse(w, http.StatusOK, filter)

View File

@ -1,27 +0,0 @@
package common
type Filter struct {
Room struct {
State struct {
Types []string `json:"types"`
NotRooms []string `json:"not_rooms"`
} `json:"state"`
Timeline struct {
Limit int `json:"limit"`
Types []string `json:"types"`
NotRooms []string `json:"not_rooms"`
NotSenders []string `json:"not_senders"`
} `json:"timeline"`
Ephemeral struct {
Types []string `json:"types"`
NotRooms []string `json:"not_rooms"`
NotSenders []string `json:"not_senders"`
} `json:"ephemeral"`
} `json:"room"`
Presence struct {
Types []string `json:"types"`
NotSenders []string `json:"not_senders"`
} `json:"presence"`
EventFormat string `json:"event_format"`
EventFields []string `json:"event_fields"`
}

View File

@ -0,0 +1,64 @@
package filter
type EventFormat string
const (
EventFormatClient = "client"
EventFormatFederation = "federation"
)
type Request struct {
EventFields []string `json:"event_fields"` // List of event fields to include. If this list is absent then all fields are included. The entries may include '.' charaters to indicate sub-fields. So ['content.body'] will include the 'body' field of the 'content' object. A literal '.' character in a field name may be escaped using a '\'. A server may include more fields than were requested.
EventFormat EventFormat `json:"event_format"` // The format to use for events. 'client' will return the events in a format suitable for clients. 'federation' will return the raw event as receieved over federation. The default is 'client'. One of: ["client", "federation"]
Presence EventFilter `json:"presence"` // The presence updates to include.
AccountData EventFilter `json:"account_data"` // The user account data that isn't associated with rooms to include.
Room RoomFilter `json:"room"` // Filters to be applied to room data.
}
type EventFilter struct {
Limit int `json:"limit"` // The maximum number of events to return.
NotSenders []string `json:"not_senders"` // A list of sender IDs to exclude. If this list is absent then no senders are excluded. A matching sender will be excluded even if it is listed in the 'senders' filter.
NotTypes []string `json:"not_types"` // A list of event types to exclude. If this list is absent then no event types are excluded. A matching type will be excluded even if it is listed in the 'types' filter. A '*' can be used as a wildcard to match any sequence of characters.
Senders []string `json:"senders"` // A list of senders IDs to include. If this list is absent then all senders are included.
Types []string `json:"types"` // A list of event types to include. If this list is absent then all event types are included. A '*' can be used as a wildcard to match any sequence of characters.
}
type RoomFilter struct {
NotRooms []string `json:"not_rooms"` // A list of room IDs to exclude. If this list is absent then no rooms are excluded. A matching room will be excluded even if it is listed in the 'rooms' filter. This filter is applied before the filters in ephemeral, state, timeline or account_data
Rooms []string `json:"rooms"` // A list of room IDs to include. If this list is absent then all rooms are included. This filter is applied before the filters in ephemeral, state, timeline or account_data
Ephemeral RoomEventFilter `json:"ephemeral"` // The events that aren't recorded in the room history, e.g. typing and receipts, to include for rooms.
IncludeLeave bool `json:"include_leave"` // Include rooms that the user has left in the sync, default false
State StateFilter `json:"state"` // The state events to include for rooms.
Timeline RoomEventFilter `json:"timeline"` // The message and state update events to include for rooms.
AccountData RoomEventFilter `json:"account_data"` // The per user account data to include for rooms.
}
type StateFilter struct {
Limit int `json:"limit"` // The maximum number of events to return.
NotSenders []string `json:"notSenders"` // A list of sender IDs to exclude. If this list is absent then no senders are excluded. A matching sender will be excluded even if it is listed in the 'senders' filter.
NotTypes []string `json:"notTypes"` // A list of event types to exclude. If this list is absent then no event types are excluded. A matching type will be excluded even if it is listed in the 'types' filter. A '*' can be used as a wildcard to match any sequence of characters.
Senders []string `json:"senders"` // A list of senders IDs to include. If this list is absent then all senders are included.
Types []string `json:"types"` // A list of event types to include. If this list is absent then all event types are included. A '*' can be used as a wildcard to match any sequence of characters.
LazyLoadMembers bool `json:"lazyLoadMembers"` // If true, enables lazy-loading of membership events. See Lazy-loading room members for more information. Defaults to false.
IncludeRedundantMembers bool `json:"includeRedundantMembers"` // If true, sends all membership events for all events, even if they have already been sent to the client. Does not apply unless lazyLoadMembers is true. See Lazy- loading room members for more information. Defaults to false.
NotRooms []string `json:"notRooms"` // A list of room IDs to exclude. If this list is absent then no rooms are excluded. A matching room will be excluded even if it is listed in the 'rooms' filter.
Rooms []string `json:"rooms"` // A list of room IDs to include. If this list is absent then all rooms are included.
Contains_url bool `json:"contains_url"` // If true, includes only events with a url key in their content. If false, excludes those events. If omitted, url key is not considered for filtering.
}
type RoomEventFilter struct {
Limit int `json:"limit"` // The maximum number of events to return.
NotSenders []string `json:"notSenders"` // A list of sender IDs to exclude. If this list is absent then no senders are excluded. A matching sender will be excluded even if it is listed in the 'senders' filter.
NotTypes []string `json:"notTypes"` // A list of event types to exclude. If this list is absent then no event types are excluded. A matching type will be excluded even if it is listed in the 'types' filter. A '*' can be used as a wildcard to match any sequence of characters.
Senders []string `json:"senders"` // A list of senders IDs to include. If this list is absent then all senders are included.
Types []string `json:"types"` // A list of event types to include. If this list is absent then all event types are included. A '*' can be used as a wildcard to match any sequence of characters.
LazyLoadMembers bool `json:"lazyLoadMembers"` // If true, enables lazy-loading of membership events. See Lazy-loading room members for more information. Defaults to false.
IncludeRedundantMembers bool `json:"includeRedundantMembers"` // If true, sends all membership events for all events, even if they have already been sent to the client. Does not apply unless lazyLoadMembers is true. See Lazy- loading room members for more information. Defaults to false.
NotRooms []string `json:"notRooms"` // A list of room IDs to exclude. If this list is absent then no rooms are excluded. A matching room will be excluded even if it is listed in the 'rooms' filter.
Rooms []string `json:"rooms"` // A list of room IDs to include. If this list is absent then all rooms are included.
Contains_url bool `json:"contains_url"` // If true, includes only events with a url key in their content. If false, excludes those events. If omitted, url key is not considered for filtering.
}
type Response struct {
FilterID string `json:"filter_id"` // Required. The ID of the filter that was created. Cannot start with a { as this character is used to determine if the filter provided is inline JSON or a previously declared filter by homeservers on some APIs.
}