dzhw / metadatamanagement

Metadatamanagement (MDM) - Data Search for Higher Education Research and Science Studies
https://metadata.fdz.dzhw.eu
GNU Affero General Public License v3.0
25 stars 9 forks source link

Backend: Use DLP as OpenID Connect Provider #2999

Open rreitmann opened 2 years ago

rreitmann commented 2 years ago
rreitmann commented 2 years ago

DLP User API must provide the following methods:

  /** Get a list of all users having the specified role. Used to send email to all users havin a role. */
  List<User> findAllByAuthoritiesContaining(Authority authority);
  /** Get a list of all users where login or email adress starts with the given strings. Used to assign users to projects. */
  List<User> findAllByLoginLikeOrEmailLike(String login, String email);
  /** Get a list of all users for the given logins. Used to send emails to project members */
  List<User> findAllByLoginIn(Set<String> userLoginNames);
  /** Get user details by given login or given email. Used to present details to the user. Might be obsolete. */
  Optional<User> findOneByLoginOrEmail(String login, String email);
  /** Get user by given login. Used to send email when a task of a user completed for example. */
  Optional<User> findOneByLogin(String login);

Additionally we need to be able to save a user field like welcomeDialogDeactivated.

rreitmann commented 2 years ago
/** Get a list of all users having the specified role. Used to send email to all users havin a role. */
  List<User> findAllByAuthoritiesContaining(Authority authority);

becomes:

curl --request GET \
  --url 'http://localhost:8082/jsonapi/user/user?include=roles&filter%5Broles.id%5D=role_publisher' \
  --header 'Authorization: Basic ****
/** Get a list of all users where login or email adress starts with the given strings. Used to assign users to projects. */
  List<User> findAllByLoginLikeOrEmailLike(String login, String email);

becomes:

curl --request GET \
  --url 'http://localhost:8082/jsonapi/user/user?include=roles&filter%5Bor-group%5D%5Bgroup%5D%5Bconjunction%5D=OR&filter%5Bname-00-filter%5D%5Bcondition%5D%5Bpath%5D=name&filter%5Bname-00-filter%5D%5Bcondition%5D%5Boperator%5D=STARTS_WITH&filter%5Bname-00-filter%5D%5Bcondition%5D%5Bvalue%5D=r&filter%5Bname-00-filter%5D%5Bcondition%5D%5BmemberOf%5D=or-group&filter%5Bmail-00-filter%5D%5Bcondition%5D%5Bpath%5D=mail&filter%5Bmail-00-filter%5D%5Bcondition%5D%5Boperator%5D=STARTS_WITH&filter%5Bmail-00-filter%5D%5Bcondition%5D%5Bvalue%5D=r&filter%5Bmail-00-filter%5D%5Bcondition%5D%5BmemberOf%5D=or-group' \
  --header 'Authorization: Basic ****
/** Get a list of all users for the given logins. Used to send emails to project members */
  List<User> findAllByLoginIn(Set<String> userLoginNames);

becomes:

curl --request GET \
  --url 'http://localhost:8082/jsonapi/user/user?filter%5Bname-filter%5D%5Bcondition%5D%5Bpath%5D=name&filter%5Bname-filter%5D%5Bcondition%5D%5Boperator%5D=IN&filter%5Bname-filter%5D%5Bcondition%5D%5Bvalue%5D%5B1%5D=rreitmann&filter%5Bname-filter%5D%5Bcondition%5D%5Bvalue%5D%5B2%5D=adaniel&include=roles' \
  --header 'Authorization: Basic *****
/** Get user details by given login or given email. Used to present details to the user. Might be obsolete. */
  Optional<User> findOneByLoginOrEmail(String login, String email);

becomes:

curl --request GET \
  --url 'http://localhost:8082/jsonapi/user/user?filter%5Bor-group%5D%5Bgroup%5D%5Bconjunction%5D=OR&filter%5Bname-filter%5D%5Bcondition%5D%5Bpath%5D=name&filter%5Bname-filter%5D%5Bcondition%5D%5Boperator%5D=%3D&filter%5Bname-filter%5D%5Bcondition%5D%5Bvalue%5D=rreitmann&filter%5Bname-filter%5D%5Bcondition%5D%5BmemberOf%5D=or-group&filter%5Bmail-filter%5D%5Bcondition%5D%5Bpath%5D=mail&filter%5Bmail-filter%5D%5Bcondition%5D%5Boperator%5D=%3D&filter%5Bmail-filter%5D%5Bcondition%5D%5Bvalue%5D=reitmann%40dzhw.eu&filter%5Bmail-filter%5D%5Bcondition%5D%5BmemberOf%5D=or-group' \
  --header 'Authorization: Basic *****
  /** Get user by given login. Used to send email when a task of a user completed for example. */
  Optional<User> findOneByLogin(String login);

becomes:

curl --request GET \
  --url 'http://localhost:8082/jsonapi/user/user?filter%5Bname-filter%5D%5Bcondition%5D%5Bpath%5D=name&filter%5Bname-filter%5D%5Bcondition%5D%5Boperator%5D=%3D&filter%5Bname-filter%5D%5Bcondition%5D%5Bvalue%5D=rreitmann&include=roles' \
  --header 'Authorization: *****
rreitmann commented 2 years ago

For saving a field like welcome_dialog_deactivated we neeed to allow jsonApi to update users: http://localhost:8082/admin/config/services/jsonapi

Additionally we need to add the field to the account and hide it from displaying: http://localhost:8082/admin/config/people/accounts/fields http://localhost:8082/admin/config/people/accounts/form-display http://localhost:8082/admin/config/people/accounts/display

Then you can update a user with PATCH:

curl --request PATCH \
  --url http://localhost:8082/jsonapi/user/user/12170c0d-853b-4a8c-9780-873b10da4562 \
  --header 'Authorization: Basic *****' \
  --header 'Content-Type: application/vnd.api+json' \
  --data '{
  "data": {
    "type": "user--user",
    "id": "12170c0d-853b-4a8c-9780-873b10da4562",
    "attributes": {
        "field_welcome_dialog_deactivated": false
    }
  }
}'
rreitmann commented 2 years ago

There is a Pull Request for this: https://github.com/dzhw/metadatamanagement/pull/3037

We have setup an additional branch sso-workaround which disables JWT Validation due to an issue in the identity provider image (see below).

The following topics are open:

Documentation can be found here: https://github.com/dzhw/metadatamanagement/wiki/Drupal-Identity-Provider-Overview-and-Setup

There are currently the following issues with the identity provider image (https://hub.docker.com/r/sanduhrs/identity-provider), which have been reported to the DLP maintainers:

  1. issuerUri im Access-Token enthält trailing Forward-Slash (e.g. "http://localhost:8082/"), wodurch Token-Validierung fehlschlägt <- im branch sso-workaround ist die Token-Validierung aus diesem Grund gerade ausgebaut
  2. Access-Token enthält user-id anstatt username/loginname => usernames sollen unveränderlich sein <- als workaround lokal kann man in den SecurityUtils die user-id auf den username mappen:
    
    public static String getCurrentUserLogin() {
     var authentication = SecurityContextHolder.getContext().getAuthentication();

3. welcome_dialog_deactivated wird nicht mit ID-Token ausgeliefert
4. Anonymous Zugriff zu JSONAPI ist möglich (i.e. man kann alle Userdaten lesen wenn man kein Filter benutzt)
5. JSON:API Setting "Allowed Operations" sollte von Anfang an "Accept all JSON:API create, read, update, and delete operations" sein.

Ideally the identity provider image would be fully configured with all roles, languages and oauth2 clients.