This was the error I was recently faced with when I re-enabled user registrations here on the DeeEmm site.
You may recall from my last blog post Virtuemart Revisited that I have recently re-installed Virtuemart so that I can sell some extensions via a store front right here on the site. As part of my testing I run through the usual user experience to check that things work as they should and found that after registering a user, confirming the account and then being enabled by an administrator the 'You cannot access the private section of this site.' message was displayed and the new user could not log in.
Hmmnnn, not good.
So I check the ACL to ensure that the 'registered' user level has login access to the site. All good there so that isn't the issue. I then turn to Google to see what that turns up and find that most of the solutions given relate to the ACL permissions.
Hmmnnn, so what next?
A bit more digging and I find that this was a common error when migrating from 1.5, which is exactly what I had done, albeit at some point in the distant past. Obviously this had never been raised as an issue as I did not have user registrations enabled but now that I needed to reenable them it was time to fix the problem.
The cause of the issue is somewhat odd and is related to the #__assets table. The assets table stores the relational data that is used to determine the parent > child relationships of all site content. Normally the top level entry is the 'Root Asset' with a parent_id of 0 along side the top level categories which may also have a parent_id of 0. The issue arises if there are any articles that have a parent_id of 0, for some reason this messes with the permissions engine and will not allow normal users to log in.
It's pretty easy to check by either browsing to the #__assets table in phpMyAdmin and filtering the results on the parent_id field or by simply running the following SQL Query.
SELECT * FROM `#__assets` WHERE `parent_id` = 0
The fix is equally as simple, or at least it can be if you want to assign all the stray articles to a single category. Simply run the following SQL Query and replace the parent_id value with the id corresponding to the category you want to assign the rogue articles to
UPDATE `#__assets` SET `parent_id` = 1 WHERE `parent_id`= 0 AND NOT `id` = 1
This will update all records except the very first record which should be the aforementioned 'Root Asset'
You can verify that the Root Asset still has correct parent_id by running the following SQL Query
SELECT * FROM `#__assets` WHERE `id` = 0 OR `parent_id` = 0
This should return just the Root Asset record. If for some reason it does not you can correct this and set parent_id back to 0 with the following SQL Query
UPDATE `#__assets` SET `parent_id` = 0 WHERE `title = "Root Asset"
I opted to manually trawl through my records and assign each item to the correct category but I only did this as I have a variety of articles in a variety of categories and only about a dozen or so entries that needed fixing. The end result was that a plethora of articles that had been MIA for some time suddenly appeared back in the tutorials section. The mismatched parent_id value was actually preventing the articles from showing.