use v5.14;
use Apache2::Authen::Passphrase qw/pwcheck/;
+use Apache2::AuthzCaps qw/hascaps/;
+use Gruntmaster::Data;
use Plack::App::Gruntmaster;
use Plack::Builder;
use Plack::Request;
+$Apache2::AuthzCaps::rootdir = $Apache2::Authen::Passphrase::rootdir;
+my $word = qr,(\w+),a;
+
+sub debug {
+ local $Log::Log4perl::caller_depth = $Log::Log4perl::caller_depth + 1;
+ $_[0]->{'psgix.logger'}->({qw/level debug message/ => $_[1]})
+}
+
sub some_auth_required {
my $r = Plack::Request->new($_[0]);
- my $word = qr,(\w+),a;
- return 1 if $r->path eq '/action/passwd' || $r->path =~ m,/pb/$word/submit$,;
+ return 1 if $_[0]->{'gruntmaster.reqadmin'} || $r->path eq '/action/passwd' || $r->path =~ m,/pb/$word/submit$,;
+ 0
+}
+
+sub admin_required {
+ local $_ = $_[0];
+ return 1 if m,^/pb/$word, && problem_private $1;
+ return 1 if m,^/log/(?:job|src)/$word, && job_private $1;
+ return 1 if m,^/ct/$word/(?:pb|log), && time < contest_start $1;
+ return 1 if m,^/ct/$word/log/src, && time < contest_end $1;
0
}
+sub require_admin {
+ my $app = $_[0];
+ sub {
+ *__ANON__ = "require_admin_middleware";
+ my $env = $_[0];
+ my $r = Plack::Request->new($env);
+ $env->{'gruntmaster.reqadmin'} = 1 if admin_required $r->path;
+ $app->($env)
+ }
+}
+
+sub authenticate {
+ my ($user, $pass, $env) = @_;
+ return unless eval {
+ pwcheck $user, $pass;
+ 1
+ };
+
+ return if $env->{'gruntmaster.reqadmin'} && !hascaps $user, 'gmadm';
+ 1
+}
+
builder {
enable 'ContentLength';
enable 'Static', path => qr,/static/,;
enable 'Log4perl', category => 'plack', conf => 'log.conf';
- enable_if \&some_auth_required, 'Auth::Basic', authenticator => sub { eval {pwcheck @_; 1} }, realm => 'Gruntmaster 6000';
+ enable \&require_admin;
+ enable_if \&some_auth_required, 'Auth::Basic', authenticator => \&authenticate, realm => 'Gruntmaster 6000';
Plack::App::Gruntmaster->to_app
}