Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit ad7233c

Browse files
committed
Merge branch 'develop' of github.com:matrix-org/synapse into anoa/clean_up_admin_api_docs
* 'develop' of github.com:matrix-org/synapse: Return total number of users and profile attributes in admin users endpoint (#6881) Add some replication tests (#7278)
2 parents 84654ae + 04dd7d1 commit ad7233c

File tree

9 files changed

+399
-47
lines changed

9 files changed

+399
-47
lines changed

changelog.d/6881.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Return total number of users and profile attributes in admin users endpoint. Contributed by Awesome Technologies Innovationslabor GmbH.

changelog.d/7278.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add some unit tests for replication.

docs/admin_api/user_admin_api.rst

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,17 +91,22 @@ A JSON body is returned with the following shape:
9191
"is_guest": 0,
9292
"admin": 0,
9393
"user_type": null,
94-
"deactivated": 0
94+
"deactivated": 0,
95+
"displayname": <User One>,
96+
"avatar_url": null
9597
}, {
9698
"name": "<user_id2>",
9799
"password_hash": "<password_hash2>",
98100
"is_guest": 0,
99101
"admin": 1,
100102
"user_type": null,
101-
"deactivated": 0
103+
"deactivated": 0,
104+
"displayname": <User Two>,
105+
"avatar_url": "<avatar_url>"
102106
}
103107
],
104-
"next_token": "100"
108+
"next_token": "100",
109+
"total": 200
105110
}
106111
107112
To paginate, check for ``next_token`` and if present, call the endpoint again

synapse/rest/admin/users.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,10 @@ async def on_GET(self, request):
9494
guests = parse_boolean(request, "guests", default=True)
9595
deactivated = parse_boolean(request, "deactivated", default=False)
9696

97-
users = await self.store.get_users_paginate(
97+
users, total = await self.store.get_users_paginate(
9898
start, limit, user_id, guests, deactivated
9999
)
100-
ret = {"users": users}
100+
ret = {"users": users, "total": total}
101101
if len(users) >= limit:
102102
ret["next_token"] = str(start + len(users))
103103

@@ -199,7 +199,7 @@ async def on_PUT(self, request, user_id):
199199
user_id, threepid["medium"], threepid["address"], current_time
200200
)
201201

202-
if "avatar_url" in body:
202+
if "avatar_url" in body and type(body["avatar_url"]) == str:
203203
await self.profile_handler.set_avatar_url(
204204
target_user, requester, body["avatar_url"], True
205205
)
@@ -276,7 +276,7 @@ async def on_PUT(self, request, user_id):
276276
user_id, threepid["medium"], threepid["address"], current_time
277277
)
278278

279-
if "avatar_url" in body:
279+
if "avatar_url" in body and type(body["avatar_url"]) == str:
280280
await self.profile_handler.set_avatar_url(
281281
user_id, requester, body["avatar_url"], True
282282
)

synapse/storage/data_stores/main/__init__.py

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,8 @@ def get_users_paginate(
503503
self, start, limit, name=None, guests=True, deactivated=False
504504
):
505505
"""Function to retrieve a paginated list of users from
506-
users list. This will return a json list of users.
506+
users list. This will return a json list of users and the
507+
total number of users matching the filter criteria.
507508
508509
Args:
509510
start (int): start number to begin the query from
@@ -512,35 +513,44 @@ def get_users_paginate(
512513
guests (bool): whether to in include guest users
513514
deactivated (bool): whether to include deactivated users
514515
Returns:
515-
defer.Deferred: resolves to list[dict[str, Any]]
516+
defer.Deferred: resolves to list[dict[str, Any]], int
516517
"""
517-
name_filter = {}
518-
if name:
519-
name_filter["name"] = "%" + name + "%"
520-
521-
attr_filter = {}
522-
if not guests:
523-
attr_filter["is_guest"] = 0
524-
if not deactivated:
525-
attr_filter["deactivated"] = 0
526-
527-
return self.db.simple_select_list_paginate(
528-
desc="get_users_paginate",
529-
table="users",
530-
orderby="name",
531-
start=start,
532-
limit=limit,
533-
filters=name_filter,
534-
keyvalues=attr_filter,
535-
retcols=[
536-
"name",
537-
"password_hash",
538-
"is_guest",
539-
"admin",
540-
"user_type",
541-
"deactivated",
542-
],
543-
)
518+
519+
def get_users_paginate_txn(txn):
520+
filters = []
521+
args = []
522+
523+
if name:
524+
filters.append("name LIKE ?")
525+
args.append("%" + name + "%")
526+
527+
if not guests:
528+
filters.append("is_guest = 0")
529+
530+
if not deactivated:
531+
filters.append("deactivated = 0")
532+
533+
where_clause = "WHERE " + " AND ".join(filters) if len(filters) > 0 else ""
534+
535+
sql = "SELECT COUNT(*) as total_users FROM users %s" % (where_clause)
536+
txn.execute(sql, args)
537+
count = txn.fetchone()[0]
538+
539+
args = [self.hs.config.server_name] + args + [limit, start]
540+
sql = """
541+
SELECT name, user_type, is_guest, admin, deactivated, displayname, avatar_url
542+
FROM users as u
543+
LEFT JOIN profiles AS p ON u.name = '@' || p.user_id || ':' || ?
544+
{}
545+
ORDER BY u.name LIMIT ? OFFSET ?
546+
""".format(
547+
where_clause
548+
)
549+
txn.execute(sql, args)
550+
users = self.db.cursor_to_dict(txn)
551+
return users, count
552+
553+
return self.db.runInteraction("get_users_paginate_txn", get_users_paginate_txn)
544554

545555
def search_users(self, term):
546556
"""Function to search users list for one or more users with

0 commit comments

Comments
 (0)