Add basic implementation of Post publicRooms method

This commit is contained in:
nxshock 2019-08-03 19:47:33 +05:00
parent 90270cfd61
commit d47457a67c
5 changed files with 76 additions and 50 deletions

View File

@ -114,7 +114,7 @@ Implemented from [Client-Server API](https://matrix.org/docs/spec/client_server/
- [x] [10.5.2 PUT /_matrix/client/r0/directory/list/room/{roomId}](https://matrix.org/docs/spec/client_server/latest#put-matrix-client-r0-directory-list-room-roomid) - [x] [10.5.2 PUT /_matrix/client/r0/directory/list/room/{roomId}](https://matrix.org/docs/spec/client_server/latest#put-matrix-client-r0-directory-list-room-roomid)
- [x] [10.5.3 GET /_matrix/client/r0/publicRooms](https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-publicrooms) - [x] [10.5.3 GET /_matrix/client/r0/publicRooms](https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-publicrooms)
- [ ] [10.5.4 POST /_matrix/client/r0/publicRooms](https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-publicrooms) - [x] [10.5.4 POST /_matrix/client/r0/publicRooms](https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-publicrooms)
## [11 User Data](https://matrix.org/docs/spec/client_server/latest#user-data) ## [11 User Data](https://matrix.org/docs/spec/client_server/latest#user-data)

View File

@ -15,7 +15,7 @@ type Backend interface {
GetUserByName(userName string) User GetUserByName(userName string) User
GetRoomByID(id string) Room GetRoomByID(id string) Room
Sync(token string, request sync.SyncRequest) (response *sync.SyncReply, err models.ApiError) Sync(token string, request sync.SyncRequest) (response *sync.SyncReply, err models.ApiError)
PublicRooms() []Room PublicRooms(filter string) []Room
ValidateUsernameFunc() func(string) error ValidateUsernameFunc() func(string) error
} }

View File

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"regexp" "regexp"
"sort" "sort"
"strings"
"sync" "sync"
"github.com/signaller-matrix/signaller/internal" "github.com/signaller-matrix/signaller/internal"
@ -125,14 +126,17 @@ func (backend *Backend) GetUserByName(userName string) internal.User {
return nil return nil
} }
func (backend *Backend) PublicRooms() []internal.Room { func (backend *Backend) PublicRooms(filter string) []internal.Room {
backend.mutex.Lock() backend.mutex.Lock()
defer backend.mutex.Unlock() defer backend.mutex.Unlock()
var rooms []internal.Room var rooms []internal.Room
for _, room := range backend.rooms { for _, room := range backend.rooms {
if room.State() == createroom.PublicChat { if room.State() == createroom.PublicChat &&
(strings.Contains(room.Name(), filter) ||
strings.Contains(room.Topic(), filter) ||
strings.Contains(room.AliasName(), filter)) {
rooms = append(rooms, room) rooms = append(rooms, room)
} }
} }

View File

@ -412,54 +412,68 @@ func listRoomHandler(w http.ResponseWriter, r *http.Request) {
// https://matrix.org/docs/spec/client_server/latest#id335 // https://matrix.org/docs/spec/client_server/latest#id335
func publicRoomsHandler(w http.ResponseWriter, r *http.Request) { func publicRoomsHandler(w http.ResponseWriter, r *http.Request) {
switch r.Method { if r.Method != http.MethodGet && r.Method != http.MethodPost {
case http.MethodGet: errorResponse(w, models.M_UNKNOWN, http.StatusBadRequest, "wrong method: "+r.Method)
var request publicrooms.Request return
err := getRequest(r, &request) }
if err != nil {
errorResponse(w, models.M_BAD_JSON, http.StatusBadRequest, err.Error()) var request publicrooms.Request
err := getRequest(r, &request)
if err != nil {
errorResponse(w, models.M_BAD_JSON, http.StatusBadRequest, err.Error())
return
}
if request.Limit <= 0 {
request.Limit = 50 // TODO: move to const
}
if r.Method == http.MethodPost {
token := getTokenFromResponse(r)
if token == "" {
errorResponse(w, models.M_FORBIDDEN, http.StatusForbidden, "")
return return
} }
if request.Limit <= 0 { user := currServer.Backend.GetUserByToken(token)
request.Limit = 50 // TODO: move to const if user == nil {
errorResponse(w, models.M_UNKNOWN_TOKEN, http.StatusBadRequest, "")
return
} }
chunks := roomsToPublicRoomsChunks(currServer.Backend.PublicRooms())
var response publicrooms.Response
// TODO: test and rewrite this code
if request.Since == "" {
if request.Limit >= len(chunks) {
response.Chunk = chunks
// TODO: should fill response.TotalRoomCountEstimate?
} else {
response.Chunk = chunks[:request.Limit]
response.NextBatch = strconv.Itoa(request.Limit + 1)
response.TotalRoomCountEstimate = len(chunks)
}
} else {
response.PrevBatch = "0"
from, err := strconv.Atoi(request.Since)
if err != nil {
errorResponse(w, models.M_INVALID_PARAM, http.StatusBadRequest, "Wrong Since field specified") // TODO: check code
return
}
if len(chunks) >= from {
if request.Limit >= len(chunks) {
response.Chunk = chunks[from : from+request.Limit]
} else {
response.Chunk = chunks[from:]
}
}
}
sendJsonResponse(w, http.StatusOK, response)
case http.MethodPost: // TODO: implement
default:
errorResponse(w, models.M_UNKNOWN, http.StatusBadRequest, "wrong method: "+r.Method)
} }
publicRooms := currServer.Backend.PublicRooms(request.Filter.GenericSearchTerm) // TODO: make Post request as User method
chunks := roomsToPublicRoomsChunks(publicRooms)
var response publicrooms.Response
// TODO: test and rewrite this code
if request.Since == "" {
if request.Limit >= len(chunks) {
response.Chunk = chunks
// TODO: should fill response.TotalRoomCountEstimate?
} else {
response.Chunk = chunks[:request.Limit]
response.NextBatch = strconv.Itoa(request.Limit + 1)
response.TotalRoomCountEstimate = len(chunks)
}
} else {
response.PrevBatch = "0"
from, err := strconv.Atoi(request.Since)
if err != nil {
errorResponse(w, models.M_INVALID_PARAM, http.StatusBadRequest, "Wrong Since field specified") // TODO: check code
return
}
if len(chunks) >= from {
if request.Limit >= len(chunks) {
response.Chunk = chunks[from : from+request.Limit]
} else {
response.Chunk = chunks[from:]
}
}
}
sendJsonResponse(w, http.StatusOK, response)
} }
func sendJsonResponse(w http.ResponseWriter, httpStatus int, data interface{}) error { func sendJsonResponse(w http.ResponseWriter, httpStatus int, data interface{}) error {

View File

@ -1,9 +1,13 @@
package publicrooms package publicrooms
// Merged request for Get and Post methods
type Request struct { type Request struct {
Limit int `json:"limit"` // Limit the number of results returned. Limit int `json:"limit"` // Limit the number of results returned.
Since string `json:"since"` // A pagination token from a previous request, allowing clients to get the next (or previous) batch of rooms. The direction of pagination is specified solely by which token is supplied, rather than via an explicit flag. Since string `json:"since"` // A pagination token from a previous request, allowing clients to get the next (or previous) batch of rooms. The direction of pagination is specified solely by which token is supplied, rather than via an explicit flag.
Server string `json:"server"` // The server to fetch the public room lists from. Defaults to the local server. Server string `json:"server"` // The server to fetch the public room lists from. Defaults to the local server.
Filter Filter `json:"filter"` // Filter to apply to the results.
IncludeAllNetworks bool `json:"include_all_networks"` // Whether or not to include all known networks/protocols from application services on the homeserver. Defaults to false.
ThirdPartyInstanceID string `json:"third_party_instance_id"` // The specific third party network/protocol to request from the homeserver. Can only be used if include_all_networks is false.
} }
type Response struct { type Response struct {
@ -24,3 +28,7 @@ type PublicRoomsChunk struct {
GuestCanJoin bool `json:"guest_can_join"` // Required. Whether guest users may join the room and participate in it. If they can, they will be subject to ordinary power level rules like any other user. GuestCanJoin bool `json:"guest_can_join"` // Required. Whether guest users may join the room and participate in it. If they can, they will be subject to ordinary power level rules like any other user.
AvatarURL string `json:"avatar_url,omitempty"` // The URL for the room's avatar, if one is set. AvatarURL string `json:"avatar_url,omitempty"` // The URL for the room's avatar, if one is set.
} }
type Filter struct {
GenericSearchTerm string `json:"generic_search_term,omitempty"` // A string to search for in the room metadata, e.g. name, topic, canonical alias etc. (Optional).
}