mirror of
https://github.com/element-hq/synapse.git
synced 2024-12-14 11:57:44 +00:00
Add an option to the set password API to choose whether to logout other devices. (#7085)
This commit is contained in:
parent
6d110ddea4
commit
88b41986db
5 changed files with 38 additions and 19 deletions
1
changelog.d/7085.feature
Normal file
1
changelog.d/7085.feature
Normal file
|
@ -0,0 +1 @@
|
|||
Add an optional parameter to control whether other sessions are logged out when a user's password is modified.
|
|
@ -38,6 +38,7 @@ The parameter ``threepids`` is optional.
|
|||
The parameter ``avatar_url`` is optional.
|
||||
The parameter ``admin`` is optional and defaults to 'false'.
|
||||
The parameter ``deactivated`` is optional and defaults to 'false'.
|
||||
The parameter ``password`` is optional. If provided the user's password is updated and all devices are logged out.
|
||||
If the user already exists then optional parameters default to the current value.
|
||||
|
||||
List Accounts
|
||||
|
@ -168,11 +169,14 @@ with a body of:
|
|||
.. code:: json
|
||||
|
||||
{
|
||||
"new_password": "<secret>"
|
||||
"new_password": "<secret>",
|
||||
"logout_devices": true,
|
||||
}
|
||||
|
||||
including an ``access_token`` of a server admin.
|
||||
|
||||
The parameter ``new_password`` is required.
|
||||
The parameter ``logout_devices`` is optional and defaults to ``true``.
|
||||
|
||||
Get whether a user is a server administrator or not
|
||||
===================================================
|
||||
|
|
|
@ -13,10 +13,12 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from twisted.internet import defer
|
||||
|
||||
from synapse.api.errors import Codes, StoreError, SynapseError
|
||||
from synapse.types import Requester
|
||||
|
||||
from ._base import BaseHandler
|
||||
|
||||
|
@ -32,14 +34,17 @@ class SetPasswordHandler(BaseHandler):
|
|||
self._device_handler = hs.get_device_handler()
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def set_password(self, user_id, newpassword, requester=None):
|
||||
def set_password(
|
||||
self,
|
||||
user_id: str,
|
||||
new_password: str,
|
||||
logout_devices: bool,
|
||||
requester: Optional[Requester] = None,
|
||||
):
|
||||
if not self.hs.config.password_localdb_enabled:
|
||||
raise SynapseError(403, "Password change disabled", errcode=Codes.FORBIDDEN)
|
||||
|
||||
password_hash = yield self._auth_handler.hash(newpassword)
|
||||
|
||||
except_device_id = requester.device_id if requester else None
|
||||
except_access_token_id = requester.access_token_id if requester else None
|
||||
password_hash = yield self._auth_handler.hash(new_password)
|
||||
|
||||
try:
|
||||
yield self.store.user_set_password_hash(user_id, password_hash)
|
||||
|
@ -48,14 +53,18 @@ class SetPasswordHandler(BaseHandler):
|
|||
raise SynapseError(404, "Unknown user", Codes.NOT_FOUND)
|
||||
raise e
|
||||
|
||||
# we want to log out all of the user's other sessions. First delete
|
||||
# all his other devices.
|
||||
yield self._device_handler.delete_all_devices_for_user(
|
||||
user_id, except_device_id=except_device_id
|
||||
)
|
||||
# Optionally, log out all of the user's other sessions.
|
||||
if logout_devices:
|
||||
except_device_id = requester.device_id if requester else None
|
||||
except_access_token_id = requester.access_token_id if requester else None
|
||||
|
||||
# and now delete any access tokens which weren't associated with
|
||||
# devices (or were associated with this device).
|
||||
yield self._auth_handler.delete_access_tokens_for_user(
|
||||
user_id, except_token_id=except_access_token_id
|
||||
)
|
||||
# First delete all of their other devices.
|
||||
yield self._device_handler.delete_all_devices_for_user(
|
||||
user_id, except_device_id=except_device_id
|
||||
)
|
||||
|
||||
# and now delete any access tokens which weren't associated with
|
||||
# devices (or were associated with this device).
|
||||
yield self._auth_handler.delete_access_tokens_for_user(
|
||||
user_id, except_token_id=except_access_token_id
|
||||
)
|
||||
|
|
|
@ -221,8 +221,9 @@ class UserRestServletV2(RestServlet):
|
|||
raise SynapseError(400, "Invalid password")
|
||||
else:
|
||||
new_password = body["password"]
|
||||
logout_devices = True
|
||||
await self.set_password_handler.set_password(
|
||||
target_user.to_string(), new_password, requester
|
||||
target_user.to_string(), new_password, logout_devices, requester
|
||||
)
|
||||
|
||||
if "deactivated" in body:
|
||||
|
@ -536,9 +537,10 @@ class ResetPasswordRestServlet(RestServlet):
|
|||
params = parse_json_object_from_request(request)
|
||||
assert_params_in_dict(params, ["new_password"])
|
||||
new_password = params["new_password"]
|
||||
logout_devices = params.get("logout_devices", True)
|
||||
|
||||
await self._set_password_handler.set_password(
|
||||
target_user_id, new_password, requester
|
||||
target_user_id, new_password, logout_devices, requester
|
||||
)
|
||||
return 200, {}
|
||||
|
||||
|
|
|
@ -265,8 +265,11 @@ class PasswordRestServlet(RestServlet):
|
|||
|
||||
assert_params_in_dict(params, ["new_password"])
|
||||
new_password = params["new_password"]
|
||||
logout_devices = params.get("logout_devices", True)
|
||||
|
||||
await self._set_password_handler.set_password(user_id, new_password, requester)
|
||||
await self._set_password_handler.set_password(
|
||||
user_id, new_password, logout_devices, requester
|
||||
)
|
||||
|
||||
return 200, {}
|
||||
|
||||
|
|
Loading…
Reference in a new issue