diff --git a/synapse/handlers/deactivate_account.py b/synapse/handlers/deactivate_account.py
index 7f9435179a..bd7b1f30e0 100644
--- a/synapse/handlers/deactivate_account.py
+++ b/synapse/handlers/deactivate_account.py
@@ -96,7 +96,7 @@ class DeactivateAccountHandler(BaseHandler):
yield self.store.user_set_password_hash(user_id, None)
user = UserID.from_string(user_id)
- yield self._profile_handler.set_active(user, False)
+ yield self._profile_handler.set_active(user, False, False)
# Add the user to a table of users pending deactivation (ie.
# removal from all the rooms they're a member of)
diff --git a/synapse/handlers/profile.py b/synapse/handlers/profile.py
index 65e29518f0..0a952dab97 100644
--- a/synapse/handlers/profile.py
+++ b/synapse/handlers/profile.py
@@ -270,10 +270,13 @@ class BaseProfileHandler(BaseHandler):
run_in_background(self._replicate_profiles)
@defer.inlineCallbacks
- def set_active(self, target_user, active):
+ def set_active(self, target_user, active, hide):
"""
Sets the 'active' flag on a user profile. If set to false, the user account is
- considered deactivated.
+ considered deactivated or hidden.
+ If 'hide' is true, then we interpret active=False as a request to try to hide the
+ user rather than deactivating it. This means withholding the profile from replication
+ (and mark it as inactive) rather than clearing the profile from the HS DB.
Note that unlike set_displayname and set_avatar_url, this does *not* perform
authorization checks! This is because the only place it's used currently is
in account deactivation where we've already done these checks anyway.
@@ -284,7 +287,7 @@ class BaseProfileHandler(BaseHandler):
else:
new_batchnum = None
yield self.store.set_profile_active(
- target_user.localpart, active, new_batchnum
+ target_user.localpart, active, hide, new_batchnum
)
# start a profile replication push
diff --git a/synapse/rest/client/v2_alpha/account_data.py b/synapse/rest/client/v2_alpha/account_data.py
index 371e9aa354..21c734e525 100644
--- a/synapse/rest/client/v2_alpha/account_data.py
+++ b/synapse/rest/client/v2_alpha/account_data.py
@@ -19,6 +19,7 @@ from twisted.internet import defer
from synapse.api.errors import AuthError, SynapseError
from synapse.http.servlet import RestServlet, parse_json_object_from_request
+from synapse.types import UserID
from ._base import client_v2_patterns
@@ -38,6 +39,7 @@ class AccountDataServlet(RestServlet):
self.auth = hs.get_auth()
self.store = hs.get_datastore()
self.notifier = hs.get_notifier()
+ self._profile_handler = hs.get_profile_handler()
@defer.inlineCallbacks
def on_PUT(self, request, user_id, account_data_type):
@@ -47,6 +49,11 @@ class AccountDataServlet(RestServlet):
body = parse_json_object_from_request(request)
+ if account_data_type == "im.vector.hide_profile":
+ user = UserID.from_string(user_id)
+ hide_profile = body.get('hide_profile')
+ yield self._profile_handler.set_active(user, not hide_profile, True)
+
max_id = yield self.store.add_account_data_for_user(
user_id, account_data_type, body
)
diff --git a/synapse/storage/profile.py b/synapse/storage/profile.py
index 10133f0a4a..488e31c8b2 100644
--- a/synapse/storage/profile.py
+++ b/synapse/storage/profile.py
@@ -147,12 +147,14 @@ class ProfileWorkerStore(SQLBaseStore):
lock=False # we can do this because user_id has a unique index
)
- def set_profile_active(self, user_localpart, active, batchnum):
+ def set_profile_active(self, user_localpart, active, hide, batchnum):
values = {
"active": int(active),
"batch": batchnum,
}
- if not active:
+ if not active and not hide:
+ # we are deactivating for real (not in hide mode)
+ # so clear the profile.
values["avatar_url"] = None
values["displayname"] = None
return self._simple_upsert(
|