mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-13 01:43:09 -06:00
Implement retrieval in /sync
This commit is contained in:
parent
f461e456ff
commit
94088a829e
|
|
@ -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
|
|
||||||
}
|
|
||||||
|
|
@ -16,7 +16,8 @@ package accounts
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
|
|
||||||
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
)
|
)
|
||||||
|
|
||||||
const accountDataSchema = `
|
const accountDataSchema = `
|
||||||
|
|
@ -77,56 +78,54 @@ func (s *accountDataStatements) insertAccountData(localpart string, roomID strin
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *accountDataStatements) selectGlobalAccountData(localpart string) ([]authtypes.AccountData, error) {
|
func (s *accountDataStatements) selectGlobalAccountData(localpart string) ([]gomatrixserverlib.ClientEvent, error) {
|
||||||
var data []authtypes.AccountData
|
var events []gomatrixserverlib.ClientEvent
|
||||||
|
|
||||||
rows, err := s.selectGlobalAccountDataStmt.Query(localpart)
|
rows, err := s.selectGlobalAccountDataStmt.Query(localpart)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return data, err
|
return events, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var dataType string
|
var dataType string
|
||||||
var content string
|
var content []byte
|
||||||
|
|
||||||
if err := rows.Scan(&dataType, &content); err != nil && err != sql.ErrNoRows {
|
if err := rows.Scan(&dataType, &content); err != nil && err != sql.ErrNoRows {
|
||||||
return data, err
|
return events, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ac := authtypes.AccountData{
|
ac := gomatrixserverlib.ClientEvent{
|
||||||
Localpart: localpart,
|
|
||||||
Type: dataType,
|
Type: dataType,
|
||||||
Content: content,
|
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) {
|
func (s *accountDataStatements) selectRoomAccountData(localpart string, roomID string) ([]gomatrixserverlib.ClientEvent, error) {
|
||||||
var data []authtypes.AccountData
|
var events []gomatrixserverlib.ClientEvent
|
||||||
|
|
||||||
rows, err := s.selectRoomAccountDataStmt.Query(localpart)
|
rows, err := s.selectRoomAccountDataStmt.Query(localpart, roomID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return data, err
|
return events, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var dataType string
|
var dataType string
|
||||||
var content string
|
var content []byte
|
||||||
|
|
||||||
if err := rows.Scan(&dataType, &content); err != nil && err != sql.ErrNoRows {
|
if err := rows.Scan(&dataType, &content); err != nil && err != sql.ErrNoRows {
|
||||||
return data, err
|
return events, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ac := authtypes.AccountData{
|
ac := gomatrixserverlib.ClientEvent{
|
||||||
Localpart: localpart,
|
|
||||||
Type: dataType,
|
Type: dataType,
|
||||||
Content: content,
|
Content: content,
|
||||||
}
|
}
|
||||||
data = append(data, ac)
|
events = append(events, ac)
|
||||||
}
|
}
|
||||||
|
|
||||||
return data, nil
|
return events, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -198,6 +198,20 @@ func (d *Database) SaveAccountData(localpart string, roomID string, dataType str
|
||||||
return d.accountDatas.insertAccountData(localpart, roomID, dataType, content)
|
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) {
|
func hashPassword(plaintext string) (hash string, err error) {
|
||||||
hashBytes, err := bcrypt.GenerateFromPassword([]byte(plaintext), bcrypt.DefaultCost)
|
hashBytes, err := bcrypt.GenerateFromPassword([]byte(plaintext), bcrypt.DefaultCost)
|
||||||
return string(hashBytes), err
|
return string(hashBytes), err
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/matrix-org/dendrite/clientapi/auth/storage/accounts"
|
||||||
"github.com/matrix-org/dendrite/clientapi/auth/storage/devices"
|
"github.com/matrix-org/dendrite/clientapi/auth/storage/devices"
|
||||||
"github.com/matrix-org/dendrite/common"
|
"github.com/matrix-org/dendrite/common"
|
||||||
"github.com/matrix-org/dendrite/common/config"
|
"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)
|
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()
|
pos, err := db.SyncStreamPosition()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panicf("startup: failed to get latest sync stream position : %s", err)
|
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)
|
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))
|
log.Fatal(http.ListenAndServe(string(cfg.Listen.SyncAPI), nil))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,22 +20,25 @@ import (
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
|
"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/httputil"
|
||||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||||
"github.com/matrix-org/dendrite/syncapi/storage"
|
"github.com/matrix-org/dendrite/syncapi/storage"
|
||||||
"github.com/matrix-org/dendrite/syncapi/types"
|
"github.com/matrix-org/dendrite/syncapi/types"
|
||||||
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
"github.com/matrix-org/util"
|
"github.com/matrix-org/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RequestPool manages HTTP long-poll connections for /sync
|
// RequestPool manages HTTP long-poll connections for /sync
|
||||||
type RequestPool struct {
|
type RequestPool struct {
|
||||||
db *storage.SyncServerDatabase
|
db *storage.SyncServerDatabase
|
||||||
|
accountDB *accounts.Database
|
||||||
notifier *Notifier
|
notifier *Notifier
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRequestPool makes a new RequestPool
|
// NewRequestPool makes a new RequestPool
|
||||||
func NewRequestPool(db *storage.SyncServerDatabase, n *Notifier) *RequestPool {
|
func NewRequestPool(db *storage.SyncServerDatabase, n *Notifier, adb *accounts.Database) *RequestPool {
|
||||||
return &RequestPool{db, n}
|
return &RequestPool{db, adb, n}
|
||||||
}
|
}
|
||||||
|
|
||||||
// OnIncomingSyncRequest is called when a client makes a /sync request. This function MUST be
|
// OnIncomingSyncRequest is called when a client makes a /sync request. This function MUST be
|
||||||
|
|
@ -74,6 +77,10 @@ func (rp *RequestPool) OnIncomingSyncRequest(req *http.Request, device *authtype
|
||||||
timer.Stop()
|
timer.Stop()
|
||||||
syncData, err := rp.currentSyncForUser(*syncReq, currentPos)
|
syncData, err := rp.currentSyncForUser(*syncReq, currentPos)
|
||||||
var res util.JSONResponse
|
var res util.JSONResponse
|
||||||
|
if err != nil {
|
||||||
|
res = httputil.LogThenError(req, err)
|
||||||
|
} else {
|
||||||
|
syncData, err = rp.appendAccountData(syncData, device.UserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
res = httputil.LogThenError(req, err)
|
res = httputil.LogThenError(req, err)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -82,6 +89,7 @@ func (rp *RequestPool) OnIncomingSyncRequest(req *http.Request, device *authtype
|
||||||
JSON: syncData,
|
JSON: syncData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
done <- res
|
done <- res
|
||||||
close(done)
|
close(done)
|
||||||
}()
|
}()
|
||||||
|
|
@ -104,3 +112,27 @@ func (rp *RequestPool) currentSyncForUser(req syncRequest, currentPos types.Stre
|
||||||
}
|
}
|
||||||
return rp.db.IncrementalSync(req.userID, req.since, currentPos, req.limit)
|
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
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue