Go to main content

Textpattern CMS support forum

You are not logged in. Register | Login | Help

#1 2010-04-26 14:43:03

Siguo
Member
From: Beijing, China
Registered: 2008-05-22
Posts: 44

1. Topics about User & Permissions: the three level permissions

I’ve read:
zem’s section permission design
squaredeye’s Rights and Permissions Workgroup
janvi’s Modifying User Account Roles and Privileges, Sections

all posts are valuable, but most are 2005s, 2006s, and in the admin_config.php, Dean has said from txp 1.0rc4:

“Only the Permission-Settings at the bottom this file are still actively used, and these will be moved to the db before the next release”.

now is 2010, we haven’t event step a little foot.

So, I want to begin this work just now, maybe my work is not perfect, but even a little step is a step.

In this thread, you can help me through these ways:

1. Share your thoughts about this topic.
2. Point out what’s wrong and what’s right about my thoughts.
3. What’s your need with users, rights and permissions.
4. Any other ways that help this work.

Ok, let’s begin. One thread One Topic.
—————————————————————————————————————

When I plan to begin this work, I realized I must learn(or borrow?) something from other projects. At last, I prefer to the famous vBulletin, after studied it’s code, I think that will be good start. (Is this borrow legal or illegal?)

In vBulletin manual, the Users, and Usergroups and Permissions chapter give detail about how the users rights and permissions designed. If you interested in this topic, I recommend you take a look.
you can download it from here

In vBulletin’s design, four concept are the core:

1). Inheritance. The permissions you specify in usergroup level(global level) will be used everywhere unless you override them at a low level, like a section.

2). bitwise Or exceptions. The basic idea is that if a user specify conflicting permissions, the greater permission overrides. this apply to multiple groups.

3). bitwise And exceptions. The basic idea is that if different level specify different permissions, all level permissions are caculated. this apply to section level permissions.

4). the highest exceptions. the basic idea is the user permission is the highest permission, it overrides the usergroup and section persions.

Permissions are applied with this flow:

usergroup permission = usergroup1 permission | usergroup2 permission | …

if(we are in a section[or event]))
{
    if(we has user permissions)
    {
          if(user permissions set to yes)
          {
               use usergroup permission;
          }else{
               deny;
          }
    }else{
          if(we has section permission)
          {
               use (usergroup permission & section permission);
          }else{
               use usergroup permission;
          }
    }
}else{
    use usergroup permission;
}

So there will be three level permission: usergroup permission, section(event) permission, user permission.

What do you think? any comment are welcome.

Last edited by Siguo (2010-04-26 14:43:36)

Offline

#2 2010-04-26 15:56:39

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 11,392
Website GitHub

Re: 1. Topics about User & Permissions: the three level permissions

First of all, thanks for re-opening the debate. I agree permissions is long overdue for a look.

I do, however, wonder if user-level permissions are a tad over-the-top. How many times does one need to give a single user different permissions to someone else? Do you have some concrete examples that make sense for a TXP site you have in mind? The complexity it adds to the interface is the key thing I’m worried about here; configuring it all becomes a sea of dropdowns and widgets, which is just plain ugly to deal with and off-putting for people to administer.

So my first question is: can we get away with the current granularity of group-level permissions?

My gut instinct is yes as long as the groups (“roles”) are extendable/editable. If you need to make a special user, make a group first and assign the permissions to the group, adding the user to that group. Yes it’s one extra step in the short-term (1: make role, 2: make/assign user in role) but it simplifies everything and still allows the flexibility to define your own special roles if you wish.

I wonder if the reason the $txp_privileges array hasn’t been migrated from the config file to the database in all these years is twofold:

  1. File access is faster than the database by several orders of magnitude
  2. The existing six (seven if counting from 0) levels cover 98% of use cases of TXP

So is it really worth making changes for 2% of users? That’s a rhetorical point, btw :-)

I’ve recently had the privilege of working on a site where we needed a couple more roles to be defined. It was simple to add the two new roles into the admin_config.php file, assign the roles to users and TXP just worked. The reason? They’re just numbers: there’s no hierarchical relevance associated with the numbers whatsoever. It’s beautiful and elegant. Except it requires a hack to a core file which I don’t like.

As I mentioned in another thread, one way around this is to have a dedicated, known file that users can create/edit which the core reads to define other roles (or even, perhaps, override the built-in roles?) It’s simple, it’s ugly, but it means upgrades are simpler and the speed is retained.

If, however, the database is the correct place for the privs, my thinking for at least a part-way solution is as follows. Essentially, for minimum impact with the rest of the codebase, $txp_privileges as an array has to exist as soon as admin_config.php is included. So what if there were two tables in TXP called txp_privs and txp_roles. The latter simply comprises an ID (0-6 currently) and name (for gTxt() purposes) :

ID | Name
---------------------
0  | none
1  | publisher
2  | managing_editor
...

The txp_privs table simply maps tabs/features to roles:

area        | priv
-----------------------
admin       | 0
admin       | 1
admin       | 2
admin       | 3
admin       | 4
admin       | 5
admin       | 6
admin.edit  | 1
...
css         | 1
css         | 2
css         | 6
...

A simple query on txp_privs using ‘GROUP BY area’ returns — give or take — the $txp_privileges array as it is today. A second call could fetch the roles list, which could be made global and saves having to redefine it in the few places it pops up throughout the core (or indeed in plugins).

So admin_config.php is simply two extra DB calls at the start of processing to retrieve the lists and create $txp_privileges / $txp_roles dynamically. From then on, no further speed impact.

So far no benefit to TXP, and it’s slower.

As a point of reference, I’d change add_privs() so it could take either a list of numbers (as now) or names. Same with any of the privs functions that deal in numbers now. Existing plugins can add to the array exactly as they do currently, using add_privs() on the fly each page load, but they can — and probably should — start to use names instead of IDs.

For the fixed 6 (7) roles that cannot be deleted it doesn’t matter so much — aside from readability — but for user-defined roles it becomes important. Either way, plugins need never touch the tables and are largely oblivious to the new structure behind the scenes.

But now, a judicial management plugin could allow someone to define a role by adding it to the database using a new function we could(?) provide in the core — add_role() — which auto-increments the ID. That’s a permanent change to the txp_roles table. You then have a further choice: utilise this role in a plugin by using add_privs() and giving its ID (preferably name), or directly add an area/priv combo to the txp_privs table. If you do the latter it again changes the table and becomes available automatically so you don’t need to add_privs each time — thus making admin-side plugins (slightly) faster.

Plugins could create_privs() in the database at install time using the plugin lifecycle callback and not have to do it every page load. A new remove_privs() function would allow clean up on uninstall if necessary.

This is where it becomes important to use names instead of IDs because plugins adding roles to the database willy nilly from different load orders cannot guarantee a dedicated ID across installations. Since names are governed by the plugin prefix, we should be ok here from a clashing point of view — but if you wish to violate this rule, it’s up to the administrator, and standard disclaimers apply.

The benefits:

  • backwards compatibility is preserved
  • it creates a platform for plugins, not a raft of core features so no new interface widgets are required
  • plugins can create roles ad-hoc, or on install
  • plugins can create arbitrary priv areas either permanently or on-the-fly
  • plugins have greater freedom: get the privs from the arrays or make calls to the txp_privs/txp_roles tables directly at their discretion
  • management plugins can spring up that allow people to create more roles and use them creatively in apps
  • management plugins that allow people to reassign existing roles can appear (whether this is a good idea or not is up to the core: should you be allowed to reassign the core 6 levels, or should you only be allowed to augment them so if one doesn’t fit your needs you create a new role and define it?)
  • new roles can be labelled in different languages as now using entries in txp_lang — the management plugin for creating roles should also manage this — and of course can be overriden with wet_babble
  • single access point in the core: no need to redefine roles inside functions that need them = easier maintenance
  • no hacking of a core file means smoother upgrades for developers

Negatives:

  • a smidge slower to initially grab the stuff from the DB

One thing it doesn’t address is section hierarchy. Imagine having hundreds of sub-sections in some future TXP version and you begin to see how tricky it would be to build an interface for someone to manage which roles/users can access which sections. I wonder again if the existing roles can be used here with a slight tweak to the admin side code in txp_section.php? So instead of simply:

'section' => '1,2,3,    6',

a plugin could offer the ability (behind the scenes of course, wrapped up in a shiny interface) to create new roles that ended up like this:

'section.about' => '1,2,3',
'section.blog' => '3,6',
'section.products' => '4,5,6,7,11',
'section.products.robots-in-disguise' => '9,12',
...

If the core simply honoured whatever sections were defined — even though it wouldn’t define any out of the box — plugins could spring up to help people manage this. This could be extended to the Write tab so you could only allow certain priv levels to post to certain sections.

The advantage? Site admins can define their own hierarchy. If you want to give certain roles access to all sections, add them to a top-level section and they can automatically see sub-sections. The only thing this doesn’t address very neatly is exceptions. If you want someone to see all (sub)sections except one or two, you could define a new role but you’d have to add them to each subsection via this mythical section-admin plugin, which could be interesting. But ultimately, not out of the realms of possiblity.

All this is actually a fairly small change set to the core code. It keeps the core light and airy with no implied restrictions on how site admins define their user base. And it alllows unending flexibility depending on the cunning of site administrators / plugin authors. And it keeps things backwards-compatible because, as far as older versions of plugins are concerned, $txp_permissions is defined for them.

I’ve not thought it through fully yet so I’ve probably missed something obvious. Errors, omissions, extensions or better ideas are welcome.

Last edited by Bloke (2010-04-26 16:02:02)


The smd plugin menagerie — for when you need one more gribble of power from Textpattern. Bleeding-edge code available on GitHub.

Txp Builders – finely-crafted code, design and Txp

Offline

#3 2010-04-26 18:52:37

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 11,392
Website GitHub

Re: 1. Topics about User & Permissions: the three level permissions

Addendum: normalization purists may notice that txp_privs barely meets second normal form. There is a reason for this seeming oversight: ease of query when performing CRUD on the table. Having to join txp_privs to txp_areas every time we wanted to find something out or make a change was an overhead I thought was outweighed in lieu of satisfying the academics.

Although looking at the table structure does give me the uncontrollable urge to have a wash. If anyone can think of a better way to do it, please shout.


The smd plugin menagerie — for when you need one more gribble of power from Textpattern. Bleeding-edge code available on GitHub.

Txp Builders – finely-crafted code, design and Txp

Offline

#4 2010-04-27 01:54:58

Siguo
Member
From: Beijing, China
Registered: 2008-05-22
Posts: 44

Re: 1. Topics about User & Permissions: the three level permissions

How many times does one need to give a single user different permissions to someone else?

not so many. the multigroup, section(event) and suer permissions are just exceptions. If someone doesn’t need them, just use the usergroup permissions, and leave these alone.

However, the three level design open a door for txp to fit more need with build more interactive sites, like bbs, sns, etc.

Do you have some concrete examples that make sense for a TXP site you have in mind?

yes, for example, if one of site users is good at css, and we want temporarily allow him to improve the site’s css, then we can give him css permission for a while, after the work is done, we can remove this permission.

The complexity it adds to the interface is the key thing I’m worried about here;

that’s not so complex, if someone don’t need it, just leave it alone. We just got the power, you may use it, and may not use it.

If you need to make a special user, make a group first and assign the permissions to the group, adding the user to that group. Yes it’s one extra step in the short-term (1: make role, 2: make/assign user in role) but it simplifies everything and still allows the flexibility to define your own special roles if you wish.

the key of the three level permissions is you can make exceptions, without losing his/her original group permission. this is a power, not a flexibility.
for example, imaging one of our designers is good at design topics, then we can give him article permissions, meanwhile he is still a designer.
the three level permission design simplify the work, not flexify the work.

File access is faster than the database by several orders of magnitude.

I don’t think so, most time database operation is faster than file access.

for example, like the has_privs() function in txplib_misc.php, which use two function, in_array() and explode() to get the true or false result.

in_array($privs[$user], explode(‘,’, $txp_permissions[$res])) —>result

the in_array() function, which cost arraysize * arrayitemlength times comparation.
the explode() function, which cost strlength times comparation.

if we use database, though we use one or two more sql query, but we can get the same result just use one comparation:

if(a & b) —> result

The existing six (seven if counting from 0) levels cover 98% of use cases of TXP

Maybe we can also say this is txp’s limit. I think you haven’t count all of the “use cases”, like a bulletin board, you just count the “txp’s use case”.

my thinking for at least a part-way solution is as follows….

1. the first question is where do you put the area names? you can put them in an array, or put them in a table. but we must know where to get them.

2. the shortcoming your design is that it will be difficult when deal with exceptions, like section or even user permissions.

for example:
if we want set usergroup A can publish article, except section B

first, we set publish permission:

area | pirvs
article.publish | usergroupA

second, you should set section permission:
area | pirvs
sectionB.article.not.publish | usergroupA

or you have to set each usergroups permissions,
area | pirvs
sectionB.article.publish | usergroupB
sectionB.article.publish | usergroupC
…but not usergroupA

All this lead to the first quesion, where do these areanames come from? how do you produce them? when you deal with plenty of areas, sections, even users, it will be too complex.

my design put the section permission in an alone table, all is simple.
in usergroup table, we can set:
usergroup | pirvsmask (this will include article.publish, set 0 or 1)
usergroupA | 111(this 1 is article publish)001

in section permission table, we can set:
section | usergroup | pirvsmask (this will include article.publish, set 0 or 1)
sectionB | usergroupA | 110(this 0 is article publish)111

So, your design just put all these in one table, this makes the logic very complex.
my design just divide these into two table, this makes the logic very simple.

Last edited by Siguo (2010-04-28 04:05:35)

Offline

#5 2010-04-27 07:53:54

Siguo
Member
From: Beijing, China
Registered: 2008-05-22
Posts: 44

Re: 1. Topics about User & Permissions: the three level permissions

some examples your design is difficult to deal with:

how can you deal with “allow file upload but limit file size to 200k”?

and “allow article publish but can’t make it sticky”?

and “allow edit own article only witnin 10 days”?

and more and more……

Last edited by Siguo (2010-04-27 23:22:05)

Offline

#6 2010-04-27 16:34:15

edmungo
Member
Registered: 2006-07-10
Posts: 12

Re: 1. Topics about User & Permissions: the three level permissions

I don’t know the back end code well enough to know the best technical route, but I use TXP for a range of sites, small to large, and by far the weakest aspect of this otherwise great CMS is the user permissions. For my needs TXP privileges are all wrong. Restrictive or permissive in an entirely ineffective and obtuse way. So bad I’ve hardly found one instance where they’ve proved useful.

As the administrator of a large collaborative TXP based corporate website (dartington.org) with thousands of pages and many sections the first thing I’d like to do is restrict editors’ ability to access sections they have ‘no right’ to edit. But TXP doesn’t do this. Second it makes sense for me to allow editors to do basically what they like within their own section and colleagues in the same department should be able to edit each other’s content. Again TXP can’t do this.

What we have instead is very clunky. The granularity and structure of access rights makes no sense at all to me. What’s the point in restricting edit rights after an article is published – it’s more important to be able to amend something if it’s live. Far more fundamental the lack of a usergroup methodology seems a huge omission – I can either only edit my own images, files and articles, or I can edit everybody’s!?

It frustrates me to see Textpattern described as ‘good for blogging’ etc. on review sites, when I know it’s capable of running sophisticated web sites of any form. If TXP only had sensible section-based admin restrictions it would immediately become more attractive to website managers. Indeed, if we could just extend the envelope a bit further into the realm of front end user permissions (aka membership) and bingo you have a solid Web 2.0 platform as well.

I’m sure the current system sufficed when TXP developed. It’s quick and fairly straightforward to implement, and it does give an administrator some kind of restrictive capability, even if it is half-baked. But the TXP developers are knobbling the strength and power of their own CMS. With just a few changes to the privileges system you could have a much more powerful platform for any type of site.

PS: The other reason for TXP being misunderstood as a mere blogging tool is it’s out-of-the-box implementation which is awful and doesn’t do it any justice.

Offline

#7 2010-04-27 19:43:41

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 11,392
Website GitHub

Re: 1. Topics about User & Permissions: the three level permissions

edmungo wrote:

the first thing I’d like to do is restrict editors’ ability to access sections they have ‘no right’ to edit.

That makes sense. TXP’s granularity doesn’t currently cater for this but there’s no reason it couldn’t do it (almost) right now with a tiny mod. Add your section names to lib/admin_config.php like:

'section.name1' => '5,6,7',
'section.name2' => '5,7,9',
...

Define your new user roles (if you want them) in the $levels array in include/txp_admin.php and then write a plugin like this:

if (@txpinterface == 'admin') {
	register_callback('smd_per_sec', 'article_ui', 'section');
}

function smd_per_sec($event, $step, $data, $rec) {
	global $txp_user;

	$seclist = array();
	$out = '';

	$rs = safe_column('name', 'txp_section', "name != 'default'");
	foreach ($rs as $sec) {
		if (has_privs('section.'.$sec)) {
			$seclist[] = $sec;
		}
	}

	if ($seclist) {
		$seclist = selectInput('Section', $seclist, $rec['Section'], false, '', 'section');
	} else {
		$seclist = 'No sections permitted';
	}

	return n.graf('<label for="section">'.gTxt('section').'</label> '.
		'<span class="small">['.eLink('section', '', '', '', gTxt('edit')).']</span>'.br.
		$seclist).n.'</fieldset>';
}

Assign users to new priv levels as you see fit. Job done.

OK, it’s not exactly out-of-the-box yet, and there’s very little defensive coding in there yet, but it goes to show it’s very simple to do with the current roles-based system.

The question here is how to open up the permissions such that a plugin (or possibly the core if it doesn’t add too much overhead) can take advantage of them and save you having to hack the two core files just to define new roles and new areas. After that’s done people can code away to their heart’s content writing management and privs plugins to help move TXP towards the powerhouse you describe.

Siguo has approached it from the ground-up, doing it “properly”. And it’s impressive. Bitwise operators make a lot of sense to computers at the machine level for the simple fact they’re damn quick — as pointed out by Siguo. At the PHP level the performance gain is probably not as pronounced. But I’m no opcoder any more so that’s fine and I’m cool with it as long as an interface can be constructed such that you don’t require a degree in nuclear physics to be able to assign roles/users/sections to your community!

If we can do it like that and it proves to be insanely useful and doesn’t add much overhead and can maintain some semblance of backwards compatibility with prior versions/plugins then that works for me. I’ve not thought about how to even begin to implement such a beast so I’m not qualified to comment yet.

But I don’t think the roles-based system is dead quite yet. Perhaps I’ve missed the point, though, given that both of you feel so strongly about it :-)

From what I can see, if we could create our own roles and create our own area rules to assign to those roles, that’s 80% of the system done. I’ve just proved above that TXP can do it right now with very minimal changes. The only missing things that are not catered for are individual user privs (if required), multiple groups, and ‘exceptions’. So if the above changes could be made right now such that the current privs/areas are defined in a user-editable file OR put into the database in a suitable table structure, we’re nearly there. All it then takes is a clever plugin author.

the lack of a usergroup methodology seems a huge omission – I can either only edit my own images, files and articles, or I can edit everybody’s!?

Fair point. But if you could create your own roles (a.k.a. usergroups), surely you could create a group called ‘products-dept’ as priv level, I dunno, 9 or something and then assign all the members of that department to that new group. They can all then edit each other’s articles because they’re all ‘the owner’.

The problem here is what if you want someone to be a member of more than one group — e.g. they’re in the Products Department but they also volunteer in the library so they need to be able to administer the library section too. I fully admit the current, simple roles-based system won’t solve that even if it’s extendable. One way round this could be to allow the select list in the Admin->Users screen to be a multi-select. Essentially then you could assign someone to N roles and it’d store them in the user’s table as a list of numbers. If the require_privs/has_privs functions can be altered to cater for a list of privs here, that might just do it. It feels dirty and hackish because it should be done in a separate table so perhaps that’s not the way to go. But it’d work.

the TXP developers are knobbling the strength and power of their own CMS

Thanks! We aim to please ;-)

With just a few changes to the privileges system you could have a much more powerful platform for any type of site.

Exactly my point. The debate here is how to go about it. A full, heavy and ultra-configurable user-system with management screens and stuff built into the core, or a more low-key approach to allow plugin authors to carry the torch.

The other reason for TXP being misunderstood as a mere blogging tool is it’s out-of-the-box implementation which is awful and doesn’t do it any justice.

True. Does this help ? (discussion)

Last edited by Bloke (2010-04-27 19:46:40)


The smd plugin menagerie — for when you need one more gribble of power from Textpattern. Bleeding-edge code available on GitHub.

Txp Builders – finely-crafted code, design and Txp

Offline

#8 2010-04-28 06:47:17

Siguo
Member
From: Beijing, China
Registered: 2008-05-22
Posts: 44

Re: 1. Topics about User & Permissions: the three level permissions

But I don’t think the roles-based system is dead quite yet. Perhaps I’ve missed the point, though, given that both of you feel so strongly about it :-)
——————————————————-

No, I too don’t think the roles-based system is dead, and I think it will not.

The reason we want an improved system is because the txp’s present roles-based system is only a basic roles-based system, it’s lack of deal with exceptions. As if it only has usergroup in my design.

And in my design, the multigroup, section permission and user permission are all exceptions, with these exceptions, the present basic roles system just become more powerful.

But that still is roles-based system.

Last edited by Siguo (2010-04-28 07:34:49)

Offline

Board footer

Powered by FluxBB