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 implementation of the authorizations endpoints #2663
Conversation
The reason for the change done in it seems to duplicate the behaviour assigned to the but in the same refactoring the default implementation was dropped @KevinVdV can you summarize the reason for this change to me or link me to the relevant previous conversations? why we need to introduce a new way to name our classes other than the Constants that were already in place in Constants.typeText? does it make sense to reintroduce a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@abollini The changes to the indexableObject were documented on the following places:
- https://jira.lyrasis.org/browse/DS-4287
- [DS 4287] Refactoring the IndexableObject & SolrServiceImpl #2612
getTextType() method
The getTypeText() does indeed reuse the Constants.typeText[integer] for DSpace Objects, it doesn't do this for non indexable objects "IndexableClaimedTask", "IndexableWorkflowItem", ... as these aren't DSpaceObjects & the Constants.typeText array was limited to DSpaceObjects up until DSpace 6 & I think we should keep it like this.
FindableObject
I also took a quick look at your code & I see no need for the FindableObject interface, every instance of the "FindableObject" can be removed & replaced with DSpaceObject in the code. I did notice that the AuthorizationRestUtil returns non DSpace objects like WorkspaceItem & WorkflowItem but these objects aren't supported using the "AuthorizeUtil" method, so their inclusion here is unneeded.
I'm in favor of a more extensive system that leaves room for other objects to be supported but then we need to move away from the Constants integers & move more towards using the actual class names as types instead of integers. We don't want to add integers for example of we just want to add support for the MetadataSchema, MetadataField, ... objects.
thanks @KevinVdV for point me to the previous discussions. I don't completely agree with the change done, especially with the use of the SimpleName to identify the object but ok, that's it and we can always discuss that again later if needed and time allowed. So I'm working on solving the conflict retaining the FindableObject but removing the need to add additional ID to the Constants class and instead using the class name aka the new |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did expect the structure of the implementation to be different based on what was previously discussed.
One of the things which was discussed was to make sure it's a spring configuration of the list of "features" which can be offered. I noticed it is now completely autowired, making it harder to e.g. disable a feature
I would also have expected that type of Rest Object would be determined using a Generic type at the interface level, and e.g. CCLicenseFeature would use ItemRest public class CCLicenseFeature implements AuthorizationFeature<ItemRest>
. This would allow the supported type to be identified automatically and would avoid the instanceof and casting in each implementation
hi @benbosman thanks for your initial feedback. I don't have an use case in mind right now that require to completele remove "core" feature maybe what is needed is that some feature will return always false if a dspace.cfg property is set (for instance if an institution doesn't want to use the request a copy). Anyway, if we want to allow an autowired component to be disabled the SpringBoot Conditional annotation should help us about the GenericType suggestion the current contract says that a feature can support multiple object types so it is not necessary tied to a single object but we can of course revisit this decision if needed (here or in a future PR) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@abollini : I've given this an initial code review today. Some inline comments below. I don't think anything here is major, but a lot of minor suggestions / requests. I haven't had a chance to test this yet.
As a sidenote regarding @benbosman's comments about configuring which "features" that can be offered...I agree with the approach taken in this PR. Since "features" only exist in the REST API layer, they should be configured via Spring Annotations (and as necessary @Conditional
or @ConditionalOnProperty
annotations). For example, we already have code that uses @ConditionalOnProperty
annotations to only enable OAI-PMH, RDF & SWORD when corresponding configs are set to true
. The main reason I prefer this approach as it's the best practice for Spring Boot webapps. So, my preference is to keep Spring XML based configurations limited to dspace-api
as much as possible, and keep dspace-server-webapp
aligned with Spring Boot best practices. (That said, I'm noticing we have had a few Spring XMLs added to the dspace-server-webapp
without my realizing it. But, I'd rather avoid that in the future, and in fact look to remove the XMLs that exist.)
dspace-api/src/main/java/org/dspace/authorize/AuthorizeConfiguration.java
Show resolved
Hide resolved
dspace-api/src/main/java/org/dspace/authorize/AuthorizeConfiguration.java
Show resolved
Hide resolved
dspace-api/src/main/java/org/dspace/authorize/AuthorizeConfiguration.java
Show resolved
Hide resolved
dspace-server-webapp/src/main/java/org/dspace/app/rest/authorization/Authorization.java
Outdated
Show resolved
Hide resolved
dspace-server-webapp/src/main/java/org/dspace/app/rest/authorization/AuthorizationFeature.java
Outdated
Show resolved
Hide resolved
dspace-server-webapp/src/test/java/org/dspace/app/rest/AuthorizationRestRepositoryIT.java
Outdated
Show resolved
Hide resolved
dspace-server-webapp/src/test/java/org/dspace/app/rest/AuthorizationRestRepositoryIT.java
Outdated
Show resolved
Hide resolved
dspace-server-webapp/src/test/java/org/dspace/app/rest/AuthorizationRestRepositoryIT.java
Outdated
Show resolved
Hide resolved
dspace-server-webapp/src/test/java/org/dspace/app/rest/AuthorizationRestRepositoryIT.java
Show resolved
Hide resolved
@abollini : Thanks for the quick updates. I only have one minor code review feedback remaining here #2663 (comment) I'll also run some tests on this to make sure it's working for me, but the code looks good! UPDATE: After testing, I've found a few minor issues relating to how the implementation works when compared to the contract.
The |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have performed an initial review of the code excluding the ITs. I also still have to test the functionality.
I included some feedback inline, but most things are most likely small changes.
Regarding @tdonohue 's feedback: I do prefer the syntax core.item
since it better guarantees uniqueness (although I don't think the same name is used in 2 categories so far), perhaps the contract should be updated?
dspace-api/src/test/java/org/dspace/AbstractIntegrationTest.java
Outdated
Show resolved
Hide resolved
dspace-server-webapp/src/main/java/org/dspace/app/rest/authorization/Authorization.java
Show resolved
Hide resolved
dspace-server-webapp/src/main/java/org/dspace/app/rest/authorization/AuthorizationFeature.java
Show resolved
Hide resolved
dspace-server-webapp/src/main/java/org/dspace/app/rest/authorization/impl/CCLicenseFeature.java
Outdated
Show resolved
Hide resolved
...-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorizationRestRepository.java
Show resolved
Hide resolved
...-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorizationRestRepository.java
Show resolved
Hide resolved
dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/FindableObjectRepository.java
Outdated
Show resolved
Hide resolved
...p/src/main/java/org/dspace/app/rest/security/ReadAuthorizationPermissionEvaluatorPlugin.java
Outdated
Show resolved
Hide resolved
...-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorizationRestRepository.java
Show resolved
Hide resolved
...-server-webapp/src/main/java/org/dspace/app/rest/repository/AuthorizationRestRepository.java
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While reviewing the ITs, I noticed e.g. AuthorizationFeatureRestRepositoryIT assumes the AuthorizationFeatureService works correctly, but there are no JUnit tests for AuthorizationFeatureService despite the fact that it's a new Service
I've included some inline feedback on the ITs as well.
Next I will test the functionality, but since I did report quite some feedback, I'll wait until that's resolved
...ce-server-webapp/src/test/java/org/dspace/app/rest/AuthorizationFeatureRestRepositoryIT.java
Show resolved
Hide resolved
Matchers.anyOf( | ||
JsonPathMatchers.hasJsonPath("$.type", is("authorization")), | ||
JsonPathMatchers.hasJsonPath("$._embedded.feature", | ||
Matchers.not(Matchers.anyOf( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This tests which features are not embedded, but doesn't verify which features are embedded. The same applies for tests below
Also, I don't expect anything to be embedded since no projection is requested
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the reason why projection was not requested is because it was introduced after than these test were written. I have updated them now.
I cannot test that the expected features are included because we don't know all of them in advance. We will add more and more features soon and I prefer to avoid the need to update such test for each new feature. Instead, it would be sufficient to verify that what is returned match the request.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed the $._embedded.feature
is currently still not verifying which data is present (only which data is not present). The test would be more reliable if it can verify the expected features are present
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@abollini where has this been fixed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry, you are right the check were still missing. Added here 59b7716
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the updates, that's really helpful.
I think you missed one though:
DSpace/dspace-server-webapp/src/test/java/org/dspace/app/rest/AuthorizationRestRepositoryIT.java
Line 536 in 59b7716
JsonPathMatchers.hasJsonPath("$._embedded.feature", |
dspace-server-webapp/src/test/java/org/dspace/app/rest/AuthorizationRestRepositoryIT.java
Show resolved
Hide resolved
...ce-server-webapp/src/test/java/org/dspace/app/rest/authorization/CCLicenseFeatureRestIT.java
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made a small code review & found some very easy to fix things.
/** | ||
* An authorization is the right for a specific {@link EPerson}, eventually null to indicate unauthenticated users, to | ||
* use a specific {@link AuthorizationFeature} on a defined object. The target object must implement the | ||
* {@link IndexableObject} interface so to have an unique ID and type |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The IndexableObject is mentioned here, but it isn't used in this class, I assume it should be the "BaseObjectRest" ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed thanks
return false; | ||
} | ||
Item item = (Item) utils.getDSpaceAPIObjectFromRest(context, object); | ||
if (!item.isWithdrawn()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if the item is Null ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the AuthorizeFeatureService protects against NPE, it is stated in the interface contract (javadoc). I have added a test in the service test to demonstrate that as well see commit 4192b09
try { | ||
featureName = authorizationRestUtil.getFeatureName(id); | ||
} catch (IllegalArgumentException e) { | ||
log.warn(e.getMessage(), e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps add a small message here for the log ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is provided by the getFeatureName inside the IllegalArgumentException. For such reason the exception is stated in the method javadoc despite to be a runtime exception
* user. Only administrators and the user identified by the epersonUuid parameter can access this method | ||
* | ||
* | ||
* @param context |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This param isn't used in this method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed thanks
* the uri of the object to check the authorization against | ||
* @param epersonUuid | ||
* the eperson uuid to use in the authorization evaluation | ||
* @param featureName |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This param isn't used in this method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed thanks
* anonymous user. Only administrators and the user identified by the epersonUuid parameter can access this method | ||
* | ||
* | ||
* @param context |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This param isn't used in this method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed thanks
* | ||
* @author Andrea Bollini (andrea.bollini at 4science.it) | ||
* | ||
* @param <F> the ReloadableEntity type |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This , should be
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is now the ReloadableEntityObjectRepository, I guess you noted that F was used instead than T, now fixed
} | ||
} | ||
} catch (SQLException e) { | ||
log.error(e.getMessage(), e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps add a small message here for the log ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know exactly what useful information can be added, all the other PermissionEvalutorPlugin do the same. This don't mean that we cannot improve the logging here but I really like to get suggestion :)
@abollini : it looks like Travis CI is throwing a compilation error on this PR where the same method exists twice. Here's the error:
|
hi @tdonohue yes the compilation error was trivial, the oddity here is that it was due to a wrong automatic merge of git that Travis due to build the PR. Indeed, the branch itself have had not failure. Anyway, I have now pulled from the master and solved the error manually |
@abollini thanks for the updates, most of my feedback was resolved. I've updated a few things but marked most as resolved. I didn't see the JUnit tests yet, and there's some feedback from Kevin and Tim including the |
hi @benbosman thanks for reviewing that, I will check in more details tomorrow. The test for the new service has been introduced here with this commit: 616323a |
Thanks @abollini I missed that class but it looks good |
@benbosman @tdonohue @KevinVdV all the feedback above have been processed as far as I know, the only missing one could be #2663 (comment) but I really don't know how to process it |
@abollini I can see only one comment from me for which I can't see the code: #2663 (comment) I've tested this branch locally, and didn't see any problems, I think this is almost ready now (but I haven't reviewed whether the feedback from Tim or Kevin has been resolved, only what I had discovered) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code changes/updates look good to me, and I see DS-4460 has been created to ensure we fix the duplication between RestAddressableModel.getUniqueType()
and RestModel.getType()
in a future PR (as this will be necessary for consistency in the Angular UI).
However, after manually tested this, I'm having difficulty getting any results to return from the /api/authz/authorizations/search/object
endpoint. Previously, I thought this was working correctly. But, now if I authenticate as an Administrator, and use an Item URI, I'm getting zero results for every Item URI that I try. Here's an example request: http://localhost:8080/server/api/authz/authorizations/search/object?uri=http://localhost:8080/server/api/core/items/d1fb08bd-a514-492c-83c2-09eae0bec044
It's always possible there is something in my test environment causing this, but I'd recommend retesting this endpoint to ensure it is returning results as expected.
@tdonohue everything have been addressed now, Travis has had a temporary hangoff now it should work. The reason why you don't see result in your search is because your are searching for the anonymous user as no eperson param is specified in your request. It should look like that |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 @abollini : thanks for the updates & note on my prior testing. You are correct, I was not including the "eperson" param in my tests. After doing so, it all works great.
This looks good to me now. However, it is failing Travis CI builds cause of minor Checkstyle issues (related to the Checkstyle update it looks like). Once the Checkstyle issues are fixed & this passes Travis CI, then it looks good to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @abollini , that solves my open feedback
This is the implementation of the authorization features and authorization endpoints according to the REST Contract in
https://github.com/DSpace/Rest7Contract/blob/master/features.md
https://github.com/DSpace/Rest7Contract/blob/master/authorizations.md
DONE: