From 3fa77dcdb020cfdb11e9020b8365e8554354ac77 Mon Sep 17 00:00:00 2001 From: Irina Peshinskaya Date: Wed, 5 Nov 2014 08:23:56 +0200 Subject: [PATCH] MT#9177 Refactor code to separate vendor specific and common logic --- lib/NGCP/Panel/Utils/DeviceBootstrap.pm | 153 +++++++++----- .../Panel/Utils/DeviceBootstrap/Panasonic.pm | 194 ++++++++---------- lib/NGCP/Panel/Utils/DeviceBootstrap/RPC.pm | 137 +++++++++++++ 3 files changed, 314 insertions(+), 170 deletions(-) create mode 100644 lib/NGCP/Panel/Utils/DeviceBootstrap/RPC.pm diff --git a/lib/NGCP/Panel/Utils/DeviceBootstrap.pm b/lib/NGCP/Panel/Utils/DeviceBootstrap.pm index 519fe1aa59..5b5bf8610c 100644 --- a/lib/NGCP/Panel/Utils/DeviceBootstrap.pm +++ b/lib/NGCP/Panel/Utils/DeviceBootstrap.pm @@ -1,42 +1,85 @@ package NGCP::Panel::Utils::DeviceBootstrap; -use Sipwise::Base; + +use strict; +use Data::Dumper; +use NGCP::Panel::Utils::DeviceBootstrap::RPC; use NGCP::Panel::Utils::DeviceBootstrap::Panasonic; -sub get_baseuri { - my ($c) = @_; +#NGCP::Panel::Utils::DeviceBootstrap::RPC params => + #$params = { + # redirect_uri + # redirect_uri_params + # mac + # mac_old (optional) + # c for log, config sync uri from config + # credentials => {user=>, password=>} + #}; - my $uri = - ($c->config->{deviceprovisioning}->{secure} ? 'https' : 'http'). - '://'. - ($c->config->{deviceprovisioning}->{host} // $c->req->uri->host). - ':'. - ($c->config->{deviceprovisioning}->{port} // 1444). - '/device/autoprov/config/'; - return $uri; +sub redirect_register{ + my ($params) = @_; + my $ret; + my $redirect_processor = get_redirect_processor($params); + if($redirect_processor){ + $ret = $redirect_processor->redirect_register; + } + return $ret; +} +sub redirect_unregister{ + my ($params) = @_; + my $ret; + my $redirect_processor = get_redirect_processor($params); + if($redirect_processor){ + $ret = $redirect_processor->redirect_unregister; + } + return $ret; } -sub dispatch { - my ($c, $action, $dev, $old_mac) = @_; +sub get_redirect_processor{ + my ($params) = @_; + my $c = $params->{c}; + my $bootstrap_method = $params->{bootstrap_method}; - my $btype = $dev->profile->config->device->bootstrap_method; - my $mod = 'NGCP::Panel::Utils::DeviceBootstrap'; + $c->log->debug( "bootstrap_method=$bootstrap_method;" ); + my $redirect_processor; + if('redirect_panasonic' eq $bootstrap_method){ + $redirect_processor = NGCP::Panel::Utils::DeviceBootstrap::Panasonic->new( params => $params ); + }elsif('redirect_linksys' eq $bootstrap_method){ + }elsif('http' eq $bootstrap_method){ + #$ret = panasonic_bootstrap_register($params); + } + return $redirect_processor; +} + +sub bootstrap_config{ + my($c, $fdev, $old_identifier) = @_; + + my $device = $fdev->profile->config->device; - if($btype eq 'redirect_panasonic') { - $mod .= '::Panasonic'; - } elsif($btype eq 'http') { - return; - } else { - return; + my $credentials = $fdev->profile->config->device->autoprov_redirect_credentials; + my $vcredentials; + if($credentials){ + $vcredentials = { map { $_ => $credentials->$_ } qw/user password/}; } - $mod .= '::'.$action; - $c->log->debug("dispatching bootstrap call to '$mod'"); - no strict "refs"; - return $mod->($c, $dev, $dev->identifier, $old_mac); + my $sync_params_rs = $device->autoprov_sync->search_rs({ + 'autoprov_sync_parameters.parameter_name' => 'sync_params', + },{ + join => 'autoprov_sync_parameters', + select => ['me.parameter_value'], + }); + my $sync_params = $sync_params_rs->first ? $sync_params_rs->first->parameter_value : ''; + my $ret = redirect_register({ + c => $c, + mac => $fdev->identifier, + mac_old => $old_identifier, + bootstrap_method => $device->bootstrap_method, + redirect_uri_params => $sync_params, + credentials => $vcredentials, + }); + return $ret; } - sub devmod_sync_parameters_prefetch{ my($c,$devmod,$params) = @_; my $schema = $c->model('DB'); @@ -53,41 +96,12 @@ sub devmod_sync_parameters_prefetch{ }; push @parameters,$sync_parameter; } - return \@parameters; -} -sub devmod_sync_credentials_prefetch{ - my($c,$devmod,$params) = @_; - my $schema = $c->model('DB'); - my $bootstrap_method = $params->{'bootstrap_method'}; - my $credentials = { - device_id => $devmod ? $devmod->id : undef, - }; - foreach (qw/user password/){ - $credentials->{$_} = delete $params->{'bootstrap_config_'.$bootstrap_method.'_'.$_}; - } - return $credentials; -} -sub devmod_sync_credentials_store{ - my($c,$devmod,$credentials) = @_; - my $schema = $c->model('DB'); - my $credentials_rs = $schema->resultset('autoprov_redirect_credentials')->search_rs({ - 'device_id' => $devmod->id - }); - if(!$credentials_rs->first){ - $credentials->{device_id} = $devmod->id; - $schema->resultset('autoprov_redirect_credentials')->create($credentials); - }else{ - $credentials_rs->update($credentials); - } -} - -sub devmod_sync_clear { - my($c,$params) = @_; foreach (keys %$params){ if($_ =~/^bootstrap_config_/i){ delete $params->{$_}; } } + return \@parameters; } sub devmod_sync_parameters_store { my($c,$devmod,$sync_parameters) = @_; @@ -97,3 +111,30 @@ sub devmod_sync_parameters_store { $schema->resultset('autoprov_sync')->create($sync_parameter); } } +1; + +=head1 NAME + +NGCP::Panel::Utils::DeviceBootstrap + +=head1 DESCRIPTION + +Make API requests to configure remote redirect servers for requested MAC with autorpov uri. + +=head1 METHODS + +=head2 bootstrap + +Dispatch to proper vendor API call. + +=head1 AUTHOR + +Irina Peshinskaya C<< >> + +=head1 LICENSE + +This library is free software. You can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut +# vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Utils/DeviceBootstrap/Panasonic.pm b/lib/NGCP/Panel/Utils/DeviceBootstrap/Panasonic.pm index 3538ba0c0a..f383992c14 100644 --- a/lib/NGCP/Panel/Utils/DeviceBootstrap/Panasonic.pm +++ b/lib/NGCP/Panel/Utils/DeviceBootstrap/Panasonic.pm @@ -1,134 +1,100 @@ package NGCP::Panel::Utils::DeviceBootstrap::Panasonic; -use Sipwise::Base; -use URI::Escape; -use MIME::Base64 qw/encode_base64/; -use Net::HTTPS::Any qw/https_post/; -use RPC::XML::ParserFactory 'XML::LibXML'; -use RPC::XML; -use Data::Dumper; - -my $cfg = { - proto => 'https', - host => 'provisioning.e-connecting.net', - port => '443', - path => '/redirect/xmlrpc', -}; - -sub prepare { - my ($c, $fdev) = @_; - my $p = {}; - - my $devmod = $fdev->profile->config->device; - my $creds = $devmod->autoprov_redirect_credentials; - if($creds) { - $p->{auth} = encode_base64($creds->user.':'.$creds->password); - } +use strict; +use Moose; +extends 'NGCP::Panel::Utils::DeviceBootstrap::RPC'; + +has 'rpc_server_params' => ( + is => 'rw', + isa => 'HashRef', + accessor => '_rpc_server_params', +); +has 'register_content' => ( + is => 'rw', + isa => 'Str', + accessor => '_register_content', +); +has 'unregister_content' => ( + is => 'rw', + isa => 'Str', + accessor => '_unregister_content', +); +sub rpc_server_params{ + my $self = shift; + my $cfg = { + proto => 'https', + host => 'provisioning.e-connecting.net', + port => '443', + path => '/redirect/xmlrpc', + }; + $cfg->{headers} = { $self->get_basic_authorization($self->params->{credentials}) }; + $self->{rpc_server_params} = $cfg; + return $self->{rpc_server_params}; +} - $p->{uri} = ($devmod->bootstrap_uri) - ? $devmod->bootstrap_uri - : NGCP::Panel::Utils::DeviceBootstrap::get_baseuri($c); - - if ($p->{uri} !~/\{MAC\}$/){ - if ($p->{uri} !~/\/$/){ - $p->{uri} .= '/' ; - } - $p->{uri} .= '{MAC}' ; - } - $p->{uri} = URI::Escape::uri_escape($p->{uri}); - - return $p; +sub register_content { + my $self = shift; + $self->{register_content} = " + +ipredirect.registerPhone + +".$self->content_params->{mac}." +".$self->content_params->{uri}." + +"; + return $self->{register_content}; } -# return faultString or undef if ok -sub check_result { - my ($c, $data) = @_; - my $val = ''; - if($data){ - my $parser = RPC::XML::ParserFactory->new(); - my $rpc = $parser->parse($data); - $val = $rpc->value->value; - } +sub unregister_content { + my $self = shift; + $self->{unregister_content} = " + +ipredirect.unregisterPhone + +".$self->content_params->{mac_old}." + +"; + return $self->{unregister_content}; +} - $c->log->debug("panasonic redirect call returned: " . Dumper $val); +sub parse_rpc_response{ + my($self,$rpc_response) = @_; + return $rpc_response->value->value; +} + +sub extract_response_description{ + my($self,$response_value) = @_; - if(ref $val eq 'HASH' && $val->{faultString}) { - return $val->{faultString}; + if(('HASH' eq ref $response_value) && $response_value->{faultString}){ + return $response_value->{faultString}; } else { return; } } +1; -sub normalize_mac { - my ($mac) = @_; - return unless($mac); - $mac =~s/[^A-F0-9]//gi; - $mac = uc($mac); - return $mac; -} +=head1 NAME -sub unregister { - my ($c, $fdev, $mac, $old_mac) = @_; +NGCP::Panel::Utils::DeviceBootstrap - my $p = prepare($c, $fdev); - $old_mac = normalize_mac($old_mac); +=head1 DESCRIPTION - my $data = " - -ipredirect.unregisterPhone - -".$old_mac." - -"; - $c->log->debug("panasonic redirect call $data"); - - my($res, $code) = https_post({ - 'host' => $cfg->{host}, - 'port' => $cfg->{port}, - 'path' => $cfg->{path}, - 'headers' => { 'Authorization' => 'Basic '.$p->{auth} }, - 'Content-Type' => 'text/xml', - 'content' => $data, - }); - return check_result($c, $res); -} +Make API requests to configure remote redirect servers for requested MAC with autorpov uri. -sub register { - my ($c, $fdev, $mac, $old_mac) = @_; +=head1 METHODS - my $p = prepare($c, $fdev); - $mac = normalize_mac($mac); - $old_mac = normalize_mac($old_mac); +=head2 bootstrap - # we don't check for the result here, in the worst case - # we leave an orphaned entry behind - unregister($c, $fdev, $mac, $old_mac) if($old_mac && $old_mac ne $mac); - - my $data = " - -ipredirect.registerPhone - -".$mac." -".$p->{uri}." - -"; - $c->log->debug("panasonic redirect call $data"); - - my($res, $code) = https_post({ - 'host' => $cfg->{host}, - 'port' => $cfg->{port}, - 'path' => $cfg->{path}, - 'headers' => { 'Authorization' => 'Basic '.$p->{auth} }, - 'Content-Type' => 'text/xml', - 'content' => $data, - }); - if($res){ - $c->log->debug("register returned with code $code and data $res"); - return check_result($c, $res); - }else{ - return 'Empty response'; - } -} +Dispatch to proper vendor API call. -1; +=head1 AUTHOR + +Irina Peshinskaya C<< >> + +=head1 LICENSE + +This library is free software. You can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut # vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Utils/DeviceBootstrap/RPC.pm b/lib/NGCP/Panel/Utils/DeviceBootstrap/RPC.pm new file mode 100644 index 0000000000..e2a146054e --- /dev/null +++ b/lib/NGCP/Panel/Utils/DeviceBootstrap/RPC.pm @@ -0,0 +1,137 @@ +package NGCP::Panel::Utils::DeviceBootstrap::RPC; + +use strict; +use URI::Escape; +use MIME::Base64 qw/encode_base64/; +use Net::HTTPS::Any qw/https_post/; +use RPC::XML::ParserFactory 'XML::LibXML'; +use RPC::XML; +use Data::Dumper; +use Moose; + +has 'params' => ( + is => 'rw', + isa => 'HashRef', +); +has 'content_params' => ( + is => 'rw', + isa => 'HashRef', +); +has 'rpc_server_params' => ( + is => 'rw', + isa => 'HashRef', +); + +sub redirect_register{ + my ($self) = @_; + my $c = $self->params->{c}; + $self->init_content_params(); + $c->log->debug(Dumper ($self->content_params)); + my($content,$response_value); + if(defined $self->content_params->{mac_old} && $self->content_params->{mac} ne $self->content_params->{mac_old}) { + $content = $self->unregister_content(); + $response_value = $self->rpc_https_call($content); + } + $content = $self->register_content(); + $response_value = $self->rpc_https_call($content); + return $self->extract_response_description($response_value); +} + +sub rpc_https_call{ + my($self, $content, $cfg) = @_; + $cfg //= $self->rpc_server_params; + my $c = $self->params->{c}; + $c->log->debug( "host=$cfg->{host}; port=$cfg->{port}; path=$cfg->{path}; content=$content;" ); + my( $page, $response_code, %reply_headers ) = https_post({ + 'host' => $cfg->{host}, + 'port' => $cfg->{port}, + 'path' => $cfg->{path}, + 'headers' => $cfg->{headers}, + 'Content-Type' => 'text/xml', + 'content' => $content, + },); + $c->log->info( "response=$response_code; page=$page;" ); + my $response_value = ''; + if($page){ + my $parser = RPC::XML::ParserFactory->new(); + my $rpc_response = $parser->parse($page); + $response_value = $self->parse_rpc_response($rpc_response); + $c->log->info("response_value=".Dumper($response_value)); + } + return $response_value; +} +sub init_content_params{ + my($self) = @_; + $self->params->{redirect_uri_params} ||= '{MAC}'; + my $uri = $self->get_bootstrap_uri(); + $self->{content_params} ||= {}; + $self->content_params->{uri} = URI::Escape::uri_escape($uri); + my $mac = $self->params->{mac}; + $mac =~s/[^A-F0-9]//gi; + $self->content_params->{mac} = uc($mac); + my $mac_old = $self->params->{mac_old}; + if(defined $mac_old) { + $mac_old =~s/[^A-F0-9]//gi; + $mac_old = uc($mac_old); + $self->content_params->{mac_old} = $mac_old; + } +} +sub get_basic_authorization{ + my($self) = @_; + my $authorization = encode_base64(join(':',@{$self->params->{credentials}}{qw/user password/})); + $authorization =~s/[ \s]//gis; + $authorization .= '='; + return { 'Authorization' => 'Basic '.$authorization }; +} +sub get_bootstrap_uri{ + my ($self) = @_; + my $uri = $self->params->{redirect_uri}; + my $uri_params = $self->params->{redirect_uri_params} || ''; + if($uri){ + if(!$uri =~/^https?:\/\//i ){ + $uri = 'http://'.$uri; + } + }else{ + my $cfg = $self->get_bootstrap_uri_conf(); + $uri = "$cfg->{schema}://$cfg->{host}:$cfg->{port}/device/autoprov/config/"; + } + $uri .= $uri_params; + return $uri; +} +sub get_bootstrap_uri_conf{ + my ($self) = @_; + my $c = $self->params->{c}; + my $cfg = { + schema => $c->config->{deviceprovisioning}->{secure} ? 'https' : 'http', + host => $c->config->{deviceprovisioning}->{host} // $c->req->uri->host, + port => $c->config->{deviceprovisioning}->{port} // 1444, + }; + return $cfg; +} +1; + +=head1 NAME + +NGCP::Panel::Utils::DeviceBootstrap + +=head1 DESCRIPTION + +Make API requests to configure remote redirect servers for requested MAC with autorpov uri. + +=head1 METHODS + +=head2 bootstrap + +Dispatch to proper vendor API call. + +=head1 AUTHOR + +Irina Peshinskaya C<< >> + +=head1 LICENSE + +This library is free software. You can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut +# vim: set tabstop=4 expandtab: