aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build/gobind-pinecone/monolith.go21
-rw-r--r--clientapi/auth/authtypes/profile.go1
-rw-r--r--clientapi/clientapi.go3
-rw-r--r--clientapi/routing/routing.go2
-rw-r--r--clientapi/routing/userdirectory.go14
-rw-r--r--cmd/dendrite-demo-pinecone/main.go21
-rw-r--r--cmd/dendrite-demo-pinecone/users/users.go145
-rw-r--r--cmd/dendrite-polylith-multi/personalities/clientapi.go2
-rw-r--r--setup/base/base.go1
-rw-r--r--setup/monolith.go9
-rw-r--r--userapi/api/api.go4
-rw-r--r--userapi/storage/postgres/profile_table.go11
-rw-r--r--userapi/storage/postgres/storage.go4
-rw-r--r--userapi/storage/sqlite3/profile_table.go10
-rw-r--r--userapi/storage/sqlite3/storage.go4
-rw-r--r--userapi/storage/storage.go6
-rw-r--r--userapi/storage/storage_wasm.go3
-rw-r--r--userapi/userapi_test.go2
18 files changed, 226 insertions, 37 deletions
diff --git a/build/gobind-pinecone/monolith.go b/build/gobind-pinecone/monolith.go
index 8ef4bbc7..346c5d1e 100644
--- a/build/gobind-pinecone/monolith.go
+++ b/build/gobind-pinecone/monolith.go
@@ -22,6 +22,7 @@ import (
"github.com/matrix-org/dendrite/clientapi/userutil"
"github.com/matrix-org/dendrite/cmd/dendrite-demo-pinecone/conn"
"github.com/matrix-org/dendrite/cmd/dendrite-demo-pinecone/rooms"
+ "github.com/matrix-org/dendrite/cmd/dendrite-demo-pinecone/users"
"github.com/matrix-org/dendrite/cmd/dendrite-demo-yggdrasil/signing"
"github.com/matrix-org/dendrite/eduserver"
"github.com/matrix-org/dendrite/eduserver/cache"
@@ -326,6 +327,9 @@ func (m *DendriteMonolith) Start() {
// This is different to rsAPI which can be the http client which doesn't need this dependency
rsAPI.SetFederationAPI(fsAPI, keyRing)
+ userProvider := users.NewPineconeUserProvider(m.PineconeRouter, m.PineconeQUIC, m.userAPI, federation)
+ roomProvider := rooms.NewPineconeRoomProvider(m.PineconeRouter, m.PineconeQUIC, fsAPI, federation)
+
monolith := setup.Monolith{
Config: base.Cfg,
AccountDB: accountDB,
@@ -333,13 +337,14 @@ func (m *DendriteMonolith) Start() {
FedClient: federation,
KeyRing: keyRing,
- AppserviceAPI: asAPI,
- EDUInternalAPI: eduInputAPI,
- FederationAPI: fsAPI,
- RoomserverAPI: rsAPI,
- UserAPI: m.userAPI,
- KeyAPI: keyAPI,
- ExtPublicRoomsProvider: rooms.NewPineconeRoomProvider(m.PineconeRouter, m.PineconeQUIC, fsAPI, federation),
+ AppserviceAPI: asAPI,
+ EDUInternalAPI: eduInputAPI,
+ FederationAPI: fsAPI,
+ RoomserverAPI: rsAPI,
+ UserAPI: m.userAPI,
+ KeyAPI: keyAPI,
+ ExtPublicRoomsProvider: roomProvider,
+ ExtUserDirectoryProvider: userProvider,
}
monolith.AddAllPublicRoutes(
base.ProcessContext,
@@ -357,10 +362,12 @@ func (m *DendriteMonolith) Start() {
httpRouter.PathPrefix(httputil.PublicMediaPathPrefix).Handler(base.PublicMediaAPIMux)
pMux := mux.NewRouter().SkipClean(true).UseEncodedPath()
+ pMux.PathPrefix(users.PublicURL).HandlerFunc(userProvider.FederatedUserProfiles)
pMux.PathPrefix(httputil.PublicFederationPathPrefix).Handler(base.PublicFederationAPIMux)
pMux.PathPrefix(httputil.PublicMediaPathPrefix).Handler(base.PublicMediaAPIMux)
pHTTP := m.PineconeQUIC.HTTP()
+ pHTTP.Mux().Handle(users.PublicURL, pMux)
pHTTP.Mux().Handle(httputil.PublicFederationPathPrefix, pMux)
pHTTP.Mux().Handle(httputil.PublicMediaPathPrefix, pMux)
diff --git a/clientapi/auth/authtypes/profile.go b/clientapi/auth/authtypes/profile.go
index 902850bc..29468c16 100644
--- a/clientapi/auth/authtypes/profile.go
+++ b/clientapi/auth/authtypes/profile.go
@@ -17,6 +17,7 @@ package authtypes
// Profile represents the profile for a Matrix account.
type Profile struct {
Localpart string `json:"local_part"`
+ ServerName string `json:"server_name,omitempty"` // NOTSPEC: only set by Pinecone user provider
DisplayName string `json:"display_name"`
AvatarURL string `json:"avatar_url"`
}
diff --git a/clientapi/clientapi.go b/clientapi/clientapi.go
index 31a53a70..d0ef368d 100644
--- a/clientapi/clientapi.go
+++ b/clientapi/clientapi.go
@@ -45,6 +45,7 @@ func AddPublicRoutes(
transactionsCache *transactions.Cache,
fsAPI federationAPI.FederationInternalAPI,
userAPI userapi.UserInternalAPI,
+ userDirectoryProvider userapi.UserDirectoryProvider,
keyAPI keyserverAPI.KeyInternalAPI,
extRoomsProvider api.ExtraPublicRoomsProvider,
mscCfg *config.MSCs,
@@ -58,7 +59,7 @@ func AddPublicRoutes(
routing.Setup(
router, synapseAdminRouter, cfg, eduInputAPI, rsAPI, asAPI,
- userAPI, federation,
+ userAPI, userDirectoryProvider, federation,
syncProducer, transactionsCache, fsAPI, keyAPI,
extRoomsProvider, mscCfg,
)
diff --git a/clientapi/routing/routing.go b/clientapi/routing/routing.go
index e173831a..218087bb 100644
--- a/clientapi/routing/routing.go
+++ b/clientapi/routing/routing.go
@@ -51,6 +51,7 @@ func Setup(
rsAPI roomserverAPI.RoomserverInternalAPI,
asAPI appserviceAPI.AppServiceQueryAPI,
userAPI userapi.UserInternalAPI,
+ userDirectoryProvider userapi.UserDirectoryProvider,
federation *gomatrixserverlib.FederationClient,
syncProducer *producers.SyncAPIProducer,
transactionsCache *transactions.Cache,
@@ -904,6 +905,7 @@ func Setup(
device,
userAPI,
rsAPI,
+ userDirectoryProvider,
cfg.Matrix.ServerName,
postContent.SearchString,
postContent.Limit,
diff --git a/clientapi/routing/userdirectory.go b/clientapi/routing/userdirectory.go
index 2659bc9c..ab73cf43 100644
--- a/clientapi/routing/userdirectory.go
+++ b/clientapi/routing/userdirectory.go
@@ -16,6 +16,7 @@ package routing
import (
"context"
+ "database/sql"
"fmt"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
@@ -35,6 +36,7 @@ func SearchUserDirectory(
device *userapi.Device,
userAPI userapi.UserInternalAPI,
rsAPI api.RoomserverInternalAPI,
+ provider userapi.UserDirectoryProvider,
serverName gomatrixserverlib.ServerName,
searchString string,
limit int,
@@ -50,13 +52,12 @@ func SearchUserDirectory(
}
// First start searching local users.
-
userReq := &userapi.QuerySearchProfilesRequest{
SearchString: searchString,
Limit: limit,
}
userRes := &userapi.QuerySearchProfilesResponse{}
- if err := userAPI.QuerySearchProfiles(ctx, userReq, userRes); err != nil {
+ if err := provider.QuerySearchProfiles(ctx, userReq, userRes); err != nil {
errRes := util.ErrorResponse(fmt.Errorf("userAPI.QuerySearchProfiles: %w", err))
return &errRes
}
@@ -67,7 +68,12 @@ func SearchUserDirectory(
break
}
- userID := fmt.Sprintf("@%s:%s", user.Localpart, serverName)
+ var userID string
+ if user.ServerName != "" {
+ userID = fmt.Sprintf("@%s:%s", user.Localpart, user.ServerName)
+ } else {
+ userID = fmt.Sprintf("@%s:%s", user.Localpart, serverName)
+ }
if _, ok := results[userID]; !ok {
results[userID] = authtypes.FullyQualifiedProfile{
UserID: userID,
@@ -87,7 +93,7 @@ func SearchUserDirectory(
Limit: limit - len(results),
}
stateRes := &api.QueryKnownUsersResponse{}
- if err := rsAPI.QueryKnownUsers(ctx, stateReq, stateRes); err != nil {
+ if err := rsAPI.QueryKnownUsers(ctx, stateReq, stateRes); err != nil && err != sql.ErrNoRows {
errRes := util.ErrorResponse(fmt.Errorf("rsAPI.QueryKnownUsers: %w", err))
return &errRes
}
diff --git a/cmd/dendrite-demo-pinecone/main.go b/cmd/dendrite-demo-pinecone/main.go
index 45f18698..87054dc8 100644
--- a/cmd/dendrite-demo-pinecone/main.go
+++ b/cmd/dendrite-demo-pinecone/main.go
@@ -35,6 +35,7 @@ import (
"github.com/matrix-org/dendrite/cmd/dendrite-demo-pinecone/conn"
"github.com/matrix-org/dendrite/cmd/dendrite-demo-pinecone/embed"
"github.com/matrix-org/dendrite/cmd/dendrite-demo-pinecone/rooms"
+ "github.com/matrix-org/dendrite/cmd/dendrite-demo-pinecone/users"
"github.com/matrix-org/dendrite/cmd/dendrite-demo-yggdrasil/signing"
"github.com/matrix-org/dendrite/eduserver"
"github.com/matrix-org/dendrite/eduserver/cache"
@@ -198,6 +199,9 @@ func main() {
rsComponent.SetFederationAPI(fsAPI, keyRing)
+ userProvider := users.NewPineconeUserProvider(pRouter, pQUIC, userAPI, federation)
+ roomProvider := rooms.NewPineconeRoomProvider(pRouter, pQUIC, fsAPI, federation)
+
monolith := setup.Monolith{
Config: base.Cfg,
AccountDB: accountDB,
@@ -205,13 +209,14 @@ func main() {
FedClient: federation,
KeyRing: keyRing,
- AppserviceAPI: asAPI,
- EDUInternalAPI: eduInputAPI,
- FederationAPI: fsAPI,
- RoomserverAPI: rsAPI,
- UserAPI: userAPI,
- KeyAPI: keyAPI,
- ExtPublicRoomsProvider: rooms.NewPineconeRoomProvider(pRouter, pQUIC, fsAPI, federation),
+ AppserviceAPI: asAPI,
+ EDUInternalAPI: eduInputAPI,
+ FederationAPI: fsAPI,
+ RoomserverAPI: rsAPI,
+ UserAPI: userAPI,
+ KeyAPI: keyAPI,
+ ExtPublicRoomsProvider: roomProvider,
+ ExtUserDirectoryProvider: userProvider,
}
monolith.AddAllPublicRoutes(
base.ProcessContext,
@@ -250,10 +255,12 @@ func main() {
embed.Embed(httpRouter, *instancePort, "Pinecone Demo")
pMux := mux.NewRouter().SkipClean(true).UseEncodedPath()
+ pMux.PathPrefix(users.PublicURL).HandlerFunc(userProvider.FederatedUserProfiles)
pMux.PathPrefix(httputil.PublicFederationPathPrefix).Handler(base.PublicFederationAPIMux)
pMux.PathPrefix(httputil.PublicMediaPathPrefix).Handler(base.PublicMediaAPIMux)
pHTTP := pQUIC.HTTP()
+ pHTTP.Mux().Handle(users.PublicURL, pMux)
pHTTP.Mux().Handle(httputil.PublicFederationPathPrefix, pMux)
pHTTP.Mux().Handle(httputil.PublicMediaPathPrefix, pMux)
diff --git a/cmd/dendrite-demo-pinecone/users/users.go b/cmd/dendrite-demo-pinecone/users/users.go
new file mode 100644
index 00000000..ffbd27ee
--- /dev/null
+++ b/cmd/dendrite-demo-pinecone/users/users.go
@@ -0,0 +1,145 @@
+package users
+
+import (
+ "bytes"
+ "context"
+ "encoding/json"
+ "fmt"
+ "net/http"
+ "sync"
+ "time"
+
+ "github.com/matrix-org/dendrite/clientapi/auth/authtypes"
+ clienthttputil "github.com/matrix-org/dendrite/clientapi/httputil"
+ userapi "github.com/matrix-org/dendrite/userapi/api"
+ "github.com/matrix-org/gomatrixserverlib"
+ "github.com/matrix-org/util"
+
+ pineconeRouter "github.com/matrix-org/pinecone/router"
+ pineconeSessions "github.com/matrix-org/pinecone/sessions"
+)
+
+type PineconeUserProvider struct {
+ r *pineconeRouter.Router
+ s *pineconeSessions.Sessions
+ userAPI userapi.UserProfileAPI
+ fedClient *gomatrixserverlib.FederationClient
+}
+
+const PublicURL = "/_matrix/p2p/profiles"
+
+func NewPineconeUserProvider(
+ r *pineconeRouter.Router,
+ s *pineconeSessions.Sessions,
+ userAPI userapi.UserProfileAPI,
+ fedClient *gomatrixserverlib.FederationClient,
+) *PineconeUserProvider {
+ p := &PineconeUserProvider{
+ r: r,
+ s: s,
+ userAPI: userAPI,
+ fedClient: fedClient,
+ }
+ return p
+}
+
+func (p *PineconeUserProvider) FederatedUserProfiles(w http.ResponseWriter, r *http.Request) {
+ req := &userapi.QuerySearchProfilesRequest{Limit: 25}
+ res := &userapi.QuerySearchProfilesResponse{}
+ if err := clienthttputil.UnmarshalJSONRequest(r, &req); err != nil {
+ w.WriteHeader(400)
+ return
+ }
+ if err := p.userAPI.QuerySearchProfiles(r.Context(), req, res); err != nil {
+ w.WriteHeader(400)
+ return
+ }
+ j, err := json.Marshal(res)
+ if err != nil {
+ w.WriteHeader(400)
+ return
+ }
+ w.WriteHeader(200)
+ _, _ = w.Write(j)
+}
+
+func (p *PineconeUserProvider) QuerySearchProfiles(ctx context.Context, req *userapi.QuerySearchProfilesRequest, res *userapi.QuerySearchProfilesResponse) error {
+ list := map[string]struct{}{}
+ for _, k := range p.r.Peers() {
+ list[k.PublicKey] = struct{}{}
+ }
+ res.Profiles = bulkFetchUserDirectoriesFromServers(context.Background(), req, p.fedClient, list)
+ return nil
+}
+
+// bulkFetchUserDirectoriesFromServers fetches users from the list of homeservers.
+// Returns a list of user profiles.
+func bulkFetchUserDirectoriesFromServers(
+ ctx context.Context, req *userapi.QuerySearchProfilesRequest,
+ fedClient *gomatrixserverlib.FederationClient,
+ homeservers map[string]struct{},
+) (profiles []authtypes.Profile) {
+ jsonBody, err := json.Marshal(req)
+ if err != nil {
+ return nil
+ }
+
+ limit := 200
+ // follow pipeline semantics, see https://blog.golang.org/pipelines for more info.
+ // goroutines send rooms to this channel
+ profileCh := make(chan authtypes.Profile, int(limit))
+ // signalling channel to tell goroutines to stop sending rooms and quit
+ done := make(chan bool)
+ // signalling to say when we can close the room channel
+ var wg sync.WaitGroup
+ wg.Add(len(homeservers))
+ // concurrently query for public rooms
+ reqctx, reqcancel := context.WithTimeout(ctx, time.Second*5)
+ for hs := range homeservers {
+ go func(homeserverDomain string) {
+ defer wg.Done()
+ util.GetLogger(reqctx).WithField("hs", homeserverDomain).Info("Querying HS for users")
+
+ jsonBodyReader := bytes.NewBuffer(jsonBody)
+ httpReq, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("matrix://%s%s", homeserverDomain, PublicURL), jsonBodyReader)
+ if err != nil {
+ util.GetLogger(reqctx).WithError(err).WithField("hs", homeserverDomain).Warn(
+ "bulkFetchUserDirectoriesFromServers: failed to create request",
+ )
+ }
+ res := &userapi.QuerySearchProfilesResponse{}
+ if err = fedClient.DoRequestAndParseResponse(reqctx, httpReq, res); err != nil {
+ util.GetLogger(reqctx).WithError(err).WithField("hs", homeserverDomain).Warn(
+ "bulkFetchUserDirectoriesFromServers: failed to query hs",
+ )
+ return
+ }
+ for _, profile := range res.Profiles {
+ profile.ServerName = homeserverDomain
+ // atomically send a room or stop
+ select {
+ case profileCh <- profile:
+ case <-done:
+ case <-reqctx.Done():
+ util.GetLogger(reqctx).WithError(err).WithField("hs", homeserverDomain).Info("Interrupted whilst sending profiles")
+ return
+ }
+ }
+ }(hs)
+ }
+
+ select {
+ case <-time.After(5 * time.Second):
+ default:
+ wg.Wait()
+ }
+ reqcancel()
+ close(done)
+ close(profileCh)
+
+ for profile := range profileCh {
+ profiles = append(profiles, profile)
+ }
+
+ return profiles
+}
diff --git a/cmd/dendrite-polylith-multi/personalities/clientapi.go b/cmd/dendrite-polylith-multi/personalities/clientapi.go
index a2036de3..978d8b0a 100644
--- a/cmd/dendrite-polylith-multi/personalities/clientapi.go
+++ b/cmd/dendrite-polylith-multi/personalities/clientapi.go
@@ -33,7 +33,7 @@ func ClientAPI(base *basepkg.BaseDendrite, cfg *config.Dendrite) {
clientapi.AddPublicRoutes(
base.ProcessContext, base.PublicClientAPIMux, base.SynapseAdminMux, &base.Cfg.ClientAPI,
- federation, rsAPI, eduInputAPI, asQuery, transactions.New(), fsAPI, userAPI,
+ federation, rsAPI, eduInputAPI, asQuery, transactions.New(), fsAPI, userAPI, userAPI,
keyAPI, nil, &cfg.MSCs,
)
diff --git a/setup/base/base.go b/setup/base/base.go
index c3ed0541..6135e080 100644
--- a/setup/base/base.go
+++ b/setup/base/base.go
@@ -289,6 +289,7 @@ func (b *BaseDendrite) CreateAccountsDB() userdb.Database {
b.Cfg.UserAPI.BCryptCost,
b.Cfg.UserAPI.OpenIDTokenLifetimeMS,
userapi.DefaultLoginTokenLifetime,
+ b.Cfg.Global.ServerNotices.LocalPart,
)
if err != nil {
logrus.WithError(err).Panicf("failed to connect to accounts db")
diff --git a/setup/monolith.go b/setup/monolith.go
index 8e6240d3..cf6872f9 100644
--- a/setup/monolith.go
+++ b/setup/monolith.go
@@ -51,16 +51,21 @@ type Monolith struct {
KeyAPI keyAPI.KeyInternalAPI
// Optional
- ExtPublicRoomsProvider api.ExtraPublicRoomsProvider
+ ExtPublicRoomsProvider api.ExtraPublicRoomsProvider
+ ExtUserDirectoryProvider userapi.UserDirectoryProvider
}
// AddAllPublicRoutes attaches all public paths to the given router
func (m *Monolith) AddAllPublicRoutes(process *process.ProcessContext, csMux, ssMux, keyMux, wkMux, mediaMux, synapseMux *mux.Router) {
+ userDirectoryProvider := m.ExtUserDirectoryProvider
+ if userDirectoryProvider == nil {
+ userDirectoryProvider = m.UserAPI
+ }
clientapi.AddPublicRoutes(
process, csMux, synapseMux, &m.Config.ClientAPI,
m.FedClient, m.RoomserverAPI,
m.EDUInternalAPI, m.AppserviceAPI, transactions.New(),
- m.FederationAPI, m.UserAPI, m.KeyAPI,
+ m.FederationAPI, m.UserAPI, userDirectoryProvider, m.KeyAPI,
m.ExtPublicRoomsProvider, &m.Config.MSCs,
)
federationapi.AddPublicRoutes(
diff --git a/userapi/api/api.go b/userapi/api/api.go
index 513a060c..a9544f00 100644
--- a/userapi/api/api.go
+++ b/userapi/api/api.go
@@ -54,6 +54,10 @@ type UserInternalAPI interface {
QueryNotifications(ctx context.Context, req *QueryNotificationsRequest, res *QueryNotificationsResponse) error
}
+type UserDirectoryProvider interface {
+ QuerySearchProfiles(ctx context.Context, req *QuerySearchProfilesRequest, res *QuerySearchProfilesResponse) error
+}
+
// UserProfileAPI provides functions for getting user profiles
type UserProfileAPI interface {
QueryProfile(ctx context.Context, req *QueryProfileRequest, res *QueryProfileResponse) error
diff --git a/userapi/storage/postgres/profile_table.go b/userapi/storage/postgres/profile_table.go
index 32a4b550..6d336eb8 100644
--- a/userapi/storage/postgres/profile_table.go
+++ b/userapi/storage/postgres/profile_table.go
@@ -53,6 +53,7 @@ const selectProfilesBySearchSQL = "" +
"SELECT localpart, display_name, avatar_url FROM account_profiles WHERE localpart LIKE $1 OR display_name LIKE $1 LIMIT $2"
type profilesStatements struct {
+ serverNoticesLocalpart string
insertProfileStmt *sql.Stmt
selectProfileByLocalpartStmt *sql.Stmt
setAvatarURLStmt *sql.Stmt
@@ -60,8 +61,10 @@ type profilesStatements struct {
selectProfilesBySearchStmt *sql.Stmt
}
-func NewPostgresProfilesTable(db *sql.DB) (tables.ProfileTable, error) {
- s := &profilesStatements{}
+func NewPostgresProfilesTable(db *sql.DB, serverNoticesLocalpart string) (tables.ProfileTable, error) {
+ s := &profilesStatements{
+ serverNoticesLocalpart: serverNoticesLocalpart,
+ }
_, err := db.Exec(profilesSchema)
if err != nil {
return nil, err
@@ -126,7 +129,9 @@ func (s *profilesStatements) SelectProfilesBySearch(
if err := rows.Scan(&profile.Localpart, &profile.DisplayName, &profile.AvatarURL); err != nil {
return nil, err
}
- profiles = append(profiles, profile)
+ if profile.Localpart != s.serverNoticesLocalpart {
+ profiles = append(profiles, profile)
+ }
}
return profiles, nil
}
diff --git a/userapi/storage/postgres/storage.go b/userapi/storage/postgres/storage.go
index c74a999f..b2a51760 100644
--- a/userapi/storage/postgres/storage.go
+++ b/userapi/storage/postgres/storage.go
@@ -30,7 +30,7 @@ import (
)
// NewDatabase creates a new accounts and profiles database
-func NewDatabase(dbProperties *config.DatabaseOptions, serverName gomatrixserverlib.ServerName, bcryptCost int, openIDTokenLifetimeMS int64, loginTokenLifetime time.Duration) (*shared.Database, error) {
+func NewDatabase(dbProperties *config.DatabaseOptions, serverName gomatrixserverlib.ServerName, bcryptCost int, openIDTokenLifetimeMS int64, loginTokenLifetime time.Duration, serverNoticesLocalpart string) (*shared.Database, error) {
db, err := sqlutil.Open(dbProperties)
if err != nil {
return nil, err
@@ -77,7 +77,7 @@ func NewDatabase(dbProperties *config.DatabaseOptions, serverName gomatrixserver
if err != nil {
return nil, fmt.Errorf("NewPostgresOpenIDTable: %w", err)
}
- profilesTable, err := NewPostgresProfilesTable(db)
+ profilesTable, err := NewPostgresProfilesTable(db, serverNoticesLocalpart)
if err != nil {
return nil, fmt.Errorf("NewPostgresProfilesTable: %w", err)
}
diff --git a/userapi/storage/sqlite3/profile_table.go b/userapi/storage/sqlite3/profile_table.go
index d85b19c7..3050ff4b 100644
--- a/userapi/storage/sqlite3/profile_table.go
+++ b/userapi/storage/sqlite3/profile_table.go
@@ -54,6 +54,7 @@ const selectProfilesBySearchSQL = "" +
type profilesStatements struct {
db *sql.DB
+ serverNoticesLocalpart string
insertProfileStmt *sql.Stmt
selectProfileByLocalpartStmt *sql.Stmt
setAvatarURLStmt *sql.Stmt
@@ -61,9 +62,10 @@ type profilesStatements struct {
selectProfilesBySearchStmt *sql.Stmt
}
-func NewSQLiteProfilesTable(db *sql.DB) (tables.ProfileTable, error) {
+func NewSQLiteProfilesTable(db *sql.DB, serverNoticesLocalpart string) (tables.ProfileTable, error) {
s := &profilesStatements{
- db: db,
+ db: db,
+ serverNoticesLocalpart: serverNoticesLocalpart,
}
_, err := db.Exec(profilesSchema)
if err != nil {
@@ -131,7 +133,9 @@ func (s *profilesStatements) SelectProfilesBySearch(
if err := rows.Scan(&profile.Localpart, &profile.DisplayName, &profile.AvatarURL); err != nil {
return nil, err
}
- profiles = append(profiles, profile)
+ if profile.Localpart != s.serverNoticesLocalpart {
+ profiles = append(profiles, profile)
+ }
}
return profiles, nil
}
diff --git a/userapi/storage/sqlite3/storage.go b/userapi/storage/sqlite3/storage.go
index b5bb96c4..03c013f0 100644
--- a/userapi/storage/sqlite3/storage.go
+++ b/userapi/storage/sqlite3/storage.go
@@ -31,7 +31,7 @@ import (
)
// NewDatabase creates a new accounts and profiles database
-func NewDatabase(dbProperties *config.DatabaseOptions, serverName gomatrixserverlib.ServerName, bcryptCost int, openIDTokenLifetimeMS int64, loginTokenLifetime time.Duration) (*shared.Database, error) {
+func NewDatabase(dbProperties *config.DatabaseOptions, serverName gomatrixserverlib.ServerName, bcryptCost int, openIDTokenLifetimeMS int64, loginTokenLifetime time.Duration, serverNoticesLocalpart string) (*shared.Database, error) {
db, err := sqlutil.Open(dbProperties)
if err != nil {
return nil, err
@@ -78,7 +78,7 @@ func NewDatabase(dbProperties *config.DatabaseOptions, serverName gomatrixserver
if err != nil {
return nil, fmt.Errorf("NewSQLiteOpenIDTable: %w", err)
}
- profilesTable, err := NewSQLiteProfilesTable(db)
+ profilesTable, err := NewSQLiteProfilesTable(db, serverNoticesLocalpart)
if err != nil {
return nil, fmt.Errorf("NewSQLiteProfilesTable: %w", err)
}
diff --git a/userapi/storage/storage.go b/userapi/storage/storage.go
index 4711439a..f372fe7d 100644
--- a/userapi/storage/storage.go
+++ b/userapi/storage/storage.go
@@ -30,12 +30,12 @@ import (
// NewDatabase opens a new Postgres or Sqlite database (based on dataSourceName scheme)
// and sets postgres connection parameters
-func NewDatabase(dbProperties *config.DatabaseOptions, serverName gomatrixserverlib.ServerName, bcryptCost int, openIDTokenLifetimeMS int64, loginTokenLifetime time.Duration) (Database, error) {
+func NewDatabase(dbProperties *config.DatabaseOptions, serverName gomatrixserverlib.ServerName, bcryptCost int, openIDTokenLifetimeMS int64, loginTokenLifetime time.Duration, serverNoticesLocalpart string) (Database, error) {
switch {
case dbProperties.ConnectionString.IsSQLite():
- return sqlite3.NewDatabase(dbProperties, serverName, bcryptCost, openIDTokenLifetimeMS, loginTokenLifetime)
+ return sqlite3.NewDatabase(dbProperties, serverName, bcryptCost, openIDTokenLifetimeMS, loginTokenLifetime, serverNoticesLocalpart)
case dbProperties.ConnectionString.IsPostgres():
- return postgres.NewDatabase(dbProperties, serverName, bcryptCost, openIDTokenLifetimeMS, loginTokenLifetime)
+ return postgres.NewDatabase(dbProperties, serverName, bcryptCost, openIDTokenLifetimeMS, loginTokenLifetime, serverNoticesLocalpart)
default:
return nil, fmt.Errorf("unexpected database type")
}
diff --git a/userapi/storage/storage_wasm.go b/userapi/storage/storage_wasm.go
index 701dcd83..779f7756 100644
--- a/userapi/storage/storage_wasm.go
+++ b/userapi/storage/storage_wasm.go
@@ -29,10 +29,11 @@ func NewDatabase(
bcryptCost int,
openIDTokenLifetimeMS int64,
loginTokenLifetime time.Duration,
+ serverNoticesLocalpart string,
) (Database, error) {
switch {
case dbProperties.ConnectionString.IsSQLite():
- return sqlite3.NewDatabase(dbProperties, serverName, bcryptCost, openIDTokenLifetimeMS, loginTokenLifetime)
+ return sqlite3.NewDatabase(dbProperties, serverName, bcryptCost, openIDTokenLifetimeMS, loginTokenLifetime, serverNoticesLocalpart)
case dbProperties.ConnectionString.IsPostgres():
return nil, fmt.Errorf("can't use Postgres implementation")
default:
diff --git a/userapi/userapi_test.go b/userapi/userapi_test.go
index 25319c4b..8c3608bd 100644
--- a/userapi/userapi_test.go
+++ b/userapi/userapi_test.go
@@ -52,7 +52,7 @@ func MustMakeInternalAPI(t *testing.T, opts apiTestOpts) (api.UserInternalAPI, s
MaxOpenConnections: 1,
MaxIdleConnections: 1,
}
- accountDB, err := storage.NewDatabase(dbopts, serverName, bcrypt.MinCost, config.DefaultOpenIDTokenLifetimeMS, opts.loginTokenLifetime)
+ accountDB, err := storage.NewDatabase(dbopts, serverName, bcrypt.MinCost, config.DefaultOpenIDTokenLifetimeMS, opts.loginTokenLifetime, "")
if err != nil {
t.Fatalf("failed to create account DB: %s", err)
}