User API and URLs

Hi devs,

Simon asked the question about how do we now compute the user profile URL with the new User API. Here’s my proposal:

  1. Create a new xwiki-platform-user-resource module to implement the following classes:
    • UserResourceReference (takes a UserReference as input) and implements ResourceReference (from the xwiki-platform-resource module). Represents a User URI (ie a User profile URI).
    • ResourceReferenceSerializer: takes a UserResourceReference and generate an ExtendedURL. The goal is to generate the URL for a user profile. Ideally this should extend or reuse the serializer for entity types but since there isn’t one for now, it will use FTM the XWikiServletURLFactory for its implementation.
  2. (Future) Add a new optional property for users. We need to define a key name for it. I propose profileURL. If this property is defined then ResourceReferenceSerializer uses it, otherwise it computes an XWiki User Profile URL. This allows users to have external profile URLs.
  3. (Future) Add a new User ResourceReferenceHandler (i.e. introduce a /user/ URL type to point to a user profile instead of using the Entity Reference Handler).

WDYT?

Thanks

+1

I don’t understand this part: EntityReferenceHandler takes an EntityResourceReference if I’m right, which needs an EntityReference. But a UserResourceReference would take a UserReference as input which is not an EntityReference.
So I think you’d need a custom handler right away no?

ResourceReferenceSerializer#serialize is a bit too limited, we need to be able to generate both local and external user URLs.

You don’t need a ResourceReferenceHandler if you don’t introduce a new URL type (i.e. if you continue to use the “bin” and “wiki” URL type for users). Right now for your user case which is “how do get a User profile URL”, all you’ll need to do is:

@Inject
private ResourceReferenceSerializer<UserResourceReference, ExtendedURL> serializer

....
serializer.serialize(new UserResourceReference(myUserReference));

+1 for custom URL. It’s just an implementation detail that the users are stored in XWiki pages right now. That would be subject to change and should be abstracted by the /user/ URL.

Side note: would also like to see the user ID/reference not exposing document reference implementation details, e.g. user ID “JohnDoe” would internally be resolved to a document reference “XWiki.JohnDoe” and “xwiki:JackDoe” would resolve internally to the document reference “xwiki:XWiki.JackDoe”. The document reference would/should only be relevant to the document-based user storage implemnetation and should not be part of / exposed in the (serialized) UserReference.

This is what I mentioned in point 2 above. The only issue is that ResourceReferenceSerializer<UserResourceReference, ExtendedURL> will generate a relative URL. To make it work for both cases we would need a ResourceReferenceSerializer<UserResourceReference, URL> implementation.

Unless you mean something else?

Should be possible by using URLURLNormalizer (if we finish to implement it).

Definitely. I haven’t defined the URL proposal for item 3 above but it could be something like:

<URL domain part>/xwiki/user/[wiki/]<username>

Examples:

  • https://localhost:8080/xwiki/user/Admin
  • https://localhost:8080/xwiki/user/subwiki/Admin

You need a ResourceReferenceSerializer<UserResourceReference, URL> because the optional URL set in the user profile configuration would be a full URL to a different domain than the xwiki instance domain.

We can also define an abstraction of a URL so that we can represent either a relative URL or a full URL and resolve to that. Something like: FullExtendedURL which would be made of an ExtendedURL and a scheme + authority parts (see https://docs.oracle.com/javase/7/docs/api/java/net/URI.html) and then ResourceReferenceSerializer<UserResourceReference, FullExtendedURL>.

Note: we can already construct an ExtendedURL from a URL: public ExtendedURL(URL url, String ignorePrefix). All we need is to store the authority part (so that a serializer to URL can use it).