#!/usr/bin/perl
#@LICENSE@#
package RVL::oAuth;
use strict;
use warnings;
use RVL::Serialize;
use Digest::MD5 qw(md5 md5_hex md5_base64);
use OAuth::Lite;
use OAuth::Lite::Consumer;
use Crypt::OpenSSL::RSA;
use MIME::Base64;
use IPC::Open2;
use JSON::PP;
use Crypt::CBC;
use Class::Std::Utils;
{
sub new {
my ($class, $dsn) = @_;
my (%hash);
my ($this) = bless( \%hash, $class);
$this->{secret} = 'a0493ee0babf9db92f2586ca07bc041b';
$this->_init($dsn);
$this->{token} = '';
return $this;
}
sub _init {
my ($this, $dsn) = @_;
unless($dsn->{cp_perms}) {
if (RVL::CpHandle::singleton()->isRoot()) {
$dsn->{cp_perms} = 'root';
} elsif (RVL::CpHandle::singleton()->isReseller()) {
$dsn->{cp_perms} = 'reseller';
} else {
$dsn->{cp_perms} = 'user';
}
}
unless($dsn->{url}) {
$dsn->{url} = RVL::CpHandle::singleton()->getApiUrl();
}
RVL::logMessage("Usage API URL: " . $dsn->{url}, __CONSTANT__::RVL_LOG_DEBUG);
$this->{DSN} = $dsn;
}
sub singleton {
my ($dsn) = @_;
if ($dsn) {
$RVL::INSTANCE{'OAUTH_LASTDSN'} = md5(RVL::Serialize::serialize($dsn));
}
if (!defined $RVL::INSTANCE{__PACKAGE__ . '_' . $RVL::INSTANCE{'OAUTH_LASTDSN'}}) {
my ($class) = __PACKAGE__->new($dsn);
$class->setUid($class->{DSN}->{'uid'});
$class->setUrl($class->{DSN}->{'url'});
$class->{oAuth} = OAuth::Lite::Consumer->new(
consumer_key => $class->{DSN}->{'uid'},
consumer_secret => $class->{secret},
site => $class->{DSN}->{'url'},
request_token_path => q{/request_token},
access_token_path => q{/accept_token},
authorize_path => q{/authorize},
auth_method => 'post_body',
);
$RVL::INSTANCE{__PACKAGE__ . '_' . $RVL::INSTANCE{'OAUTH_LASTDSN'}} = $class;
}
if (defined $RVL::INSTANCE{__PACKAGE__ . '_' . $RVL::INSTANCE{'OAUTH_LASTDSN'}}->{DSN}->{'publickey'}) {
$RVL::INSTANCE{__PACKAGE__ . '_' . $RVL::INSTANCE{'OAUTH_LASTDSN'}}->restoreToken();
}
if ($RVL::INSTANCE{__PACKAGE__ . '_' . $RVL::INSTANCE{'OAUTH_LASTDSN'}}->isError()) {
my ($error) = RVL::Error::getLast(); #join("<br />\n", @{$RVL::INSTANCE{__PACKAGE__ . '_' . $RVL::INSTANCE{'OAUTH_LASTDSN'}}->getError()});
RVL::logMessage("oAuth has Error!! $error", __CONSTANT__::RVL_LOG_DEBUG);
#RVL::fatalErrors("oAuth has Error!! $error");
}
return $RVL::INSTANCE{__PACKAGE__ . '_' . $RVL::INSTANCE{'OAUTH_LASTDSN'}};
}
sub setToken {
my ($this, $token) = @_;
$this->{token} = $token;
}
sub getToken {
my ($this) = @_;
return $this->{token};
}
sub setUid {
my ($this, $uid) = @_;
$this->{uid} = $uid;
}
sub getUid {
my ($this, $uid) = @_;
return $this->{uid};
}
sub setPublickey {
my ($this, $publicekey) = @_;
$this->{DSN}->{publickey} = $publicekey;
}
sub getPublickey {
my ($this) = @_;
return $this->{DSN}->{publickey};
}
sub setUrl {
my ($this, $url) = @_;
$this->{url} = $url;
}
sub request_apikey {
my ($this, %args) = @_;
$args{url} ||= $this->{oAuth}->authorization_url;
my $request_token_url = delete $args{url};
$args{cp_perms} = $this->{DSN}->{cp_perms};
# defined CP Info
$args{cp_owner} = $this->{DSN}->{cp_owner} if (defined $this->{DSN}->{cp_owner});
$args{cp_hostname} = $this->{DSN}->{cp_hostname} if (defined $this->{DSN}->{cp_hostname});
$args{cp_username} = $this->{DSN}->{cp_username} if (defined $this->{DSN}->{cp_username});
my $realm = delete $args{realm} || $this->{oAuth}->{realm} || '';
my ($response) = $this->{oAuth}->__request(
realm => $realm,
url => $request_token_url,
params => {%args, oauth_callback => 'oob'},
);
my (@inLine) = split(/\n/, $response->decoded_content(), 2);
my ($apiRes) = {};
foreach (@inLine) {
my ($k, $v) = split(/=/, $_, 2);
chomp($k);
chomp($v);
$apiRes->{$k} = $v;
}
if (defined $apiRes->{'key'} && defined $apiRes->{'code'}) {
$apiRes->{'code'} = decode_base64($apiRes->{'code'});
return $apiRes;
} else {
return $this->decodeData($response);
}
}
sub restoreToken {
my ($this) = @_;
my ($token);
my ($sessionKey) = 'oauth_token.' . $this->getUid();
RVL::logMessage($sessionKey, __CONSTANT__::RVL_LOG_DEBUG);
$token = $this->getToken();
if (!$token || $token eq '') {
$token = RVL::Session::get($sessionKey);
}
if (!$token || $token eq '') {
$this->getRequestToken();
} else {
$this->setToken($token);
$this->validateToken($token);
}
}
sub getRequestToken {
RVL::logMessage("getRequestToken", __CONSTANT__::RVL_LOG_DEBUG);
my ($this) = shift;
my ($res) = $this->{oAuth}->_get_request_token(@_);
my ($data) = $this->decodeData($res);
if (!$this->isError()) {
$this->acceptToken($data);
} else {
my ($errorMsg) = RVL::Error::getLast();
RVL::logMessage('On Error' . $errorMsg->{message}, __CONSTANT__::RVL_LOG_DEBUG);
}
}
sub acceptToken {
my ($this, $token) = @_;
RVL::logMessage("Token: $token", __CONSTANT__::RVL_LOG_DEBUG);
my ($access_token_url) = $this->{oAuth}->access_token_url;
my ($res) = $this->{oAuth}->__request(
url => $access_token_url,
token => $token,
params => { },
);
my ($data) = $this->decodeData($res);
if (!$this->isError()) {
RVL::logMessage("Accept token ID: " . $token, __CONSTANT__::RVL_LOG_DEBUG);
$this->setToken($token);
RVL::Session::set('oauth_token.' . $this->{uid}, $token);
}
}
sub validateToken {
my ($this, $token) = @_;
RVL::logMessage("Token: $token", __CONSTANT__::RVL_LOG_DEBUG);
my ($res) = $this->{oAuth}->__request(
url => $this->{DSN}->{'url'} . '/validate_token',
token => $token,
params => { },
);
my ($data) = $this->decodeData($res);
if ($this->isError()) {
RVL::Error::pop();
$this->getRequestToken();
}
}
sub request {
my ($this, $methon, $module, $parame) = @_;
if ($module !~/^\//) {
$module = '/' . $module;
}
$this->restoreToken();
my ($token) = $this->getToken();
my ($response);
my ($url) = $this->{DSN}->{'url'} . $module;
if (lc($methon) eq 'get') {
my ($oauth) = OAuth::Lite::Consumer->new(
consumer_key => $this->{DSN}->{'uid'},
consumer_secret => $this->{secret},
auth_method => 'url_query',
use_request_body_hash => 1,
);
$response = $oauth->get($url, {params => \%$parame, token => $token});
} elsif (lc($methon) eq 'post') {
my ($oauth) = OAuth::Lite::Consumer->new(
consumer_key => $this->{DSN}->{'uid'},
consumer_secret => $this->{secret},
auth_method => 'post_body',
);
$response = $oauth->post($url, '', {params => \%$parame, token => $token});
} elsif (lc($methon) eq 'put') {
my ($oauth) = OAuth::Lite::Consumer->new(
consumer_key => $this->{DSN}->{'uid'},
consumer_secret => $this->{secret},
auth_method => 'post_body',
);
$response = $oauth->put($url, '', {params => \%$parame, token => $token});
} elsif (lc($methon) eq 'delete') {
my ($oauth) = OAuth::Lite::Consumer->new(
consumer_key => $this->{DSN}->{'uid'},
consumer_secret => $this->{secret},
auth_method => 'url_query',
);
$parame->{token} = $token;
$response = $oauth->delete($url, {params => \%$parame, token => $token});
}
my ($data) = $this->decodeData($response);
if ($this->isError()) {
return RVL::Error::getLast();
} else {
return $data;
}
}
sub decodeData {
my ($this, $response) = @_;
unless ($response->status_line =~/^40.*$/gi || $response->status_line !~/^200$/gi) {
RVL::raiseError($response->status_line, 0);
return 0;
} else {
my ($data) = $response->decoded_content ||$response->content;
my ($contentType) = $response->header('content-type');
if ($contentType =~/^application\/rvglobalstore;/gi) {
$data = encode_base64($data);
$data = $this->encryptPublic($this->{DSN}->{publickey}, $data);
} elsif ($contentType =~/^text\/json;/gi || $contentType =~/^application\/json;/gi) {
$data = decode_json $data;
$this->errormsg($data);
}
return $data;
}
}
sub errormsg {
my ($this, $data) = @_;
if (ref $data eq 'HASH' && defined $data->{errors}) {
my (@aError) = @{$data->{errors}};
RVL::logMessage($aError[0]->{message}, __CONSTANT__::RVL_LOG_DEBUG);
RVL::raiseError($aError[0]->{message}, -1)
}
}
sub getError {
return RVL::Error::getAll();
}
sub isError {
return RVL::Error::isError();
}
sub encryptPublic {
my ($this, $public_key, $string) = @_;
RVL::logMessage('', __CONSTANT__::RVL_LOG_DEBUG);
#my $public = Crypt::OpenSSL::RSA->new_public_key($public_key);
#my $res = $public->encrypt($string);
#chomp($res);
#return $res;
$ENV{'RVCODE_PUBLIC_KEY'} = $public_key;
$ENV{'RVCODE_DATA'} = $string;
$ENV{'RVCODE_BASE64'} = 1;
my ($code) = __CONSTANT__::RVL_PATH . "/bin/openssl_decode";
my($chld_out, $chld_in);
RVL::logMessage("$public_key $string", __CONSTANT__::RVL_LOG_DEBUG);
my ($pid) = open2($chld_out, $chld_in, $code);
my ($res) = join('', <$chld_out>);
waitpid( $pid, 0 );
chomp($res);
my @data = split(undef,$res);
my $dataVal = '';
foreach my $val (@data){
my $ord = ord($val);
$dataVal .= $val if($ord ne 0);
}
return $dataVal;
}
sub decryptPublickey {
my ($this, $encrypted, $passphrase) = @_;
RVL::logMessage('', __CONSTANT__::RVL_LOG_DEBUG);
my ($iv) = '12345678';
my ($data) = encode_base64($encrypted);
RVL::logMessage('KEY: ' . $passphrase, __CONSTANT__::RVL_LOG_DEBUG);
RVL::logMessage('Data: ' .$data, __CONSTANT__::RVL_LOG_DEBUG);
$ENV{'RCRYPT_KEY'} = $passphrase;
$ENV{'RCRYPT_IV'} = $iv;
$ENV{'RCRYPT_DATA'} = $data;
$ENV{'RCRYPT_CMD'} = 'decrypt';
my ($code) = __CONSTANT__::RVL_PATH . "/bin/rvcrypt";
my($chld_out, $chld_in);
my ($pid) = open2($chld_out, $chld_in, $code);
my ($res) = join('', <$chld_out>);
waitpid( $pid, 0 );
chomp($res);
my @data = split(undef,$res);
my $dataVal = '';
foreach my $val (@data){
my $ord = ord($val);
$dataVal .= $val if($ord ne 0);
}
return $dataVal;
}
}
1;
Copyright 2K16 - 2K18 Indonesian Hacker Rulez