CallBackery
view release on metacpan or search on metacpan
lib/CallBackery/Controller/RpcService.pm view on Meta::CPAN
target plugin opts into anonymous access (C<mayAnonymous>). The plugin
instantiation is wrapped in C<eval>, because instantiating a plugin as an
unauthenticated user commonly dies (plugins read user rights/config); such a
death resolves to "not anonymous" here and must never escape as a generic
code 9999 error.
=item *
Otherwise the method requires authentication the user does not have: if the
user's session has merely expired, C<die> a C<RPC_SESSION_EXPIRED> (code 7)
exception; otherwise C<return 0> for the ordinary login-required path.
=back
=cut
my %allow = (
getBaseConfig => 1,
login => 1,
logout => 1,
ping => 1,
getUserConfig => 2,
getPluginConfig => 3,
validatePluginData => 3,
processPluginData => 3,
getPluginData => 3,
getSessionCookie => 2
);
has config => sub ($self) {
$self->app->config;
}, weak => 1;
has user => sub ($self) {
my $obj = $self->app->userObject->new(app=>$self->app,controller=>$self,log=>$self->log);
return $obj;
};
has pluginMap => sub ($self) {
my $map = $self->config->cfgHash->{PLUGIN};
return $map;
}, weak => 1;
sub allow_rpc_access ($self,$method) {
if (not $self->req->method eq 'POST') {
# sorry we do not allow GET requests
$self->log->error("refused ".$self->req->method." request");
return 0;
}
if (not exists $allow{$method}){
return 0;
}
for ($allow{$method}){
/1/ && return 1; # public method
return 1 if ($self->user->isUserAuthenticated); # forces cookieConf (sets sessionExpired)
/3/ && do {
# Level-3: allowed only for plugins that opt into anonymous access.
# Guard the instantiation: for an unauthenticated user it commonly
# dies (plugins read user rights/config); that death must resolve to
# "not anonymous" here, never escape as a generic code-9999 popup.
my $plugin = $self->rpcParams->[0];
my $anon = eval {
$self->config->instantiatePlugin($plugin,$self->user)->mayAnonymous
};
return 1 if $anon;
};
# Method needs auth and the user is not authenticated. If a session was
# present and merely expired, signal that distinctly (code 7 -> reload);
# otherwise fall through to code 6 (login dialog).
die mkerror(RPC_SESSION_EXPIRED,
trm('Your session has expired. Please reload to log in.'))
if $self->user->sessionExpired;
last;
}
return 0;
};
has passMatch => sub ($self) {
qr{(?i)(?:password|_pass)};
};
sub perMethodCleaner ($self,$method=undef) {
$method or return;
return {
login => sub {
my $data = shift;
if (ref $data eq 'ARRAY'){
$data->[1] = 'xxx';
}
return;
}
}->{$method};
};
sub dataCleaner ($self,$data,$method=undef) {
if (my $perMethodCleaner = $self->perMethodCleaner($method)){
return $perMethodCleaner->($data);
}
my $match = $self->passMatch;
my $type = ref $data;
for ($type) {
/ARRAY/ && do {
$self->dataCleaner($_) for @$data;
};
/HASH/ && do {
for my $key (keys %$data) {
my $value = $data->{$key};
if ($key =~ /$match/){
$data->{$key} = 'xxx';
}
elsif (ref $value){
$self->dataCleaner($value);
}
}
}
}
}
=head2 logRpcCall
( run in 1.520 second using v1.01-cache-2.11-cpan-364913b4093 )