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

Commit 8327eb9

Browse files
authored
Add options to prevent users from changing their profile. (#7096)
1 parent ae219fb commit 8327eb9

File tree

7 files changed

+449
-1
lines changed

7 files changed

+449
-1
lines changed

changelog.d/7096.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add options to prevent users from changing their profile or associated 3PIDs.

docs/sample_config.yaml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,6 +1086,29 @@ account_threepid_delegates:
10861086
#email: https://example.com # Delegate email sending to example.com
10871087
#msisdn: http://localhost:8090 # Delegate SMS sending to this local process
10881088

1089+
# Whether users are allowed to change their displayname after it has
1090+
# been initially set. Useful when provisioning users based on the
1091+
# contents of a third-party directory.
1092+
#
1093+
# Does not apply to server administrators. Defaults to 'true'
1094+
#
1095+
#enable_set_displayname: false
1096+
1097+
# Whether users are allowed to change their avatar after it has been
1098+
# initially set. Useful when provisioning users based on the contents
1099+
# of a third-party directory.
1100+
#
1101+
# Does not apply to server administrators. Defaults to 'true'
1102+
#
1103+
#enable_set_avatar_url: false
1104+
1105+
# Whether users can change the 3PIDs associated with their accounts
1106+
# (email address and msisdn).
1107+
#
1108+
# Defaults to 'true'
1109+
#
1110+
#enable_3pid_changes: false
1111+
10891112
# Users who register on this homeserver will automatically be joined
10901113
# to these rooms
10911114
#

synapse/config/registration.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@ def read_config(self, config, **kwargs):
129129
raise ConfigError("Invalid auto_join_rooms entry %s" % (room_alias,))
130130
self.autocreate_auto_join_rooms = config.get("autocreate_auto_join_rooms", True)
131131

132+
self.enable_set_displayname = config.get("enable_set_displayname", True)
133+
self.enable_set_avatar_url = config.get("enable_set_avatar_url", True)
134+
self.enable_3pid_changes = config.get("enable_3pid_changes", True)
135+
132136
self.disable_msisdn_registration = config.get(
133137
"disable_msisdn_registration", False
134138
)
@@ -330,6 +334,29 @@ def generate_config_section(self, generate_secrets=False, **kwargs):
330334
#email: https://example.com # Delegate email sending to example.com
331335
#msisdn: http://localhost:8090 # Delegate SMS sending to this local process
332336
337+
# Whether users are allowed to change their displayname after it has
338+
# been initially set. Useful when provisioning users based on the
339+
# contents of a third-party directory.
340+
#
341+
# Does not apply to server administrators. Defaults to 'true'
342+
#
343+
#enable_set_displayname: false
344+
345+
# Whether users are allowed to change their avatar after it has been
346+
# initially set. Useful when provisioning users based on the contents
347+
# of a third-party directory.
348+
#
349+
# Does not apply to server administrators. Defaults to 'true'
350+
#
351+
#enable_set_avatar_url: false
352+
353+
# Whether users can change the 3PIDs associated with their accounts
354+
# (email address and msisdn).
355+
#
356+
# Defaults to 'true'
357+
#
358+
#enable_3pid_changes: false
359+
333360
# Users who register on this homeserver will automatically be joined
334361
# to these rooms
335362
#

synapse/handlers/profile.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,15 @@ def set_displayname(self, target_user, requester, new_displayname, by_admin=Fals
157157
if not by_admin and target_user != requester.user:
158158
raise AuthError(400, "Cannot set another user's displayname")
159159

160+
if not by_admin and not self.hs.config.enable_set_displayname:
161+
profile = yield self.store.get_profileinfo(target_user.localpart)
162+
if profile.display_name:
163+
raise SynapseError(
164+
400,
165+
"Changing display name is disabled on this server",
166+
Codes.FORBIDDEN,
167+
)
168+
160169
if len(new_displayname) > MAX_DISPLAYNAME_LEN:
161170
raise SynapseError(
162171
400, "Displayname is too long (max %i)" % (MAX_DISPLAYNAME_LEN,)
@@ -218,6 +227,13 @@ def set_avatar_url(self, target_user, requester, new_avatar_url, by_admin=False)
218227
if not by_admin and target_user != requester.user:
219228
raise AuthError(400, "Cannot set another user's avatar_url")
220229

230+
if not by_admin and not self.hs.config.enable_set_avatar_url:
231+
profile = yield self.store.get_profileinfo(target_user.localpart)
232+
if profile.avatar_url:
233+
raise SynapseError(
234+
400, "Changing avatar is disabled on this server", Codes.FORBIDDEN
235+
)
236+
221237
if len(new_avatar_url) > MAX_AVATAR_URL_LEN:
222238
raise SynapseError(
223239
400, "Avatar URL is too long (max %i)" % (MAX_AVATAR_URL_LEN,)

synapse/rest/client/v2_alpha/account.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,11 @@ async def on_GET(self, request):
605605
return 200, {"threepids": threepids}
606606

607607
async def on_POST(self, request):
608+
if not self.hs.config.enable_3pid_changes:
609+
raise SynapseError(
610+
400, "3PID changes are disabled on this server", Codes.FORBIDDEN
611+
)
612+
608613
requester = await self.auth.get_user_by_req(request)
609614
user_id = requester.user.to_string()
610615
body = parse_json_object_from_request(request)
@@ -649,6 +654,11 @@ def __init__(self, hs):
649654

650655
@interactive_auth_handler
651656
async def on_POST(self, request):
657+
if not self.hs.config.enable_3pid_changes:
658+
raise SynapseError(
659+
400, "3PID changes are disabled on this server", Codes.FORBIDDEN
660+
)
661+
652662
requester = await self.auth.get_user_by_req(request)
653663
user_id = requester.user.to_string()
654664
body = parse_json_object_from_request(request)
@@ -744,10 +754,16 @@ class ThreepidDeleteRestServlet(RestServlet):
744754

745755
def __init__(self, hs):
746756
super(ThreepidDeleteRestServlet, self).__init__()
757+
self.hs = hs
747758
self.auth = hs.get_auth()
748759
self.auth_handler = hs.get_auth_handler()
749760

750761
async def on_POST(self, request):
762+
if not self.hs.config.enable_3pid_changes:
763+
raise SynapseError(
764+
400, "3PID changes are disabled on this server", Codes.FORBIDDEN
765+
)
766+
751767
body = parse_json_object_from_request(request)
752768
assert_params_in_dict(body, ["medium", "address"])
753769

tests/handlers/test_profile.py

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
from twisted.internet import defer
2020

2121
import synapse.types
22-
from synapse.api.errors import AuthError
22+
from synapse.api.errors import AuthError, SynapseError
2323
from synapse.handlers.profile import MasterProfileHandler
2424
from synapse.types import UserID
2525

@@ -70,6 +70,7 @@ def register_query_handler(query_type, handler):
7070
yield self.store.create_profile(self.frank.localpart)
7171

7272
self.handler = hs.get_profile_handler()
73+
self.hs = hs
7374

7475
@defer.inlineCallbacks
7576
def test_get_my_name(self):
@@ -90,6 +91,33 @@ def test_set_my_name(self):
9091
"Frank Jr.",
9192
)
9293

94+
# Set displayname again
95+
yield self.handler.set_displayname(
96+
self.frank, synapse.types.create_requester(self.frank), "Frank"
97+
)
98+
99+
self.assertEquals(
100+
(yield self.store.get_profile_displayname(self.frank.localpart)), "Frank",
101+
)
102+
103+
@defer.inlineCallbacks
104+
def test_set_my_name_if_disabled(self):
105+
self.hs.config.enable_set_displayname = False
106+
107+
# Setting displayname for the first time is allowed
108+
yield self.store.set_profile_displayname(self.frank.localpart, "Frank")
109+
110+
self.assertEquals(
111+
(yield self.store.get_profile_displayname(self.frank.localpart)), "Frank",
112+
)
113+
114+
# Setting displayname a second time is forbidden
115+
d = self.handler.set_displayname(
116+
self.frank, synapse.types.create_requester(self.frank), "Frank Jr."
117+
)
118+
119+
yield self.assertFailure(d, SynapseError)
120+
93121
@defer.inlineCallbacks
94122
def test_set_my_name_noauth(self):
95123
d = self.handler.set_displayname(
@@ -147,3 +175,38 @@ def test_set_my_avatar(self):
147175
(yield self.store.get_profile_avatar_url(self.frank.localpart)),
148176
"http://my.server/pic.gif",
149177
)
178+
179+
# Set avatar again
180+
yield self.handler.set_avatar_url(
181+
self.frank,
182+
synapse.types.create_requester(self.frank),
183+
"http://my.server/me.png",
184+
)
185+
186+
self.assertEquals(
187+
(yield self.store.get_profile_avatar_url(self.frank.localpart)),
188+
"http://my.server/me.png",
189+
)
190+
191+
@defer.inlineCallbacks
192+
def test_set_my_avatar_if_disabled(self):
193+
self.hs.config.enable_set_avatar_url = False
194+
195+
# Setting displayname for the first time is allowed
196+
yield self.store.set_profile_avatar_url(
197+
self.frank.localpart, "http://my.server/me.png"
198+
)
199+
200+
self.assertEquals(
201+
(yield self.store.get_profile_avatar_url(self.frank.localpart)),
202+
"http://my.server/me.png",
203+
)
204+
205+
# Set avatar a second time is forbidden
206+
d = self.handler.set_avatar_url(
207+
self.frank,
208+
synapse.types.create_requester(self.frank),
209+
"http://my.server/pic.gif",
210+
)
211+
212+
yield self.assertFailure(d, SynapseError)

0 commit comments

Comments
 (0)