The OData Server module integrates a third-party library called the OData PHP Producer, along with Drupal's Field API to expose all Drupal entities via an OData v2 compliant web service. Installation procedures are noted in README.txt.
OData, for those unfamiliar, is a specification for RESTful web services: http://www.odata.org/
The OData Server module is designed to expose all entities and all core fields (and a few contrib fields like Date) using the OData PHP Producer library to parse requests according to the OData specification, at which point requests are translated into EntityFieldQueries. Results are then serialized and delivered by the OData PHP Producer library.
An administration screen under admin/config/development/odata allows administrators to select precisely which bundles, properties, and fields to expose.
Project Page: http://drupal.org/sandbox/r2integrated/1561302
Git:
git clone --recursive --branch 7.x-1.x http://git.drupal.org/sandbox/r2integrated/1561302.git odata_server
cd odata_server
Comment | File | Size | Author |
---|---|---|---|
#9 | drupalcs-result.txt | 12.01 KB | klausi |
Comments
Comment #1
Eyal Shalev@r2integrated,
There is a sum of Drupal coding standards errors found using ventral.org you can view them with this link.
Things I recommend fixing first (by priority):
Comment #2
r2integrated CreditAttribution: r2integrated commented@Eyal Shalev
Thanks for checking things out - I have (before submitting the project for review) run the module through the PAreview script and can confirm I have seen item 2 in the past, however I believe the review script is incorrect, which I've noted below.
Please let me know if I have misunderstood any of the issues you posted or if you find any other issues. Thank you very much for helping this get through the review process!
Patrick
Comment #3
r2integrated CreditAttribution: r2integrated commentedComment #4
vaibhavjainplease rectify the issues stated in automation testing - http://ventral.org/pareview/httpgitdrupalorgsandboxr2integrated1561302git
Comment #5
patrickd CreditAttribution: patrickd commentedfixing all coding standard issues is NOT mandatory - DON'T change to needs work without explanation/major issues
Comment #6
r2integrated CreditAttribution: r2integrated commentedElevating priority in accordance with guidelines on http://drupal.org/node/539608
Comment #7
klausiComment #8
dman CreditAttribution: dman commentedGood clear introduction and summary of what the module does and how. It's surprising how many applications leave us guessing from the beginning :-)
.. This can and should be done using the hook_requirements() instead. When used, this allows the enable process to prevent installation (if that's what you are trying to do), and also helps by providing status reports as well, that confirm when things are good, even if you move servers etc later.
Good on you for checking though!
Thanks for using the libraries API, it's a good way to be doing this.
I can't fully evaluate all the functionality of the code by tracing it in my head and also understanding the API you are interacting with, but it looks well structured, very well documented and very consistent.
It's not clear to me where, how, or if, access controls are checked. Does this respect field privacy, unpublished content and restriction by role? This is the first security concern in the service as described.
Looking at things like DrupalQueryProvider.php, I can tell you've taken a very robust approach, and clearly know what you are doing there. Perhaps a summary of the extent to which this service respects normal Drupal access controls would be helpful. Is there any expected authentication to read from this service? I see no API key code or anything except
in that respect. Maybe I just can't see where to look for that.
If "security" is totally out-of-scope, please make that very clear. We can't have modules that inadvertently make private information public when enabled.
...
Small niggles :
I get the feeling there are cleaner ways of doing this though: ( odata_server_settings() )
This (and things like it) should be passed through t() as a matter of course. Preferably without markup.
I'd be interested in really trying this whole out, but it looks like a large job to spin up. Is there a way to test it, or a demo you could recommend as an example of how this odata works, or can you describe how you are using it currently?
Code-review-wise:
It's just important If you can let us know what's happening (or not) with security and/or maybe provide *some* sort of authentication layer (Drupal roles probably won't be appropriate for REST, so maybe an API key or IP lock)
Comment #9
klausiReview of the 7.x-1.x branch:
This automated report was generated with PAReview.sh, your friendly project application review script. You can also use the online version to check your project. You have to get a review bonus to get a review from me.
manual review:
require_once 'mymodule.inc';
. Also elsewhere.Comment #10
r2integrated CreditAttribution: r2integrated commentedThanks guys, tons of feedback! @dman, I'll need to take some time reviewing everything, but off the bat, I'm having difficulties with your suggestion of using hook_requirements. The libraries module is not picking up on my hook_libraries_info implementation and so I can't check for the odata library during the install phase in hook_requirements. Apparently module_implements doesn't work during this phase of the bootstrap if the module has not been installed? I can still use it during the runtime phase, but I believe I need to leave my hook_enable implementation, unless I'm missing something. Any ideas?
Comment #11
dman CreditAttribution: dman commentedYeah, I guess I can see why the library func would not be available before the module is activated.
A reasonably common pattern is for a .install hook to module_load_include() its own module file when needed (during the first .install, the .module isn't loaded yet) and then usually that has any requirements check function needed there.
BUT ... yeah, it's not going to work well on a library (under libraries API) that the module provides itself. It's a puzzler.
Will work fine if doing hook_requirements(runtime) I'd imagine, but install-time... may have to do a work-around of some type. I can't think of a short answer.
Maybe they will have an idea or example in the libraries issue queue.
Comment #12
r2integrated CreditAttribution: r2integrated commentedSo, I've checked the Libraries API issue queue and it would seem that this is a known issue which is still not fixed as of the stable 7.x-2.0 release (issue was discovered last year). I'm tempted to only check the library's presence during the runtime bootstrap phase in hook_requirements(). I could also issue a drupal_set_message() to indicate to the user that something isn't working right. Any thoughts?
Comment #13
r2integrated CreditAttribution: r2integrated commentedI've committed my latest, fixing issues identified by @klausi and @dman. Known remaining issues:
Regarding security, this module is designed to be as generic as possible. It therefore doesn't make any assumptions about node visibility. "Status" is just another property to this module, so unpublished and published nodes will be visible. Ultimately, admins are responsible for exposing only the entities/bundles, properties, and fields that are appropriate. I think the idea of an API key is excellent and fully intend on exploring that and other options for 7.x-2.0. That said, I consider 7.x-1.0 to be feature complete. In the README I have a brief discussion of security considerations but would be more than happy to expand on it or explain in other locations the module's security impact.
Comment #14
dman CreditAttribution: dman commentedSounds like a runtime requirements check is the most practical at this time. Thanks for looking in to it.
It's good you are considering the security aspect. Personally, I think that the built-in access controls we expect to work - "published" and "role can view content" MUST be respected by default. Any module that was found in the repository that failed to do so would have a security issue raised against it immediately. So a note on the README is not enough. The project page must loudly announce that installing this module would make previously private data public. Sorry, but it is a big deal, so make a clear disclaimer - and in the interim until this can be applied, mark the current release as "requires bad_judgement" Thats what bad_judgement is for - to mark a module as an insecure thing that you probably should not put on a real live site as-is
Comment #15
r2integrated CreditAttribution: r2integrated commentedHrmm, I'm thinking that given the choices of either respecting the status property on nodes OR going out of my way to scare potential users of the module, I think it's more desirable to just respect the status property ;)
I'll implement this special case shortly. Can you think of any other entities I should handle specially? Should I also respect the status property on users? I'm thinking yes, for consistency's sake at least.
Comment #16
dman CreditAttribution: dman commentedThere are a number of access check APIs for the core entities - node_access() etc which are the ones to use. When using Drupal like a data service without authentication, the default will be what is available to the anon user. Don't check the published yourself, but use these if possible. Access permissions rapidly can be modified by other processes, so this API func is the one to trust. I don't know if any support for other new entities is available.
Comment #17
r2integrated CreditAttribution: r2integrated commentedExcellent point on node_access(), but I'm not sure the query system can directly use this as it would interfere with result pagination. In this module we're using EntityFieldQuery, and I believe there are some permissions checks at this level at least for node entities.
Comment #18
chx CreditAttribution: chx commentedDo you need help with EntityFieldQuery?
Comment #19
r2integrated CreditAttribution: r2integrated commented@chx - I would love some feedback and guidance, thanks! The outstanding issue it would seem is node_access compliance. I'm not sure that queries done at such a low level, like in this module, can benefit from this hook. Any thoughts?
Comment #20
a_thakur CreditAttribution: a_thakur commentedManual Review:
# README.txt: looks good
# odata_server.info: Why a blank line on line#6.
There are not a blockers.
# But in the file odata_server.admin.inc
At various places in this file, you have used variable_get() to asssign #default_value to form elements, so these variables would be stored in the database, but these variables have to be deleted when the module is uninstalled, so the implementation of hook_uninstall() is required in the odata_server.install file which would use variable_del() to delete these variables.
This would delete all the variables created.
More review..need some time to understand the code a bit more..
Comment #21
r2integrated CreditAttribution: r2integrated commentedThanks @a__thakur, please follow development on the issue tracker for the sandbox project. I'm closing this issue as we've successfully completed a review for another module of ours.
Comment #22
a_thakur CreditAttribution: a_thakur commentedPlease make sure to change the status in that case, as reviewers usually pick up the issues which have "need review" status..