Fine-tuning user profile permissions
jim0203 - August 11, 2009 - 16:47
In D6, is there a way to fine-tune permissions related to user profiles? By default there only appears to be one permission - "view user profiles" - and I'd like users to only be able to view their own user profiles, or only view profiles which users have marked as public in some way.
I have a feeling that I've seen permissions like this listed before - is there a module that adds them? I might be wrong, of course; if that's the case then I'm happy to write a module which adds finer-grained user profile permissions.

Haven't found it myself
I've been looking around for something like this and haven't found it. The closest I've found is Profile Permission (http://drupal.org/project/profile_permission) but it's slightly different.
I'm trying to make role specific access to user profiles so that anonymous users can only access the profiles of certain users (based on their role). Additionally (and this seems to be what the profile permission does work for) each specific role would have different fields.
I'm not sure how similar or different what I'm after is to what you are looking for but I was intrigued when you said you would write a module. I've been looking for fine grained user profile permissions for a while and there isn't much out there. Please post if you find something or build it.
Profile Permission seems to
Profile Permission seems to limit access to profile fields, a bit like the similar CCK module - so it seems we're still in need of a module that will allow/deny access to user profiles as a whole.
I am happy to write this module - I think it would be quite useful to a lot of people. I'm not sure how the user profile access sytem works (when I originally said I'd write a module I thought I'd be able to do it like a node access module but I don't think this is the case) but I'll try and work it out.
I think we should use this thread to work out exactly what the module needs to do. I'm guessing, for starters, that it should create a permission titled "view user accounts for users with role xxx" for each user role.
You're exactly right. I
You're exactly right. I think that the profile permission module has a place because it is quite useful to be able to customize user data based on role. I only say this to suggest that I would hope that whatever functionality this module would create would work in conjunction with the profile permission module (or add that functionality internally though I think that's much more work). I also just came across profile role module (http://drupal.org/project/profile_role - which seems very similar to profile permission except with profile categories but I haven't tested it yet).
In my mind, this is what we would be talking about:
Assume 3 users, 'a', 'b', and 'c' with three separate roles - anonymous, 'b' and 'c'.
user -> accessing profile of user -> result
'a' -> 'b' -> no access
'a' -> 'c' -> 'c' profile
'b' -> 'c' -> 'c' profile
'c' -> 'b' -> 'b' profile
If it helps to describe it, assume 'a' is anonymous, 'b' is a user, and 'c' is a staff member.
Now here is where it gets a little complicated (for what I'm looking for anyway). I would also like to limit whether or not 'b' can see other members of that role. Thus if we were to limit seeing profiles to just 'b' and 'c', all members of 'b' role would be able to see other members of 'b' role. I'd like for them to only be able to access their own profile, not those of other members of the role. Thus we would need an access permission system that allows a user of a role viewing access to the profiles of another specified role and a separate permission that allows them access to themselves. These are all viewing permissions, not editing permissions. I don't know if access to editing/viewing oneself is inherent in drupal or not, but I imagine that if we start limiting it, there is the possibility of conflicts. (I'm also not speaking specifically to "change own username" permission as that is different than being able to edit one's own profile.) I would think that roles with "administer users" would still be able to edit all users. I believe that is what Administer Users by Role does (http://drupal.org/project/administerusersbyrole), but I haven't played with the module yet.
Does all this make sense? I can clarify in necessary. Is it inline with what you are after?
That is very similar to what
That is very similar to what I am looking for. The way I envisage the module working is that it will add in a number of new permissions, which can then be allocated to users on a per-role basis.
For example, if a site had user roles "user", "editor", and "administrator", the following permissions would be added and could be allocated role-by-role:
view own user profile
view user profiles for users with role "user"
view user profiles for users with role "editor"
view user profiles for users with role "administrator"
edit own user profile
edit user profiles for users with role "user"
edit user profiles for users with role "editor"
edit user profiles for users with role "administrator"
delete users with role "user"
delete user profiles for users with role "editor"
delete user profiles for users with role "administrator"
block users with role "user"
block user profiles for users with role "editor"
block user profiles for users with role "administrator"
This is fine in theory, but there is a limitation in Drupal's architecture which means that writing this module will not be as easy as I had assumed - it will probably require a patch to core. The reason for this is that there is no API (or, at least, I can't find one) that deals with accessing user profiles. With nodes there is a table in the Drupal database called node_access which can be written to and read from using a couple of hooks. Whenever a user does something to a node (i.e. views, edits or deletes the node), Drupal checks this table and sees if the user is allowed to do what they are trying to do. All of this is built into node.module; there is no similar functionality with user.module, where the permissions are just hard-coded.
I have posted a support request for user.module at http://drupal.org/node/548230 so I guess it's just a matter of waiting for those guys to get back to us. In the meantime we can continue sketching out what the module should do. I think it might even be possible to add an extra line to user.module which will provide a basic API.
As for whether this module should be part of profile_role or a new module in its own right, I think it should be developed on its own to start with, as that will get the required functionality available as quickly as is possible. We can then merge the modules if necessary.
I agree with making it a
I agree with making it a module of its own. And your description of control would be great.
If we add an extra line in user.module, the one concern would be security issue. I wonder if that is what has been holding up this type of development. I don't know enough to give insight one way or the other. What are you thinking in terms of modification?
The patch I have in mind
The patch I have in mind would essentially call a function that was present in the custom module. That function would return either TRUE or FALSE; if it returned TRUE then access would be granted; if it returned FALSE then access would be denied.
I'm not an expert on security but lots of Drupal people are; I'm sure we could find someone to vet the code.
That sounds great. Anything
That sounds great. Anything I can do to speed up or help the process along?
Nope, it's fine. I don't see
Nope, it's fine. I don't see it taking too long and I could do with a break from my current project (which I've been on for about a million years and is close to killing me :-P).
I'm going out now but I might make a start on this when I get back in. I'll let you know when I've got something.
I'm not sure how the guys who maintain user.module are going to react to this but they haven't responded to my support request yet so I guess we just press on.
dev release 0.0.0.1
See http://state68.com/content/fine-grained-user-profile-permissions and pay heed to the warnings!
Note that you need to patch your user.module to get this to work. Once user.module is patched it should work with or without the new module installed. The patch works agains 6.13. See http://drupal.org/patch/apply for instructions on how to apply patches, if you need them.
This really is a very hacky version but the "view user profiles of users who have permission xxxxx" stuff seems to work. Is this heading in the right direction? It's partly up here so that other people can see it and shout at me if I'm doing something really bad - I'll upload newer versions as and when I've written them.
Most certainly not for production sites!
It looks good, but I have a
It looks good, but I have a few questions...
What does the "block users..." do differently than not having the access do? It seems like it's a white list versus black list approach, but couldn't having both create internal conflicts of access permission?
What does "ONLY THE VIEWING PERMISSIONS WORK" do?
The module seems to allow access to the user profile generally, but not to any custom profile fields or even general profile fields other than name. In other words, if I go to user 'a' as a person with greater access (access granted via stock user permissions) I see the whole users profile. But if I go to a user as a visitor, I only see their name and history. Does this have to do with whether the field is public or private? I think that may be the case...
I'll keep playing with it.
Any user with the "block user
Any user with the "block user with role a" permission would be able to block any user accont which has role "a". It is possible to block a Drupal user account to prevent that user logging in; the extra permission that I've added means that it would be possible, for example, for "admins" to block "editors" but not vice-versa.
The "ONLY THE VIEWING PERMISSIONS WORK" doesn't do anything - it's just there to tell you that "ONLY THE VIEWING PERMISSIONS WORK" :-) - in other words, only the permissions that start "view user profiles for users with role..." do anything.
With regards to your last question, I think that is based on whether the field is public or private.
I've not been able to spend any time on this during the past week and I'm at Drupalcon in Paris all this week, but I might see if I can find an hour or two - and a user.module guru - to do some work on this. Otherwise I'll be able to add some more stuff next week.
What about ACL?
Instead of hacking Core and possibly causing yourself some grief, why not hang this off an existing module?
ACL provides and API for access control lists, which might do what you want, for example?
At any rate, what you are doing is checking a users permission to view or edit a node, then probably doing a goto if they dont have the right permissions. I don't think this requires a core hack.
It could be something like defining hook_node_api() for view or edit, checking the permission, then using drupal_goto if they dont have the required perms.
xtfer.com
Does hook_nodeapi() or ACL
Does hook_nodeapi() or ACL work with user profiles as well as nodes? What we are trying to achieve is some degree of control on the CRUD for user profiles, which AFAIK do not work like nodes. I can't find any API or hook that would let me get at user profiles in this way, so I guess I'm trying to build one.
I don't think it does... A
I don't think it does... A solution that I'm considering is to create a node content type that will act as a placeholder for ACL. These control lists are really only useful for lists (i.e. user search) since checking the database for the user's visibility preference is pretty easy when viewing one profile at a time (assuming you're building a custom module).
Has anyone else tried this before?
I'm struggling a little to
I'm struggling a little to understand what you've written here. Do you intend to create a node type which is associated with a user account (via content profile module) and then use this node type to limit access to the user account via the standard node access methods?
If so, I'm not sure this is a great solution - wouldn't it still allow access to the standard user account page?
I will be putting some time into developing this soon, but have just got back from Drupalcon and have a big project to finish by the end of the month, so have lots of stuff to wade through first.
--Jim
custom user-profile.tpl
i was discussing using this change with a friend and he suggested creating a custom user-profile.tpl page instead of actually hacking the user.module. what do you think of that approach? the module you came up with works, but i am a bit concerned about putting it on a production site given that it requires modifications to the core. i just don't know enough about programming to feel confident from a security standpoint. what do you think of adding this kind of check to a custom user-profile.tpl? the idea would be that the current user role is checked and given the result, the page is populated accordingly.
That could be a better way to
That could be a better way to go - certainly better than hacking core (ultimately I want user.module patched in core, but that's a long journey I think).
Could you ask your friend whether he means that we write a module that includes two custom user-profile.tpl.php pages, so that a user who is allowed to view a profile views one of the pages, and a user who isn't views another of the pages - with the second one being blank?
Or better still, get your friend to post directly to this thread :-)
I'm not sure this would really help with the editing permissions (which I need for my own purposes) but it could be a step in the right direction.
I'll be getting this sorted in the next few days, by the way, so watch this space!
user-profile.tpl.php
Hey Jim, I'm working with Jaron on this setup. Our friend that made the suggestion said this:
"I was just saying put a validation check in user-profile.tpl.php
and deciding what info is displayed in the template there"
Does that make sense to you?
I'll try to get him to respond directly to this, but he is usually inundated with his current projects.
Thanks - Phil
Phil - yes, this would be a
Phil - yes, this would be a good way to solve the visibility issue at least - the editing issue, etc, will be a bit more tricky. Should be able to knock this up with a custom module that allows you set appropriate permissions; then creating user-profile.tpl.php is easy. I'll get back to you soon - project just launching so will have more time very soon!
I just found
I just found http://drupal.org/project/administerusersbyrole which does part of what we need - I'll get in touch with the dev and see if he can shed any light on the other bits we need implemented.