-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Administration functionalities #1784
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ | |
|
||
from synapse.api.errors import AuthError, SynapseError | ||
from synapse.types import UserID | ||
from synapse.http.servlet import parse_json_object_from_request | ||
|
||
from .base import ClientV1RestServlet, client_path_patterns | ||
|
||
|
@@ -25,6 +26,34 @@ | |
logger = logging.getLogger(__name__) | ||
|
||
|
||
class UsersRestServlet(ClientV1RestServlet): | ||
PATTERNS = client_path_patterns("/admin/users/(?P<user_id>[^/]*)") | ||
|
||
def __init__(self, hs): | ||
super(UsersRestServlet, self).__init__(hs) | ||
self.handlers = hs.get_handlers() | ||
|
||
@defer.inlineCallbacks | ||
def on_GET(self, request, user_id): | ||
target_user = UserID.from_string(user_id) | ||
requester = yield self.auth.get_user_by_req(request) | ||
is_admin = yield self.auth.is_server_admin(requester.user) | ||
|
||
if not is_admin: | ||
raise AuthError(403, "You are not a server admin") | ||
|
||
# To allow all users to get the users list | ||
# if not is_admin and target_user != auth_user: | ||
# raise AuthError(403, "You are not a server admin") | ||
|
||
if not self.hs.is_mine(target_user): | ||
raise SynapseError(400, "Can only users a local user") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this error makes no sense There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you are right. |
||
|
||
ret = yield self.handlers.admin_handler.get_users() | ||
|
||
defer.returnValue((200, ret)) | ||
|
||
|
||
class WhoisRestServlet(ClientV1RestServlet): | ||
PATTERNS = client_path_patterns("/admin/whois/(?P<user_id>[^/]*)") | ||
|
||
|
@@ -128,8 +157,199 @@ def on_POST(self, request, target_user_id): | |
defer.returnValue((200, {})) | ||
|
||
|
||
class ResetPasswordRestServlet(ClientV1RestServlet): | ||
"""Post request to allow an administrator reset password for a user. | ||
This need a user have a administrator access in Synapse. | ||
Example: | ||
http://localhost:8008/_matrix/client/api/v1/admin/reset_password/ | ||
@user:to_reset_password?access_token=admin_access_token | ||
JsonBodyToSend: | ||
{ | ||
"new_password": "secret" | ||
} | ||
Returns: | ||
200 OK with empty object if success otherwise an error. | ||
""" | ||
PATTERNS = client_path_patterns("/admin/reset_password/(?P<target_user_id>[^/]*)") | ||
|
||
def __init__(self, hs): | ||
self.store = hs.get_datastore() | ||
super(ResetPasswordRestServlet, self).__init__(hs) | ||
self.hs = hs | ||
self.auth = hs.get_auth() | ||
self.auth_handler = hs.get_auth_handler() | ||
|
||
@defer.inlineCallbacks | ||
def on_POST(self, request, target_user_id): | ||
"""Post request to allow an administrator reset password for a user. | ||
This need a user have a administrator access in Synapse. | ||
""" | ||
UserID.from_string(target_user_id) | ||
requester = yield self.auth.get_user_by_req(request) | ||
is_admin = yield self.auth.is_server_admin(requester.user) | ||
|
||
if not is_admin: | ||
raise AuthError(403, "You are not a server admin") | ||
|
||
params = parse_json_object_from_request(request) | ||
new_password = params['new_password'] | ||
if not new_password: | ||
raise SynapseError(400, "Missing 'new_password' arg") | ||
|
||
logger.info("new_password: %r", new_password) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we really shouldn't log passwords at info. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should be removed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes it should... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this finally got fixed by #4965 |
||
|
||
yield self.auth_handler.set_password( | ||
target_user_id, new_password, requester | ||
) | ||
defer.returnValue((200, {})) | ||
|
||
|
||
class GetUsersPaginatedRestServlet(ClientV1RestServlet): | ||
"""Get request to get specific number of users from Synapse. | ||
This need a user have a administrator access in Synapse. | ||
Example: | ||
http://localhost:8008/_matrix/client/api/v1/admin/users_paginate/ | ||
@admin:user?access_token=admin_access_token&start=0&limit=10 | ||
Returns: | ||
200 OK with json object {list[dict[str, Any]], count} or empty object. | ||
""" | ||
PATTERNS = client_path_patterns("/admin/users_paginate/(?P<target_user_id>[^/]*)") | ||
|
||
def __init__(self, hs): | ||
self.store = hs.get_datastore() | ||
super(GetUsersPaginatedRestServlet, self).__init__(hs) | ||
self.hs = hs | ||
self.auth = hs.get_auth() | ||
self.handlers = hs.get_handlers() | ||
|
||
@defer.inlineCallbacks | ||
def on_GET(self, request, target_user_id): | ||
"""Get request to get specific number of users from Synapse. | ||
This need a user have a administrator access in Synapse. | ||
""" | ||
target_user = UserID.from_string(target_user_id) | ||
requester = yield self.auth.get_user_by_req(request) | ||
is_admin = yield self.auth.is_server_admin(requester.user) | ||
|
||
if not is_admin: | ||
raise AuthError(403, "You are not a server admin") | ||
|
||
# To allow all users to get the users list | ||
# if not is_admin and target_user != auth_user: | ||
# raise AuthError(403, "You are not a server admin") | ||
|
||
if not self.hs.is_mine(target_user): | ||
raise SynapseError(400, "Can only users a local user") | ||
|
||
order = "name" # order by name in user table | ||
start = request.args.get("start")[0] | ||
limit = request.args.get("limit")[0] | ||
if not limit: | ||
raise SynapseError(400, "Missing 'limit' arg") | ||
if not start: | ||
raise SynapseError(400, "Missing 'start' arg") | ||
logger.info("limit: %s, start: %s", limit, start) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should probably be debug level logging. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should probably be debug level logging. |
||
|
||
ret = yield self.handlers.admin_handler.get_users_paginate( | ||
order, start, limit | ||
) | ||
defer.returnValue((200, ret)) | ||
|
||
@defer.inlineCallbacks | ||
def on_POST(self, request, target_user_id): | ||
"""Post request to get specific number of users from Synapse.. | ||
This need a user have a administrator access in Synapse. | ||
Example: | ||
http://localhost:8008/_matrix/client/api/v1/admin/users_paginate/ | ||
@admin:user?access_token=admin_access_token | ||
JsonBodyToSend: | ||
{ | ||
"start": "0", | ||
"limit": "10 | ||
} | ||
Returns: | ||
200 OK with json object {list[dict[str, Any]], count} or empty object. | ||
""" | ||
UserID.from_string(target_user_id) | ||
requester = yield self.auth.get_user_by_req(request) | ||
is_admin = yield self.auth.is_server_admin(requester.user) | ||
|
||
if not is_admin: | ||
raise AuthError(403, "You are not a server admin") | ||
|
||
order = "name" # order by name in user table | ||
params = parse_json_object_from_request(request) | ||
limit = params['limit'] | ||
start = params['start'] | ||
if not limit: | ||
raise SynapseError(400, "Missing 'limit' arg") | ||
if not start: | ||
raise SynapseError(400, "Missing 'start' arg") | ||
logger.info("limit: %s, start: %s", limit, start) | ||
|
||
ret = yield self.handlers.admin_handler.get_users_paginate( | ||
order, start, limit | ||
) | ||
defer.returnValue((200, ret)) | ||
|
||
|
||
class SearchUsersRestServlet(ClientV1RestServlet): | ||
"""Get request to search user table for specific users according to | ||
search term. | ||
This need a user have a administrator access in Synapse. | ||
Example: | ||
http://localhost:8008/_matrix/client/api/v1/admin/search_users/ | ||
@admin:user?access_token=admin_access_token&term=alice | ||
Returns: | ||
200 OK with json object {list[dict[str, Any]], count} or empty object. | ||
""" | ||
PATTERNS = client_path_patterns("/admin/search_users/(?P<target_user_id>[^/]*)") | ||
|
||
def __init__(self, hs): | ||
self.store = hs.get_datastore() | ||
super(SearchUsersRestServlet, self).__init__(hs) | ||
self.hs = hs | ||
self.auth = hs.get_auth() | ||
self.handlers = hs.get_handlers() | ||
|
||
@defer.inlineCallbacks | ||
def on_GET(self, request, target_user_id): | ||
"""Get request to search user table for specific users according to | ||
search term. | ||
This need a user have a administrator access in Synapse. | ||
""" | ||
target_user = UserID.from_string(target_user_id) | ||
requester = yield self.auth.get_user_by_req(request) | ||
is_admin = yield self.auth.is_server_admin(requester.user) | ||
|
||
if not is_admin: | ||
raise AuthError(403, "You are not a server admin") | ||
|
||
# To allow all users to get the users list | ||
# if not is_admin and target_user != auth_user: | ||
# raise AuthError(403, "You are not a server admin") | ||
|
||
if not self.hs.is_mine(target_user): | ||
raise SynapseError(400, "Can only users a local user") | ||
|
||
term = request.args.get("term")[0] | ||
if not term: | ||
raise SynapseError(400, "Missing 'term' arg") | ||
|
||
logger.info("term: %s ", term) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should probably be debug level logging. |
||
|
||
ret = yield self.handlers.admin_handler.search_users( | ||
term | ||
) | ||
defer.returnValue((200, ret)) | ||
|
||
|
||
def register_servlets(hs, http_server): | ||
WhoisRestServlet(hs).register(http_server) | ||
PurgeMediaCacheRestServlet(hs).register(http_server) | ||
DeactivateAccountRestServlet(hs).register(http_server) | ||
PurgeHistoryRestServlet(hs).register(http_server) | ||
UsersRestServlet(hs).register(http_server) | ||
ResetPasswordRestServlet(hs).register(http_server) | ||
GetUsersPaginatedRestServlet(hs).register(http_server) | ||
SearchUsersRestServlet(hs).register(http_server) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is my understanding correct? this takes a user_id, and then ignores it? @morteza-araby
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you are right, I must have missed that. The UsersRest Api, has not been used at my client side implementation and I think that's why I've missed all of your comments here. Probably should have wrote some test cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is now tracked as #2522