package DPAE::Plugin::Admin;
# adapted from Dancer2::Plugin::Auth::Tiny
# usage: get '/foo' => needs_admin sub { ... };
our $VERSION = '0.1';
# use Carp::Always::Color; # stacktrace on warn
use Dancer2::Plugin;
use Data::Printer;
use Data::Dumper;
use Modern::Perl;
register 'needs_admin' => sub {
my ($dsl, @args) = @_; # p $_ for ($dsl, @args); plugin_args() no longer used
my $builder = \&_builder; # p $builder;
return $builder->($dsl, @args);
};
register_plugin;
#==============================================================================
sub _builder {
my ($dsl, $coderef) = @_; # p $dsl; # p$coderef;
# original D2::Plugin assumed caller would be under D2::Plugin namespace, here
# we will check this package is under any Plugin namespace (eg MyApp::Plugin::Foo):
my $package = __PACKAGE__; # adapted from Dancer2::Plugin::plugin_setting():
my ($plugin_name) = $package =~ /Plugin::(.*)/ # need 'or' here, not '||':
or die "$package package expected to live under 'Plugin' namespace"; # p $plugin_name;
my $conf = $dsl->app->config->{plugins}->{$plugin_name} || {}; # p $conf;
my @users = @{ $conf->{users} }; # p @users;
return sub {
my $app = shift; # Dancer2::Core::App object (same as $dsl->app)
my $session_user_var = $conf->{session_user_var};
my $logged_in_user = $app->session->read($session_user_var)
or return $app->redirect(
$app->request->uri_for('/login',
{ return_url => $app->request->uri_for( # original request:
$app->request->path, $app->request->params )
}
)
); # redirect
if ( @users && grep $logged_in_user eq $_, @users ) {
# ok, current user *is* in @users list:
return &$coderef; # same functionality as original "goto $coderef";
}
# either no defined admin users, or logged in user not in admin list:
elsif ( my $handler = $conf->{permission_denied_handler} ) {
my $route_filename = $app->name; # p $route_filename; # this is NOT same as config "appname"
my $denied = join '::', $route_filename, $handler; # p $denied;
no strict 'refs'; # suppress inevitable warning
return &$denied; # sub to handle 'permission_denied' requests in route file
}
else {
# return $app->redirect( $app->request->uri_for('/denied') ); # redirect
return _default_permission_denied_html(); # html from local sub
}
};
}
sub _default_permission_denied_html {
return '<h1>Permission Denied</h1>'
. '<p>Sorry, you\'re not allowed to access that page.</p>';
}
1;