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

Initial contract for the authorizations endpoints #92

Merged
merged 9 commits into from Dec 5, 2019
93 changes: 93 additions & 0 deletions authorizations.md
@@ -0,0 +1,93 @@
# Authorizations Endpoints
[Back to the list of all defined endpoints](endpoints.md)

An authorizations is the representation of some rights that are available to a specific user (eperson) on a defined object, eventually the whole repository (site object).
All the authorizations are always explicitly listed regardless to how they are grant, by direct policies via groups' membership or open to everyone (anonymous users).
Please note that these endpoints are all READ-ONLY, authorizations are granted and withdrawn as result of business processes, configurations and resource policies.

## Main Endpoint
**/api/authz/authorizations**
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure exactly what this endpoint might retrieve. I think it would be useful to have an example here.
Also, if this retrieves a list of "my" authorizations, should I assume a nonexistent authorization is a DENIED one?

Copy link
Member Author

Choose a reason for hiding this comment

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

well nothing :)
the /api/authz/authorizations is not implemented and will return a 405 code as stated in the contract.

Keep in mind the general approach that we have adopted for our REST api. Each endpoints represent a collection of resources. The GET method over the collection should return, where it makes sense, all the resources in the collection. Don't be confused by the term collection here, it is referred to the REST side, see
https://github.com/DSpace/Rest7Contract/blob/master/README.md#use-of-the-http-verbs-and-http-response-code

About the "denied" authorizations: yes, we keep the general dspace principle here. If you don't have an explicit authorization then it is denied. So, assuming that you want to know if an user is authorized or not to withdraw an Item you can use
/api/authz/authorizations/search/object?uri=https://dspace.url/api/core/items/<item-uuid>&eperson=<eperson-uuid>&feature=withdrawItem
if you get a not empty answer, i.e. you have a matching authorization, the user is allowed otherwise he is denied

Copy link
Member

Choose a reason for hiding this comment

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

Throwing a 405 Method Not Allowed to all requests on this endpoint seems appropriate for now.


As we don't have yet an use case to iterate over all the existent authorizations the main endpoint is not implemented and a 405 error code is returned according to our [general error response codes](README.md#Error-codes).

## Single Authorization
**/api/authz/authorizations/<:id>**

Provide detailed information about a specific authorization. The JSON response document is as follow

```json
{
"id": [eperson-uuid_]feature-id_object-type_object-id,
"type": "authorization"
}
```

Attributes
* id: the id of the authorization resource is defined by the combination of the eperson uuid (if not null), the feature id and the object type and (uu)id joined with an underscore

Exposed links:
* eperson: link to the eperson that the authorization belong to. Can be null for authorizations grant to unlogged users
* feature: link to the feature enabled by this authorization
* object: link to the object where this authorization apply. Not limited to DSpace objects, see the controlled list defined for the type attribute in the [features endpoint](features.md#resourcetype) for more details

Return codes:
* 200 OK - if the operation succeed
* 401 Unauthorized - if you are not authenticated and the policy is not related to the ANONYMOUS user (eperson null)
* 403 Forbidden - if you are not logged in with sufficient permissions. Only system administrators and the user mentioned in the authorization can access
* 404 Not found - if the authorization doesn't exist (or was already deleted)

### Search methods
#### object
**/api/authz/authorizations/search/object?uri=<:uri>[&eperson=<:uuid>&feature=<:string>]**

The supported parameters are:
* page, size [see pagination](README.md#Pagination)
* uri: mandatory, the object to use for the authorization check. The full URI of the rest resource must be specified, i.e. https://{dspace.url}/api/core/community/{uuid}
* eperson: optional, the uuid of the eperson to evaluate for authorization. If not specified authorization of anonymous users will be returned
Copy link
Member

Choose a reason for hiding this comment

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

Why is this required. I would expect the current user to be used for verifying the user's authorizations

Copy link
Member Author

Choose a reason for hiding this comment

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

this would allow an administrator to inspect witch permissions has a different user. If we found difficult to implement we can always reduce the first version to "only the current user" but, also if we do that, keeping this as parameter will allow us to evolve without changing the contract.
Anyway, we can and should revisit that after some concrete experiment in the implementation

* feature: optional, limit the returned authorization to the specified feature (this provide an alternative to codify the authorization id rule on the client side)

It returns the list of matching authorizations. Please note that all the matching authorizations available for the requested user will be returned including the one available to anonymous users. There is no need on the client side to combine the authorizations of the current, logged-in, user with the authorizations of anonymous users.

Return codes:
* 200 OK - if the operation succeed
* 400 Bad Request - if the uuid parameter is missing or invalid
* 401 Unauthorized - if you are not authenticated and an eperson is specified
* 403 Forbidden - if you are not logged in with sufficient permissions. Only system administrators and the user specified in the eperson parameter can access

## Other HTTP verbs than GET
No other verbs are supported right now, these endpoints are all READ-ONLY. Authorizations cannot be grant or revoke directly, they are generated by the system via interaction with other endpoint such as the resourcepolicies, the submission, the workflow, etc.

## Linked entities
### EPerson
**/api/authz/authorizations/<:string>/eperson**

Return the eperson linked by this authorization

Return codes:
* 200 Ok - if the operation succeed and an eperson is set for this policy
* 204 No content - if the authorization is related to anonymous users
* 401 Unauthorized - if you are not authenticated and the authorization is not related to the Anonymous user
* 403 Forbidden - if you are not logged in with sufficient permissions. See the requirement in the GET Single Authorization endpoint
* 404 Not found - if the authorization doesn't exist

### Object
**/api/authz/authorizations/<:string>/object**

Return the resource where the authorization is scoped.

Return codes:
* 200 Ok if the operation succeed
* 401 Unauthorized - if you are not authenticated and the authorization is not related to the Anonymous user
* 403 Forbidden - if you are not logged in with sufficient permissions. See the requirement in the GET Single Authorization endpoint
* 404 Not found - if the authorization doesn't exist

### Feature
**/api/authz/authorizations/<:string>/feature**

Return the feature resource that the user can access thanks to this authorization.

Return codes:
* 200 Ok if the operation succeed
* 401 Unauthorized - if you are not authenticated and the authorization is not related to the Anonymous user
* 403 Forbidden - if you are not logged in with sufficient permissions. See the requirement in the GET Single Authorization endpoint
* 404 Not found - if the authorization doesn't exist
2 changes: 2 additions & 0 deletions endpoints.md
Expand Up @@ -36,6 +36,8 @@

## Endpoints Under Development/Discussion
* [/api/authz/resourcepolicies](resourcepolicies.md)
* [/api/authz/authorizations](authorizations.md)
* [/api/authz/features](features.md)
* [/api/statistics](statistics.md)
* [/api/tools/itemrequests](item-requests.md)

Expand Down
60 changes: 60 additions & 0 deletions features.md
@@ -0,0 +1,60 @@
# Features Endpoints
[Back to the list of all defined endpoints](endpoints.md)

A feature is the representation of a business goal used in the [Authorization endpoint](authorizations.md) to declare what an user can do on a specific object.

## Main Endpoint
**/api/authz/features**

List all the available features in the system. Access is restricted to system administrators.

Parameters:
* page, size [see pagination](README.md#Pagination)

Return codes:
* 200 OK - if the operation succeed
* 401 Unauthorized - if you are not authenticated
* 403 Forbidden - if you are not logged in with sufficient permissions. Only system administrators can access

## Single Feature
**/api/authz/features/<:string>**

Provide detailed information about a specific feature. Access is restricted to system administrators. The JSON response document is as follow

```json
{
"id": "withdrawItem",
"description": "The feature allows to withdrawn an item from the repository without deleting it. The restoreItem feature allow to undo the process",
"resourcetypes": [
"item"
Copy link
Contributor

Choose a reason for hiding this comment

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

I think having features locked to resource types might be limiting. I understand that we need to have somehow controlled values for them, but I may have a feature that doesn't relate with any of them, for instance "edit news" or "edit registry" are specific features for the ADMIN user and I think they doesn't apply for any of these resource types. Or perhaps I'm not seeing this properly.

Copy link
Member Author

Choose a reason for hiding this comment

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

hi @paulo-graca ,
for such cases I expect that we would have a "administer" authorization or more fine-grains editNews, editRegistry that will apply to the "site" resourcetype

Copy link
Member

Choose a reason for hiding this comment

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

Separately from this PR we need to hold a discussion of the wider application of access control and of finer-grained control.

Copy link
Member

Choose a reason for hiding this comment

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

I'd recommend we start with something simple for now. Tying a "feature" to a resource type seems OK for now -- as @abollini notes the Site resource type can be used for global features that apply at the site level.

In the future (v8 or later) we may wish to revisit this (as @mwoodiupui notes) as we may want to eventually adopt an enhanced authorization / access control system. However, that is out of scope for v7.

],
"type": "feature"
}
```

Attributes
* id: the id of the feature is an unique shortname
* description: an human readable description of the feature purpose
* resourcetypes: an array of types of objects where this feature apply in the textual, singular, lowercase, form. See org.dspace.core.Constants.typeText can be one of site, community, collection, item, bundle, bitstream, eperson, group, workspaceitem, workflowitem, pooltask, claimedtask

Return codes:
* 200 OK - if the operation succeed
* 401 Unauthorized - if you are not authenticated
* 403 Forbidden - if you are not logged in with sufficient permissions. Only system administrators can access
* 404 Not found - if the authorization doesn't exist (or was already deleted)

### Search methods
#### resourcetype
**/api/authz/features/search/resourcetype?type=<:string>**

The supported parameters are:
* page, size [see pagination](README.md#Pagination)
* type: see org.dspace.core.Constants.typeText can be one of site, community, collection, item, bundle, bitstream, eperson, group, workspaceitem, workflowitem, pooltask, claimedtask

It returns the list of features that apply to the specified type.

Return codes:
* 200 OK - if the operation succeed
* 400 Bad Request - if the type parameter is missing or invalid
* 401 Unauthorized - if you are not authenticated
* 403 Forbidden - if you are not logged in with sufficient permissions. Only system administrators can access