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

[port dspace-8_x] Enhanced Login flow for ORCID Authorization feature #293

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion csrf-tokens.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ A `GET` endpoint is also available to force a CSRF token refresh. See below.

### GET /api/security/csrf

Provides a new CSRF Token to the client for usage in later requests. This endpoint SHOULD BE USED SPARINGLY as every call to this endpoint will create a new CSRF token. The DSpace REST API automatically manages CSRF tokens and sends them back to the client _only when the token needs to be changed_ (e.g. on login/logout, etc). Using this endpoint to refresh CSRF tokens frequently may result in unexpected behaviors or even performance issues. The primary purpose of this endpoint is to obtain the *first* CSRF token (if not yet sent by the REST API).
Provides a new CSRF Token to the client for usage in later requests. This endpoint SHOULD BE USED SPARINGLY as every call to this endpoint will create a new CSRF token. The DSpace REST API automatically manages CSRF tokens and sends them back to the client _only when the token needs to be changed_ (e.g. on login/logout, etc). Using this endpoint to refresh CSRF tokens frequently may result in unexpected behaviors or even performance issues on the client side. The primary purpose of this endpoint is to obtain the *first* CSRF token (if not yet sent by the REST API).

This endpoint returns an empty response with the newly generated CSRF Token in the `DSPACE-XSRF-TOKEN` HTTP Header. It will also save this CSRF Token to the `DSPACE-XSRF-COOKIE` server-side Cookie, for later verification. See [How does CSRF protection work in DSpace REST API?](#how-does-csrf-protection-work-in-dspace-rest-api) below for more details about this header and cookie.

Expand Down
1 change: 1 addition & 0 deletions endpoints.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
* [/api/integration/suggestionsources](suggestionsources.md)
* [/api/integration/suggestiontargets](suggestiontargets.md)
* [/api/submission/duplicates](duplicates.md)
* [/api/security/csrf](csrf-tokens.md) (added in DS8)

## Endpoints Under Development/Discussion
* [/api/authz/resourcepolicies](resourcepolicies.md)
Expand Down
150 changes: 147 additions & 3 deletions epersonregistrations.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,168 @@ As we don't have a use case to retrieve an eperson registration based on the ema
## Search EPerson registration
**/api/eperson/registrations/search/findByToken?token=<:token>**

Exposes the registered email address based on the token.
Also exposes whether it's a new user registration, or a password reset for an existing user.
Exposes the registered email address based on the token or the `netId`.
Also exposes whether it's a new user registration, or a password reset for an existing user. It can expose also `metadata` involved during the registration process, with the overridden values. Lastly, the `registrationType` fields is used to discriminate between the registration flow / procedure.

### Examples
1. User registration not linked to an eperson:
```json
{
"id": 1,
"email": "[email protected]",
"user": null,
"type": "registration"
}
```

2. User registration linked to an eperson:
```json
{
"id": 2,
"email": "[email protected]",
"user": "028dcbb8-0da2-4122-a0ea-254be49ca107",
"type": "registration"
}
```
3. User registration done using **orcid** that didn't provide an email:
```json
{
"id": 3,
"email": null,
"user": "028dcbb8-0da2-4122-a0ea-254be49ca107",
"type": "registration",
"registrationType": "orcid",
"netId": "0000-1111-2222-3333",
"registrationMetadata": {
"eperson.orcid": [
{
"value": "0000-1111-2222-3333",
"language": null,
"authority": "",
"confidence": -1,
"place": -1
}
],
"eperson.firstname": [
{
"value": "Power",
"language": null,
"authority": "",
"confidence": -1,
"place": -1,
"overrides": "Power U."
}
],
"eperson.lastname": [
{
"value": "User",
"language": null,
"authority": "",
"confidence": -1,
"place": -1
}
]
}
}
```
> Note that the `registrationMetadata` is filled with metadata coming from the external login provider (i.e. **ORCID**) and enriched with the `overrides` field containg metadata value coming from the linked `user`.
>
> In the previous case the `eperson.firstname` metadata related to the `registration-data` **overrides** the value of the `metadata` previously setted for that related `user` (i.e. `Power U.`).

4. User registration done using **orcid** that provided an email:
```json
{
"id": 4,
"email": "[email protected]",
"user": "028dcbb8-0da2-4122-a0ea-254be49ca107",
"type": "registration",
"registrationType": "orcid",
"netId": "0000-1111-2222-3333",
"registrationMetadata": {
"email": [
{
"value": "[email protected]",
"language": null,
"authority": "",
"confidence": -1,
"place": -1,
"overrides": "[email protected]"
}
],
"eperson.orcid": [
{
"value": "0000-1111-2222-3333",
"language": null,
"authority": "",
"confidence": -1,
"place": -1
}
],
"eperson.firstname": [
{
"value": "Power",
"language": null,
"authority": "",
"confidence": -1,
"place": -1,
"overrides": "Power U."
}
],
"eperson.lastname": [
{
"value": "User",
"language": null,
"authority": "",
"confidence": -1,
"place": -1
}
]
}
}
```
> In the previous case the registration has been confirmed by providing a valid email, or just because the orcid login provided an email-account. This email is treated as an additional metadata, but in fact it's just duplicating the `email` field to provide the `overrides` fields.

## Updated EPerson registration
**PATCH /api/eperson/registrations/<:id>?token=<:token>**

To update the EPerson registration, perform a patch with the JSON below to the eperson registrations endpoint, by providing the registration `token` and the `id` of the registration.

1. Replace the existing email inside the registration:
```json
[
{
"op": "replace",
"path": "/email",
"value": [ "[email protected]" ]
}
]
```
2. Add an email inside the registration:
```json
[
{
"op": "add",
"path": "/email",
"value": [ "[email protected]" ]
}
]
```

The allowed path is the one involving the `email` field, while the operation allowed are:

- `replace` - if a different value was set
- `add` - if none already set

This method, if successful, will renew the `token` and as a side effect it will send a new Email to the provided `email` value.

We can have the following cases:
- `email` related to an account: a validation link for reviewing the information is sent to that email address.
- new `email`: a link to the same authentication method provided is sent to that email address

Status codes:

* 204 Created - if the operation succeed with a new token generated, and e new mail sent to the `email` provided in the request
* 401 Unauthorized - if registration is disabled the token provided is not valid or absent
* 422 Unprocessable Entity - if the email address was omitted or the operation is not valid

## Create new EPerson registration
**POST /api/eperson/registrations?accountRequestType={requestType_forgot_or_register}**
Expand Down
28 changes: 28 additions & 0 deletions epersons.md
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,34 @@ Status codes:
* 401 Unauthorized - if the token doesn't allow you to create this account
* 422 Unprocessable Entity - If the provided password not respects the rules configured in the regular expression

## Merge eperson registration data
**POST /api/eperson/epersons/<:uuid>?token=<:token>&override=<:metadata-fields>**

Allows the merge of some `registrationData` related to the provided *registration-token* (i.e. `<:token>`) into an already actived user account.
This action is permitted by:
- ***logged-user***: that has the same `uuid` as the one specified with the `<:uuid>` param.
- ***anonymous-user***: that provides a `validation-token` (i.e. a token obtained via email confirmation)

The `override` parameter contains the list of *metadata-fields* that will be overwritten for that linked user.

The token was previously sent via Email from the [Create new EPerson registration](epersonregistrations.md#create-new-eperson-registration).

This example shows a simlpe request:

```bash
curl -X POST http://${dspace.url}/api/eperson/epersons/${id-eperson}?token=${token}&override=${metadata-fields} \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${bearer-token}" \
```

As you can see, the request has an ***empty body***.

Status codes:
* 201 Created - if the operation succeed
* 400 Bad Request - if the `uuid` provided doesn't exist, or if some `override` element isn't found inside the linked user item.
* 401 Unauthorized - The user is anonymous, the `uuid` of the user is not the same as the one logged in, or if the `token` is not valid (i.e. expired or wrong type).
* 403 Forbidden - The user is authenticated, the `token` is not valid or the `uuid` is not the same as the one of the user.

## Linked entities
### Groups
**GET /api/eperson/epersons/<:uuid>/groups**
Expand Down
2 changes: 1 addition & 1 deletion items.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Example: <https://demo.dspace.org/server/#/server/api/core/items>
**/api/core/items/<:uuid>**

***
:warning: In the below example response, the existence of the `place` field for specific metadata values is still under analysis. We are determining whether it can be removed entirely in favor of using the array index (as the `place` field represents the index of each value in an ordered array). For more details see https://jira.duraspace.org/browse/DS-4242
:warning: In the below example response, the existence of the `place` field for specific metadata values is still under analysis. We are determining whether it can be removed entirely in favor of using the array index (as the `place` field represents the index of each value in an ordered array). For more details see Github issue https://github.com/DSpace/DSpace/issues/7582
***

Provide detailed information about a specific item. The JSON response document is as follow
Expand Down
49 changes: 43 additions & 6 deletions resourcepolicies.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,14 @@ Return codes:
The add operation allows to initialize or replace information with new one.

To set a startDate
`curl --data '[ { "op": "add", "path": "/startDate", "value": "2019-10-31" }]' -H "Authorization: Bearer ..." -H "content-type: application/json" -X PATCH ${dspace7-url}/api/authz/resourcepolicies/${resourcepolicy-id}`

```
curl --data '[ { "op": "add", "path": "/startDate", "value": "2019-10-31" }]' \
-H 'Authorization: Bearer ...' \
-H 'content-type: application/json' \
-X PATCH \
'${dspace7-url}/api/authz/resourcepolicies/${resourcepolicy-id}'
```

```json
"id": 2844,
Expand All @@ -164,8 +171,14 @@ the add operation will result in:
```

To set a name and a description
`curl --data '[ { "op": "add", "path": "/name", "value": "my name" }, { "op": "add", "path": "/description", "value": "my description"}]' -H "Authorization: Bearer ..." -H "content-type: application/json" -X PATCH ${dspace7-url}/api/authz/resourcepolicies/${resourcepolicy-id}`

```
curl --data '[ { "op": "add", "path": "/name", "value": "my name" }, { "op": "add", "path": "/description", "value": "my description"}]' \
-H 'Authorization: Bearer ...' \
-H 'content-type: application/json' \
-X PATCH \
'${dspace7-url}/api/authz/resourcepolicies/${resourcepolicy-id}'
```

```json
"id": 2844,
Expand Down Expand Up @@ -207,7 +220,14 @@ With the `remove` operation, you can delete:
the other properties cannot be nullified.

To remove an embargo you can for instance use the following
`curl --data '[ { "op": "remove", "path": "/startDate" }]' -H "Authorization: Bearer ..." -H "content-type: application/json" -X PATCH ${dspace7-url}/api/authz/resourcepolicies/${resourcepolicy-id}`

```
curl --data '[ { "op": "remove", "path": "/startDate" }]'
-H 'Authorization: Bearer ...' \
-H 'content-type: application/json' \
-X PATCH \
'${dspace7-url}/api/authz/resourcepolicies/${resourcepolicy-id}'
```

that will transform

Expand Down Expand Up @@ -245,7 +265,14 @@ Return codes, see also general [return codes for PATCH requests](patch.md#error-
The replace operation allows to replace *existent* information with new one. Attempt to use the replace operation to set not yet initialized information must return an error. See [general errors on PATCH requests](patch.md)

To change the startDate
`curl --data '[ { "op": "replace", "path": "/startDate", "value": "2020-01-01" }]' -H "Authorization: Bearer ..." -H "content-type: application/json" -X PATCH ${dspace7-url}/api/authz/resourcepolicies/${resourcepolicy-id}`

```
curl --data '[ { "op": "replace", "path": "/startDate", "value": "2020-01-01" }]' \
-H 'Authorization: Bearer ...' \
-H 'content-type: application/json' \
-X PATCH \
'${dspace7-url}/api/authz/resourcepolicies/${resourcepolicy-id}'
```

For example, starting with the following item data:

Expand Down Expand Up @@ -310,9 +337,14 @@ Return codes:
Update the eperson linked by this resource policy

Sample CURL command:

```
curl -i -X PUT 'https://demo.dspace.org/server/api/authz/resourcepolicies/3/eperson' -H 'Authorization: Bearer eyJhbGciOiJ…' -H "Content-Type:text/uri-list" --data 'https://demo.dspace.org/server/api/eperson/epersons/ba05e3dd-aa20-4441-ac05-8ceef6f67ac7'
curl -X PUT '${dspace7-url}/api/authz/resourcepolicies/3/eperson' \
-H 'Authorization: Bearer eyJhbGciOiJ…' \
-H 'Content-Type:text/uri-list' \
--data '${dspace7-url}/api/eperson/epersons/ba05e3dd-aa20-4441-ac05-8ceef6f67ac7'
```

The uri-list should always contain exactly 1 eperson. This eperson will be assigned to the resource policy

Return codes:
Expand Down Expand Up @@ -342,9 +374,14 @@ Return codes:
Update the group linked by this resource policy

Sample CURL command:

```
curl -i -X PUT 'https://demo.dspace.org/server/api/authz/resourcepolicies/4/group' -H 'Authorization: Bearer eyJhbGciOiJ…' -H "Content-Type:text/uri-list" --data 'https://demo.dspace.org/server/api/eperson/groups/db337ae5-abd2-4a28-b4ad-918cf7779e25'
curl -X PUT '${dspace7-url}/api/authz/resourcepolicies/4/group' \
-H 'Authorization: Bearer eyJhbGciOiJ…' \
-H 'Content-Type:text/uri-list' \
--data '${dspace7-url}/api/eperson/groups/db337ae5-abd2-4a28-b4ad-918cf7779e25'
```

The uri-list should always contain exactly 1 group. This group will be assigned to the resource policy

Return codes:
Expand Down
11 changes: 10 additions & 1 deletion workspaceitems.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ In addition, it allows in future to change the 1:1 association between collectio
#### findBySubmitter
**/api/submission/workspaceitems/search/findBySubmitter?uuid=<:submitter-uuid>**

It returns the workspaceitem created by the specified submitter
It returns the list of workspaceitems created by the specified submitter (eperson).

## Get Single Workspace Item from Item UUID

Expand All @@ -207,6 +207,15 @@ It would respond with:
* 403 Forbidden - if you are not logged in with sufficient permissions to view the workspace item
* 204 if the workspace item doesn't exist

## DELETE Method

**/api/submission/workspaceitems/<:ws-item-uuid>**

Deletes workspace item with the given UUID. The deletion includes the deletion of the item object that is associated to the given workspace item.

Available Response Codes are

* 204 No content - if the operation succeed
* 401 Unauthorized - if the requester is not authenticated
* 403 Forbidden - if the requester does not have sufficient permissions ((deletion of workspace items can only be requested by the submitter of the workspace item or administrators)
* 404 Not found - if the workspace item doesn't exist