Looking for a advanced and fast search solution I tried Apache Solr Search Integration on my test machine.
My site uses Content Access to limit the access to the content + Domain Access to bind the content to the one of two domains (forum.example.com and kb.example.com; more domains to add). Domain Access is set up to publish the content to all configured domains (called affiliates) + we are using the Domain Advanced that changes the Domain Access to use db_rewrite_query() instead of node access (so the node_access table is only ruled by the Content Access module).
I have installed two Lucene based solutions in parallel - Apache Solr Search Integration and Search Lucene API. Then I run the cron jobs to get the content indexed. The issue is thatSearch Lucene API handles restricted content just fine, but the Apache Solr Search Integration returns restricted content results to the not authorized user (and when this user tries to open them - Access Denied message is shown).
Please advise as Apache Solr Search Integration is much faster in returning the results and filtering by facets. I would really want to get it sorted out.
| Comment | File | Size | Author |
|---|---|---|---|
| #53 | access.patch | 3.92 KB | robertdouglass |
| #51 | access.patch | 0 bytes | robertdouglass |
| #45 | 556426-apachesolr-access-45.patch | 4 KB | dixon_ |
| #35 | access.patch | 4.12 KB | robertdouglass |
| #34 | access.patch | 3.75 KB | jody lynn |
Comments
Comment #1
Scott Reynolds commentedThis seems silly to ask but you used apache solr node access module right?
Comment #2
duozerskYes, I did enabled the apachesolr_nodeaccess module... didn't find any settings for it - so I assume it should just work once enabled. But it really didn't produce the results I expect.
Comment #3
duozerskI'm not that proficient in D6 node access, the only thing I noticed is that Domain Access still adds one entry to the node_access table on the install (even when using the Domain Advanced module):
And then from looking into the code of apachesolr_nodeaccess module I see that it tries to handle the node_access grants... probably the above entry somehow confuses the apachesolr_nodeaccess algorithm. But still, another module figured it out correctly...
Let me know if I can provide anything else to get to the root cause of this behavior.
Comment #4
duozerskChanging to bug report, I believe it is appropriate.
Comment #5
Scott Reynolds commentedThe trick is actually really simple. Give each subdomain a different apachesolr_site_hash.
That will filter the results for you per domain. so you search from suba.domain.com will only be suba results
you search from subb.domain.com will only be
subasubb resultsThis is centered around the node_access module saying "Anything user 0 can see, it is node_access_all"
Comment #6
duozerskThanks Scott. It seems I didn't describe it correctly. I do want to search both domains content from any domain (be it kb.example.com or forum.example.com).
And we restrict the access to the content not by domain, but by roles (using the Content Access module). So that we have roleA, roleB and roleC and want these roles to get the search results with only the content items they have access to.
Comment #7
duozerskAny help with this one, please? Can someone point me to the right direction if I don't get it right?...
Comment #8
duozerskUp... still can't figure it out.
Comment #9
Scott Reynolds commented...not critical.
Comment #10
duozerskYes, it is not - the search still works :) People tend to raise the priority if the issue is not closed in the expected timeframe ;)
Anyway, I figured it out by writing the custom module based of the apachesolr_nodeaccess. Removed some stuff from it and slightly modified the queries (basically, they were around the multisite that is not critical for me as I don't use it). Not sure what was causing the issue.
Attaching it here for reference.
Comment #11
jody lynnI had the same problem.
Apachesolr_node_access makes the assumption that if the anonymous user can access a node that there is no node access to worry about. This is not true when using domain module because the anonymous user can access content on one domain but not on another.
This patch does the same thing as the .zip module above, removing that flawed assumption.
Comment #12
robertdouglass commentedA new version to test. I'm testing against 6.2 but it should apply to 6.1 as well.
Comment #13
robertdouglass commentedSame patch with a corrected code comment.
Comment #14
agentrickardNote: The domain_all grant is put there by Domain Access for just the situation you describe. DA has a setting -- read the documentation -- for "Search content on active domain" or "search content from all domains." It also allows path-based registration of URLs on which you want to disable DA.
In those cases, we pass the 'domain_all' grant, which effectively removes DA from the node access query. However, I do not know if Domain Access Advanced (a separate module that I do not maintain), actually respects this setting.
See
domain_grant_all()anddomain_node_grants()in domain.module.SOLR module + DA respects this setting properly. I do not know how the patch would affect that.
Comment #15
robertdouglass commentedYeah. It's complicated. Any direct testing is greatly appreciated. Thanks!
Comment #16
agentrickardThe hard part is using multiple node access modules, which doesn't really work in Drupal anyway. And Domain Access Advanced, technically, is not a node access module. It replaces the node access elements with its own db_rewrite_sql.
Comment #17
pwolanin commentedI think in some cases, people will have to write their own versions of the nodeaccess module - it's only ~100 lines...
Comment #18
agentrickardI'm basically with Peter on this. If ApacheSolr can support one node access module at a time (which is basically all core can do), then it's ok, and anything else requires custom code.
Comment #19
robertdouglass commentedGood, we agree on that (#17 & #18)
Hopefully we can get some review of #13 http://drupal.org/node/556426#comment-2304968
Comment #20
agentrickardWhat are we actually testing in #13? I never had a DA+Solr problem. The issue may be DA Advanced and its use of hook_db_rewrite_sql().
Comment #21
robertdouglass commentedtesting #13 for general compatibility with node_access. If you could test it with DA that'd be great. I tested it with workflow_access. The current implementation doesn't work with workflow access. I think this is more robust.
Comment #22
pwolanin commentedThe main reason I had the anonymous check there and did not bypass all checkes for adminiuster nodes was to maintain the viability of doing multi-site searches. The proposed patch destroys that.
Comment #23
duozerskOk, since I started it all - here is my take on this.
I'm using the two node access modules as I need the Content Access to control the actual access and the Domain Access to have two different domains. Basically, all the content should be searchable from any domain. I'm using the Domain Access Advanced as it is recommended not to have 2 modules that are using the node_access table.
I will refer to the situation before the patch. The apachesolr_nodeaccess handles the things quite good and is able to handle the multi-site setups using the node_access('view', $node, drupal_anonymous_user()) check. This check runs fine and returns the correct information. I removed it only for the sake of simplicity as I didn't need the multi-site options.
But when the above check returns FALSE - there is a query to a node_access table:
which is when parsed and added as fields to the Apache SOLR index.
Even when using the Domain Access Advanced module there is one record in the node_access table:
and if we apply the above SQL query to this row - we will get the nodeaccess_sitehash_domain_all field added to the Apache SOLR index for all nodes that return FALSE on the node_access('view', $node, drupal_anonymous_user()) check. For me this is where it all fails (though not confirmed). So that when the subquery is being added it effectively adds the OR condition against this nodeaccess_sitehash_domain_all field which returns TRUE and all the nodes are exposed to every user.
Probably this is not 100% correct. But from looking into how the Lucene API module handles it - it doesn't query the node_access table for the rows that contain nid=0 and it works just fine. The interesting thing is that Chris wrote in comments for his Lucene API node access implementation that he got the idea on how to make it from this project.
Hope this helps.
Thank you all for you hard work on this Apache SOLR initiative, really saves time and money.
Comment #24
rooby commentedI'm trying to use apachesolr with domain access and OG. I will possibly need to add more access control later but I'll be getting this to work before I think about that.
Re #23:
I have come to the same conclusion when I looked into it.
These are the grants that get added to my search index:
When a user searches who only has access to domain_id 0 it checks:
This means that any og_public content will not obey domain access rules because it is ORing instead of ANDing
So what we need is something that says if "Check Domain Access in addition to other modules (AND)"
is selected for domain access' "Node access settings:" setting, we need to AND instead of OR.
Although I imagine this would also be a problem if you are using multiple node access modules that aren't domain access.
Is that an accurate assumption or do I misunderstand how apachesolr's filtering works (very possible :))?
Comment #25
rooby commented@duozersk
You will probably also run into problems using the domain_adv module because it doesn't store all node access rules in the node access table, so because this module checks node access by querying the node access table directly you will miss out on some of your access control.
I propose changing the title of this issue to something along the lines of "Multiple access control support". And then it would probably be a feature request too.
- Because it seems to an AND/OR issue as opposed to a domain access + content access issue specifically.
- domain_adv I would say is another case altogether because it doesn't use the node_access table for access control.
Comment #26
rooby commentedAlso, just changing all OR to AND and leaving everything else as is won't work either.
It would have to do something like (this isn't code for use but brainstorming):
Even this wouldn't work because modules don't always add all realms for all nodes.
For axample, the domain access moduel doesn't always add the domain_site realm.
So in this case it would have to be ('domain_site' = 0 OR 'domain_id' = 0) AND 'og_public' = 0
Also (this is something that does make domain access a different case to other multiple node access usage),
In the domain access module's hook_node_grants it does (line 1248 of domain.module 6.x-2.0):
So when the apachesolr_nodeaccess module calls node_access_grants() in _apachesolr_nodeaccess_build_subquery()
it gets that grant entry, which will not match anything in the database node_access table.
So all AND's will certainly not work in this case.
My node_access knowledge is not 100% so I think i'm confusing myself a bit now so I think i'll take a break from this issue.
Maybe i'll learn more about node access.
Or look into luceneapi and confirm whether or not that works as duozersk has mentioned.
Comment #27
rooby commentedI've come to the conclusion that it is pretty much not going to happen with the use of the functions apachesolr_nodeaccess_apachesolr_update_index() and apachesolr_nodeaccess_build_subquery().
I have a different approach though which works for me :D
Here is a patch that implements node access using hook_apachesolr_process_results().
It isn't a full solution yet but it is a working example to get feedback on.
If no one has any reason why doing it this way is a bad idea then I think this might be a good way to go.
Regardless, if you are using domain access & og or something this is a working solution.
If it isn't viable for apachesolr to implement this then domain_access probably should.
The patch is for 6.x-1.0-rc3 but applies to 6.x-2.x-dev with a slight offset.
Comment #28
agentrickard@rooby This is not solvable at the module level. OR checking of node grants is a well-documented core deficiency. See the "multiple_node_access" patch that comes with Domain Access for the only supported solution, and the README.txt file for an explanation.
You can also use hook_domaingrants() and hook_domainrecords() to write custom fixes for the modules you are running. (In D7, this is done with hook_node_grants_alter() and hook_node_access_records_alter().)
The lack of AND grant support in core is what prompted my comments in #16 and #18.
@duozersk Domain Access Advanced might need to remove the domain_all grant from the {node_access} table, but that isn't my module, so I can't say.
Comment #29
somebodysysop commentedAs a couple of people have pointed out earlier, apachesolr_nodeaccess is not going to work here because core Drupal node access does not support multiple access control modules itself. The only way to do it in apachesolr is by customization, but not necessarily customizing apachesolr code.
I think, in may cases, it can be accomplished by using apachesolr hooks:
apachesolr_update_index()
hook_apachesolr_modify_query()
I needed a solution which respected both OG and TAC. In addition, I needed to filter files which are marked "Private" (apachesolr_attachments). Nodes that the anonymous user can see must be both "og_public" and have a taxonomy term that allows "public" access (in my specific case, NOT "draft"). The way apachesolr_nodeaccess, and, indeed, Drupal core node access, works is to allow access if one or the other is true. I needed both rules to be respected.
I have the "multiple_node_access" patch referred to in #28 installed, but apachesolr_nodeaccess uses core logic, and therefore nodes appear in search results that should not. Below is how I resolved the issue using apachesolr hooks alone:
Needless to say, it's extremely customized to my needs, but it hopefully does demonstrate the possibility of multiple node access control using available hooks alone.
Comment #30
rooby commented- Putting status back to what it was -
Sorry, I should have mentioned before, I am using DA and OG with the multiple_node_access patch.
I understand the core logic limitation and also that the solution in #27 may not be great performance wise on large result sets but for my usage with the multiple_node_access patch it works. The main reason I posted it is to get feedback from people who know better on whether or not it is a bad idea to do this at the results stage as opposed to the query stage.
Seeing as there are so many node access modules that do their own things I agree that it isn't feasible for apachesolr_nodeaccess to be able to implent "support for multiple node access modules" and have it work for everyone, so the best thing is to use all the wonderful hooks provided and make a custom solution for oneself depending on the needs.
@agentrickard
Is it possible an issue posted to the DA queue that resolves this issue for the supported case of the multiple_node_access patch along with the "Check Domain Access in addition to other modules (AND)" setting might be considered. Or should I just stick to a custom module for my needs.
Comment #31
agentrickardCustom module. DA 6.x is closed to new features, and this type of non-core integration is always left to 3rd-party modules.
Comment #32
Scott Reynolds commentedRe #27
That patch is a very very bad thing. If i search for something, Solr module says "Solr, return to me 10 documents matching this query" and then when processing the results you remove some of them from it. So if the ten best matching documents are nodes that i don't have access too and 11-20 are nodes I do have access too, the search results page will be blank with a pager at the bottom. If i were to click page 2, it would display results 11-20 which I have access too.
And it undoubtly creates a bunch of different issues with facet blocks, current search box. Facet block might say "Taxonomy term 1 (5)" but if you only have access to 1 of those 5, you would only see one result, expecting to see 5.
Don't filter at output
Comment #33
rooby commentedThanks for the feedback Scott.
I'll go back to doing it at the indexing/query stage.
Comment #34
jody lynnI tested the patch in #13 by applying and reindexing. It's an improvement and the attached patch is a cleaned up version of it (there were some busted old $account parameters floating around in it).
I however have the added complication of using domain module with the patch to allow multiple node access systems, so the patch didn't fix my problem that search results weren't being restricted by domain. I agree that this is not core functionality though. I added my own additional hook_apachesolr_modify_query as well that along with the patch did the trick. Maybe the following could be a candidate to belong in domain module:
Comment #35
robertdouglass commentedI think we need the global $user so that we only ask for the access grants of that user, not ever user in the database:
Also, I'm honestly a bit fuzzy in the mind about what this code is doing, and whether it is doing it correctly. To my eyes it says "If the node is being updated or saved, don't mark it for being reindexed."
Comment #36
robertdouglass commentedAs for the all grants that are needed for multisite, I think we need to solve that problem when we have a multisite module. That's why it's not included in this patch.
Comment #37
pwolanin commented@Robert - a minimal multisite module (e.g. only keywords) is trivial and I was already thinking about rolling it out sometime in the next week or two.
I think I have the code in the hook_nodeapi to avoid marking the node 2x, though maybe it doesn't matter. The code in apachesolr.module will already mark it for reindexing.
The goal is to catch cases where the node access grants for one node change but it's not a normal node_save() operation.
Comment #38
robertdouglass commented@pwolanin FYI Nick Thompson is running a working multisite module #655412: Get Multisite into contrib... on 5.2, which is more or less the same code as 6.1.
Comment #39
BenK commentedNeed to keep track of this thread...
Comment #40
smithn.nc commentedSubscribe.
Comment #41
blackdog commentedWhat's the current status on this?
Is the patch in #35 the patch to review? I'm asking because with 2.x-beta2 we're experiencing issues with the Domain module, where results show up from all domains. This was not the case with 1.x though, so something has changed since then?
Comment #42
blackdog commentedFWIW - I tried the patch in #35 (manually patched), and everything looks good so far, using Domain Access.
Comment #43
tbenice commentedI have this problem using only content_access, not with DA or any other access module. I have apachesolr_nodeacess enabled but the search does not seem to respect content_access settings.
have apachesolr_nodeaccess 6.x-2.x-dev
Trying patch in #13.
---EDIT---
No change, content types still show in list without proper access.
---EDIT---
Had to re-index. Sorry about that, I always forget that step. Seems to work fine for this version.
Comment #44
blackdog commentedWe're running the patch from #35 in production and haven't seen anything wrong, so I would say it's ready. Probably needs a re-roll, but I can't help with that right now.
Comment #45
dixon_Here is a reroll that should apply to 6.x-2.x. I can't get it to work properly, though. The search doesn't seem to respect the node access rules. Clicking on one of the results (that I should not be able to see) gives me a "Access denied" which proves that my node access rules should be in order.
@blackdog: Hej! What version of apachesolr do you run?
Comment #46
blackdog commentedHej!
We're running 2.0-beta2 at the moment, with the patch from #35/#45.
Did you re-index your site after the patch was applied?
Comment #47
dixon_Yeah, we've reindexed the site and even tried to delete the whole index to start from the beginning. I've started to believe that there is something other that is wrong.
Comment #48
dixon_But I would like someone to review and test the rerolled patch in #45 to see if they experience the same thing.
Comment #49
dixon_The problems we encountered was not because of ApacheSolr. It was a weird bug in one of the node access modules we were using. That module is now thrown out of the window.
The patch in #45 is rerolled against 6.x-2.x and works great. The node access system is taken into account! This one is good to go imo!
Comment #50
pwolanin commentedThis seems to destroy some of the existing functionality, especially in terms of supporting multi-site search.
Can you explain the changes in more detail?
Comment #51
robertdouglass commentedI also rerolled - am using this patch for current testing.
Comment #52
robertdouglass commented@pwolanin, I need to test the attached patch against a number of node access modules. After doing that I'm going to look at the multisite search issue. The main benefit of the code in the patch is simplicity.
Comment #53
robertdouglass commentedPatch didn't attach
Comment #54
blackdog commentedFWIW - I don't really see why multi site search and the node access system is handled by the same code. If people want multi site search, I believe that should be a separate module, just as people needing node access capabilities.
Comment #55
robertdouglass commented@blackdog, I agree with this, and that's why the current proposed patch rips that element out. It's still instructive to understand how the problem is to be solved, though, even if the solution finds its way into the apachesolr_multisite module.
Comment #56
nick_vhIs this still the case with the 7.x-1.x version? If so we should handle it as priority
Comment #57
agentrickardI tested Acquia (SOLR) Search with Domain Access (7.x-3.1) recently with no issues.
Comment #58
nick_vhComment #59
nick_vhComment #60
barwonhack commentedIts my experience that Domain Access search settings are not respecting the "Search content for the current domain only" option.
(Apache Solr framework 7.x-1.1 & Facet API 7.x-1.2 & Domain Access 7.x-3.7-dev)
Comment #61
nick_vhPlease open a new issue, this is a very old issue. In your new issue, describe the complete setup and where it fails to work. Thanks