[Sputnik-list] [RFC] Permissions System

Yuri Takhteyev yuri at sims.berkeley.edu
Thu Mar 27 18:47:47 GMT+2 2008


This may work, though we'll have to answer a few questions.

1. Where will the roles be defined?  Another field in the nodes?
2. How will the users be matched to roles?  Will this be up to the
authentication module?  Something like auth:user_has_role("Yuri", "Admin"),
returning true or false?
3. How do things like "edit_own" map onto specific actions.  Obviously there
is an extra step of indirection involved here.

This last part worries me most.  Do we need to assume the concept of
ownership upfront or will there be a way for a custom application like
forums to add a concept of ownership and then define things like edit_own?
How?

Let me make a pitch for what I was thinking myself.

Note that the current permission system is a bit bare, but is extensible.
Basically, to determine if the user is allowed to do something, you _run_
permissions with their username and the desired action as inputs, and get
true/false as output.  Right now the environment in which the permissions
are executed is fixed, but my plan was to make it easy you to add functions
to it and to allow passing lists and functions instead of single users and
actions.

So, instead of doing:

    deny(all, "save")
    deny(all, "edit")
    allow("Admin", "save")
    allow("Admin", "edit")

You could do something like this in @Root:

    save_and_edit = {"save", "edit"}
    is_admin = function() return user=="Admin" end
    is_authenticated = function() return user~=nil end
    deny(all, "delete")

And then put the following into @Lua_Config:

    deny(all, save_and_edit)
    all (is_admin, save_and_edit)

In @Forum:

    is_owner = function() return node.owner == user end
    deny(all, edit_and_save)
    allow(is_owner, edit_and_save)
    allow(is_moderator, edit_and_save)
    allow(is_admin, "delete")

Note that in this case we do not assume the concept of ownership.  We
introduce it on the spot.  This makes it possible to add anything else that
we want instead.  E.g., it wouldn't be too hard to do this instead:

    has_karma = function() return user.karma > 5 end
    allow(has_karma, edit_and_save)

Or, for that matter:

    allow(user.karma > 5, edit_and_save)

Could we perhaps organize this into two tiers: keep a procedural permission
system as a foundation and look at how one could add a declarative system
along the lines that you are describing on top of it?

Any comments or further ideas on how to make the system more flexible,
> without being absurdly comlpex?


I probably didn't do a good job (or, rather, didn't do the job) of
explaining how the current permission system works, but I think it _is_
simple: "permissions" are lua code that is run in a restrictive environment
that includes, among other things, the user name and the action that the
user is about to do.  This code returns true or false.  The permission
language that is provided by default is very bare.  But nodes can extend it
as they like, by defining functions into the environment of permissions, and
allowing downstream nodes to express permissions in pretty much any way you
want.

For instance, to implement your system, you can override my default "allow"
and "deny" and just use a single allow() function that expects a role and a
bundle of actions and calls deny(all, ...) before doing anything else:

    allow(edit_own, "Authenticated")
    allow(edit, "Moderator")
    allow(move, "Moderator")
    allow(delete, "Admin")

Can we somehow combine those ideas?

- yuri

-- 
http://sputnik.freewisdom.org/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.luaforge.net/pipermail/sputnik-list/attachments/20080327/5ff2bd6b/attachment.html


More information about the Sputnik-list mailing list