WordPress.org

Make WordPress Core

Opened 6 years ago

Last modified 8 months ago

#10201 assigned enhancement

Switch roles to use single role, and no user-specific caps — at Version 57

Reported by: Denis-de-Bernardy Owned by:
Milestone: Future Release Priority: normal
Severity: normal Version: 2.8
Component: Role/Capability Keywords: dev-feedback
Focuses: Cc:

Description (last modified by dd32)

See IRC discussions from June 18th 2009

---

summary courtesy of DD32:

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..)
        • This could also be done as a multi-meta system, ie. 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.
      • 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)
  • 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.

Change History (58)

comment:1 @Denis-de-Bernardy6 years ago

  • Component changed from General to Role/Capability
  • Owner set to Denis-de-Bernardy
  • Status changed from new to accepted

posting the raw log, will summarize later:

ddebernardy: you mean roles control in admin like wp-roles did?
12:08 AM MarkJaquith
ddebernardy: here is my idea on roles:
12:08 AM jeffr0
wow, alot of people would be cheering if role management received an overhaul and was more user friendly/ more granular
12:08 AM Jane_
will post on dev blog later this week or more likely early next week with prioritization poll. hopefully using andy peatling's nifty drag and drop feature ranking system from buddypress site.
12:08 AM jeffr0
heh I saw Andys roadmap stuff
12:08 AM aaroncampbell
jeffr0: I think you're the first one to mention "sitemap"
12:08 AM rboren
http://bbpress.org/plugins/topic/user-roles-table-for-bbpress/
12:09 AM
Used on talkpress on some other places.
12:09 AM ddebernardy
aaroncampbell - I was meaning this:
12:09 AM
http://core.trac.wordpress.org/ticket/2531#comment:20
12:09 AM
and rboren's reference
12:09 AM MarkJaquith
My idea: Get rid of the concept of negated capabilities. No one uses them. Get rid of the idea of standalone capability  granting. Almost no one uses it. Get rid of the idea of multiple roles. No one uses it. Just have wp_user_role = 'author' in the meta table.
12:10 AM Jane_
see you guys
12:10 AM Jane_ is now known as jane|dinner
12:10 AM aaroncampbell
ddebernardy: I thought that jeffr0 was talking about the permalink history.  Not sure I was correct, but is there a ticket for that one?
12:11 AM ddebernardy
oh, sorry, was meaning to reply to bi0xid
12:11 AM bi0xid
MarkJaquith: I think i don't understand. I use roles subscriber, author, editor and admin in almost all the blogs i admin. Do you want to eliminate them?
12:11 AM ddebernardy
yeah, permalink history would mean being able to drop all of the redirection plugins
12:11 AM MarkJaquith
bi0xid: no.
12:11 AM
bi0xid: by multiple roles, I mean a person who is both an admin and an subscriber.
12:12 AM bi0xid
ooh
12:12 AM
MarkJaquith:
12:12 AM MarkJaquith
You probably didn't know WP could do that. Because NO ONE uses it. :-)
12:12 AM bi0xid
MarkJaquith: agreed. If you want to have 2 profiles, then use 2 users.
12:12 AM Fredelig
:)
12:12 AM aaroncampbell
MarkJaquith: since there's not a limit to the number of roles, I think that the few people that use that could just create another role that is the equivalent to those two roles combined
12:13 AM ddebernardy
bi0xid - not so, if you've a membership plugin of sorts
12:13 AM MarkJaquith
aaroncampbell: exactly.
12:13 AM bi0xid
that's the poing
12:13 AM
*point
12:13 AM rboren
To get user with a certain cap, see which roles have that cap, see if user has one of those roles.
12:14 AM MarkJaquith
yep, rboren.
12:14 AM ddebernardy
and seeing which users have those roles amounts to querying all users
12:14 AM
it's a major problem atm
12:14 AM MarkJaquith
ddebernardy: indeed. users.php doesn't scale because of it.
12:14 AM ddebernardy
exactly
12:15 AM MarkJaquith
The authors dropdown doesn't scale because of it.
12:15 AM ddebernardy
ok, so I take it that new roles tables will have more traction?
12:15 AM nikolayb has left IRC (Read error: 54 (Connection reset by peer))
12:15 AM MarkJaquith
ddebernardy: I don't see that a table is needed.
12:15 AM ddebernardy
it's needed for joins
12:15 AM
you don't want this stuff in a meta table
12:15 AM MarkJaquith
you can use usermeta as user-to-role
12:16 AM ddebernardy
meta joining an integrer on a text field is not the most efficient thing there is
12:16 AM
sql joining even
12:17 AM MarkJaquith
agreed. But I don't think the speed you lose in storing it in usermeta is worth adding a whole new table just for that.
12:17 AM ddebernardy
if we decide to drop the true|false thingy as you suggest, we've less tables but it's less flexbile
12:17 AM
MarkJaquith - it is, when you implement a membership plugin
12:17 AM MarkJaquith
It's just as flexible. It may just require more roles to do it.
12:17 AM ddebernardy
it makes evry difference in teh world, in fact
12:18 AM
so much so, that the better membership plugins create a separate table, memberships
12:18 AM rboren
Well, a problem with usermeta is that you have to use db prefixes to get the role for a given blog.  Having a blog id would be nicer.
12:18 AM ddebernardy
and then user2membership and membership2post
12:19 AM nikolayb has joined the channel.
12:19 AM ddebernardy
rboren - there is a ticket related to a CAPS define, related to that
12:19 AM
added a patch a few days ago
12:19 AM
but obvious not relevant if we get the roles tables fixed
12:19 AM
because we also need to be able to sort out a common desire for users to have the same role across blogs
12:22 AM
#8663
12:22 AM wp-trac-bot
ddebernardy: http://core.trac.wordpress.org/ticket/8663 normal, normal, 2.9, hudatoriq->hudatoriq, new, Allow customizing capabilities prefix through wp-config.php
12:22 AM Viper007Bond has left IRC ("http://www.viper007bond.com/ | http://www.finalgear.com/" )
12:23 AM MarkJaquith
Oh neat... that's been bothering me for a long time that you couldn't do that. I have a script that syncs the caps :-)
12:23 AM ddebernardy
anyway, is that a go for it for a role revamp in 2.9?
12:24 AM DD32
Little late i know, But Roles: Just simplify them, Dont bother with a new table unless its absolutely needed, Theres no need to move from an awkwardly complex system no-one uses, to another complex setup that no-one uses. - A single role per user + serialised caps for each role loaded once in memory, simple and do-able with the current layout
12:24 AM ddebernardy
or shall we stick to 8663?
12:24 AM photomatt
ddebernardy: to your earlier point of discussion, in many years of doing this I have seen zero correlation between a longer release cycle and more stable product
12:24 AM
in fact it seems to be the opposite
12:24 AM MarkJaquith
DD32: that would be my choice.
12:25 AM ddebernardy
DD32 - there's a half dozen tickets related to roles/caps
12:25 AM bi0xid
photomatt: people relax when having more time :P
12:25 AM MarkJaquith
Simple, no new tables. And we can totally handle upgrades without changing anyone's caps.
12:25 AM photomatt
so about 3 per year seems to be the best balance of plenty of room for testing and getting improvements into users hands as frequently as possible
12:25 AM ddebernardy
that are related to changing the way it's managed for all sorts of reasons
12:25 AM
photomatt - 3 per year is fine, not 4 :-)
12:25 AM DD32
ddebernardy: I dont care if there is, That doesnt make much of a difference, people have troubles with the current role system, Anyone who needs extreme grain control over it, can use a plugin, just like they have to do in the first place to change the roles caps anyway
12:26 AM ddebernardy
photomatt - are you in SF next month, so we can have a beer at some point?
12:26 AM jeffr0
what is this canonical plugins i keep hearing about. I don't understand what that means
12:26 AM photomatt
I'm actually gone all of july, until the very end
12:27 AM ddebernardy
that's fine, I'll be in Merced, probably for 2-3 months
12:27 AM photomatt
an obvious improvement for roles for 2.9 could be: there is no place in the interface that says what any role does
12:27 AM ddebernardy
just let me know when you're around (ddebernardy at yahoo.com
12:27 AM photomatt
even just a listing of capabilities in a human readable form would be a nice improvement for folks
12:27 AM DD32
jeffr0: Its for those who change their permalink strucutre so damn often. Ie. /2009/09/<postid>// - gets changed to /september/2009/<postname>/ and WP remembers the old format...
12:27 AM MarkJaquith
photomatt: I'd be up for simple role management if we got the whole system to a simple caps, bucket system.
12:27 AM aaroncampbell
jeffr0: The idea would be that a specific plugin would be the "recommended" solution for a particular issue, and rather than getting 50 developers to create 50 different competing solutions, they could work together on one.
12:27 AM photomatt
some checkboxes for modifying non-admin capabilities would be icing on the cake
12:27 AM DD32
oh.. wrong thing :)
12:27 AM jeffr0
no you're speaking of canonical urls
12:27 AM
lol
12:28 AM DD32
Still too early here :P
12:28 AM aaroncampbell
Also, as mentioned, there's the possibility to get those added as part of the testing process (or even as unit tests)
12:28 AM photomatt
MarkJaquith: I think the user side should be done before any backend changes
12:28 AM
unless there's something inherit in the current structure that prevents us from moving forward
12:28 AM jeffr0
I know some plugin authors are already working behind the scenes together, collaborating together
12:28 AM
would this system help that?
12:28 AM photomatt
the consensus seems to be it's too flexible, not too little
12:29 AM ddebernardy
photomatt - there is. it prevents the likes of list authors with cap A or B to scale, for one thing
12:29 AM MarkJaquith
photomatt: yep. Too much flexibility, and it's actually constraining performance. Could do UI first, but it wouldn't support any of the soon-to-be-deprecated features.
12:29 AM aaroncampbell
jeffr0: yeah, but I think it's just an idea at this point.  it was mentioned in photomatt's state of the word in SF.
12:29 AM ddebernardy
and it prevents plugin authors from having a ready API to add memberships
12:29 AM MarkJaquith
Like multiple roles per person, or role + additional cap.
12:31 AM ddebernardy
right
12:31 AM aaroncampbell
jeffr0: I talked about it a little in part 2 of my summary of the state of the word from SF: http://wpinformer.com/state-word-wordcamp-part-2/ ...I'm not much of a writer, but it's there
12:31 AM photomatt
MarkJaquith: I think having a UI would be a good constraint for us when we want to do a rearchitect in a future version
12:32 AM
because creating the UI will force us to figure out what people actually want from it
12:32 AM
what the most popular plugins are doing with it, etc
12:32 AM
without taking out the plumbing before we have a place to pee
12:32 AM
so to speak
12:32 AM ddebernardy
photomatt - no no, the good membership plugins are ignoring wp roles altogether
12:32 AM bi0xid
Sorry guys. Off to bed. Must be awake in 5 hours to work ^_^. Will read u tomorrow.
12:32 AM ddebernardy
precisely because it's not query'able
12:32 AM bi0xid is now known as bi0xid[a]
12:33 AM aaroncampbell
MarkJaquith: just to add my two cents, I use "role + additional caps" fairly regularly, but I'm not against having to create a new role to do that.
12:33 AM photomatt
ddebernardy: point me to the plugins, I'm happy to take a look at them
12:33 AM MarkJaquith
aaroncampbell: And the upgrade could create that new role for you.
12:33 AM ddebernardy
photomatt - they're all paid for stuff, sadly
12:33 AM photomatt
then I don't care about them
12:33 AM ddebernardy
but wp wishlist, for one, is one of them
12:33 AM
and my own (yet to be released, so not very relevant) is another
12:34 AM photomatt
if people are restricted to a single role, which is totally fair, then we could put an index back into wp_users using the old user_level field (or a new one) which would make querying easy-peasy
12:34 AM ddebernardy
I plan to place mine in the wp repo
12:34 AM
and I'd ideally want the roles table revamped by then
12:34 AM aaroncampbell
MarkJaquith: true.  Another FYI, I use Role Manager (http://www.im-web-gefunden.de/wordpress-plugins/role-manager/) and I think it's pretty popular.
12:34 AM ddebernardy
else I'll just add a few more defines
12:34 AM
and db tables
12:34 AM MarkJaquith
photomatt: the only issue is that you can have different roles on different blogs, so you can't store it in the user table.
12:35 AM jeffr0
role manager is very popular
12:36 AM ddebernardy
as much as role manager is popular it still doesnt' make it possible to query users who can edit posts or pages, for instance
12:36 AM DD32
MarkJaquith: Thats the only case i see against it..  infact, integrating with other sites/setups is the only time you'd use a roll+cap or multiple roles ideally..
12:36 AM photomatt
as far as I can tell role-scoper is the most popular role plugin, and #657 overall
12:36 AM ddebernardy
and that's like.. a must have, based on teh role/caps tickets
12:36 AM MarkJaquith
DD32: I'm not talking about multiple roles on one blog. Multiple roles on multiple blogs. One role per blog.
12:36 AM photomatt
MarkJaquith: good point, so in usermeta it should say
12:37 AM
*stay
12:37 AM MarkJaquith
photomatt: but as role in plaintext only.
12:37 AM photomatt
yep
12:37 AM ddebernardy
ok, let me get this right
12:37 AM photomatt
I've always liked the approach of capabilities as a big array, which anyone could filter
12:37 AM DD32
MarkJaquith: Ah yeah slight mis-understanding there.. But yeah ok that makes sense
12:37 AM photomatt
rather than being stored in the DB as primary store after installation
12:38 AM
there's nothing in the code we can rely on any role existing, iirc
12:38 AM MarkJaquith
photomatt: you can still do that. Most of the sites I create, I hardcode roles using pre_option_* filters
12:39 AM ddebernardy
photomatt - see the performance/optimization tickets
12:39 AM
and a few template tickets
12:39 AM photomatt
yeah but when you do that you're making assumptions -- we do the same on wp.com
12:39 AM MarkJaquith
What assumptions?
12:39 AM ddebernardy
there are a few that relate to not being able to query users having a cap
12:40 AM photomatt
ddebernardy: I'm familiar with the problem. if you'd like me to look at a specific ticket, please link it
12:40 AM MarkJaquith
ddebernardy: it's roundly agreed that cap-to-user is needed. I've been honking that horn for over three years.
12:40 AM Viper007Bond has joined the channel.
12:40 AM ddebernardy
#2787
12:40 AM wp-trac-bot
ddebernardy: http://core.trac.wordpress.org/ticket/2787 normal, normal, Future Release, markjaquith->jacobsantos, new, New Method of storing and calculating cap2user and user2cap
12:40 AM ddebernardy
#2531
12:40 AM wp-trac-bot
ddebernardy: http://core.trac.wordpress.org/ticket/2531 normal, normal, Future Release, markjaquith->jacobsantos, new, Functions for registering additional capabilities and getting a list of all capabilities
12:40 AM clioweb has left IRC ()
12:40 AM photomatt
MarkJaquith: that nothing has modified in the DB. usually when I use a pre_option hook it feels like a hack
12:40 AM ddebernardy
#5942
12:40 AM wp-trac-bot
ddebernardy: http://core.trac.wordpress.org/ticket/5942 normal, normal, Future Release, tellyworth->, new, Add Owner role
12:40 AM ddebernardy
#5255
12:40 AM wp-trac-bot
ddebernardy: http://core.trac.wordpress.org/ticket/5255 normal, normal, Future Release, markjaquith->jacobsantos, new, Simplify role/capability for easier cap => user lookups
12:40 AM ddebernardy
#5540
12:41 AM wp-trac-bot
ddebernardy: http://core.trac.wordpress.org/ticket/5540 normal, normal, Future Release, tellyworth->jacobsantos, new, User roles overhaul
12:41 AM ddebernardy
#5541
12:41 AM photomatt
ddebernardy: no need for a ticket flood, feel free to filter
12:41 AM wp-trac-bot
ddebernardy: http://core.trac.wordpress.org/ticket/5541 normal, normal, Future Release, tellyworth->jacobsantos, new, Refactor and simplify WP_Roles
12:41 AM MarkJaquith
photomatt: I think of it as a hedge against silly users updating things they shouldn't be.
12:41 AM photomatt
otherwise it's annoying
12:41 AM ddebernardy
need more? :-)
12:42 AM
sorry ;-)
12:42 AM photomatt
was the role system from owen? I don't remember that
12:42 AM ddebernardy
I think so, yeah
12:43 AM MarkJaquith
yes. as with the original role manager plugin.
12:43 AM photomatt
this is a pretty good summary of how I still feel 3 years later: http://core.trac.wordpress.org/ticket/2531#comment:10
12:44 AM MarkJaquith
He over-engineered it.
12:44 AM ddebernardy
MarkJaquith - agreed, that is totally needed in my experience of role management as well
12:44 AM
photomatt - agreed, but only one one front
12:45 AM
that caps can be managed as a serialized array
12:45 AM
roles, however, should not
12:45 AM MarkJaquith
photomatt: my only objection to that remains that people adding new roles have to store them somewhere.
12:45 AM ddebernardy
if you want to allow the viewing of this or that post by members of this or that product, then you need a table
12:45 AM MarkJaquith
So why not have a canonical storage location?
12:46 AM photomatt
the pivot point to me is whether we want them to be editable in core
12:47 AM ddebernardy
and even then, the current setup introduces performance issues related to fetch all users with this or that cap, in wp
12:47 AM MarkJaquith
Without any editing, I agree. Hardcode that sucker and use IDs.
12:47 AM photomatt
if not, then new plugins with new roles would just filter the array and add them, or a "role manager" plugin would override the array with something pulled from the DB, in however it wants to store it
12:47 AM jeffr0
editable as in checkboxes and drop down menus?
12:48 AM ddebernardy
jeffr0 - yes
12:48 AM MarkJaquith
photomatt: upgrade issues sort of box us in on that... unless we want to break people's custom roles.
12:48 AM photomatt
ddebernardy: since that's not core functionality, a plugin having a new table to optimize for its use case is totally fine
12:49 AM
that's why I suggested it in alex's patch on #5540
12:49 AM wp-trac-bot
photomatt: http://core.trac.wordpress.org/ticket/5540 normal, normal, Future Release, tellyworth->jacobsantos, new, User roles overhaul
12:49 AM ddebernardy
photomatt - I'm fine with the idea, as long as it's clear-cut and clearly defined as wontfix for the remaining tickets in WP :-)
12:50 AM
your statement prompts me to close like... about 20 or so performance related tickets as wontfix
12:50 AM photomatt
the closest it gets to core is in MU, which has to jump through hoops to get the users of a blog
12:50 AM
ddebernardy: don't jump the gun, it's a discussion
12:50 AM ddebernardy
photomatt - that's interesting
12:50 AM
define users of a blog
12:50 AM
it's all users with edit cap, no?
12:51 AM
if so, you're making my point (for 4-5 extra tables) exactly
12:51 AM JamesCollins has joined the channel.
12:51 AM MarkJaquith
it's all users with a role on that blog.
12:51 AM photomatt
any role
12:52 AM ddebernardy
so that's only a two tables -- roles, user2role
12:52 AM
role could be defined in the db, and that's no biggy
12:52 AM
until we need to fetch users with a specific cap
12:52 AM
if we need that, we also need role2cap and user2cap
12:52 AM
so two extra
12:52 AM photomatt
ddebernardy: it's being done now without additional tables, and has been for years
12:52 AM
it's just annoying
12:53 AM DD32
fetch specific: Thats simpler to just do an array filter, get the list of roles, query users based on roles
12:53 AM ddebernardy
yaya, I realize, but it coudl scale a lot better with the extra tables (and indexes)
12:53 AM DD32
scale past what? 10 roles and 50 caps?
12:53 AM ddebernardy
I'm not managing wp.com though, only you have the gory details ;-)
12:53 AM photomatt
the key in scaling is usually caching, not as much normalized data storage
12:54 AM ddebernardy
dd32: on a mu install such as wp.com we're talking hundreds of thousands of actual users
12:55 AM
photomatt - not so, even with memcached on you won't get past the bottleneck that goes, fetch all users, foreach users that has this cap add to array
12:55 AM DD32
ddebernardy: Yes, Which is why you'd optimize user fetching on roles, but actual cap -> user would be done as a PHP cap-> roles, then a SQL of roles -> users. Still scales very well for thousands of users if the user->role part is optimized
12:55 AM MarkJaquith
ddebernardy: that's not how you'd do it...
12:55 AM
figure out which roles have the cap. Easy, done in PHP, very fast.
12:56 AM
With roles in hand, do one query on usermeta.
12:57 AM ddebernardy
MarkJaquith - until you've users who have several roles
12:58 AM MarkJaquith
ddebernardy: I was proposing dropping multi-role.
12:58 AM ddebernardy
and even then, if you've a user who has caps on top of roles, your query is erroneous ;-)
12:58 AM MarkJaquith
And I was proposing dropping caps on tops of roles.
12:58 AM
wp_user_role => 'editor'
12:58 AM ddebernardy
I'm fine with both ideas and will be happy to contribute the patch, as long as it's a clear-cut decision
12:59 AM rboren
All customization done through roles.  One role per user.
12:59 AM ddebernardy
as long as we can get all of those performance tickets closed I'm happy
12:59 AM rboren
Has the benefit of simplicity.  Most priv systems are confusing as hell.
12:59 AM aaroncampbell
I need to go, but I agree with MarkJaquith ...drop the multiple roles per user, drop the added caps (make new roles instead), and keep it relatively simple (IMO)
12:59 AM ddebernardy
rboren - they sure are
1:00 AM DD32
and mutli-blog systems would still be clear-cut, as the role for the other blogs would be different meta rows..
1:00 AM ddebernardy
ok
1:00 AM
so are we all agreeing with dropping multi-roles and user caps?
1:00 AM rboren
Seems like.
1:00 AM ddebernardy
photomatt?
1:01 AM photomatt
rboren: I like that
1:01 AM ddebernardy
ok
1:01 AM
let's do that
1:01 AM rboren
Makes code and queries much simpler.  And UI could be pretty simple too.
1:01 AM DD32
Before making a rush to close all those tickets though, Just think it over and open a new ticket based on that idea, see the reaction, and then close the non-needed stuff.....?
1:01 AM photomatt
MU is handled by the prefix
1:01 AM
DD32: makes sense
1:01 AM rboren
DD32: Mark and I have a ticket where we debated this very thing somewhere.
1:01 AM photomatt
rboren: what would the compatability implications be?
1:02 AM rboren
For stock WP, no problem. For those who use role manager, could be some headaches.
1:02 AM MarkJaquith
I really think it can be handled in upgrade.
1:02 AM rboren
Might need something to translate multiple roles + caps into new roles.
1:02 AM MarkJaquith
rboren: yep.
1:03 AM
If a role doesn't exist with those exact GRANT capabilities, we create one.
1:03 AM photomatt
do any plugins enable multiple roles?

1:03 AM
on a single blog
1:03 AM ddebernardy
#10201
1:03 AM MarkJaquith
I've never seen it.
1:03 AM wp-trac-bot
ddebernardy: http://core.trac.wordpress.org/ticket/10201 normal, normal, 2.9, Denis-de-Bernardy->, new, Switch roles to use single role, and no user-specific caps
1:03 AM rboren
Haven't look at role manager forever. Is it even maintained any more?
1:03 AM MarkJaquith
rboren: by someone else, I believe.
1:04 AM ddebernardy
rboren - it is, but not very well
1:04 AM
photomatt - yes, membership plugins
1:04 AM DD32
Alright, 9am, better get to work. - Someone save a chanlog and post it up later please? (If theres anything else further said)
1:04 AM ddebernardy
we're absolutely guaranteed to break all of the poorly written ones if we implement this
1:05 AM rboren
Off to the airport. Dropping off the wife. Later all.
1:05 AM ruslany has joined the channel.
1:05 AM ddebernardy
by poorly written ones, I'm meaning those that are sub-optimal from a db performance standpoint
1:06 AM
DD32: will add a big copy of the discussion in 10201
1:06 AM jeffr0
heh
1:06 AM ddebernardy
I actually like this idea
1:07 AM
it means membership plugins need to manage their own multi-role tables
1:07 AM
and that is good
1:07 AM
because roles and memberships are different animals
1:07 AM MarkJaquith
Yay. Three years and I finally got consensus on this! :-D
1:07 AM ddebernardy
:-)

comment:2 @Denis-de-Bernardy6 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.

comment:6 @thee176 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?

comment:7 follow-up: @ShaneF6 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.

comment:8 @dd326 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)
  • 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 :)

comment:9 @Denis-de-Bernardy6 years ago

  • Description modified (diff)

comment:10 in reply to: ↑ 7 ; follow-up: @Denis-de-Bernardy6 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...

comment:11 @Denis-de-Bernardy6 years ago

cross-referencing: #8648, #5407, #9938

comment:12 in reply to: ↑ 10 @ShaneF6 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.

comment:13 @Denis-de-Bernardy6 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.

comment:14 @hakre6 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.

comment:15 follow-up: @Denis-de-Bernardy6 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

comment:16 in reply to: ↑ 15 @ryan6 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.

comment:17 @hakre6 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.

comment:18 @hakre6 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.

comment:19 @Denis-de-Bernardy6 years ago

  • Owner Denis-de-Bernardy deleted
  • Status changed from accepted to assigned

comment:20 @hakre6 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

@hakre6 years ago

Stub of existing globals, functions and classes.

comment:21 @ryan6 years ago

  • Type changed from enhancement to task (blessed)

comment:22 @westi6 years ago

  • Cc westi added

comment:23 @aaroncampbell6 years ago

  • Cc aaroncampbell added

Just adding my +1 and adding myself to Cc

comment:24 @dd326 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

comment:25 follow-up: @sambauers6 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.

comment:26 in reply to: ↑ 25 @Denis-de-Bernardy6 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.

comment:27 @dd326 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

comment:28 @Denis-de-Bernardy6 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.

comment:29 follow-up: @sambauers6 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.

comment:30 in reply to: ↑ 29 @Denis-de-Bernardy6 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.

comment:31 @hakre6 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.

comment:32 @hakre6 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.

comment:33 @ryan6 years ago

  • Milestone changed from 2.9 to Future Release

comment:34 @apljdi5 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.

comment:35 follow-up: @dd325 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.

comment:36 in reply to: ↑ 35 ; follow-up: @apljdi5 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.

comment:37 in reply to: ↑ 36 ; follow-up: @Denis-de-Bernardy5 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.

comment:38 in reply to: ↑ 37 ; follow-up: @apljdi5 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.

comment:39 @Denis-de-Bernardy5 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

comment:40 follow-up: @hakre5 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.

comment:41 in reply to: ↑ 40 @Denis-de-Bernardy5 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.

comment:42 @hakre5 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).

comment:44 @voyagerfan57615 years ago

  • Cc WordPress@… added

comment:45 @Txanny5 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.

comment:46 @dd325 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).

comment:47 @janeforshort5 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).

comment:48 @dd325 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.

comment:49 @dd325 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.

comment:50 @mikeschinkel5 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?

comment:51 @t31os_5 years ago

  • Cc wp-t31os@… added

comment:52 in reply to: ↑ 38 @earthman1005 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!

http://earthman.ca/images/rolescaps1.jpg

comment:53 @demetris5 years ago

  • Cc dkikizas@… added

comment:54 @nacin5 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.

comment:55 @ashfame5 years ago

  • Cc ashishsainiashfame@… added

comment:56 @scribu4 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.

comment:57 @dd324 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.

Note: See TracTickets for help on using tickets.