From: Victor Wagner Date: Fri, 21 Mar 2008 15:02:02 +0000 (+0000) Subject: Отлажена работа кода проверки прав (хотя бы для администратора) X-Git-Url: http://www.wagner.pp.ru/gitweb/?a=commitdiff_plain;h=89f2fc99e9e637eb9f383f277e68021828ba5fe2;p=oss%2Fstilllife.git Отлажена работа кода проверки прав (хотя бы для администратора) --- diff --git a/forum/forum b/forum/forum index 91961bf..c714859 100755 --- a/forum/forum +++ b/forum/forum @@ -36,9 +36,25 @@ my %actions = ( openidlogin=>\&openid_login, openidvfy =>\&openid_verify ); +# +# Уровень прав, которые необходимо иметь пользователю для совершения +# определенного действия +# иерархия вида undef < banned < normal < author < moderator "login", + edit => "author", + delete => "author", + newtopic => "normal", + move => "moderator", + newforum => "moderator", + profile => "normal", + setrights => "admin", +); - - my $cgi = new CGI; print STDERR "--------------------\n"; my $forum=get_forum_config(); @@ -83,8 +99,14 @@ if ($cgi->request_method ne "POST") { # Запрос методом POST. Вызываем обработчик for my $param ($cgi->param) { if (exists $actions{$param}) { - $actions{$param}->($param,$cgi,$forum); - exit; + if (allow_operation($param,$cgi,$forum)) { + $actions{$param}->($param,$cgi,$forum); + exit; + } else { + show_error($forum,"У Вас нет прав на выполнение этой + операции") + } + } } print STDERR "Получены параметры ",join(" ",$cgi->param),"\n"; @@ -346,7 +368,6 @@ sub fix_forum_links { $attr ="src"; } my $link = $element->attr($attr); - print STDERR "Fixing link $link\n"; # Абсолютная ссылка - оставляем как есть. next ELEMENT if (! defined $link || $link=~/^\w+:/); # Ссылка от корня сайта. @@ -363,7 +384,6 @@ sub fix_forum_links { !($link =~ s!^forum\b!$script_with_path!)) { $link = $forum->{"forumtop"}."/".$link } - print STDERR "Fixed to $link\n"; $element->attr($attr,$link); } } @@ -501,7 +521,6 @@ sub authenticate { dbmopen %userbase,datafile($forum,"passwd"),0644; my $user = $cgi->param("user"); my $password = $cgi->param("password"); - print STDERR "user=>'$user'\npassword=>'$password'\n"; $cgi->delete("password"); if (! $userbase{$user}) { set_error($forum,"Неверное имя пользователя или пароль"); @@ -509,7 +528,7 @@ sub authenticate { } my $userinfo = thaw($userbase{$user}) ; dbmclose %userbase; - while (my ($key,$val)=each %$userinfo) { print STDERR "$key => '$val'\n";} + #while (my ($key,$val)=each %$userinfo) { print STDERR "$key => '$val'\n";} if (crypt($password,$userinfo->{passwd}) eq $userinfo->{passwd}) { delete $userinfo->{"passwd"}; $cgi->delete("password"); @@ -681,8 +700,24 @@ sub logout { } sub allow_operation { my ($operation,$cgi,$forum) = @_; - return 1 if (grep $operation eq $_,"register","login","reply"); - + return 1 if (!exists($permissions{$operation})); + if (!$forum->{authenticated}) { + return 1 if ($permissions{$operation} eq "login"); + return 0; + } + my $user = $forum->{authenticated}{user} ; + my $accesslevel=getrights($cgi,$forum); + # Если permissions{$operation} равны author, нам нужно извлечь + # текст из соответствующего файла и положить его в + # cgi->param("text"); Заодно определим и автора + my ($itemauthor,$itemtext)=get_message_by_id($cgi->param("id")) if + $permissions{$operation} eq "author"; + + return 1 if ($accesslevel eq "admin"); + return 0 if ($permissions{$operation} eq "admin"); + return 1 if ($accesslevel eq "moderator"); + return 0 if $accesslevel eq "banned"; + return 0 if $permissions{$operation} eq "author" && $user ne $itemauthor; return 1; } @@ -726,4 +761,50 @@ sub reply { } } } - +# +# читает файлы прав доступа в дереве форума, и возвращает +# статус текущего пользователя (undef - аноним, banned, normal, +# moderator или admin + +sub getrights { + my ($cgi,$forum) = @_; + if (!$forum->{authenticated}) { + return undef; + } + my $user = $forum->{authenticated}{user}; + my $dir = $ENV{'PATH_TRANSLATED'}; + $dir =~s/\/[^\/]+$// if (!-d $dir); + my $f; + my $user_status = "normal"; + LEVEL: + while (length($dir)) { + if (-f "$dir/perms.txt") { + open $f,"<","$dir/perms.txt"; + my $status = undef; + while (<$f>) { + if (/^\[\s*(admins|moderators|banned)\s*\]/) { + $status = $1; + } else { + chomp; + if ($user eq $_ && defined $status) { + if ($status eq "banned") { + return $status; + } + if ($status eq "admins" ) { + return "admin"; + } + $user_status = "moderator"; + } + } + } + close $f; + last LEVEL if -f "$dir/.forum"; + # Strip last path component. + $dir =~s/\/[^\/]+$// + } + } + return $user_status; + +} + +