Add API and retrieval and update of visibility for a single room

This commit is contained in:
Brendan Abolivier 2017-08-08 19:44:41 +01:00
parent 41b6411389
commit 584ebe7725
No known key found for this signature in database
GPG key ID: 8EF1500759F70623
2 changed files with 299 additions and 0 deletions

View file

@ -0,0 +1,141 @@
// Copyright 2017 Vector Creations Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package api
import (
"net/http"
)
// SetRoomVisibilityRequest is a request to SetRoomVisibility
type SetRoomVisibilityRequest struct {
// ID of the room of which the visibility will be updated
RoomID string `json:"room_id"`
// The new visibility of the room. Either "public" or "private"
Visibility string `json:"visibility"`
}
// SetRoomVisibilityResponse is a response to SetRoomVisibility
type SetRoomVisibilityResponse struct{}
// GetRoomVisibilityRequest is a request to GetRoomVisibility
type GetRoomVisibilityRequest struct {
// ID of the room to get the visibility of
RoomID string `json:"room_id"`
}
// GetRoomVisibilityResponse is a response to GetRoomVisibility
type GetRoomVisibilityResponse struct {
// Visibility of the room. Either "public" or "private"
Visibility string `json:"visibility"`
}
// GetPublicRoomsRequest is a request to GetPublicRooms
type GetPublicRoomsRequest struct {
Limit int16 `json:"limit"`
Since string `json:"since"`
}
// GetPublicRoomsResponse is a response to GetPublicRooms
type GetPublicRoomsResponse struct {
Chunk []PublicRoomsChunk `json:"chunk"`
NextBatch string `json:"next_batch"`
PrevBatch string `json:"prev_batch"`
TotalRoomCountEstimate int64 `json:"total_room_count_estimate"`
}
// PublicRoomsChunk implements the PublicRoomsChunk structure from the Matrix spec
type PublicRoomsChunk struct {
RoomID string `json:"room_id"`
Aliases []string `json:"aliases"`
CanonicalAlias string `json:"canonical_alias"`
Name string `json:"name"`
Topic string `json:"topic"`
AvatarURL string `json:"avatar_url"`
JoinedMembers int64 `json:"num_joined_members"`
WorldReadable bool `json:"world_readable"`
GuestCanJoin bool `json:"guest_can_join"`
}
// RoomserverPublicRoomAPI is used to update or retrieve the visibility setting
// of a room, or to retrieve all of the public rooms
type RoomserverPublicRoomAPI interface {
// Set the visibility for a room
SetRoomVisibility(
req *SetRoomVisibilityRequest,
response *SetRoomVisibilityResponse,
) error
// Get the visibility for a room
GetRoomVisibility(
req *GetRoomVisibilityRequest,
response *GetRoomVisibilityResponse,
) error
// Get all rooms publicly visible rooms on the server
GetPublicRooms(
req *GetPublicRoomsRequest,
response *GetPublicRoomsResponse,
) error
}
// RoomserverSetRoomVisibilityPath is the HTTP path for the SetRoomVisibility API
const RoomserverSetRoomVisibilityPath = "/api/roomserver/setRoomVisibility"
// RoomserverGetRoomVisibilityPath is the HTTP path for the GetRoomVisibility API
const RoomserverGetRoomVisibilityPath = "/api/roomserver/getRoomVisibility"
// RoomserverGetPublicRoomsPath is the HTTP path for the GetPublicRooms API
const RoomserverGetPublicRoomsPath = "/api/roomserver/getPublicRooms"
// NewRoomserverPublicRoomAPIHTTP creates a RoomserverPublicRoomAPI implemented by talking to a HTTP POST API.
// If httpClient is nil then it uses the http.DefaultClient
func NewRoomserverPublicRoomAPIHTTP(roomserverURL string, httpClient *http.Client) RoomserverPublicRoomAPI {
if httpClient == nil {
httpClient = http.DefaultClient
}
return &httpRoomserverPublicRoomAPI{roomserverURL, httpClient}
}
type httpRoomserverPublicRoomAPI struct {
roomserverURL string
httpClient *http.Client
}
// SetRoomVisibility implements RoomserverPublicRoomAPI
func (h *httpRoomserverPublicRoomAPI) SetRoomVisibility(
request *SetRoomVisibilityRequest,
response *SetRoomVisibilityResponse,
) error {
apiURL := h.roomserverURL + RoomserverSetRoomVisibilityPath
return postJSON(h.httpClient, apiURL, request, response)
}
// GetRoomVisibility implements RoomserverPublicRoomAPI
func (h *httpRoomserverPublicRoomAPI) GetRoomVisibility(
request *GetRoomVisibilityRequest,
response *GetRoomVisibilityResponse,
) error {
apiURL := h.roomserverURL + RoomserverGetRoomVisibilityPath
return postJSON(h.httpClient, apiURL, request, response)
}
// GetPublicRooms implements RoomserverPublicRoomAPI
func (h *httpRoomserverPublicRoomAPI) GetPublicRooms(
request *GetPublicRoomsRequest,
response *GetPublicRoomsResponse,
) error {
apiURL := h.roomserverURL + RoomserverGetPublicRoomsPath
return postJSON(h.httpClient, apiURL, request, response)
}

View file

@ -0,0 +1,158 @@
// Copyright 2017 Vector Creations Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package publicroom
import (
"encoding/json"
"errors"
"net/http"
"github.com/matrix-org/dendrite/common"
"github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/dendrite/roomserver/types"
"github.com/matrix-org/util"
)
// RoomserverPublicRoomAPIDatabase has the storage APIs needed to implement the
// public room API.
type RoomserverPublicRoomAPIDatabase interface {
// Lookup the numeric ID for the room.
// Returns 0 if the room doesn't exists.
// Returns an error if there was a problem talking to the database.
RoomNID(roomID string) (types.RoomNID, error)
// Checks the visibility of the room identified by the given numeric ID.
// Returns true if the room is publicly visible, returns false if not.
// If there's no room matching this numeric ID, or if the retrieval failed,
// returns an error.
IsRoomPublic(roomNID types.RoomNID) (bool, error)
// Returns an array of string containing the room IDs of the rooms that are
// publicly visible.
// Returns an error if the retrieval failed.
GetPublicRoomIDs() ([]string, error)
// Updates the visibility for a room to the given value: true means that the
// room is publicly visible, false means that the room isn't publicly visible.
// Returns an error if the update failed.
UpdateRoomVisibility(roomNID types.RoomNID, visibility bool) error
// Returns a map of the aliases bound to a given set of room IDs, ordered
// by room ID (ie map[roomID] = []alias)
// Returns an error if the retrieval failed
GetAliasesFromRoomIDs(roomIDs []string) (map[string][]string, error)
}
// RoomserverPublicRoomAPI is an implementation of api.RoomserverPublicRoomAPI
type RoomserverPublicRoomAPI struct {
DB RoomserverPublicRoomAPIDatabase
}
// SetRoomVisibility implements api.RoomserverPublicRoomAPI
func (r *RoomserverPublicRoomAPI) SetRoomVisibility(
req *api.SetRoomVisibilityRequest,
response *api.SetRoomVisibilityResponse,
) error {
roomNID, err := r.DB.RoomNID(req.RoomID)
if err != nil || roomNID == 0 {
return err
}
var visibility bool
if req.Visibility == "public" {
visibility = true
} else if req.Visibility == "private" {
visibility = false
} else {
return errors.New("Invalid visibility setting")
}
if err = r.DB.UpdateRoomVisibility(roomNID, visibility); err != nil {
return err
}
return nil
}
// GetRoomVisibility implements api.RoomserverPublicRoomAPI
func (r *RoomserverPublicRoomAPI) GetRoomVisibility(
req *api.GetRoomVisibilityRequest,
response *api.GetRoomVisibilityResponse,
) error {
roomNID, err := r.DB.RoomNID(req.RoomID)
if err != nil || roomNID == 0 {
return err
}
if isPublic, err := r.DB.IsRoomPublic(roomNID); err != nil {
return err
} else if isPublic {
response.Visibility = "public"
} else {
response.Visibility = "private"
}
return nil
}
// GetPublicRooms implements api.RoomserverPublicRoomAPI
func (r *RoomserverPublicRoomAPI) GetPublicRooms(
req *api.GetPublicRoomsRequest,
response *api.GetPublicRoomsResponse,
) error {
return nil
}
// SetupHTTP adds the RoomserverPublicRoomAPI handlers to the http.ServeMux.
func (r *RoomserverPublicRoomAPI) SetupHTTP(servMux *http.ServeMux) {
servMux.Handle(
api.RoomserverSetRoomVisibilityPath,
common.MakeAPI("setRoomVisibility", func(req *http.Request) util.JSONResponse {
var request api.SetRoomVisibilityRequest
var response api.SetRoomVisibilityResponse
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
return util.ErrorResponse(err)
}
if err := r.SetRoomVisibility(&request, &response); err != nil {
return util.ErrorResponse(err)
}
return util.JSONResponse{Code: 200, JSON: &response}
}),
)
servMux.Handle(
api.RoomserverGetRoomVisibilityPath,
common.MakeAPI("getRoomVisibility", func(req *http.Request) util.JSONResponse {
var request api.GetRoomVisibilityRequest
var response api.GetRoomVisibilityResponse
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
return util.ErrorResponse(err)
}
if err := r.GetRoomVisibility(&request, &response); err != nil {
return util.ErrorResponse(err)
}
return util.JSONResponse{Code: 200, JSON: &response}
}),
)
servMux.Handle(
api.RoomserverGetPublicRoomsPath,
common.MakeAPI("getPublicRooms", func(req *http.Request) util.JSONResponse {
var request api.GetPublicRoomsRequest
var response api.GetPublicRoomsResponse
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
return util.ErrorResponse(err)
}
if err := r.GetPublicRooms(&request, &response); err != nil {
return util.ErrorResponse(err)
}
return util.JSONResponse{Code: 200, JSON: &response}
}),
)
}