From d3ca495e61e0e9d66095b1aba2fd1995e564e841 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 8 Oct 2008 17:47:38 -0400 Subject: [PATCH] lockedit: Support specifying which users (and IP addresses) a page is locked for. This supports most of the ACL type things users have been wanting to be done. Closes: #443346 (It does not control who can read a page, but that's out of scope for ikiwiki.) --- IkiWiki.pm | 57 +++++++++++++++++++++ IkiWiki/Plugin/attachment.pm | 59 ---------------------- IkiWiki/Plugin/lockedit.pm | 10 +++- debian/changelog | 4 ++ doc/ikiwiki/pagespec.mdwn | 10 +++- doc/ikiwiki/pagespec/attachment.mdwn | 45 ++++------------- doc/plugins/lockedit.mdwn | 6 ++- doc/todo/ACL.mdwn | 3 +- po/es.po | 75 +++++++++++++++++----------- po/ikiwiki.pot | 12 ++--- 10 files changed, 147 insertions(+), 134 deletions(-) diff --git a/IkiWiki.pm b/IkiWiki.pm index 82370f430..633c51381 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -1919,4 +1919,61 @@ sub match_creation_year ($$;@) { #{{{ } } #}}} +sub match_user ($$;@) { #{{{ + shift; + my $user=shift; + my %params=@_; + + if (! exists $params{user}) { + return IkiWiki::FailReason->new("no user specified"); + } + + if (defined $params{user} && lc $params{user} eq lc $user) { + return IkiWiki::SuccessReason->new("user is $user"); + } + elsif (! defined $params{user}) { + return IkiWiki::FailReason->new("not logged in"); + } + else { + return IkiWiki::FailReason->new("user is $params{user}, not $user"); + } +} #}}} + +sub match_admin ($$;@) { #{{{ + shift; + shift; + my %params=@_; + + if (! exists $params{user}) { + return IkiWiki::FailReason->new("no user specified"); + } + + if (defined $params{user} && IkiWiki::is_admin($params{user})) { + return IkiWiki::SuccessReason->new("user is an admin"); + } + elsif (! defined $params{user}) { + return IkiWiki::FailReason->new("not logged in"); + } + else { + return IkiWiki::FailReason->new("user is not an admin"); + } +} #}}} + +sub match_ip ($$;@) { #{{{ + shift; + my $ip=shift; + my %params=@_; + + if (! exists $params{ip}) { + return IkiWiki::FailReason->new("no IP specified"); + } + + if (defined $params{ip} && lc $params{ip} eq lc $ip) { + return IkiWiki::SuccessReason->new("IP is $ip"); + } + else { + return IkiWiki::FailReason->new("IP is $params{ip}, not $ip"); + } +} #}}} + 1 diff --git a/IkiWiki/Plugin/attachment.pm b/IkiWiki/Plugin/attachment.pm index 2d1fe51cf..dcac3e820 100644 --- a/IkiWiki/Plugin/attachment.pm +++ b/IkiWiki/Plugin/attachment.pm @@ -289,63 +289,4 @@ sub attachment_list ($) { #{{{ return sort { $b->{mtime_raw} <=> $a->{mtime_raw} || $a->{link} cmp $b->{link} } @ret; } #}}} -package IkiWiki::PageSpec; - -sub match_user ($$;@) { #{{{ - shift; - my $user=shift; - my %params=@_; - - if (! exists $params{user}) { - return IkiWiki::FailReason->new("no user specified"); - } - - if (defined $params{user} && lc $params{user} eq lc $user) { - return IkiWiki::SuccessReason->new("user is $user"); - } - elsif (! defined $params{user}) { - return IkiWiki::FailReason->new("not logged in"); - } - else { - return IkiWiki::FailReason->new("user is $params{user}, not $user"); - } -} #}}} - -sub match_admin ($$;@) { #{{{ - shift; - shift; - my %params=@_; - - if (! exists $params{user}) { - return IkiWiki::FailReason->new("no user specified"); - } - - if (defined $params{user} && IkiWiki::is_admin($params{user})) { - return IkiWiki::SuccessReason->new("user is an admin"); - } - elsif (! defined $params{user}) { - return IkiWiki::FailReason->new("not logged in"); - } - else { - return IkiWiki::FailReason->new("user is not an admin"); - } -} #}}} - -sub match_ip ($$;@) { #{{{ - shift; - my $ip=shift; - my %params=@_; - - if (! exists $params{ip}) { - return IkiWiki::FailReason->new("no IP specified"); - } - - if (defined $params{ip} && lc $params{ip} eq lc $ip) { - return IkiWiki::SuccessReason->new("IP is $ip"); - } - else { - return IkiWiki::FailReason->new("IP is $params{ip}, not $ip"); - } -} #}}} - 1 diff --git a/IkiWiki/Plugin/lockedit.pm b/IkiWiki/Plugin/lockedit.pm index 7462de41c..f6cac6cdd 100644 --- a/IkiWiki/Plugin/lockedit.pm +++ b/IkiWiki/Plugin/lockedit.pm @@ -37,7 +37,10 @@ sub canedit ($$) { #{{{ return undef if defined $user && IkiWiki::is_admin($user); if (defined $config{locked_pages} && length $config{locked_pages} && - pagespec_match($page, $config{locked_pages})) { + pagespec_match($page, $config{locked_pages}, + user => $session->param("name"), + ip => $ENV{REMOTE_ADDR}, + )) { if (! defined $user || ! IkiWiki::userinfo_get($session->param("name"), "regdate")) { return sub { IkiWiki::needsignin($cgi, $session) }; @@ -51,7 +54,10 @@ sub canedit ($$) { #{{{ # XXX deprecated, should be removed eventually foreach my $admin (@{$config{adminuser}}) { - if (pagespec_match($page, IkiWiki::userinfo_get($admin, "locked_pages"))) { + if (pagespec_match($page, IkiWiki::userinfo_get($admin, "locked_pages"), + user => $session->param("name"), + ip => $ENV{REMOTE_ADDR}, + )) { if (! defined $user || ! IkiWiki::userinfo_get($session->param("name"), "regdate")) { return sub { IkiWiki::needsignin($cgi, $session) }; diff --git a/debian/changelog b/debian/changelog index a7b4cbb00..9947c8a58 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,6 +2,10 @@ ikiwiki (2.67) UNRELEASED; urgency=low * remove: Avoid $_ breakage. (Stupid, stupid perl.) * Updated Spanish translation from Victor Moral. + * lockedit: Support specifying which users (and IP addresses) a page + is locked for. This supports most of the ACL type things users have been + wanting to be done. Closes: #443346 (It does not control who can read a + page, but that's out of scope for ikiwiki.) -- Joey Hess Mon, 06 Oct 2008 16:07:50 -0400 diff --git a/doc/ikiwiki/pagespec.mdwn b/doc/ikiwiki/pagespec.mdwn index 156e3f6ca..c78666c40 100644 --- a/doc/ikiwiki/pagespec.mdwn +++ b/doc/ikiwiki/pagespec.mdwn @@ -22,8 +22,7 @@ match all pages except for Discussion pages and the SandBox: * and !SandBox and !*/Discussion -Some more elaborate limits can be added to what matches using any of these -functions: +Some more elaborate limits can be added to what matches using these functions: * "`link(page)`" - match only pages that link to a given page (or glob) * "`backlink(page)`" - match only pages that a given page links to @@ -41,6 +40,13 @@ functions: * "`title(glob)`", "`author(glob)`", "`authorurl(glob)`", "`license(glob)`", "`copyright(glob)`" - match pages that have the given metadata, matching the specified glob. +* "`user(username)`" - tests whether a modification is being made by a + user with the specified username. If openid is enabled, an openid can also + be put here. +* "`admin()`" - tests whether a modification is being made by one of the + wiki admins. +* "`ip(address)`" - tests whether a modification is being made from the + specified IP address. For example, to match all pages in a blog that link to the page about music and were written in 2005: diff --git a/doc/ikiwiki/pagespec/attachment.mdwn b/doc/ikiwiki/pagespec/attachment.mdwn index 1287fc0a4..2d33db748 100644 --- a/doc/ikiwiki/pagespec/attachment.mdwn +++ b/doc/ikiwiki/pagespec/attachment.mdwn @@ -16,45 +16,22 @@ check all attachments for virii, something like this could be used: The regular [[ikiwiki/PageSpec]] syntax is expanded with the following additional tests: -* maxsize(size) - - Tests whether the attachment is no larger than the specified size. - The size defaults to being in bytes, but "kb", "mb", "gb" etc can be - used to specify the units. +* "`maxsize(size)`" - Tests whether the attachment is no larger than the + specified size. The size defaults to being in bytes, but "kb", "mb", "gb" + etc can be used to specify the units. -* minsize(size) +* "`minsize(size)`" - Tests whether the attachment is no smaller than the + specified size. - Tests whether the attachment is no smaller than the specified size. - -* ispage() - - Tests whether the attachment will be treated by ikiwiki as a wiki page. - (Ie, if it has an extension of ".mdwn", or of any other enabled page - format). +* "`ispage()`" - Tests whether the attachment will be treated by ikiwiki as a + wiki page. (Ie, if it has an extension of ".mdwn", or of any other enabled + page format). So, if you don't want to allow wiki pages to be uploaded as attachments, use `!ispage()` ; if you only want to allow wiki pages to be uploaded as attachments, use `ispage()`. -* user(username) +* "`mimetype(foo/bar)`" - This checks the MIME type of the attachment. You can + include a glob in the type, for example `mimetype(image/*)`. - Tests whether the attachment is being uploaded by a user with the - specified username. If openid is enabled, an openid can also be put here. - -* admin() - - Tests whether the attachment is being uploded by one of the wiki admins. - -* ip(address) - - Tests whether the attacment is being uploaded from the specified IP - address. - -* mimetype(foo/bar) - - This checks the MIME type of the attachment. You can include a glob - in the type, for example `mimetype(image/*)`. - -* virusfree() - - Checks the attachment with an antiviral program. +* "`virusfree()`" - Checks the attachment with an antiviral program. diff --git a/doc/plugins/lockedit.mdwn b/doc/plugins/lockedit.mdwn index 07abce1af..71bf232ab 100644 --- a/doc/plugins/lockedit.mdwn +++ b/doc/plugins/lockedit.mdwn @@ -17,4 +17,8 @@ One handy thing to do if you're using ikiwiki for your blog is to lock posts in your blog, while still letting them comment via the Discussion pages. -Wiki administrators can always edit locked pages. +Wiki administrators can always edit locked pages. The [[ikiwiki/PageSpec]] +can specify that some pages are not locked for some users. For example, +"important_page and !user(joey)" locks `important_page` while still +allowing joey to edit it, while "!*/Discussion and user(bob)" prevents bob +from editing pages except for Discussion pages. diff --git a/doc/todo/ACL.mdwn b/doc/todo/ACL.mdwn index 373f89364..e9fb2717f 100644 --- a/doc/todo/ACL.mdwn +++ b/doc/todo/ACL.mdwn @@ -44,7 +44,8 @@ Also see [[!debbug 443346]]. >> Yes, writing per-user commit ACLs has become somewhat easier with recent >> features. Breaking `match_user` out of attachment, and making the >> lockedit plugin pass`user` and `ip` params when it calls `pagespec_match` ->> would be sufficient. --[[Joey]] +>> would be sufficient. And [[done]], configurable via +>> [[plugin/lockedit]]'s `locked_pages`. --[[Joey]] I am considering giving this a try, implementing it as a module. Here is how I see it: diff --git a/po/es.po b/po/es.po index 34a4d3669..ff02ea86a 100644 --- a/po/es.po +++ b/po/es.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: es\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-09-29 17:12-0400\n" +"POT-Creation-Date: 2008-10-08 17:34-0400\n" "PO-Revision-Date: 2008-10-07 12:44+0200\n" "Last-Translator: Víctor Moral \n" "Language-Team: Spanish \n" @@ -48,7 +48,7 @@ msgstr "Las preferencias se han guardado." msgid "You are banned." msgstr "Ha sido expulsado." -#: ../IkiWiki/CGI.pm:385 ../IkiWiki/CGI.pm:386 ../IkiWiki.pm:1153 +#: ../IkiWiki/CGI.pm:385 ../IkiWiki/CGI.pm:386 ../IkiWiki.pm:1166 msgid "Error" msgstr "Error" @@ -58,7 +58,8 @@ msgstr "Contenido añadido activado vía web." #: ../IkiWiki/Plugin/aggregate.pm:89 msgid "Nothing to do right now, all feeds are up-to-date!" -msgstr "¡ No hay nada que hacer, todas las fuentes de noticias están actualizadas !" +msgstr "" +"¡ No hay nada que hacer, todas las fuentes de noticias están actualizadas !" #: ../IkiWiki/Plugin/aggregate.pm:216 #, perl-format @@ -159,20 +160,20 @@ msgstr "ya existe una página de nombre %s" msgid "prohibited by allowed_attachments" msgstr "prohibido por la claúsula allowed_attachments" -#: ../IkiWiki/Plugin/attachment.pm:188 +#: ../IkiWiki/Plugin/attachment.pm:189 msgid "bad attachment filename" msgstr "nombre de archivo adjunto erróneo" -#: ../IkiWiki/Plugin/attachment.pm:230 +#: ../IkiWiki/Plugin/attachment.pm:231 msgid "attachment upload" msgstr "enviado el adjunto" -#: ../IkiWiki/Plugin/autoindex.pm:103 +#: ../IkiWiki/Plugin/autoindex.pm:105 msgid "automatic index generation" msgstr "creación de índice automática" #: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:261 -#: ../IkiWiki/Plugin/inline.pm:323 ../IkiWiki/Plugin/opendiscussion.pm:26 +#: ../IkiWiki/Plugin/inline.pm:326 ../IkiWiki/Plugin/opendiscussion.pm:26 #: ../IkiWiki/Plugin/orphans.pm:37 ../IkiWiki/Render.pm:79 #: ../IkiWiki/Render.pm:149 msgid "discussion" @@ -303,20 +304,20 @@ msgstr "falta el parámetro pages" msgid "unknown sort type %s" msgstr "no conozco este tipo de ordenación %s" -#: ../IkiWiki/Plugin/inline.pm:282 +#: ../IkiWiki/Plugin/inline.pm:285 msgid "Add a new post titled:" msgstr "Añadir una entrada nueva titulada:" -#: ../IkiWiki/Plugin/inline.pm:298 +#: ../IkiWiki/Plugin/inline.pm:301 #, perl-format msgid "nonexistant template %s" msgstr "la plantilla %s no existe " -#: ../IkiWiki/Plugin/inline.pm:331 ../IkiWiki/Render.pm:83 +#: ../IkiWiki/Plugin/inline.pm:334 ../IkiWiki/Render.pm:83 msgid "Discussion" msgstr "Comentarios" -#: ../IkiWiki/Plugin/inline.pm:568 +#: ../IkiWiki/Plugin/inline.pm:571 msgid "RPC::XML::Client not found, not pinging" msgstr "No he encontrado el componente RPC::XML::Client, no envío señal alguna" @@ -324,13 +325,15 @@ msgstr "No he encontrado el componente RPC::XML::Client, no envío señal alguna msgid "failed to run dot" msgstr "no he podido ejecutar el programa dot" -#: ../IkiWiki/Plugin/lockedit.pm:46 ../IkiWiki/Plugin/lockedit.pm:60 +#: ../IkiWiki/Plugin/lockedit.pm:49 ../IkiWiki/Plugin/lockedit.pm:66 +#, perl-format msgid "%s is locked and cannot be edited" msgstr "La página %s está bloqueada y no puede modificarse" #: ../IkiWiki/Plugin/mdwn.pm:44 msgid "multimarkdown is enabled, but Text::MultiMarkdown is not installed" -msgstr "el modo multimarkdown está activo, pero no está instalado Text::MultiMarkdown" +msgstr "" +"el modo multimarkdown está activo, pero no está instalado Text::MultiMarkdown" #: ../IkiWiki/Plugin/mdwn.pm:67 #, perl-format @@ -393,7 +396,9 @@ msgstr "Error creando la cuenta de usuario." #: ../IkiWiki/Plugin/passwordauth.pm:257 msgid "No email address, so cannot email password reset instructions." -msgstr "No tengo dirección de correo electrónica, así que no puedo enviar instrucciones para reiniciar la contraseña" +msgstr "" +"No tengo dirección de correo electrónica, así que no puedo enviar " +"instrucciones para reiniciar la contraseña" #: ../IkiWiki/Plugin/passwordauth.pm:291 msgid "Failed to send mail" @@ -401,7 +406,9 @@ msgstr "No he podido enviar el mensaje de correo electrónico" #: ../IkiWiki/Plugin/passwordauth.pm:293 msgid "You have been mailed password reset instructions." -msgstr "Las instrucciones para reinicar la contraseña se le han enviado por correo electrónico" +msgstr "" +"Las instrucciones para reinicar la contraseña se le han enviado por correo " +"electrónico" #: ../IkiWiki/Plugin/passwordauth.pm:328 msgid "incorrect password reset url" @@ -558,16 +565,16 @@ msgstr "%s no está en el directorio fuente por lo que no puede ser borrada" msgid "%s is not a file" msgstr "%s no es un archivo" -#: ../IkiWiki/Plugin/remove.pm:112 +#: ../IkiWiki/Plugin/remove.pm:115 #, perl-format msgid "confirm removal of %s" msgstr "confirme el borrado de %s" -#: ../IkiWiki/Plugin/remove.pm:148 +#: ../IkiWiki/Plugin/remove.pm:152 msgid "Please select the attachments to remove." msgstr "Por favor seleccione los adjuntos que serán borrados." -#: ../IkiWiki/Plugin/remove.pm:188 +#: ../IkiWiki/Plugin/remove.pm:192 msgid "removed" msgstr "borrado" @@ -604,20 +611,20 @@ msgstr "cambiando de nombre %s" msgid "Also rename SubPages and attachments" msgstr "También cambia de nombre las subpáginas y los adjuntos" -#: ../IkiWiki/Plugin/rename.pm:223 +#: ../IkiWiki/Plugin/rename.pm:224 msgid "Only one attachment can be renamed at a time." msgstr "Únicamente un adjunto puede ser renombrado a la vez." -#: ../IkiWiki/Plugin/rename.pm:226 +#: ../IkiWiki/Plugin/rename.pm:227 msgid "Please select the attachment to rename." msgstr "Por favor, seleccione el adjunto al que cambiar el nombre." -#: ../IkiWiki/Plugin/rename.pm:332 +#: ../IkiWiki/Plugin/rename.pm:338 #, perl-format msgid "rename %s to %s" msgstr "%s cambia de nombre a %s" -#: ../IkiWiki/Plugin/rename.pm:484 +#: ../IkiWiki/Plugin/rename.pm:490 #, perl-format msgid "update for rename of %s to %s" msgstr "actualizado el cambio de nombre de %s a %s" @@ -762,13 +769,17 @@ msgstr "complementos" #: ../IkiWiki/Plugin/websetup.pm:395 msgid "" "The configuration changes shown below require a wiki rebuild to take effect." -msgstr "Los cambios en la configuración que se muestran más abajo precisan una reconstrucción del wiki para tener efecto." +msgstr "" +"Los cambios en la configuración que se muestran más abajo precisan una " +"reconstrucción del wiki para tener efecto." #: ../IkiWiki/Plugin/websetup.pm:399 msgid "" "For the configuration changes shown below to fully take effect, you may need " "to rebuild the wiki." -msgstr "Para que los cambios en la configuración mostrados más abajo tengan efecto, es posible que necesite reconstruir el wiki." +msgstr "" +"Para que los cambios en la configuración mostrados más abajo tengan efecto, " +"es posible que necesite reconstruir el wiki." #: ../IkiWiki/Plugin/websetup.pm:433 #, perl-format @@ -780,7 +791,9 @@ msgstr "

Error: %s finaliza con código distinto de cero (%s)" msgid "" "symlink found in srcdir path (%s) -- set allow_symlinks_before_srcdir to " "allow this" -msgstr "encontrado un enlace simbólico en la ruta del directorio fuente (%s) -- use la directiva allow_symlinks_before_srcdir para permitir la acción" +msgstr "" +"encontrado un enlace simbólico en la ruta del directorio fuente (%s) -- use " +"la directiva allow_symlinks_before_srcdir para permitir la acción" #: ../IkiWiki/Render.pm:277 ../IkiWiki/Render.pm:302 #, perl-format @@ -926,12 +939,14 @@ msgstr "no puedo emplear varios complementos rcs" msgid "failed to load external plugin needed for %s plugin: %s" msgstr "no he podido cargar el complemento externo %s necesario para %s" -#: ../IkiWiki.pm:1136 +#: ../IkiWiki.pm:1149 #, perl-format msgid "preprocessing loop detected on %s at depth %i" -msgstr "se ha detectado en la página %s un bucle de preprocesado en la iteración número %i" +msgstr "" +"se ha detectado en la página %s un bucle de preprocesado en la iteración " +"número %i" -#: ../IkiWiki.pm:1645 +#: ../IkiWiki.pm:1658 msgid "yes" msgstr "si" @@ -949,7 +964,9 @@ msgstr "¿ Qué sistema de control de versiones empleará ?" #: ../auto.setup:20 msgid "What wiki user (or openid) will be wiki admin?" -msgstr "¿ Qué usuario del wiki (ó identificador openid) será el administrador del wiki ? " +msgstr "" +"¿ Qué usuario del wiki (ó identificador openid) será el administrador del " +"wiki ? " #: ../auto.setup:23 msgid "What is the domain name of the web server?" diff --git a/po/ikiwiki.pot b/po/ikiwiki.pot index dbbf986d5..f07f2bf62 100644 --- a/po/ikiwiki.pot +++ b/po/ikiwiki.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-10-05 19:11-0400\n" +"POT-Creation-Date: 2008-10-08 17:34-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -167,7 +167,7 @@ msgstr "" msgid "attachment upload" msgstr "" -#: ../IkiWiki/Plugin/autoindex.pm:103 +#: ../IkiWiki/Plugin/autoindex.pm:105 msgid "automatic index generation" msgstr "" @@ -321,7 +321,7 @@ msgstr "" msgid "failed to run dot" msgstr "" -#: ../IkiWiki/Plugin/lockedit.pm:46 ../IkiWiki/Plugin/lockedit.pm:60 +#: ../IkiWiki/Plugin/lockedit.pm:49 ../IkiWiki/Plugin/lockedit.pm:66 #, perl-format msgid "%s is locked and cannot be edited" msgstr "" @@ -554,16 +554,16 @@ msgstr "" msgid "%s is not a file" msgstr "" -#: ../IkiWiki/Plugin/remove.pm:113 +#: ../IkiWiki/Plugin/remove.pm:115 #, perl-format msgid "confirm removal of %s" msgstr "" -#: ../IkiWiki/Plugin/remove.pm:150 +#: ../IkiWiki/Plugin/remove.pm:152 msgid "Please select the attachments to remove." msgstr "" -#: ../IkiWiki/Plugin/remove.pm:190 +#: ../IkiWiki/Plugin/remove.pm:192 msgid "removed" msgstr ""