[pmwiki-users] pmwiki-2.0.beta29 out, needs testers and feedback

Joachim Durchholz jo at durchholz.org
Tue Apr 12 04:54:46 CDT 2005


Patrick R. Michaud wrote:

> Hello, all, I've just released PmWiki 2.0.beta29, which contains the
> preliminary support for user-based authorization semantics.

Great!

> Multiple passwords (separated by spaces) can now be set on pages and groups,
> thus entering "one two" for an edit password will means that either "one" or
> "two" will be accepted.  Because of this, passwords cannot contain
> spaces (I hope this won't be a major loss -- let me know if it will).

It isn't for me, but in some circles, pass phrases are en vogue.

It would be helpful if passwords were internally separated by something 
that can't be input - say, a nonprinting control character. (I know this 
makes the input page more complicated since this means things like 
dynamically generating input fields for all passwords, plus an empty 
field in case the admin wishes to add an extra password - sorry about that.)

> The password request field now appears within a normal skin layout 
> (i.e., with header, sidebar, footer); previously requests for 
> passwords were undecorated forms that appeared alone in the browser
> window.

Good.

> There is an (:if auth ...:) conditional markup available for 
> processing depending on the current authorizations in effect.  For
> example, one can create a bullet list with
>     
>     (:if auth read:)* [[View page -> {$Name}?action=browse]]
>     (:if auth edit:)* [[Edit page -> {$Name}?action=edit]]
>     (:if auth upload:)* [[Attachments -> {$Name}?action=upload]]
>     (:if auth attr:)* [[Page Attributes -> {$Name}?action=attr]]
>     (:if auth admin:)* You're logged in as admin
>     (:ifend:)
> 
> and only those items corresponding to the user's current authorizations
> will appear.  This should be very useful in creating action buttons.

Indeed.

This sounds as if (:if auth <action>:) is designed to work now and in 
the future - good.

> But, assuming there's already some mechanism in place for identifying
> and authenticating someone, pages can specify a password field of
> "id:xyz", which means to allow only user "xyz" the specified
> access.  For example, specifying an edit password of "id:alice"
> means that only user "alice" (and the admin) is allowed to edit the 
> page.  Multiple ids can be specified as either "id:alice,bob,carol"
> or "id:alice id:bob id:carol".  The special value "id:*" is used
> to mean any authenticated user, and users can be excluded via the
> minus sign, as in "id:-eve,*".

I'm a bit adverse to having both 'id:alice,bob,carol' and 'id:alice 
id:bob id:carol'. Multiple syntaxes are just too good at confusing users 
and the software likewise. Given that checking whether authentication 
works as expected is difficult, I'd like to have the mechanism as simple 
as possible.

When repeating multiple "id:" tags becomes cumbersome, it's the right 
time for implementing user groups ;-)

I'd also like to have exclusion and inclusion facilities. I.e. every 
blank-separated entry in the authentication string is meant to add to 
the pool of allowed users, except when it's prefixed with a "-" in which 
case it subtracts.

Some examples:

User "PatrickMichaud":
   id:PatrickMichaud

Users "PatrickMichaud" and "HansB":
   id:PatrickMichaud id:HansB

All users in the "admin" group:
   grp:admin

"PatrickMichaud" and all administrators:
   grp:admin id:PatrickMichaud

"PatrickMichaud", all administrators, and anybody who knows the password 
"secret":
   grp:admin id:PatrickMichaud pwd:"secret"
(Quotes are here to allow blanks in passwords. Quotes in a password 
could be entered using \".)

All administrators except "HansB" (sorry Hans *gg*):
   grp:admin -id:HansB

All administrators except "HansB", and all contributors:
   grp:admin -id:HansB grp:contrib

Note that the previous example will let HansB in regardless if he 
happens to be in group "contrib". If that's not what's wanted, say
   grp:admin grp:contrib -id:HansB

All anonymous users:
   grp:guests

All authenticated users:
   id:*


Some additional considerations:

We could say "group:" and "user:" instead of "grp:" and "id:".

The group of authenticated users could be named "users", giving us 
"grp:users" instead of "id:*".

Users can be in multiple groups. They are always in at least one group, 
either "users" or "guests".

Not sure whether having a singular or a plural name would be better. 
Since user groups will most likely end up with wiki pages of their own, 
the group names should probably also wikified (i.e. initial capital 
letter); I'm leaving the examples in all-lowercase here because I'm lazy :-)

Interpretation of the authentication string would consider all entries 
in turn. Example algorithm for handling one entry (pseudocode):

   denied = 0; /* Allow everybody in (this is a wiki after all) */
   for entry in explode(authentication_string, " ")
     if denied and entry[1] != "-"
       denied = UserAuthenticatesAs (entry);
     elseif !denied and entry[1] = "-"
       denied = ! UserAuthenticatesAs (substr(entry, 2, -1));
     end
   end

   function UserAuthenticatesAs (entry)
     if entry matches 'user:(.*)'
       return $1 = current_user_name
     elseif entry matches 'group:(.*)'
       return current_user_name is in group $1
     elseif entry matches 'pwd:"((\\"|\\\\|[^"\\])*?)"' then
       if ! isset (password)
         show password page
         abort processing
       else
         return password == $1
       end
     else
       return 0
     end

> Now then, how to activate user-based authorization?  Well, that's
> the part I need to work on next.  If you already have an authorization
> system in place for your webserver (e.g., through the use of .htaccess
> and/or .htpasswd files), then you may be able to simply do
> 
>     include_once('scripts/httpauth.php');
> 
> and PmWiki will automatically begin grabbing authentication information
> from the REMOTE_USER environment variable when it exists.
> 
> For others, I'm presently working on three modules:
>    1. A simple extension to perform authentication against ids/passwords
>       held and maintained in a .htpasswd file (i.e., bypassing the 
>       webserver's authentication but re-using existing tools)
>    2. A registration system to allow users to create an account and
>       passwords that are held in users' profiles pages
>    3. An system for sites that already have single-sign-on systems 
>       (e.g., LDAP, Active Directory, or RADIUS servers)

My knee-jerk reaction was to recommend PAM for all that - it already 
does everything and would give you a unified interface.
Sadly, PHP doesn't come with PAM support :-((
... but here's an interface library: ftp://ftp.netexpress.net/pub/pam
Compiles as a loadable PHP module, so it's still an option for those who 
can load custom PHP modules.

Unfortunately, PAM doesn't support setting up a local authentication 
framework. This means you live in the authentication framework of the 
server and can't set up your own user groups unless you have write 
access to /etc/pam.conf or /etc/pam.d/. Which (in 99.9% of cases) means 
you need root access, or a system administrator who's willing to set up 
a PAM service for you.

(Dunno why PAM isn't configurable picking up the configuration from a 
local directory.)

> Again, I'm looking for feedback, testing, suggestions, and questions
> so that I can improve the interfaces for this new system.

Done :-)

Regards
Jo



More information about the pmwiki-users mailing list