From 3a69868b3fa425c2d46e3c28943ba52fdd4e8e71 Mon Sep 17 00:00:00 2001 From: George Clark Date: Fri, 20 Mar 2015 20:06:21 -0400 Subject: [PATCH] Item13315: Improve usability of config auth - Refactor the code. Move redundant auth logic into a new module Foswiki::Configure::Auth. Used in 4 places. - Change auth routine to throw Json errors instead of "die" when used in ConfigurePlugin. - Always allow the Sudo super admin access to configure. If we would rather force users to add AdminUser to the {FeatureAccess}{Configure} simple change, and now would be done by WikiName not BaseUserMapping. --- .../lib/Foswiki/Plugins/ConfigurePlugin.pm | 29 +---- core/lib/Foswiki/Configure/Auth.pm | 103 ++++++++++++++++++ .../Foswiki/Macros/PERLDEPENDENCYREPORT.pm | 21 +--- core/lib/Foswiki/Macros/SERVERINFORMATION.pm | 21 +--- core/lib/Foswiki/UI/Configure.pm | 27 +---- 5 files changed, 112 insertions(+), 89 deletions(-) create mode 100644 core/lib/Foswiki/Configure/Auth.pm diff --git a/ConfigurePlugin/lib/Foswiki/Plugins/ConfigurePlugin.pm b/ConfigurePlugin/lib/Foswiki/Plugins/ConfigurePlugin.pm index 1a1e3873f6..9d1e36352f 100644 --- a/ConfigurePlugin/lib/Foswiki/Plugins/ConfigurePlugin.pm +++ b/ConfigurePlugin/lib/Foswiki/Plugins/ConfigurePlugin.pm @@ -34,6 +34,7 @@ our $VERSION = '1.01'; use Assert; use Foswiki::Contrib::JsonRpcContrib (); +use Foswiki::Configure::Auth (); use Foswiki::Configure::LoadSpec (); use Foswiki::Configure::Load (); use Foswiki::Configure::Root (); @@ -140,33 +141,7 @@ sub _JSONwrap { my ( $session, $request ) = @_; if ( $Foswiki::cfg{isVALID} ) { - - if ( defined $Foswiki::cfg{FeatureAccess}{Configure} - && length( $Foswiki::cfg{FeatureAccess}{Configure} ) ) - { - my $authorized; - foreach my $authuser ( - split( /[,\s]/, $Foswiki::cfg{FeatureAccess}{Configure} ) ) - { - if ( $session->{user} eq $authuser ) { - $authorized = 1; - last; - } - } - die -"You must have special permission to use this interface. Denied by {FeatureAccess}{Configure} Setting" - unless ($authorized); - } - else { - # Check rights to use this interface - admins only - die -"You must be logged in as an administrator to use this interface." - unless Foswiki::Func::isAnAdmin(); - } - } - else { - # Otherwise we must be bootstrapping - an inherently dangerous - # operation. TODO: check we can do this safely. + Foswiki::Configure::Auth::checkAccess( $session, 1 ); } my $reporter = Foswiki::Configure::Reporter->new(); diff --git a/core/lib/Foswiki/Configure/Auth.pm b/core/lib/Foswiki/Configure/Auth.pm new file mode 100644 index 0000000000..b2f41b8438 --- /dev/null +++ b/core/lib/Foswiki/Configure/Auth.pm @@ -0,0 +1,103 @@ +# See bottom of file for license and copyright information + +package Foswiki::Configure::Auth; + +use Foswiki::Func; +use Foswiki::AccessControlException; +use Foswiki::Contrib::JsonRpcContrib::Error; + +=begin TML + +---+ package Foswiki::Configure::Auth + +Implements authorization checking for access to configure. + +=cut + +use strict; +use warnings; + +=begin TML + +---++ StaticMethod checkAccess( $session, $die ) + +Throws an AccessControlException if access is denied. + +=cut + +sub checkAccess { + my $session = shift; + my $json = shift; # JSON needs throw JSON errors. + + my $wikiname = Foswiki::Func::getWikiName( $session->{user} ); + + return + if ( defined $Foswiki::cfg{AdminUserWikiName} + && $Foswiki::cfg{AdminUserWikiName} eq $wikiname ); + + if ( defined $Foswiki::cfg{FeatureAccess}{Configure} + && length( $Foswiki::cfg{FeatureAccess}{Configure} ) ) + { + my $authorized = ''; + foreach my $authuser ( + split( /[,\s]/, $Foswiki::cfg{FeatureAccess}{Configure} ) ) + { + if ( $wikiname eq $authuser ) { + $authorized = 1; + last; + } + } + unless ($authorized) { + if ($json) { + throw Foswiki::Contrib::JsonRpcContrib::Error( -32600, +'Access to configure denied by {FeatureAccess}{Configure} Setting' + ); + } + else { + throw Foswiki::AccessControlException( 'VIEW', + $session->{user}, 'System', 'Configuration', + 'Denied by {FeatureAccess}{Configure} Setting' ); + } + } + } + else { + unless ( Foswiki::Func::isAnAdmin() ) { + if ($json) { + throw Foswiki::Contrib::JsonRpcContrib::Error( -32600, + 'Access to configure denied for non-admin users' ); + } + else { + throw Foswiki::AccessControlException( 'VIEW', + $session->{user}, 'System', 'Configuration', + 'Not an admin' ); + } + } + } +} + +1; +__END__ +Foswiki - The Free and Open Source Wiki, http://foswiki.org/ + +Copyright (C) 2008-2014 Foswiki Contributors. Foswiki Contributors +are listed in the AUTHORS file in the root of this distribution. +NOTE: Please extend that file, not this notice. + +Additional copyrights apply to some or all of the code in this +file as follows: + +Copyright (C) 2000-2006 TWiki Contributors. All Rights Reserved. +TWiki Contributors are listed in the AUTHORS file in the root +of this distribution. NOTE: Please extend that file, not this notice. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. For +more details read LICENSE in the root of this distribution. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +As per the GPL, removal of this notice is prohibited. diff --git a/core/lib/Foswiki/Macros/PERLDEPENDENCYREPORT.pm b/core/lib/Foswiki/Macros/PERLDEPENDENCYREPORT.pm index ca865ee74e..265d9ce878 100644 --- a/core/lib/Foswiki/Macros/PERLDEPENDENCYREPORT.pm +++ b/core/lib/Foswiki/Macros/PERLDEPENDENCYREPORT.pm @@ -9,30 +9,13 @@ use warnings; use Foswiki::Configure::Dependency (); use Foswiki::Configure::FileUtil (); +use Foswiki::Configure::Auth (); sub PERLDEPENDENCYREPORT { my ( $this, $params ) = @_; - my $authorized; my $session = $Foswiki::Plugins::SESSION; - if ( defined $Foswiki::cfg{FeatureAccess}{Configure} - && length( $Foswiki::cfg{FeatureAccess}{Configure} ) ) - { - foreach my $authuser ( - split( /[,\s]/, $Foswiki::cfg{FeatureAccess}{Configure} ) ) - { - if ( $session->{user} eq $authuser ) { - $authorized = 1; - last; - } - } - } - else { - $authorized = Foswiki::Func::isAnAdmin(); - } - - return "Dependency report only accessible to authorized configure users." - unless $authorized; + Foswiki::Configure::Auth::checkAccess($session); if ( defined $params->{_DEFAULT} && $params->{_DEFAULT} eq 'extensions' ) diff --git a/core/lib/Foswiki/Macros/SERVERINFORMATION.pm b/core/lib/Foswiki/Macros/SERVERINFORMATION.pm index 66164282bc..7ffe9ebc52 100644 --- a/core/lib/Foswiki/Macros/SERVERINFORMATION.pm +++ b/core/lib/Foswiki/Macros/SERVERINFORMATION.pm @@ -10,31 +10,14 @@ use warnings; use File::Spec; use Foswiki::Func; use Config; +use Foswiki::Configure::Auth; sub SERVERINFORMATION { my ( $this, $params ) = @_; my $authorized; my $session = $Foswiki::Plugins::SESSION; - if ( defined $Foswiki::cfg{FeatureAccess}{Configure} - && length( $Foswiki::cfg{FeatureAccess}{Configure} ) ) - { - foreach my $authuser ( - split( /[,\s]/, $Foswiki::cfg{FeatureAccess}{Configure} ) ) - { - if ( $session->{user} eq $authuser ) { - $authorized = 1; - last; - } - } - } - else { - $authorized = Foswiki::Func::isAnAdmin(); - } - - return - "Server information is only accessible to authorized configure users." - unless $authorized; + Foswiki::Configure::Auth::checkAccess($session); my $report; if ( ( !defined $params->{_DEFAULT} ) diff --git a/core/lib/Foswiki/UI/Configure.pm b/core/lib/Foswiki/UI/Configure.pm index ad6f558b25..78fada6434 100644 --- a/core/lib/Foswiki/UI/Configure.pm +++ b/core/lib/Foswiki/UI/Configure.pm @@ -14,7 +14,8 @@ use strict; use warnings; use Assert; -use Foswiki (); +use Foswiki (); +use Foswiki::Configure::Auth (); BEGIN { if ( $Foswiki::cfg{UseLocale} ) { @@ -48,29 +49,7 @@ sub configure { } ); - if ( defined $Foswiki::cfg{FeatureAccess}{Configure} - && length( $Foswiki::cfg{FeatureAccess}{Configure} ) ) - { - my $authorized = ''; - foreach my $authuser ( - split( /[,\s]/, $Foswiki::cfg{FeatureAccess}{Configure} ) ) - { - if ( $session->{user} eq $authuser ) { - $authorized = 1; - last; - } - } - throw Foswiki::AccessControlException( 'VIEW', - $session->{user}, 'System', 'Configuration', - 'Denied by {FeatureAccess}{Configure} Setting' ) - unless ($authorized); - } - else { - unless ( Foswiki::Func::isAnAdmin() ) { - throw Foswiki::AccessControlException( 'VIEW', - $session->{user}, 'System', 'Configuration', 'Not an admin' ); - } - } + Foswiki::Configure::Auth::checkAccess($session); unless ( $Foswiki::cfg{Plugins}{ConfigurePlugin}{Enabled} ) { $tmplData =