Hi,
i use Search by page and ACL (http://drupal.org/project/acl).

Search by page indexes a user role. If I start to search with uid == 1 the searched user is found. Everything is fine.

The problem is that a guest (or every body else who is not uid==1) is not able to find anything. All users have the permissions to view profiles, use search by page and use the normal search.

If I remove ACL the guest works fine too.

Is it a bug?

Thank you.

Comments

jhodgdon’s picture

Status: Active » Postponed (maintainer needs more info)

The ACL module page says it is used as a helper for other modules. Are you using another module with it? If not, I would say just disable ACL. I'm not familiar with what ACL does or how it does it, but if it's interfering with Search by Page and you don't need it, why would you want it enabled?

Anyway... it also looks like ACL is only for node access, but you are using Search by Page to index/search user profiles... so I have no idea why it would interfere unless you are using some module that puts nodes on user profiles?

userID-1’s picture

I use an other module which needs ACL. The other module is not the problem. I tested a new drupal installation with only Search by page and ACL and is does not work.

ACL deletes one row in the sql table 'node_access'. The row looks like the "everyone is allowed to view published content" rule. If I put the row manually back in to the table Seach by page works but ACL and the other module are not able work.

I have no module which puts nodes on the userprofile.

jhodgdon’s picture

Huh. That is very odd, because Search by Page, if you are only using the Users sub-module, should not depend on node access at all. Can you let me know what you did to test SBP with ACL on your test installation: what you did, what you expected to happen, and what happened? That will save me some time running the same tests at least.

userID-1’s picture

My test was:

1. Install Drupal 7
3. Add a new text field to user which is displayed on the user profile.
2. Add new User
4. Add text to the new text field which can be searched
5. Install Search by page
6. Configure a new enviroment which indexes all users (the user used to index is authenticated user)
7. add new Search by page block to the header.
8. edit user permissons (everyone can view user profiles, use search, use search by page)
9. run cron
10. search the text which was added in step 4 with uid==1
- the new user shoud be found --> Yes the user is found
11. search with guest user
- the new user shoud be found --> Yes the user is found
12. install ACL (and rebuild permissions)
13. search the text which was added in step 4 with uid==1
- the new user shoud be found --> Yes the user is found
14. search with guest user again
- the new user shoud be found --> NO!!! Nothing is found.
15. remove the ACL module (uninstall)
16. search with guest user again
- the new user shoud be found --> YES works!

jhodgdon’s picture

Title: User seach and ACL » User search fails with ACL module enabled
Status: Postponed (maintainer needs more info) » Active

That is very odd. Again, ACL is only supposed to affect node permissions, and Search by Page the way you are using it should not be dependent at all on node permissions. Anyway, thanks for the detailed information, and I'll see if I can figure it out at some point.

Just to confirm: after step #12, if you are not logged in, and try to view the "new user" profile, you can see all the information on it, correct? [EDITED - I misread what you said above... when you say "guest user" you mean someone that is not logged in I am assuming?]

userID-1’s picture

Yes guest ist somebody how is not logged in. The guest-user is able to see profile correctly.

userID-1’s picture

Hi,

I looked at the db-queries which sbp executes.

I think this is a nomal spb query to find something. right?

SELECT SUM(i.score * t.count) AS calculated_score
FROM 
search_index i
INNER JOIN sbp_path sp ON i.sid = sp.pid
LEFT OUTER JOIN node sbpn_n ON sbpn_n.nid = sp.modid
LEFT OUTER JOIN users sbpu_u ON sbpu_u.uid = sp.modid
INNER JOIN search_total t ON i.word = t.word
WHERE  (sp.environment = :db_condition_placeholder_0) AND (sp.language = :db_condition_placeholder_1) AND(( (sbpn_n.status = :db_condition_placeholder_2) AND (sp.from_module = :db_condition_placeholder_3) )OR( (sbpu_u.status = :db_condition_placeholder_4) AND (sp.from_module = :db_condition_placeholder_5) ))AND( (i.word = :db_condition_placeholder_6) )AND (i.type = :db_condition_placeholder_7) 
GROUP BY i.type, i.sid
HAVING  (COUNT(*) >= :matches) 
ORDER BY calculated_score DESC
LIMIT 1 OFFSET 0

this query was executed with acl off.
after acl is activated the query looks different:

[LINE 1****] SELECT DISTINCT SUM(i.score * t.count) AS calculated_score
FROM 
search_index i
INNER JOIN sbp_path sp ON i.sid = sp.pid
LEFT OUTER JOIN node sbpn_n ON sbpn_n.nid = sp.modid
LEFT OUTER JOIN users sbpu_u ON sbpu_u.uid = sp.modid
INNER JOIN search_total t ON i.word = t.word
[LINE 8****] INNER JOIN node_access na ON na.nid = sbpn_n.nid
[LINE 9****] WHERE  (sp.environment = :db_condition_placeholder_0) AND (sp.language = :db_condition_placeholder_1) AND(( (sbpn_n.status = :db_condition_placeholder_2) AND (sp.from_module = :db_condition_placeholder_3) )OR( (sbpu_u.status = :db_condition_placeholder_4) AND (sp.from_module = :db_condition_placeholder_5) ))AND( (i.word = :db_condition_placeholder_6) )AND (i.type = :db_condition_placeholder_7) AND(( (na.gid = :db_condition_placeholder_8) AND (na.realm = :db_condition_placeholder_9) ))AND (na.grant_view >= :db_condition_placeholder_10) 
GROUP BY i.type, i.sid
HAVING  (COUNT(*) >= :matches) 
ORDER BY calculated_score DESC
LIMIT 1 OFFSET 0

What has changed?
- line 1 add: DISTINCT
- line 8 add: INNER JOIN node_access na ON na.nid = sbpn_n.nid
- line 9 (in the end) add: AND(( (na.gid = :db_condition_placeholder_8) AND (na.realm = :db_condition_placeholder_9) ))AND (na.grant_view >= :db_condition_placeholder_10)

I think acl applies some rules that make only sense for the node-search.

Do you see a way to fix it?

jhodgdon’s picture

Title: User search fails with ACL module enabled » User search in Search by Page fails with ACL module enabled [node access queries not working with left joined tables]
Project: Search by Page » ACL
Version: 7.x-1.2 » 7.x-1.x-dev
Component: Search by Page Users module » Code

Ummm... It looks like the ACL module is just adding standard access control to the part of the query that is doing node searching... However, it should not be doing an inner join in this case, but a left join.

I had a similar problem in the node access query stuff that the API module was adding to queries. Maybe you can point the ACL people towards this issue so they can fix their node access query modification in a similar way:
#1549188: API node access query alters are too restrictive for left joined tables

Since this is an ACL bug and not a Search by Page bug, I'm moving this over to the ACL module's issue queue. I'm happy to provide more information to the ACL maintainers if that issue doesn't explain everything...

salvis’s picture

From #2:

ACL deletes one row in the sql table 'node_access'. The row looks like the "everyone is allowed to view published content" rule. If I put the row manually back in to the table Seach by page works but ACL and the other module are not able work.

ACL does not do that. Drupal core removes that record when you install any node access module. Your second step in determining ACLs role in this (after the analysis in #4) is to uninstall ACL and its dependent, verify that the row is back, and install any other node access module. Core will again remove the free-to-all row and replace it with node-specific rows (upon rebuilding permissions).

What effect does that have on Search by Page?


I'm not convinced that this is an ACL bug. We have close to 6000 D7 sites running ACL without any problems. It's hard to believe that we should have such a fundamental bug in ACL.

Moreover, ACL does not do any query altering on its own. It relies completely on core's _node_query_node_access_alter() to do that. This is where the join is done.

Jennifer, have you tried addMetaData() according to http://drupal.org/node/1204572 ?


DISTINCT SUM(i.score * t.count)

I doubt this can work at all with node access. I think you need to resort to a subquery to perform the node access part.

jhodgdon’s picture

The node access table analysis is correct...

I am not sure I have tested Search by Page with a node access module -- it's possible that it's a core bug in that case. The node access query alter should not be assuming that the node table can be inner joined to, and not break up the table.

Search by Page doesn't have the meta-data... but it shouldn't matter, because the node table *is* joined in the query, and the code in _node_query_node_access_alter() that finds the base table if the meta-data isn't added will find it.

So maybe this is a core bug and not ACL? It shouldn't be adding an inner join to the query if the node table is only left joined in, should it? That will make *all* the results vanish from the query, whereas it should just be excluding rows from the node table's part of the results in this case.

jhodgdon’s picture

Issue summary: View changes

-

salvis’s picture

Issue summary: View changes
Status: Active » Closed (works as designed)

Did I drop the ball on this or has it been resolved?

Feel free to reopen if needed.