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

fix(gravsearch): Unify permissions handling with full resource request #1521

Merged
merged 12 commits into from
Dec 5, 2019

Conversation

benjamingeer
Copy link

This PR makes Gravsearch filter results according to user permissions in the way that the /v2/resources route does, as per https://discuss.dasch.swiss/t/change-in-the-way-gravsearch-results-are-filtered-according-to-permissions/111.

Fixes #1344
Closes #924

mrivoal
mrivoal previously approved these changes Nov 20, 2019
Copy link

@mrivoal mrivoal left a comment

Choose a reason for hiding this comment

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

I can only approve this PR on the principle, by reading the comments and not the code itself :)

There is a use case I would like to draw your attention to: given the fact that Default Access Object Permission can be defined at property level as well as at resource level, a permission schema like the one that follows is possible :

  • define a restricted Default Access Object Permission on a resource
  • define a more open Default Access Object Permission on the link property that targets this resource.

For example : given 2 resource classes, Person and Biography, Person having a link property hasBiography on Biography, what do you think would happen if the permissions were set like this:

<http://rdfh.ch/permissions/0000/example-o011> rdf:type knora-admin:DefaultObjectAccessPermission ;
     knora-admin:forProject <http://rdfh.ch/projects/0000> ;
     knora-admin:forResourceClass example:Biography ;
     knora-base:hasPermissions "CR knora-admin:ProjectAdmin|M knora-admin:ProjectMember"^^xsd:string .

<http://rdfh.ch/permissions/0000/example-o012> rdf:type knora-admin:DefaultObjectAccessPermission ;
     knora-admin:forProject <http://rdfh.ch/projects/0000> ;
     knora-admin:forProperty example:hasBiography ;
     knora-base:hasPermissions "CR knora-admin:ProjectAdmin|M knora-admin:ProjectMember|V knora-admin:KnownUser, knora-admin:KnownUser"^^xsd:string .

<http://rdfh.ch/permissions/0000/example-o013> rdf:type knora-admin:DefaultObjectAccessPermission ;
     knora-admin:forProject <http://rdfh.ch/projects/0000> ;
     knora-admin:forProperty example:hasBiographyValue ;
     knora-base:hasPermissions "CR knora-admin:ProjectAdmin|M knora-admin:ProjectMember|V knora-admin:KnownUser, knora-admin:KnownUser"^^xsd:string .

Would the user be allowed to see the link but prevented from accessing the resource itself?

@benjamingeer
Copy link
Author

@mrivoal Could you please test this PR with your use cases and see if it does what you want?

@benjamingeer benjamingeer dismissed mrivoal’s stale review November 20, 2019 12:20

Review should be based on testing the requested use case.

@mrivoal
Copy link

mrivoal commented Nov 20, 2019

Ok. I will try and do this tomorrow, as it means having an up-to-date stack on my laptop and involve @loicjaouen or @gfoo's help.

@benjamingeer benjamingeer mentioned this pull request Nov 20, 2019
Copy link

@mrivoal mrivoal left a comment

Choose a reason for hiding this comment

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

I tested the use case I was mentioning. An unauthorized user is not allowed to see the restricted resource nor the link property that targets this resource. I think this is a consistent behavior.

If it is useful I can commit my use case, as it is based on Anything ontology.

@benjamingeer
Copy link
Author

An unauthorized user is not allowed to see the restricted resource nor the link property that targets this resource. I think this is a consistent behavior.

Hmm, actually in our test, you can see the link value but not the target resource. But I've just now realised that I didn't push the test data for this before leaving Basel...

If it is useful I can commit my use case, as it is based on Anything ontology.

Yes please, that would be very helpful.

@mrivoal
Copy link

mrivoal commented Nov 21, 2019

An unauthorized user is not allowed to see the restricted resource nor the link property that targets this resource. I think this is a consistent behavior.

I meant in Salsah and Knora app. If there is a link between 2 resources, the label of the target resource is displayed in the resource which the origin of the link property. If the link was displayed, I guess the label of the target resource would be as well which might be giving too much information for a resource a user is not allowed to access.

What I see when I am logged in :

Capture d’écran 2019-11-21 à 14 24 09

What I see as an UnkwownUser:
Capture d’écran 2019-11-21 à 14 24 27

@benjamingeer
Copy link
Author

I don't know what the SALSAH app does in this case, but the API returns the link value, containing only the IRI of the target resource. This has always been the case (in API v2) when requesting just one resource, and now it is (or should be) the case when you do a Gravsearch query.

@gfoo
Copy link

gfoo commented Nov 21, 2019

Done few tests and it seems to work.

Related to @mrivoal example, with my model is Person -hasNote-> Note, in my data test, the person is related to two notes, the second one is forbidden for the current user.

Now I can get the Person and not a ForbiddenRes (as required by our issue) and you provide as well the two link values in the result. The first one (not forbidden) with a "knora-api:linkValueHasTarget" and the second one (forbidden) with a "knora-api:linkValueHasTargetIri".

Can I consider that if you provide a "knora-api:linkValueHasTargetIri", that means this related resource is forbidden?

@tobiasschweizer
Copy link
Contributor

please remember to adapt the Gravsearch design docs

@benjamingeer
Copy link
Author

Can I consider that if you provide a "knora-api:linkValueHasTargetIri", that means this related resource is forbidden?

I guess so!

@benjamingeer
Copy link
Author

As I was updating the docs for this PR, I've just realised that it produces inconsistent behaviour:

If the user does not have permission to see a matching main resource, it is replaced by a
proxy resource called knora-api:ForbiddenResource. If a user does not have permission
to see a matching dependent resource, only its IRI is returned.

What do you all think of this? Should we replace ForbiddenResource with something that just contains the IRI of the resource you don't have permission to see?

@tobiasschweizer @mrivoal @loicjaouen @gfoo

@gfoo
Copy link

gfoo commented Nov 29, 2019

I don't really understand why you want to return the IRI of the forbidden target? Is there a particular reason for that? Could we simply return a knora-api:ForbiddenResource in place of the knora-api:linkValueHasTargetIri?

The new specs will be:

If the user does not have permission to see a matching main resource or a dependent
resource, it is replaced by a proxy resource called knora-api:ForbiddenResource.

@benjamingeer
Copy link
Author

I don't really understand why you want to return the IRI of the forbidden target? Is there a particular reason for that?

Because that's what the /v2/resources route does, and this PR was supposed to make Gravsearch do the same thing as the /v2/resources route.

We could return ForbiddenResource instead, but then we'd have to change /v2/resources to make them consistent. What do you think?

@subotic
Copy link
Collaborator

subotic commented Nov 29, 2019

What does the API return if you request the returned (forbidden) IRI?

PS. Today is a university holiday and we don't work ;-)

@benjamingeer
Copy link
Author

Today is a university holiday and we don't work ;-)

Sorry, I will stop working immediately. :)

@gfoo
Copy link

gfoo commented Nov 29, 2019

Today is a university holiday and we don't work ;-)

Sorry, I will stop working immediately. :)

Good idea, I have an old movie to re-watch :))) https://media.services.cinergy.ch/media/cinemanteaser174x240x2/ce00f79b734ebedb9fcb36dc65cf3fe0a30cf74a.jpg

@gfoo
Copy link

gfoo commented Nov 29, 2019

I don't really understand why you want to return the IRI of the forbidden target? Is there a particular reason for that?

Because that's what the /v2/resources route does, and this PR was supposed to make Gravsearch do the same thing as the /v2/resources route.

We could return ForbiddenResource instead, but then we'd have to change /v2/resources to make them consistent. What do you think?

I think that there is more consistency problems than I thought, why v2/resources returns that:

{
    "knora-api:error": "org.knora.webapi.NotFoundException: One or more requested resources were not found (maybe you do not have permission to see them, or they are marked as deleted): <http://rdfh.ch/0113/XiAMcfY2Skis3j1bd-QkmA>",
    "@context": {
        "knora-api": "http://api.knora.org/ontology/knora-api/v2#"
    }
}

instead of a ForbiddenResource. Not so sure that gravsearch should follow the rules of v2/resources in any cases.

Don't know what is the good solution, our first request was to not have a ForbiddenResource in place of main resource, it's done, great! To have or not the IRI of forbidden dependent resources is just an extra for my use case (I just need to know if this dependent resource is forbidden or not...)

@gfoo
Copy link

gfoo commented Nov 29, 2019

Can we have ForbiddenResource with v2/resources? or is it only for gravsearch?

@benjamingeer
Copy link
Author

benjamingeer commented Dec 2, 2019

Now that we are saying that we don't try to pretend something doesn't exist if you don't have permission to see it, I don't think NotFoundException makes sense.

We could use HTTP 403 (Forbidden) with /v2/resources, but I think this wouldn't make sense if you requested two resources, and you only have permission to see one of them. Then you should still get that one, and you should also find out that you don't have permission to see the other one.

So I think we need something like ForbiddenResource both for /v2/resources and for Gravsearch, both for main resources and for dependent resources.

So we have two options: either ForbiddenResource or a LinkValue (or something similar) containing just the resource IRI.

One thing I don't like about ForbiddenResource is that it's rather big. I would prefer something more lightweight.

@benjamingeer
Copy link
Author

I guess the easy solution right now, to make things consistent, would be to use ForbiddenResource.

@gfoo
Copy link

gfoo commented Dec 5, 2019

@benjamingeer Is there any pending questions here? are you waiting some feedbacks from us?

I cannot descently review your scala code (out of my skills) but about the specs it is fine for me and I refactored my code to follow what you implemented in this branch.

About your last remark:

I guess the easy solution right now, to make things consistent, would be to use ForbiddenResource.

If you are talking about v2/resources, it is an new issue, isn't?

@benjamingeer
Copy link
Author

If you are talking about v2/resources, it is an new issue, isn't?

Yes, I guess we could do that in a separate PR. I would just need to know whether it would break existing client code. @tobiasschweizer

@benjamingeer benjamingeer added this to the 2019-12 milestone Dec 5, 2019
@benjamingeer benjamingeer merged commit 064ca4a into develop Dec 5, 2019
@benjamingeer benjamingeer deleted the fix/1344-gravsearch-permissions branch December 5, 2019 09:20
@tobiasschweizer
Copy link
Contributor

I would just need to know whether it would break existing client code.

So instead of a non successful HTTP response the client would get a 200 with ForbiddenResource when requesting a resource from v2/resources with insufficient permissions, right?

@benjamingeer
Copy link
Author

That’s what I was thinking, does it make sense to you? Do you know if client code would need to be changed?

@tobiasschweizer
Copy link
Contributor

Do you know if client code would need to be changed?

I cannot think of any reason why this should be necessary. Instead of a failed HTTP request (non 200 HTTP response) a resource is returned like in all cases of successful responses. I would propose that the integration with the client lib be tested when doing the PR.

@tobiasschweizer
Copy link
Contributor

in dasch-swiss/knora-api-js-lib, a unit test should be added for this case

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

Successfully merging this pull request may close these issues.

Gravsearch ForbiddenResource result and permissions of linked resources Get dependent resources Iris
5 participants