Implement retrieval in /sync

This commit is contained in:
Brendan Abolivier 2017-07-25 11:38:09 +01:00
parent f461e456ff
commit 94088a829e
No known key found for this signature in database
GPG key ID: 8EF1500759F70623
5 changed files with 83 additions and 54 deletions

View file

@ -1,22 +0,0 @@
// 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 authtypes
// AccountData represents data specific to a given account
type AccountData struct {
Localpart string
Type string
Content string
}

View file

@ -16,7 +16,8 @@ package accounts
import (
"database/sql"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/matrix-org/gomatrixserverlib"
)
const accountDataSchema = `
@ -77,56 +78,54 @@ func (s *accountDataStatements) insertAccountData(localpart string, roomID strin
return
}
func (s *accountDataStatements) selectGlobalAccountData(localpart string) ([]authtypes.AccountData, error) {
var data []authtypes.AccountData
func (s *accountDataStatements) selectGlobalAccountData(localpart string) ([]gomatrixserverlib.ClientEvent, error) {
var events []gomatrixserverlib.ClientEvent
rows, err := s.selectGlobalAccountDataStmt.Query(localpart)
if err != nil {
return data, err
return events, err
}
for rows.Next() {
var dataType string
var content string
var content []byte
if err := rows.Scan(&dataType, &content); err != nil && err != sql.ErrNoRows {
return data, err
return events, err
}
ac := authtypes.AccountData{
Localpart: localpart,
Type: dataType,
Content: content,
ac := gomatrixserverlib.ClientEvent{
Type: dataType,
Content: content,
}
data = append(data, ac)
events = append(events, ac)
}
return data, nil
return events, nil
}
func (s *accountDataStatements) selectRoomAccountData(localpart string, roomID string) ([]authtypes.AccountData, error) {
var data []authtypes.AccountData
func (s *accountDataStatements) selectRoomAccountData(localpart string, roomID string) ([]gomatrixserverlib.ClientEvent, error) {
var events []gomatrixserverlib.ClientEvent
rows, err := s.selectRoomAccountDataStmt.Query(localpart)
rows, err := s.selectRoomAccountDataStmt.Query(localpart, roomID)
if err != nil {
return data, err
return events, err
}
for rows.Next() {
var dataType string
var content string
var content []byte
if err := rows.Scan(&dataType, &content); err != nil && err != sql.ErrNoRows {
return data, err
return events, err
}
ac := authtypes.AccountData{
Localpart: localpart,
Type: dataType,
Content: content,
ac := gomatrixserverlib.ClientEvent{
Type: dataType,
Content: content,
}
data = append(data, ac)
events = append(events, ac)
}
return data, nil
return events, nil
}

View file

@ -198,6 +198,20 @@ func (d *Database) SaveAccountData(localpart string, roomID string, dataType str
return d.accountDatas.insertAccountData(localpart, roomID, dataType, content)
}
// GetAccountData returns account data related to a given localpart
// If a non-empty string is provided as the room ID, returns all account data
// related to the room
// If an empty string is provided as the room ID, returns all account data that
// aren't related to any room
// If no account data could be found, returns an empty arrays
// Returns an error if there was an issue with the retrieval
func (d *Database) GetAccountData(localpart string, roomID string) ([]gomatrixserverlib.ClientEvent, error) {
if len(roomID) > 0 {
return d.accountDatas.selectRoomAccountData(localpart, roomID)
}
return d.accountDatas.selectGlobalAccountData(localpart)
}
func hashPassword(plaintext string) (hash string, err error) {
hashBytes, err := bcrypt.GenerateFromPassword([]byte(plaintext), bcrypt.DefaultCost)
return string(hashBytes), err

View file

@ -19,6 +19,7 @@ import (
"net/http"
"os"
"github.com/matrix-org/dendrite/clientapi/auth/storage/accounts"
"github.com/matrix-org/dendrite/clientapi/auth/storage/devices"
"github.com/matrix-org/dendrite/common"
"github.com/matrix-org/dendrite/common/config"
@ -58,6 +59,11 @@ func main() {
log.Panicf("startup: failed to create device database with data source %s : %s", cfg.Database.Device, err)
}
adb, err := accounts.NewDatabase(string(cfg.Database.Account), cfg.Matrix.ServerName)
if err != nil {
log.Panicf("startup: failed to create account database with data source %s : %s", cfg.Database.Account, err)
}
pos, err := db.SyncStreamPosition()
if err != nil {
log.Panicf("startup: failed to get latest sync stream position : %s", err)
@ -76,6 +82,6 @@ func main() {
}
log.Info("Starting sync server on ", cfg.Listen.SyncAPI)
routing.SetupSyncServerListeners(http.DefaultServeMux, http.DefaultClient, sync.NewRequestPool(db, n), deviceDB)
routing.SetupSyncServerListeners(http.DefaultServeMux, http.DefaultClient, sync.NewRequestPool(db, n, adb), deviceDB)
log.Fatal(http.ListenAndServe(string(cfg.Listen.SyncAPI), nil))
}

View file

@ -20,22 +20,25 @@ import (
log "github.com/Sirupsen/logrus"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/matrix-org/dendrite/clientapi/auth/storage/accounts"
"github.com/matrix-org/dendrite/clientapi/httputil"
"github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/syncapi/storage"
"github.com/matrix-org/dendrite/syncapi/types"
"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util"
)
// RequestPool manages HTTP long-poll connections for /sync
type RequestPool struct {
db *storage.SyncServerDatabase
notifier *Notifier
db *storage.SyncServerDatabase
accountDB *accounts.Database
notifier *Notifier
}
// NewRequestPool makes a new RequestPool
func NewRequestPool(db *storage.SyncServerDatabase, n *Notifier) *RequestPool {
return &RequestPool{db, n}
func NewRequestPool(db *storage.SyncServerDatabase, n *Notifier, adb *accounts.Database) *RequestPool {
return &RequestPool{db, adb, n}
}
// OnIncomingSyncRequest is called when a client makes a /sync request. This function MUST be
@ -77,9 +80,14 @@ func (rp *RequestPool) OnIncomingSyncRequest(req *http.Request, device *authtype
if err != nil {
res = httputil.LogThenError(req, err)
} else {
res = util.JSONResponse{
Code: 200,
JSON: syncData,
syncData, err = rp.appendAccountData(syncData, device.UserID)
if err != nil {
res = httputil.LogThenError(req, err)
} else {
res = util.JSONResponse{
Code: 200,
JSON: syncData,
}
}
}
done <- res
@ -104,3 +112,27 @@ func (rp *RequestPool) currentSyncForUser(req syncRequest, currentPos types.Stre
}
return rp.db.IncrementalSync(req.userID, req.since, currentPos, req.limit)
}
func (rp *RequestPool) appendAccountData(data *types.Response, userID string) (*types.Response, error) {
localpart, _, err := gomatrixserverlib.SplitID('@', userID)
if err != nil {
return nil, err
}
events, err := rp.accountDB.GetAccountData(localpart, "")
if err != nil {
return nil, err
}
data.AccountData.Events = events
for r, j := range data.Rooms.Join {
events, err := rp.accountDB.GetAccountData(localpart, r)
if err != nil {
return nil, err
}
j.AccountData.Events = events
data.Rooms.Join[r] = j
}
return data, nil
}