Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement MSC4133 to support custom profile fields. #17488

Open
wants to merge 39 commits into
base: develop
Choose a base branch
from

Conversation

clokep
Copy link
Contributor

@clokep clokep commented Jul 25, 2024

Implementation of MSC4133 to support custom profile fields. It is behind an experimental flag and includes tests.

Pull Request Checklist

  • Pull request is based on the develop branch
  • Pull request includes a changelog file. The entry should:
    • Be a short description of your change which makes sense to users. "Fixed a bug that prevented receiving messages from other servers." instead of "Moved X method from EventStore to EventWorkerStore.".
    • Use markdown where necessary, mostly for code blocks.
    • End with either a period (.) or an exclamation mark (!).
    • Start with a capital letter.
    • Feel free to credit yourself, by adding a sentence "Contributed by @github_username." or "Contributed by [Your Name]." to the end of the entry.
  • Code style is correct
    (run the linters)

@clokep clokep marked this pull request as ready for review July 26, 2024 00:00
@clokep clokep requested a review from a team as a code owner July 26, 2024 00:00
Copy link
Member

@anoadragon453 anoadragon453 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few comments, but this is definitely on the right track. Thanks for implementing this!

synapse/handlers/profile.py Outdated Show resolved Hide resolved
synapse/handlers/profile.py Outdated Show resolved Hide resolved
synapse/handlers/profile.py Outdated Show resolved Hide resolved
synapse/handlers/profile.py Outdated Show resolved Hide resolved
synapse/handlers/sso.py Outdated Show resolved Hide resolved
synapse/rest/client/profile.py Show resolved Hide resolved
synapse/storage/databases/main/profile.py Outdated Show resolved Hide resolved
synapse/storage/databases/main/profile.py Outdated Show resolved Hide resolved
tests/rest/client/test_profile.py Outdated Show resolved Hide resolved
clokep and others added 4 commits July 31, 2024 07:25
Co-authored-by: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com>
Co-authored-by: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com>
Co-authored-by: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com>
@clokep
Copy link
Contributor Author

clokep commented Aug 9, 2024

I pushed some changes to update / flesh out the rest of the MSC, but I haven't yet gone through @anoadragon453's comments so not worth another review yet. (If folks want to test it that would be reasonable...I'm sure it'll break.)

@clokep clokep changed the title Partially implement MSC4133 to support custom profile fields. Implement MSC4133 to support custom profile fields. Sep 9, 2024
@clokep
Copy link
Contributor Author

clokep commented Nov 7, 2024

I think this is close to ready for another review. There's a few open questions on the MSC that will affect this still.

anoadragon453 pushed a commit that referenced this pull request Dec 19, 2024
This is essentially matrix-org/synapse#14392. I didn't see anything in
there about updating sytest or complement.

The main driver of this is so that I can use `jsonb_path_exists` in
#17488. 😄
@wcjord

This comment was marked as off-topic.

@clokep
Copy link
Contributor Author

clokep commented Dec 31, 2024

We're very excited to have this feature! What are the next steps?

anoadragon453 pushed a commit that referenced this pull request Jan 3, 2025
Refactor `get_profile` to avoid returning "empty" (`None` / `null`)
fields. Currently this is not very important, but will be more useful
once #17488 lands. It does update the servlet to use this now which has
a minor change in behavior: additional fields served over federation
will now be properly sent back to clients.

It also adds constants for `avatar_url` / `displayname` although I did
not attempt to use it everywhere possible.
@clokep clokep requested a review from anoadragon453 January 3, 2025 19:13
@clokep
Copy link
Contributor Author

clokep commented Jan 3, 2025

@anoadragon453 This should be ready for another review. The commits definitely became very messy so unfortunately probably needs to be reviewed as a single change.

Copy link
Member

@anoadragon453 anoadragon453 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great, thank you! ✨

Just a few minor points below, but nothing fundamental.

Comment on lines +95 to +98
if self.config.experimental.msc4133_enabled:
response["capabilities"]["uk.tcpip.msc4133.profile_fields"] = {
"enabled": True,
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MSC4133 states that when this field is missing, clients can assume that they are able to upload and modify custom profile fields. However, that won't work as the experimental feature is disabled.

Shouldn't we thus always be advertising this capability as false, to discourage clients on recent Synapse versions with the experimental feature disabled from trying to set custom profile fields? So:

Suggested change
if self.config.experimental.msc4133_enabled:
response["capabilities"]["uk.tcpip.msc4133.profile_fields"] = {
"enabled": True,
}
response["capabilities"]["uk.tcpip.msc4133.profile_fields"] = {
"enabled": self.config.experimental.msc4133_enabled,
}

retcol="fields",
desc="get_profile_fields",
)
# The SQLite driver doesn't automatically convert JSON to
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# The SQLite driver doesn't automatically convert JSON to
# The SQLite driver doesn't automatically convert JSON to
# Python objects

Comment on lines +261 to +264
if not UserID.is_valid(user_id):
raise SynapseError(
HTTPStatus.BAD_REQUEST, "Invalid user id", Codes.INVALID_PARAM
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you choose to explicitly perform this check in the GET implementation, but not in the PUT or DELETE ones?

Comment on lines +350 to +351
# Discount the opening and closing braces to avoid double counting,
# but add one for a comma.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to make it explicit what value this comment is referring to.

Suggested change
# Discount the opening and closing braces to avoid double counting,
# but add one for a comma.
# Discount the opening and closing braces to avoid double counting,
# but add one for a comma.
# -2 + 1 = -1


async def delete_profile_field(self, user_id: UserID, field_name: str) -> None:
"""
Set a custom profile field for a user.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Set a custom profile field for a user.
Remove a custom profile field for a user.

raise SynapseError(400, "User is not hosted on this homeserver")

if not by_admin and target_user != requester.user:
raise AuthError(400, "Cannot set another user's profile")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this should be a 403 according to the MSC.

Suggested change
raise AuthError(400, "Cannot set another user's profile")
raise AuthError(403, "Cannot set another user's profile")

Comment on lines +500 to +503
"""Set a new avatar URL for a user.

Args:
target_user: the user whose avatar URL is to be changed.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"""Set a new avatar URL for a user.
Args:
target_user: the user whose avatar URL is to be changed.
"""Delete a field from a user's profile.
Args:
target_user: the user whose profile is to be changed.

Args:
target_user: the user whose avatar URL is to be changed.
requester: The user attempting to make this change.
field_name: The name of the profile field to update.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
field_name: The name of the profile field to update.
field_name: The name of the profile field to remove.

@@ -962,7 +962,7 @@ def register(self, http_server: HttpServer) -> None:
"""Register this servlet with the given HTTP server."""
patterns = getattr(self, "PATTERNS", None)
if patterns:
for method in ("GET", "PUT", "POST", "DELETE"):
for method in ("GET", "PUT", "POST", "DELETE", "PATCH"):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this needed?

content={"diff_key": "test"},
access_token=self.owner_tok,
)
self.assertEqual(channel.code, 400, channel.result)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you also check for the appropriate errcodes in this test?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants