fu: Close-up of Fu, bringing a scoop of water to her mouth (Default)
fu ([personal profile] fu) wrote in [site community profile] changelog2011-12-28 07:56 am

[dw-free] Need more flexible listing of privs

[commit: http://hg.dwscoalition.org/dw-free/rev/dea9381b157c]

http://bugs.dwscoalition.org/show_bug.cgi?id=3018

Move listing and removal of privs into hooks.

Patch by [personal profile] kareila.

Files modified:
  • cgi-bin/DW/Hooks/PrivList.pm
  • cgi-bin/ljlib.pl
--------------------------------------------------------------------------------
diff -r 7320f6e8c271 -r dea9381b157c cgi-bin/DW/Hooks/PrivList.pm
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cgi-bin/DW/Hooks/PrivList.pm	Wed Dec 28 15:56:56 2011 +0800
@@ -0,0 +1,164 @@
+#!/usr/bin/perl
+#
+# DW::Hooks::PrivList
+#
+# This module implements the listing of valid arguments for each
+# known user privilege in dw-free.  Any site that defines a different
+# set of privs or privargs must create additional hooks to supplement
+# this list.
+#
+# Authors:
+#      Jen Griffin <kareila@livejournal.com>
+#
+# Copyright (c) 2011 by Dreamwidth Studios, LLC.
+#
+# This program is free software; you may redistribute it and/or modify it under
+# the same terms as Perl itself. For a copy of the license, please reference
+# 'perldoc perlartistic' or 'perldoc perlgpl'.
+#
+
+package DW::Hooks::PrivList;
+
+use strict;
+use LJ::Hooks;
+
+use LJ::DB;
+use LJ::Lang;
+use LJ::Support;
+
+
+LJ::Hooks::register_hook( 'privlist-add', sub {
+    my ( $priv ) = @_;
+    return unless defined $priv;
+    my $hr = {};
+
+    # valid admin privargs are the same as defined DB privs
+    if ( $priv eq 'admin' ) {
+        my $dbr = LJ::get_db_reader();
+        $hr = $dbr->selectall_hashref(
+            'SELECT privcode, privname FROM priv_list', 'privcode' );
+        # unfold result
+        $hr->{$_} = $hr->{$_}->{privname} foreach keys %$hr;
+        # add subprivs for supporthelp
+        my $cats = LJ::Support::load_cats();
+        $hr->{"supporthelp/$_"} = "$hr->{supporthelp} for $_"
+            foreach map { $_->{catkey} } values %$cats;
+    }
+
+    # valid support* privargs are the same as support cats
+    if ( my ( $sup ) = ( $priv =~ /^support(.*)$/ ) ) {
+        my $cats = LJ::Support::load_cats();
+        my @catkeys = map { $_->{catkey} } values %$cats;
+        if ( $priv eq 'supportread' ) {
+            $hr->{"$_+"} = "Extended $sup privs for $_ category"
+                foreach @catkeys;
+        }
+        $sup = $priv eq 'supporthelp' ? 'All' : ucfirst $sup;
+        $hr->{$_} = "$sup privs for $_ category"
+            foreach @catkeys;
+        $hr->{''} = "$sup privs for public categories";
+    }
+
+    # valid faqadd/faqedit privargs are the same as faqcats
+    if ( $priv eq 'faqadd' or $priv eq 'faqedit' ) {
+        my $dbr = LJ::get_db_reader();
+        $hr = $dbr->selectall_hashref(
+            'SELECT faqcat, faqcatname FROM faqcat', 'faqcat' );
+        # unfold result
+        $hr->{$_} = $hr->{$_}->{faqcatname} foreach keys %$hr;
+    }
+
+    # valid translate privargs are the same as defined languages
+    if ( $priv eq 'translate' ) {
+        my %langs = @{ LJ::Lang::get_lang_names() };
+        $hr->{$_} = "Can translate $langs{$_}" foreach keys %langs;
+        # plus a couple of extras
+        $hr->{'[itemdelete]'} = "Can delete translation strings";
+        $hr->{'[itemrename]'} = "Can rename translation strings";
+    }
+
+    # have to manually maintain the other lists
+    $hr = {
+        entryprops => "Access to /admin/entryprops",
+        sessions   => "Access to admin mode on /manage/logins",
+        styles     => "Access to private styles on /customize/advanced",
+        suspended  => "Access to suspended journal content",
+        userlog    => "Access to /admin/userlog",
+        userprops  => "Access to /admin/propedit",
+    } if $priv eq 'canview';
+
+    $hr = {
+        codetrace   => "Access to /admin/invites/codetrace",
+        infohistory => "Access to infohistory console command",
+    } if $priv eq 'finduser';
+
+    # extracted from grep -r statushistory_add
+    if ( $priv eq 'historyview' ) {
+        my @shtypes = qw/ account_level_change b2lid_remap capedit
+                          change_journal_type comment_action communityxfer
+                          create_from_invite create_from_promo
+                          entry_action email_changed expunge_userpic
+                          impersonate journal_status logout_user
+                          mass_privacy paid_from_invite paidstatus
+                          privadd privdel reset_email reset_password
+                          s2lid_remap set_badpassword shop_points
+                          suspend sysban_add sysban_mod synd_create
+                          synd_edit synd_merge sysban_add sysban_modify
+                          sysban_trig unsuspend vgifts viewall /;
+
+        $hr->{$_} = "Access to statushistory for $_ logs"
+            foreach @shtypes;
+    }
+
+    $hr = {
+        commentview    => "Access to /admin/recent_comments",
+        emailqueue     => "Access to /tools/recent_email",
+        entry_redirect => "Access to /misc/entry_redirect",
+        invites        => "Access to some invites functionality under /admin/invites",
+        largefeedsize  => "Overrides synsuck_max_size for a feed",
+        memcacheclear  => "Access to /admin/memcache_clear",
+        memcacheview   => "Access to /admin/memcache",
+        mysqlstatus    => "Access to /admin/mysql_status",
+        navtag         => "Access to /admin/navtag",
+        propedit       => "Allow to change userprops for other users",
+        rename         => "Access to rename_opts console command",
+        sitemessages   => "Access to /admin/sitemessages",
+        spamreports    => "Access to /admin/spamreports",
+        theschwartz    => "Access to /admin/theschwartz",
+        usernames      => "Bypasses is_protected_username check",
+        userpics       => "Access to expunge_userpic console command",
+        users          => "Access to change_journal_status console command",
+        vgifts         => "Access to approval functions on /admin/vgifts",
+    } if $priv eq 'siteadmin';
+
+    $hr = {
+        openid => "Only allowed to suspend OpenID accounts",
+    } if $priv eq 'suspend';
+
+    # extracted from LJ::Sysban::validate
+    $hr = {
+        email         => "Can ban specific email addresses",
+        email_domain  => "Can ban entire email domains",
+        invite_email  => "Can ban invites for email addresses",
+        invite_user   => "Can ban invites for users",
+        ip            => "Can ban connections from specific IPs",
+        lostpassword  => "Can ban requests for lost passwords",
+        noanon_ip     => "Can ban anonymous comments from specific IPs",
+        pay_cc        => "Can ban payments from specific credit cards",
+        pay_email     => "Can ban payments from specific emails",
+        pay_uniq      => "Can ban payments from specific sessions",
+        pay_user      => "Can ban payments from specific users",
+        spamreport    => "Can ban spam reports from specific users",
+        support_email => "Can ban support requests from emails",
+        support_uniq  => "Can ban support requests from sessions",
+        support_user  => "Can ban support requests from users",
+        talk_ip_test  => "Can force IPs to complete CAPTCHA to leave comments",
+        uniq          => "Can ban specific browser sessions",
+        user          => "Can ban specific users",
+    } if $priv eq 'sysban';
+
+    return $hr;
+} );
+
+
+1;
diff -r 7320f6e8c271 -r dea9381b157c cgi-bin/ljlib.pl
--- a/cgi-bin/ljlib.pl	Wed Dec 28 15:47:50 2011 +0800
+++ b/cgi-bin/ljlib.pl	Wed Dec 28 15:56:56 2011 +0800
@@ -87,7 +87,6 @@
 use DW::Logic::LogItems;
 use LJ::CleanHTML;
 use DW::LatestFeed;
-use LJ::Support;
 use LJ::Keywords;
 use LJ::Procnotify;
 
@@ -1723,136 +1722,27 @@
     return ! LJ::conf_test( $LJ::DISABLED{$conf}, @_ );
 }
 
-# document valid arguments for certain privs
+# document valid arguments for certain privs (using hooks)
+# argument: name of priv
+# returns: hashref of argname/argdesc, or just list of argnames if wantarray
 sub list_valid_args {
     my ( $priv ) = @_;
     my $hr = {};
 
-    # valid admin privargs are the same as defined DB privs
-    if ( $priv eq 'admin' ) {
-        my $dbr = LJ::get_db_reader();
-        $hr = $dbr->selectall_hashref(
-            'SELECT privcode, privname FROM priv_list', 'privcode' );
-        # unfold result
-        $hr->{$_} = $hr->{$_}->{privname} foreach keys %$hr;
-        # add subprivs for supporthelp
-        my $cats = LJ::Support::load_cats();
-        $hr->{"supporthelp/$_"} = "$hr->{supporthelp} for $_"
-            foreach map { $_->{catkey} } values %$cats;
+    foreach ( LJ::Hooks::run_hooks( "privlist-add", $priv ) ) {
+        my $ret = $_->[0];
+        next unless $ret;
+        # merge all results
+        @{ $hr }{ keys %$ret } = values %$ret;
     }
 
-    # valid support* privargs are the same as support cats
-    if ( my ( $sup ) = ( $priv =~ /^support(.*)$/ ) ) {
-        my $cats = LJ::Support::load_cats();
-        my @catkeys = map { $_->{catkey} } values %$cats;
-        if ( $priv eq 'supportread' ) {
-            $hr->{"$_+"} = "Extended $sup privs for $_ category"
-                foreach @catkeys;
-        }
-        $sup = $priv eq 'supporthelp' ? 'All' : ucfirst $sup;
-        $hr->{$_} = "$sup privs for $_ category"
-            foreach @catkeys;
-        $hr->{''} = "$sup privs for public categories";
+    # optionally allow someone to remove a listing that was provided elsewhere
+    foreach ( LJ::Hooks::run_hooks( "privlist-remove", $priv ) ) {
+        my @del = @$_;
+        # remove any keys listed by the hook
+        delete $hr->{$_} foreach @del;
     }
 
-    # valid faqadd/faqedit privargs are the same as faqcats
-    if ( $priv eq 'faqadd' or $priv eq 'faqedit' ) {
-        my $dbr = LJ::get_db_reader();
-        $hr = $dbr->selectall_hashref(
-            'SELECT faqcat, faqcatname FROM faqcat', 'faqcat' );
-        # unfold result
-        $hr->{$_} = $hr->{$_}->{faqcatname} foreach keys %$hr;
-    }
-
-    # valid translate privargs are the same as defined languages
-    if ( $priv eq 'translate' ) {
-        my %langs = @{ LJ::Lang::get_lang_names() };
-        $hr->{$_} = "Can translate $langs{$_}" foreach keys %langs;
-        # plus a couple of extras
-        $hr->{'[itemdelete]'} = "Can delete translation strings";
-        $hr->{'[itemrename]'} = "Can rename translation strings";
-    }
-
-    # have to manually maintain the other lists
-    $hr = {
-        entryprops => "Access to /admin/entryprops",
-        sessions   => "Access to admin mode on /manage/logins",
-        styles     => "Access to private styles on /customize/advanced",
-        suspended  => "Access to suspended journal content",
-        userlog    => "Access to /admin/userlog",
-        userprops  => "Access to /admin/propedit",
-    } if $priv eq 'canview';
-
-    $hr = {
-        codetrace   => "Access to /admin/invites/codetrace",
-        infohistory => "Access to infohistory console command",
-    } if $priv eq 'finduser';
-
-    # extracted from grep -r statushistory_add
-    if ( $priv eq 'historyview' ) {
-        my @shtypes = qw/ account_level_change b2lid_remap capedit
-                          change_journal_type comment_action communityxfer
-                          create_from_invite create_from_promo
-                          entry_action email_changed expunge_userpic
-                          impersonate journal_status logout_user
-                          mass_privacy paid_from_invite paidstatus
-                          privadd privdel reset_email reset_password
-                          s2lid_remap set_badpassword shop_points
-                          suspend sysban_add sysban_mod synd_create
-                          synd_edit synd_merge sysban_add sysban_modify
-                          sysban_trig unsuspend vgifts viewall /;
-
-        $hr->{$_} = "Access to statushistory for $_ logs"
-            foreach @shtypes;
-    }
-
-    $hr = {
-        commentview    => "Access to /admin/recent_comments",
-        emailqueue     => "Access to /tools/recent_email",
-        entry_redirect => "Access to /misc/entry_redirect",
-        invites        => "Access to some invites functionality under /admin/invites",
-        largefeedsize  => "Overrides synsuck_max_size for a feed",
-        memcacheclear  => "Access to /admin/memcache_clear",
-        memcacheview   => "Access to /admin/memcache",
-        mysqlstatus    => "Access to /admin/mysql_status",
-        navtag         => "Access to /admin/navtag",
-        propedit       => "Allow to change userprops for other users",
-        rename         => "Access to rename_opts console command",
-        sitemessages   => "Access to /admin/sitemessages",
-        spamreports    => "Access to /admin/spamreports",
-        theschwartz    => "Access to /admin/theschwartz",
-        usernames      => "Bypasses is_protected_username check",
-        userpics       => "Access to expunge_userpic console command",
-        users          => "Access to change_journal_status console command",
-        vgifts         => "Access to approval functions on /admin/vgifts",
-    } if $priv eq 'siteadmin';
-
-    $hr = {
-        openid => "Only allowed to suspend OpenID accounts",
-    } if $priv eq 'suspend';
-
-    # extracted from sysban_validate function in sysban.pl
-    $hr = {
-        email         => "Can ban specific email addresses",
-        email_domain  => "Can ban entire email domains",
-        invite_email  => "Can ban invites for email addresses",
-        invite_user   => "Can ban invites for users",
-        ip            => "Can ban connections from specific IPs",
-        lostpassword  => "Can ban requests for lost passwords",
-        noanon_ip     => "Can ban anonymous comments from specific IPs",
-        pay_cc        => "Can ban payments from specific credit cards",
-        pay_email     => "Can ban payments from specific emails",
-        pay_uniq      => "Can ban payments from specific sessions",
-        pay_user      => "Can ban payments from specific users",
-        spamreport    => "Can ban spam reports from specific users",
-        support_email => "Can ban support requests from emails",
-        support_uniq  => "Can ban support requests from sessions",
-        support_user  => "Can ban support requests from users",
-        talk_ip_test  => "Can force IPs to complete CAPTCHA to leave comments",
-        uniq          => "Can ban specific browser sessions",
-        user          => "Can ban specific users",
-    } if $priv eq 'sysban';
-
     return wantarray ? keys %$hr : $hr;
 }
 
--------------------------------------------------------------------------------