CallBackery

 view release on metacpan or  search on metacpan

lib/CallBackery/Controller/RpcService.pm  view on Meta::CPAN

package CallBackery::Controller::RpcService;

use Mojo::Base qw(Mojolicious::Plugin::Qooxdoo::JsonRpcController),
    -signatures,-async_await;
use CallBackery::Exception qw(mkerror);
use CallBackery::Translate qw(trm);
use Mojo::JSON qw(encode_json decode_json from_json);
use Syntax::Keyword::Try;
use Scalar::Util qw(blessed weaken);

=head1 NAME

CallBackery::RpcService - RPC services for CallBackery

=head1 SYNOPSIS

This module gets instantiated by L<CallBackery> and provides backend
functionality.

=head1 DESCRIPTION

This module provides the following methods

=cut

# the name of the service we provide
has service => 'default';

=head2 allow_rpc_access(method)

is this method accessible?

=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;
        return 1 if ($self->user->isUserAuthenticated);
        /3/ && do {
            my $plugin = $self->rpcParams->[0];
            if ($self->config->instantiatePlugin($plugin,$self->user)->mayAnonymous){
                return 1;
            }
        };
    }
    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);
    }

lib/CallBackery/Controller/RpcService.pm  view on Meta::CPAN

}

=head2 logRpcCall

Set CALLBACKERY_RPC_LOG for extensive logging messages. Note that all
values with keys matching /password|_pass/ do get replaced with 'xxx'
in the output.

=cut

# our own logging
sub logRpcCall {
    my $self = shift;
    if ($ENV{CALLBACKERY_RPC_LOG}){
        my $method = shift;
        my $data = shift;
        $self->dataCleaner($data,$method);
        my $userId = eval { $self->user->loginName } // '*UNKNOWN*';
        my $remoteAddr = $self->tx->remote_address;
        $self->log->debug("[$userId|$remoteAddr] CALL $method(".encode_json($data).")");
    }
    else {
        $self->SUPER::logRpcCall(@_);
    }
}

=head2 logRpcReturn

Set CALLBACKERY_RPC_LOG for extensive logging messages. Note that all
values with keys matching /password|_pass/ do get replaced with 'xxx'
in the output.

=cut

# our own logging
sub logRpcReturn {
    my $self = shift;
    if ($ENV{CALLBACKERY_RPC_LOG}){
        my $data = shift;
        $self->dataCleaner($data);
        my $userId = eval { $self->user->loginName } // '*UNKNOWN*';
        my $remoteAddr = $self->tx->remote_address;
        $self->log->debug("[$userId|$remoteAddr] RETURN ".encode_json($data).")");
    }
    else {
        $self->SUPER::logRpcReturn(@_);
    }

}

=head2 ping()

check if the server is happy with our authentication state

=cut

sub ping {
    return 'pong';
}

=head2 getSessionCookie()

Return a timeestamped session cookie. For use in the X-Session-Cookie header or as a xsc field
in form submissions. Note that session cookies for form submissions are only valid for 2 seconds.
So you have to get a fresh one from the server before submitting your form.

=cut

sub getSessionCookie {
    shift->user->makeSessionCookie();
}

=head2 getConfig()

get some gloabal configuration information into the interface

=cut

sub getBaseConfig {
    my $self = shift;
    return $self->config->cfgHash->{FRONTEND};
}

=head2 login(user,password)

Check login and provide the user specific interface configuration as a response.

=cut

async sub login { ## no critic (RequireArgUnpacking)
    my $self = shift;
    my $login = shift;
    my $password = shift;
    my $cfg = $self->config->cfgHash->{BACKEND};
    if (my $ok =
        await $self->config->promisify($self->user->login($login,$password))){
        return {
            sessionCookie => $self->user->makeSessionCookie()
        }
    } else {
        return;
    }
}

=head2 logout

Kill the session.

=cut

sub logout {
    my $self = shift;
    $self->session(expires=>1);
    return 'http://youtu.be/KGsTNugVctI';
}



=head2 instantiatePlugin_p

get an instance for the given plugin

=cut

async sub instantiatePlugin_p {
    my $self = shift;
    my $name = shift;
    my $args = shift;
    my $user = $self->user;
    my $plugin =  await $self->config->instantiatePlugin_p($name,$user,$args);
    $plugin->log($self->log);
    return $plugin;
}

sub instantiatePlugin {
    my $self = shift;
    my $name = shift;
    my $args = shift;
    my $user = $self->user;
    my $plugin =  $self->config->instantiatePlugin($name,$user,$args);
    $plugin->log($self->log);
    return $plugin;
}

=head2 processPluginData(plugin,args)

handle form sumissions

=cut

async sub processPluginData {
    my $self = shift;
    my $plugin = shift;
    # "Localizing" required as it seems to be changed somewhere.
    my @args = @_;
    # Creating two statements will make things easier to debug since
    # there is only one thing that can go wrong per line.
    my $instance = await $self->instantiatePlugin_p($plugin);



( run in 1.879 second using v1.01-cache-2.11-cpan-995e09ba956 )