Opened 15 years ago
Closed 4 years ago
#10201 closed enhancement (wontfix)
Remove user-specific caps
Reported by: | Denis-de-Bernardy | Owned by: | |
---|---|---|---|
Milestone: | Priority: | normal | |
Severity: | normal | Version: | 2.8 |
Component: | Role/Capability | Keywords: | dev-feedback close |
Focuses: | Cc: |
Description (last modified by )
See IRC discussions from June 18th 2009
- The current role system is rather complicated, But has a lot of flexibility
- A lot of the flexibility isn't even used by most (ie. the ability to have a user with a Roll + a single capability)
- The role system starts having trouble with a high number of users
- To look up every user with a certain cap. it requires loading all the users, and then checking individually.
The proposed changes are:
- That we reduce the complex system to something much more simple:
- Roles are retained: 1 role per meta entry, and since the meta API allows for multiple values for the same key, this would have the benefit of multiple roles, and direct lookups.
- However:
- Remove the ability for a user to be part of a Role, and have an extra capability added on top of that.
- This has the ability to significantly increase performance, As now:
- Looking up users with a specific cap is easy:
- Filter the role list for roles with that cap
- SQL the usermeta table for users in those roles
- Select those users (if needed, else return the ID's)
- Looking up users with a specific cap is easy:
- An upgrade path is available which doesnt require extra tables, and reduces the ammount of serialization
- The other option is a whole new set of tables.. which.. those who are sane (And there are some insane people in WP Dev..) realise that its not really needed.
- Fine grain control has never been possible from WP without a plugin, Nothing would change here, If a user wants fine grained control over permissions, They'd still have to run a plugin, Its just that that plugin may have to do more heavy lifting now -- since wordpress's API/role system would be simpler and not support the extra fangledangles.
Attachments (1)
Change History (79)
#1
@
15 years ago
- Component changed from General to Role/Capability
- Owner set to Denis-de-Bernardy
- Status changed from new to accepted
#2
@
15 years ago
so, basically, the consensus is:
- drop multi-role support
- drop user-cap support
- single-role on users
- drop true|false thingy on has _cap|hsn't_cap (use role stuff instead)
- make it so that user roles can be queried easily (we'd use a meta field with the role's key here)
leaving this open for a week or two without touching it, so that sam can take a look if needs be.
#6
@
15 years ago
I use a shared wordpress user table with 2 installs and some users can post with one but not the other would that effect this?
#7
follow-up:
↓ 10
@
15 years ago
Denis,
vB does a very good job of user-permissions/user-groups. Maybe we should look into that way as well for WordPress.
#8
@
15 years ago
- Keywords 2nd-opinion added
I use a shared wordpress user table with 2 installs and some users can post with one but not the other would that effect this?
No, As long as users have separate roles per blog.
This tickets been created rather badly; Just a placeholder with a tonne of logs which cant be read anyway.
My points from what i know:
- The current role system is rather complicated, But has a lot of flexibility
- A lot of the flexibility isn't even used by most (ie. the ability to have a user with a Roll + a single capability)
- The role system starts having trouble with a high number of users
- To look up every user with a certain cap. it requires loading all the users, and then checking individually.
The proposed changes are:
- That we reduce the complex system to something much more simple:
- Roles are retained,
- However:
- Limit users to 1 role (This would be on a per-blog basis, based off the permission prefix thinggi..)
- Remove the ability for a user to be part of a Role, and have an extra capability added on top of that.
- This has the ability to significantly increase performance, As now:
- Looking up users with a specific cap is easy:
- Filter the role list for roles with that cap
- SQL the usermeta table for users in those roles
- Select those users (if needed, else return the ID's)
- Looking up users with a specific cap is easy:
- An upgrade path is available which doesnt require extra tables, and reduces the ammount of serialization
- The other option is a whole new set of tables.. which.. those who are sane (And there are some insane people in WP Dev..) realise that its not really needed.
- Fine grain control has never been possible from WP without a plugin, Nothing would change here, If a user wants fine grained control over permissions, They'd still have to run a plugin, Its just that that plugin may have to do more heavy lifting now -- since wordpress's API/role system would be simpler and not support the extra fangledangles.
(Actually, Just note that those thoughts there in the 2nd list are just my opinion, and the method which i support. Others would suggest different methods)
The fine details will be worked out over the coming weeks.. It was raised after the weekly dev meeting on IRC today yesterday for some), probably be discussed again next meeting, so anyone's thoughts posted here in the meantime will be read. No firm decision has been made.. but it seems like most of those there agreed that something needed to change, Its just deciding on the exact way in which the role system will change.
2nd-opinion as, as much feedback possible is wanted :)
#10
in reply to:
↑ 7
;
follow-up:
↓ 12
@
15 years ago
Replying to ShaneF:
Denis,
vB does a very good job of user-permissions/user-groups. Maybe we should look into that way as well for WordPress.
Can't find the sql dump of my old VB install, but I vaguely remember it was using role/caps related DB tables. If so, that's pretty much exactly what Matt didn't want...
#12
in reply to:
↑ 10
@
15 years ago
Replying to Denis-de-Bernardy:
Replying to ShaneF:
Denis,
vB does a very good job of user-permissions/user-groups. Maybe we should look into that way as well for WordPress.
Can't find the sql dump of my old VB install, but I vaguely remember it was using role/caps related DB tables. If so, that's pretty much exactly what Matt didn't want...
vB uses a bitfield permissions system.
1 = read forum
2 = post threads
For me to have both I have a value of 3. Also assigned a permissions to a group could have the same set of permissions and then put users in it. As well as helping loading time with SQL queries to load all that information once at the start instead of each time that it's needed.
#13
@
15 years ago
sounds tricky. to do that properly, we'd likely need an extra db field that contains a big int. the users table is to be ruled out for that field since caps are on a per site basis.
also, it's not as pluggable as using varchars for caps. we'd end up limited by the size of the db field, not to mention the loads of potential conflicts between plugins that try to introduce caps.
#14
@
15 years ago
Can someone paint a picture on the old and the new structure and upload it here? i guess this will clarify a lot and it would be easier to identify current and upcomming shortcummings.
after having a useable concept then, it will be far easier to discuss on how to code it and how the data looks like.
#15
follow-up:
↓ 16
@
15 years ago
@hakre:
The current system goes:
- users can have multiple roles
- roles can have multiple caps
- users can have multiple caps that override those of roles
- roles and their caps are stored as a serialized array in the options table
- for each user we store the roles, and caps, as a serialized array in the user_meta table
- to get all users who have a role or a cap, we query all users in the db, and filter out those that don't have the cap
The one initially suggested in IRC would have gone:
- users can have multiple roles
- roles can have multiple caps
- users can have multiple caps that override those of roles
- roles and their caps are stored in newly created tables
- for each user we store the roles, and caps, in newly created tables
- to get all users who have a role or a cap, we use these newly created tables (5 of them)
The one we ended up concluding we'd want is this instead:
- users can have one role
- roles can have multiple caps
- roles and their caps are stored as a serialized array in the options table
- for each user, we store the role as a varchar in the user_meta table
- to get all users with a role or a cap, we query the user_meta table directly
#16
in reply to:
↑ 15
@
15 years ago
- roles and their caps are stored as a serialized array in the options table
We should retain the ability to define the roles array in memory. Currently WP_Roles checks for a global, $wp_user_roles, and uses that if defined. WP_Roles should abstract storage so the options table, the site options table, memory, or whatever can be used.
#17
@
15 years ago
Thanks Denis for the info, I really appreciate it. Caps bound to Roles is good. Storage I would completely ignore in the design-phase. So +1 one for abstraction, it can be improved later on, like ryan suggested.
The modell then is: User -> Role -> Caps.
What should the code actually do to verify if a request is valid? Querie Caps or Roles? My answer is Caps. Roles are not to queried any longer. Role only exist to manage Capabilities of a User.
#18
@
15 years ago
Another idea is to create a list of currently existing, user/cap related functions to get an overview of what can be condensed.
#20
@
15 years ago
Started a list of Classes/Functions/Globals (will attach as plugin zipfile) and started to document more data here: http://codex.wordpress.org/User:Hakre/Switch_roles_to_use_single_role,_and_no_user-specific_caps
#24
@
15 years ago
Discussed on the 22/July/UTC WP Dev meetup on IRC.
See 22:30 onwards: https://irclogs.wordpress.org/chanlog.php?channel=wordpress-dev&day=2009-07-22&sort=asc#m13244
#25
follow-up:
↓ 26
@
15 years ago
We experience poor performance on large usermeta tables in bbPress due to the way roles are stored. However, I overcame most of the issues with a plugin (and a single table). Might be a good reference.
http://bbpress.org/plugins/topic/user-roles-table-for-bbpress/
"The other option is a whole new set of tables.. which.. those who are sane (And there are some insane people in WP Dev..) realise that its not really needed."
Storing the role as a "varchar" in the usermeta table will require an additional column in the wp_usermeta table as current meta_value column is "longtext". If that change doesn't happen then the roles will still be non-indexed and there will be little or no speed improvement over doing a "LIKE" query on the existing serialised arrays. We might prefer a single additional table in the end instead (speed, storage and sanity wise it's a better option).
Also, the capabilities in bbPress are hardcoded (not stored in the DB at all), but pluggable. Which hasn't hindered usage of them in the slightest.
#26
in reply to:
↑ 25
@
15 years ago
Replying to sambauers:
"The other option is a whole new set of tables.. which.. those who are sane (And there are some insane people in WP Dev..) realise that its not really needed."
Storing the role as a "varchar" in the usermeta table will require an additional column in the wp_usermeta table as current meta_value column is "longtext". If that change doesn't happen then the roles will still be non-indexed and there will be little or no speed improvement over doing a "LIKE" query on the existing serialised arrays.
actually, there will. like is slower than =, and the meta key is indexed. but agreed on the note.
the issue, however, is that we can't really add this in the users table either -- we'd need an extra column *per* site, unless the roles are shared across all sites. that would be a much more major change, but not necessarily a bad one.
bottom line is, from a performance standpoint, a new table with an actual join would be *much* better, but probably not desired as things stand. we could bring this up during the next WP meet-up, though.
#27
@
15 years ago
the issue, however, is that we can't really add this in the users table either -- we'd need an extra column *per* site, unless the roles are shared across all sites. that would be a much more major change, but not necessarily a bad one.
Why not just prefix the metafield like is currently done for each install? Remember that shared usertables do not have the DB prefix on them, but the capability keys are prefixed by each blogs prefix, ie wp_, wp_1_, wp_2_ etc
#28
@
15 years ago
oh we'd need to do that no matter what with the current plan. I was just answering sam -- he's highlighting (rightly so, too) that since the column's contents isn't indexed, it's only a slight gain, rather than a huge one, when compared to an actual roles table.
#29
follow-up:
↓ 30
@
15 years ago
I don't understand the "extra column per site" requirement. I was saying that to make things fast you would need an extra column in wp_usermeta that was a varchar so that the meta_value on "XX_capabilities" keys could be stored there instead (and indexed).
But doing that is clutter and ultimately slower than a small separate table like:
CREATE TABLE `wp_userroles` ( `user_id` bigint(20) unsigned NOT NULL default 0, `role` varchar(32) NOT NULL default '', KEY `user_id` (`user_id`), KEY `role` (`role`), UNIQUE KEY `user_id__role` (`user_id`, `role`) );
Which can be a site specific table too, so in WPMU you could have one for each site, e.g.
wp_1_userroles wp_2_userroles wp_3_userroles etc.
Which limits their size and also makes for better portability.
This is how the plugin for bbPress handles multiple sites in TalkPress.
#30
in reply to:
↑ 29
@
15 years ago
Replying to sambauers:
I don't understand the "extra column per site" requirement. I was saying that to make things fast you would need an extra column in wp_usermeta that was a varchar so that the meta_value on "XX_capabilities" keys could be stored there instead (and indexed).
If you've a WP install and a BB install, you've two separate roles/caps. So the correct implementation would be a roles table per site, as you highlight. Rather than two extra columns in the users table.
#31
@
15 years ago
I really tend to seperate the database/storage layer from the actual model that is used. This will help us to improve the db implementation later on. Most of the discussions right now are mostly about the database layout.
#32
@
15 years ago
after thinking about the whole new roles thingy I the last days, I must say that for the model it's absolutely unimportant wether or not you can assign multiple roles to a user or not. the users capabilities are nevertheless multiple ones so therefore why not to have multiple roles which cover the single role as well.
this can help plugins (bbress) that add roles on their own. the roles system should (must) be re-useable for plugins as well, even for larger ones, otherwise this all does not scale well.
if you've problems to handle multiple roles for the storage layer of the new model, then you might want to re-think how you store stuff. this should not be a show-stopper at all.
#34
@
15 years ago
- Cc apljdi added
Added my +1 for most of this discussion.
The only thing I don't like about the proposed changes is the "no user-specific caps" parts. I use this feature extensively. If I didn't have it I'd be doubling the Roles on one of my sites, and I've already doubled the Roles that ship with WP. Since these extra Roles would be identical, save one or two caps, to already existing Roles that seems pointless. I also have a case where a user needs to be in a particular Role because that is here primary function on the site but that user is also the site, and business, owner and so needs far more permissions than the average user in the role. I could assign multiple Roles but since that is going away, that won't work for long.
It occurs to me that I may be looking at this backwards from some of you, maybe even most of you, in thinking of capabilities as being primary and roles as being a secondary but useful and convenient way to group capabilities.
#35
follow-up:
↓ 36
@
15 years ago
It occurs to me that I may be looking at this backwards from some of you, maybe even most of you, in thinking of capabilities as being primary and roles as being a secondary but useful and convenient way to group capabilities.
You're floating between both..
Roles are primary to group capabilities to a user, And giving a user a cap is a secondary thing, if the role doesnt manage 100%.
You'd be affected detrimentally by this change, you would HAVE to have umpteen roles, no question about it.. removing the ability to have multiple role and allowing to have user specific caps wouldnt really add that much performance benefit IMO.
#36
in reply to:
↑ 35
;
follow-up:
↓ 37
@
15 years ago
Replying to dd32:
Roles are primary to group capabilities to a user, And giving a user a cap is a secondary thing, if the role doesnt manage 100%.
I realize that this is how it currently works, but this is also what seems wrong to me. What a user can do is the important part. That is, a user's capabilities is the critical thing. Roles are just convenient ways to assign those capabilities. Really, a Role with no capabilities is just nothing. Its meaningless. So why such a strong focus on Roles? Why tie capabilities to Roles?
You'd be affected detrimentally by this change, you would HAVE to have umpteen roles, no question about it...
Yes, I know. Back a few releases ago I was looking at having to create a kind of capability system because the old style user level system wasn't flexible enough. The Role system got revamped. It became more flexible, more powerful. It became quite useful, even if it wasn't being used much as some here have suggested. Now, it looks to me like we are heading back to that inflexible and inadequate user_level system-- maybe not completely, but significantly. Why?
removing the ability to have multiple role and allowing to have user specific caps wouldnt really add that much performance benefit IMO.
I'm not just arguing about performance improvements, though the current system doesn't perform very well, which is how I came to this thread in the first place actually. I'm also arguing for a cap/role system that is powerful and flexible enough that you don't have to essentially create a second system in third party code to do anything interesting.
I don't see why both multiple Role and user specific capabilities can't be preserved, though I see less use for multiple roles. The performance problem doesn't come from the fact that multiple roles can be assigned or that user specific capabilities can be assigned. The performance problem comes from how the current system was designed.
I favor a scheme similar to one already outlined in this thread
1) users can have one role
2) roles can have multiple caps
3) roles and their caps are stored as a serialized array in the options table
4) for each user, we store the role as a varchar in the user_meta table
5) to get all users with a role or a cap, we query the user_meta table directly
But done this way, there is no good reason for item 1. You can store two roles just as easily as one and pull them both back out reasonably quickly. Items 2 and 3 can stay. If we accept item 4 there is no reason not to also store user specific capabilities in the usermeta table. But perplexingly, item 5 doesn't make sense if both roles and caps are not stored in the usermeta table in a varchar column like number item 4 has roles being stored. Sure, you can "LIKE '%cap%'" but that is no better than what is possible right now.
So it looks to me like you can:
1) Store user role(s) in the usermeta table as a varchar: wp_user_role = "editor"
2) Also store capabilities in the usermeta table as a varchar: wp_user_cap = "read", wp_user_cap = "edit_posts", etc
3) Have roles and their caps stored as a serialized array in the options table as a quick an easy way to assign multiple capabilities, but that's really what it is-- a shortcut method for assigning capabilities.
Then,
4) "to get all users with a role or a cap, we query the user_meta table directly"
You preserve everything and simplify everything at the same time. I've been playing with this a bit already and with a database of 4750 or so users this scheme adds quite few rows to the usermeta table-- about 3 per user in my case since most are subscribers-- but the 'get all users in somerole' or the 'get all users with somecap' queries (on an indexed varchar column that I added) are about 6.4 times faster than I can get them with a "LIKE '%...%"' query. And there is no complicated array parsing, just simple array parsing. Adding a new table might ramp up the performance but I haven't tested that, and I'm not sure the extra complexity is worth it.
#37
in reply to:
↑ 36
;
follow-up:
↓ 38
@
15 years ago
Replying to apljdi:
But done this way, there is no good reason for item 1. (...)
actually, there is... usermeta and postmeta are managed inconsistently: a user cannot have multiple usermeta with the same key (yet).
Adding a new table might ramp up the performance but I haven't tested that, and I'm not sure the extra complexity is worth it.
It totally is. And as pointed out by Sam, it's what they ended up doing in BBPress.
#38
in reply to:
↑ 37
;
follow-up:
↓ 52
@
15 years ago
Replying to Denis-de-Bernardy:
Replying to apljdi:
But done this way, there is no good reason for item 1. (...)
actually, there is... usermeta and postmeta are managed inconsistently: a user cannot have multiple usermeta with the same key (yet).
Right, I realize that. I've ran into the problem before in other contexts, but that is just a consequence of how the usermeta functions are written. There is nothing in the usermeta table itself that prevents it-- ie., no UNIQUE index. I avoided this problem in my testing by manually writing the INSERTs and SELECTs.
Adding a new table might ramp up the performance but I haven't tested that, and I'm not sure the extra complexity is worth it.
It totally is. And as pointed out by Sam, it's what they ended up doing in BBPress.
I saw Sam's posts and actually I'm not averse to the idea-- I'd say I even favor it--, but there are also references on the thread to 'insane' people propagating the idea of extra tables and, like I said, I haven't had time to play with that aspect so I'm holding off on judgment until I do get the time.
#39
@
15 years ago
Here's a very valid thread as far as using a user2role table, in order to be able to use proper indexes:
http://wordpress.org/support/topic/342901
400k users, wow. :D
#40
follow-up:
↓ 41
@
15 years ago
I just ask myself why he gets a blank page on the user listing page. Looks like that's a bug in core maybe.
#41
in reply to:
↑ 40
@
15 years ago
Replying to hakre:
I just ask myself why he gets a blank page on the user listing page. Looks like that's a bug in core maybe.
I'd guess a plain old out of memory limit reached error with display_errors turned off.
#42
@
15 years ago
Then this might be related to the reported memory consumtion errors co-related to ticket #11649. wpdb::get_cols was the function in use (pre-patch/pre-fix).
#45
@
15 years ago
- Cc Txanny added
I agree the most way is this going to. User->role->caps.
Removing caps at user level would make some searches more easy and quick.
Just I would allow multiple roles per user to have a bit more granular system. This would allow to create task oriented roles like we are now Author, Editor, Contributor and some admin tasck oriented created roles: Appearance Manager, User Manager and so on.
Just with that we can have a user that is Editor+UserManager and other that is Editor+AppearanceManager.
So, I would suggest to allow multiple roles per user while removing caps at user level.
#46
@
15 years ago
So, I would suggest to allow multiple roles per user while removing caps at user level.
Would it be possible to perhaps have it 1-usermeta-row-per-role and save on the serialisation? That'd allow us quicker queries, as well as multiple roles still, and only add a small ammount of overhead (load an array of rows, rather than a single row).
#47
@
15 years ago
I thought that we decided about a month ago not to touch roles in 3.0, so as not to do anything around roles/caps in conjunction with the merge. I vote we stick to that and not include changes to roles/caps until 3.1 (though obviously discussion and patch review in the meantime would make it an early add).
#48
@
15 years ago
I thought that we decided about a month ago not to touch roles in 3.0
That'd be why this is still set to Future Release instead of 3.0 :)
No harm in throwing ideas around tho on how it could be approached, for example, see the Taxonomy-as-a-cap-system thread on wp-hackers.
#49
@
15 years ago
- Keywords early added; 2nd-opinion removed
- Milestone changed from Future Release to 3.1
I'm throwing this into the 3.1 milestone, Its a pretty limiting factor with several sections of code, and could potentially help speed up many pages.
One thing that is not really possible for example, is a Theme listing of authors, That would be fine on a smaller blog, but any with multiple users (subscribers) it quickly becomes an incredibly large list of users that need to be manually filtered.
#50
@
15 years ago
- Cc mikeschinkel@… added
Why not store both roles and user capabilities on a per user basis but use the roles to define the user both with the user and when the role is updated?
The user's capabilities per role could be stored in options and the user's roles could be stored in usermeta. When changing a role's user capabilities you could lookup all users with the changed role, recalculate and then update their capabilities? This could be done asynchronously if need be via a one-time scheduled task.
Would this not work to maintain the ease of admin of multiple roles per user but make the user's capabilities more performant?
#52
in reply to:
↑ 38
@
14 years ago
- Cc earthman100 added
Out of all the options I see here, it would seem to me that allowing duplicate user-meta keys, and implementing this the way apljdi has suggested would make the most sense.
It would reduce the overall load times, create ease of searching for caps, and would still allow full functionality of assigning multiple roles and caps to users, and multiple caps to roles. It seems to me that it would require much less changes to core, and to plugins, to accomodate this.
I've attached a diagram that simplifies the way I see the difference between the 'old' and proposed way.
Just my two sense, as an active WP developer - Hope this helps!
#54
@
14 years ago
- Milestone changed from Awaiting Triage to Future Release
- Type changed from task (blessed) to enhancement
Probable for 3.2. Moving out of triage and task for now.
#56
follow-up:
↓ 58
@
14 years ago
As I've said in another - possibly duplicate - ticket that I can't find now, the proposed schema allows multiple roles (because usermeta can handle multiple values for the same meta key), while maintaining the improved performance.
#57
@
14 years ago
- Description modified (diff)
just adding that to the description. I think it may have been mentioned in this ticket, but that description was written before it was highligted.
#58
in reply to:
↑ 56
@
14 years ago
Replying to scribu:
As I've said in another - possibly duplicate - ticket that I can't find now, the proposed schema allows multiple roles (because usermeta can handle multiple values for the same meta key), while maintaining the improved performance.
You might be thinking of this blog post.
#60
@
14 years ago
- Cc jer@… added
I think keeping multiple-roles is vital if you remove per-user-caps. I agree that no one uses them now but people definitely use per-user caps if they are available. We did so in the past when the Role Manager plugin still worked because it offered the ability. Custom caps keep your roles system clean and simple while letting you satisfy edge-cases (like trusted authors who need to edit categories or widgets but not options).
In recent years no plugins have exposed the custom-caps functionality, probably because, as Nacin points out in the post linked above, the current Roles system is not only complex, it is buggy and broken. I've never used a plugin that properly and buglessly implemented custom caps/anti-caps, which I think is a big factor in their unpopularity. If there had been a core plugin that exposed the custom-caps and multiple-roles functionality (and fixes in core to support it actually working) I think the numbers would play out differently. I also think such a core plugin is exactly what core-plugins should be about: exposing functionality that is hidden from default installs to reduce UI clutter.
A good argument in favor of multiple-roles is that after creating a one-time custom role for a single user (say, author+widget manager) you then have to remember/forget to make changes to that custom role when you make changes to the 'author' role (e.g. adding the 'unfiltered_html' ability for authors, which would result in your especially-trusted author being the only one on the site without that cap, leading to frustrating debugging experiences).
There is inherent value to keeping all users in a simple set of common roles and not forcing users out of the common roles just to give them a special capability. In many cases having the users in clean roles also helps institutionally, giving managers the ability to use roles as a way of filtering groups within their organization (i.e. if you know all editors are paid and authors aren't then keeping the roles system clean gives you a lot of power you don't have otherwise). Multi-roles also offers the possibility of creating institutional roles on TOP of the generic ones (i.e. one user is author+employee, another is admin+employee and another is author+community). This would let the roles system be used for grouping users together for non-permissions purposes without having a whole separate system that duplicates most of the functionality of Roles.
The model of having a "just_edit_widgets" role to supplement an author or editor makes a lot of sense to me. It is a fair compromise for those who don't want to give up per-user-caps and from the discussions above it sounds like it is doable within the best ideas for how to update the system from a code perspective.
#61
follow-up:
↓ 69
@
14 years ago
- Cc ryan_b added
what if instead of doing away with user specific capabilities, we did away with roles. I mean since when does it make sense to link a user to an arbitrary grouping (ie role) that just links to the actual capabilities. Best I can tell this was done for simplicity, most average user's want to make a user an editor, not make a user who has capabilities a, b, c, 1, 2, 3, x, y, and z if you know what I mean. That is all fine and good and I can understand that. But who says you have to link the user to a role. Picture this, you add a new table let's call it usercaps (yes, you could use usermeta for this but it'll probably be cleaner to do this is a different table) that will link users to caps, with an arbitrary auto incremented number to act as primary key, the scheme would be like this:
ID (pk) = 1
User ID = 1
Capability = manage_options
ect...this can be done either way, select * from usercaps where User ID = 1 and Capability = manage_options to see if the user has the cap, select UserID from usercaps where Capability = manage_options to see who has manage_options, or select Capability from usercaps where User ID = 1 to see what caps user 1 has.
Now what about the general user, we want to keep simple things simple while remaining flexible is the key, you we will still have something called roles, it will be much like a template of capabilities to give the user, the net effect cleanner in the db, keeps the simple role system for the general user, but it's flexible for those power users.
Now for the power users, there would be an API that a plugin could utilize to replace the role selector with a direct capability selector so now each user can have their own distinct set of capabilities, if needed. This would be done via Plugin API with a plugin only for those requiring something more flexible than just the basic roles.
This way you change out your old V6 roles/capabilities engine with a more powerful v8, while keeping things simple for the average user but remaining flexible for advanced users giving them more power if they need it (hey that's a good analogy, I'll have to remember that one, lol).
I mentioned this in wp-hacker's this question was raised: but if you would want to add a capability to a role, you don't know which user has which role.
so you would have to do this for every user.
Which was a fair point, my response to that was there are really two options, option one is you could determain the current role by caps, ie if they can manage_options you know they are an admin, if not check a cap first avalible at the next level, or introduce a role specific cap (bring back levels for instance).
The other option, perhaps what may work best, is to still store the role in user meta, this way you can still display in the admin panel the specific role for a given user like today, it keeps things very familiar to the user. Also for those using the full capability editor which would be accessed either by plugin or setting an option somewhere, you could still let then choose roles, then customize them further, then if they are not using the exact role setup but a customized set of capabilities you could give them two options:
- A textbox to name the "role" which would just describe the capability set, this would be stored in therole meta value.
- Optionally they could save it as a role that can be assigned to other users, letting them easily mirror those exact permissions to other users, maybe give them the option to check a box and the role name, and capabilities would be stored is a setting as a serialized array, soley for prepopulating capabilities for other users in the future.
So what do you think of this method, i'm always interested in feedback.
#62
@
14 years ago
ryan_b: the reason we have roles and not individual capabilities is because, for a site with 1 million users, for example, you would end up with a table with over 10 million rows on average, versus 1 million role meta_keys.
Not to mention that, if you wanted to add a capability to one class of users, you would have to add that many rows to the already huge table. The same for deleting a capability.
Roles are here to stay.
#63
@
14 years ago
How many blogs do you know that have a million users? Also most users would be subscribers generally so they get what read and that's it. It may not be the way to do it with the fewest entries but I question how realistic the numbers you gave are.
#64
@
14 years ago
@ryan_b - Even with 100 users managing capabilities on a per user basis would quickly get so burdensome that it would be cause for people to switch to something else like Drupal (shuddering to think).
I'm working on a WordPress multisite project right now that would simply be unmanageable without roles and the client would finally give up on WordPress and switch to Drupal (they have discussed exactly that with me; no roles and I know it would send them over the edge.)
#65
@
14 years ago
Every site that I build is primarily geared toward small to medium sized businesses.
In the past, prior to the ability to create custom post types, I have had little use for roles and capabilities. I felt they were clumsy and inefficient, and for what I could achieve with them back then, not worth the effort.
However, with the abilities I now have for "departmentalizing" my client's administrative areas using custom post types, the user roles and capabilities have suddenly become incredibly important, if not vital, as I can now give my clients the ability to delegate content responsibilities for the site via already established departments/job titles within their organization. It would be a serious regression if I suddenly could not provide that.
Specific members in the organization can enter job descriptions ( the human resources department for instance ) others can enter content for product copy ( the sales team ).
I think it would be a mistake to make any historical assumptions regarding the use of roles and capabilities at this point in time as in my humble opinion, they have only recently even become relevant with the latest advancements in core.
just my 2¢ of course.
#66
follow-up:
↓ 70
@
14 years ago
10sexyapples: The issue isn't that you're using custom roles and/or capabilities - of course you should be using them!
The problem is when you're not using roles, but assigning/removing capabilities directly, on a per-user basis. Firstly, it's a bad idea. Secondly, the fact that you have this possibility leads to poor performance, due to the necessary implementation.
That's what all this is about.
#67
@
14 years ago
- Description modified (diff)
- Summary changed from Switch roles to use single role, and no user-specific caps to Remove user-specific caps
I changed the summary, since it's obvious that multiple roles are both desired and wouldn't reduce performance.
#68
@
14 years ago
Ah yes Scribu, I should have been more clear in my comment what it was I was specifically addressing.
I was answering directly to any statements or opinions regarding any lack of enthusiasm that previously existed toward roles and capabilities and their use out there in the devosphere as a whole
( to explain ... I'm having issues with the user_level != 0 check in the author dropdown metabox ( I believe you know a bit about this ? ;-) ) and have been reading for days to troubleshoot this and other issues in dealing with all the new user/role/capability stuff and I guess I somehow formed the assumption that this lack of interest existed out there.)
As well as to any opinions geared toward solutions or suggestions posted here which fail to take into consideration that Wordpress has come a very long way and is the framework of choice for folks like myself building for professional organizations, and not just bloggers ...
( ie "How many blogs do you know that have a million users? Also most users would be subscribers generally so they get what read and that's it." )
Sorry about the confusing comment ...
Especially considering all that I've been learning lately in regards to roles and capabilities, I personally cannot wait for you guys to pull the trigger on this overhaul ;-) It seems so very needed.
#69
in reply to:
↑ 61
@
13 years ago
Replying to ryan_b:
what if instead of doing away with user specific capabilities, we did away with roles. I mean since when does it make sense to link a user to an arbitrary grouping (ie role) that just links to the actual capabilities.
Convenience. You don't want to manually assign 5-20 capabilities to every user on a case by case basis. You only want to tweak the capabilities. This seems to be much the reason you yourself give.
... the scheme would be like this:
ID (pk) = 1
User ID = 1
Capability = manage_options
ect... this can be done either way, select * from usercaps where User ID = 1 and Capability = manage_options to see if the user has the cap, select UserID from usercaps where Capability = manage_options to see who has manage_options, or select Capability from usercaps where User ID = 1 to see what caps user 1 has.
Close to what I had imagined.
Now what about the general user, we want to keep simple things simple while remaining flexible is the key, you we will still have something called roles, it will be much like a template of capabilities to give the user, the net effect cleanner in the db, keeps the simple role system for the general user, but it's flexible for those power users.
Again, close to what I had imagined but I don't see in what way you are doing away with roles. You are making roles secondary to capabilities, with roles being a convenient way to group capabilities, as I was arguing.
#70
in reply to:
↑ 66
@
13 years ago
Replying to scribu:
10sexyapples: The issue isn't that you're using custom roles and/or capabilities - of course you should be using them!
The problem is when you're not using roles, but assigning/removing capabilities directly, on a per-user basis. Firstly, it's a bad idea. Secondly, the fact that you have this possibility leads to poor performance, due to the necessary implementation.
That's what all this is about.
I just noticed that my lengthy response didn't make it....
I don't understand why adding capabilities on a per user basis is a bad idea. I understand that managing capabilities capability solely by capability would be burdensome but roles would serve as a shorthand and would probably be adequate for 98% of the users. In my case, I have about 4,700 users and only about 25 of are better than subscriber status. It is only those 25 that I may need to tweak.
I also understand that adding capabilities as separate lines in a table-- usermeta or other-- could possibly lead to performance problems but I think that that problem is overstated. A million users is a the far extreme, for one. As ryan_b wrote, "How many blogs do you know that have a million users?" And adding capabilities one per line does not add ten lines per user as it would have to to get 10 million lines from 1 million users. It adds about 3 lines per user, since most users are going to be subscribers and have few capabilities. I've tested this.
I added a line for role and a line for each capability for a database of about 4700 users. It added a little better than 14,000 lines. In total the usermeta table has ~44,000 lines. Without an index I can pull up all users of x cap or x role in 0.1 seconds, and with an index it drops to 0.002 seconds. It looks like you would need a lot of users to see a performance hit. Even so, separating the roles and capabilities into separate table should help, and you could eliminate a lot of those lines by only storing the user specific role changes using keys like 'add_cap' and 'del_cap' for example.
posting the raw log, will summarize later: