Change-Id: Ifbaafdfaf2194f84729bfb91c79453fd186dc5c6changes/19/8719/16
parent
ad62a1a5a1
commit
ae5e887dc2
@ -0,0 +1,28 @@
|
|||||||
|
package NGCP::Panel::Controller::API::BannedIps;
|
||||||
|
|
||||||
|
|
||||||
|
use Sipwise::Base;
|
||||||
|
use parent qw/NGCP::Panel::Role::Entities NGCP::Panel::Role::API::BannedIps/;
|
||||||
|
|
||||||
|
|
||||||
|
use NGCP::Panel::Utils::Peering;
|
||||||
|
use HTTP::Status qw(:constants);
|
||||||
|
use NGCP::Panel::Utils::Security;
|
||||||
|
|
||||||
|
__PACKAGE__->set_config();
|
||||||
|
|
||||||
|
sub allowed_methods {
|
||||||
|
return [qw/GET OPTIONS HEAD/];
|
||||||
|
}
|
||||||
|
|
||||||
|
sub api_description {
|
||||||
|
return 'Defines banned ips.';
|
||||||
|
}
|
||||||
|
|
||||||
|
sub get_list{
|
||||||
|
my ($self, $c) = @_;
|
||||||
|
return NGCP::Panel::Utils::Security::list_banned_ips($c);
|
||||||
|
}
|
||||||
|
1;
|
||||||
|
|
||||||
|
# vim: set tabstop=4 expandtab:
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
package NGCP::Panel::Controller::API::BannedIpsItem;
|
||||||
|
|
||||||
|
use parent qw/NGCP::Panel::Role::EntitiesItem NGCP::Panel::Role::API::BannedIps/;
|
||||||
|
|
||||||
|
use Sipwise::Base;
|
||||||
|
|
||||||
|
|
||||||
|
use HTTP::Status qw(:constants);
|
||||||
|
use NGCP::Panel::Utils::Security;
|
||||||
|
|
||||||
|
|
||||||
|
__PACKAGE__->set_config();
|
||||||
|
|
||||||
|
sub allowed_methods {
|
||||||
|
return [qw/GET OPTIONS HEAD DELETE/];
|
||||||
|
}
|
||||||
|
|
||||||
|
sub delete_item {
|
||||||
|
my($self, $c, $item, $old_resource, $resource, $form) = @_;
|
||||||
|
my $ip = $item;
|
||||||
|
NGCP::Panel::Utils::Security::ip_unban($c, $ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
# vim: set tabstop=4 expandtab:
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
package NGCP::Panel::Controller::API::BannedUsers;
|
||||||
|
|
||||||
|
|
||||||
|
use Sipwise::Base;
|
||||||
|
use parent qw/NGCP::Panel::Role::Entities NGCP::Panel::Role::API::BannedUsers/;
|
||||||
|
|
||||||
|
|
||||||
|
use NGCP::Panel::Utils::Peering;
|
||||||
|
use HTTP::Status qw(:constants);
|
||||||
|
use NGCP::Panel::Utils::Security;
|
||||||
|
|
||||||
|
__PACKAGE__->set_config();
|
||||||
|
|
||||||
|
sub allowed_methods {
|
||||||
|
return [qw/GET OPTIONS HEAD/];
|
||||||
|
}
|
||||||
|
|
||||||
|
sub api_description {
|
||||||
|
return 'Defines banned users.';
|
||||||
|
}
|
||||||
|
|
||||||
|
sub get_list{
|
||||||
|
my ($self, $c) = @_;
|
||||||
|
return NGCP::Panel::Utils::Security::list_banned_users($c, data_for_json => 1);
|
||||||
|
}
|
||||||
|
1;
|
||||||
|
|
||||||
|
# vim: set tabstop=4 expandtab:
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
package NGCP::Panel::Controller::API::BannedUsersItem;
|
||||||
|
|
||||||
|
use parent qw/NGCP::Panel::Role::EntitiesItem NGCP::Panel::Role::API::BannedUsers/;
|
||||||
|
|
||||||
|
use Sipwise::Base;
|
||||||
|
|
||||||
|
|
||||||
|
use HTTP::Status qw(:constants);
|
||||||
|
use NGCP::Panel::Utils::Security;
|
||||||
|
|
||||||
|
|
||||||
|
__PACKAGE__->set_config();
|
||||||
|
|
||||||
|
sub allowed_methods {
|
||||||
|
return [qw/GET OPTIONS HEAD DELETE/];
|
||||||
|
}
|
||||||
|
|
||||||
|
sub delete_item {
|
||||||
|
my($self, $c, $item, $old_resource, $resource, $form) = @_;
|
||||||
|
my $user = $item;
|
||||||
|
NGCP::Panel::Utils::Security::user_unban($c, $user);
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
# vim: set tabstop=4 expandtab:
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
package NGCP::Panel::Role::API::BannedIps;
|
||||||
|
|
||||||
|
use Sipwise::Base;
|
||||||
|
|
||||||
|
|
||||||
|
use parent qw/NGCP::Panel::Role::API/;
|
||||||
|
|
||||||
|
use NGCP::Panel::Utils::Generic qw(:all);
|
||||||
|
use boolean qw(true);
|
||||||
|
use HTTP::Status qw(:constants);
|
||||||
|
use NGCP::Panel::Form::Peering::Group;
|
||||||
|
use NGCP::Panel::Utils::Peering;
|
||||||
|
|
||||||
|
sub item_name {
|
||||||
|
return 'bannedips';
|
||||||
|
}
|
||||||
|
|
||||||
|
sub resource_name{
|
||||||
|
return 'bannedips';
|
||||||
|
}
|
||||||
|
|
||||||
|
sub get_item_id{
|
||||||
|
my($self, $c, $item, $resource, $form) = @_;
|
||||||
|
return $item->{ip};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub valid_id {
|
||||||
|
my ($self, $c, $id) = @_;
|
||||||
|
return 1 if $id=~/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(?:\/\d{1,2})?$/;
|
||||||
|
$self->error($c, HTTP_BAD_REQUEST, "Invalid id in request URI. Should be an ip address.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sub item_by_id{
|
||||||
|
my ($self, $c, $id) = @_;
|
||||||
|
return $id;
|
||||||
|
}
|
||||||
|
1;
|
||||||
|
# vim: set tabstop=4 expandtab:
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
package NGCP::Panel::Role::API::BannedUsers;
|
||||||
|
|
||||||
|
use Sipwise::Base;
|
||||||
|
|
||||||
|
|
||||||
|
use parent qw/NGCP::Panel::Role::API/;
|
||||||
|
|
||||||
|
use NGCP::Panel::Utils::Generic qw(:all);
|
||||||
|
use boolean qw(true);
|
||||||
|
use HTTP::Status qw(:constants);
|
||||||
|
use NGCP::Panel::Form::Peering::Group;
|
||||||
|
use NGCP::Panel::Utils::Peering;
|
||||||
|
|
||||||
|
sub item_name {
|
||||||
|
return 'bannedusers';
|
||||||
|
}
|
||||||
|
|
||||||
|
sub resource_name{
|
||||||
|
return 'bannedusers';
|
||||||
|
}
|
||||||
|
|
||||||
|
sub get_item_id{
|
||||||
|
my($self, $c, $item, $resource, $form) = @_;
|
||||||
|
return $item->{username};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub valid_id {
|
||||||
|
my ($self, $c, $id) = @_;
|
||||||
|
return 1 if $id=~/^[^@]+@[^@]+$/;
|
||||||
|
$self->error($c, HTTP_BAD_REQUEST, "Invalid id in request URI. Should be an ip address.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub item_by_id{
|
||||||
|
my ($self, $c, $id) = @_;
|
||||||
|
return $id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
1;
|
||||||
|
# vim: set tabstop=4 expandtab:
|
||||||
@ -0,0 +1,138 @@
|
|||||||
|
package NGCP::Panel::Utils::Security;
|
||||||
|
use Sipwise::Base;
|
||||||
|
|
||||||
|
use XML::LibXML;
|
||||||
|
use URI::Encode;
|
||||||
|
use NGCP::Panel::Utils::XMLDispatcher;
|
||||||
|
use NGCP::Panel::Utils::DateTime;
|
||||||
|
|
||||||
|
sub list_banned_ips {
|
||||||
|
my ( $c ) = @_;
|
||||||
|
my $dispatcher = NGCP::Panel::Utils::XMLDispatcher->new;
|
||||||
|
my $xml_parser = XML::LibXML->new();
|
||||||
|
|
||||||
|
my $ip_xml = <<'EOF';
|
||||||
|
<?xml version="1.0" ?>
|
||||||
|
<methodCall>
|
||||||
|
<methodName>htable.dump</methodName>
|
||||||
|
<params>
|
||||||
|
<param><value><string>ipban</string></value></param>
|
||||||
|
</params>
|
||||||
|
</methodCall>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
my $ip_res = $dispatcher->dispatch($c, "loadbalancer", 1, 1, $ip_xml);
|
||||||
|
|
||||||
|
my @ips = ();
|
||||||
|
for my $host (grep {$$_[1]} @$ip_res) {
|
||||||
|
my $xmlDoc = $xml_parser->parse_string($host->[2]);
|
||||||
|
foreach my $node ($xmlDoc->findnodes('//member')) {
|
||||||
|
my $name = $node->findvalue('./name');
|
||||||
|
my $value = $node->findvalue('./value/string');
|
||||||
|
if ($name eq 'name') {
|
||||||
|
push @ips, { ip => $value };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return \@ips;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub list_banned_users {
|
||||||
|
my ( $c, %params ) = @_;
|
||||||
|
|
||||||
|
my $dispatcher = NGCP::Panel::Utils::XMLDispatcher->new;
|
||||||
|
my $xml_parser = XML::LibXML->new();
|
||||||
|
|
||||||
|
my $user_xml = <<'EOF';
|
||||||
|
<?xml version="1.0" ?>
|
||||||
|
<methodCall>
|
||||||
|
<methodName>htable.dump</methodName>
|
||||||
|
<params>
|
||||||
|
<param><value><string>auth</string></value></param>
|
||||||
|
</params>
|
||||||
|
</methodCall>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
my $user_res = $dispatcher->dispatch($c, "loadbalancer", 1, 1, $user_xml);
|
||||||
|
my @users = ();
|
||||||
|
my $usr = {};
|
||||||
|
for my $host (grep {$$_[1]} @$user_res) {
|
||||||
|
my $xmlDoc = $xml_parser->parse_string($host->[2]);
|
||||||
|
my $username = '';
|
||||||
|
my $key = '';
|
||||||
|
foreach my $node ($xmlDoc->findnodes('//member')) {
|
||||||
|
my $name = $node->findvalue('./name');
|
||||||
|
my $value = $node->findvalue('./value/string') ||
|
||||||
|
$node->findvalue('./value/int');
|
||||||
|
if ($name eq 'name') {
|
||||||
|
$value =~ m/(?<user>.*)::(?<key>.*)/;
|
||||||
|
$username = $+{user};
|
||||||
|
$key = $+{key};
|
||||||
|
} elsif ($name eq 'value' && $username && $key) {
|
||||||
|
# there souldn't be any other keys
|
||||||
|
$key eq 'auth_count' and $usr->{$username}->{auth_count} = $value;
|
||||||
|
$key eq 'last_auth' and $usr->{$username}->{last_auth} = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for my $key (keys %{ $usr }) {
|
||||||
|
my $last_auth = $usr->{$key}->{last_auth} ? NGCP::Panel::Utils::DateTime::epoch_local($usr->{$key}->{last_auth}) : undef;
|
||||||
|
if($last_auth && $params{data_for_json}){
|
||||||
|
$last_auth = $last_auth->ymd.' '. $last_auth->hms;
|
||||||
|
}
|
||||||
|
push @users, {
|
||||||
|
username => $key,
|
||||||
|
auth_count => $usr->{$key}->{auth_count},
|
||||||
|
last_auth => $last_auth,
|
||||||
|
} if($usr->{$key}->{auth_count} >= $c->config->{security}->{failed_auth_attempts});
|
||||||
|
}
|
||||||
|
return \@users;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub ip_unban {
|
||||||
|
my ( $c, $ip ) = @_;
|
||||||
|
my $decoder = URI::Encode->new;
|
||||||
|
$ip = $decoder->decode($ip);
|
||||||
|
my $dispatcher = NGCP::Panel::Utils::XMLDispatcher->new;
|
||||||
|
|
||||||
|
my $xml = <<"EOF";
|
||||||
|
<?xml version="1.0" ?>
|
||||||
|
<methodCall>
|
||||||
|
<methodName>htable.delete</methodName>
|
||||||
|
<params>
|
||||||
|
<param><value><string>ipban</string></value></param>
|
||||||
|
<param><value><string>$ip</string></value></param>
|
||||||
|
</params>
|
||||||
|
</methodCall>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
$dispatcher->dispatch($c, "loadbalancer", 1, 1, $xml);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub user_unban {
|
||||||
|
my ( $c, $user ) = @_;
|
||||||
|
my $decoder = URI::Encode->new;
|
||||||
|
$user = $decoder->decode($user);
|
||||||
|
my $dispatcher = NGCP::Panel::Utils::XMLDispatcher->new;
|
||||||
|
|
||||||
|
my @keys = ($user.'::auth_count', $user.'::last_auth');
|
||||||
|
foreach my $key (@keys) {
|
||||||
|
my $xml = <<"EOF";
|
||||||
|
<?xml version="1.0" ?>
|
||||||
|
<methodCall>
|
||||||
|
<methodName>htable.delete</methodName>
|
||||||
|
<params>
|
||||||
|
<param><value><string>auth</string></value></param>
|
||||||
|
<param><value><string>$key</string></value></param>
|
||||||
|
</params>
|
||||||
|
</methodCall>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
$dispatcher->dispatch($c, "loadbalancer", 1, 1, $xml);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
# vim: set tabstop=4 expandtab:
|
||||||
@ -0,0 +1,51 @@
|
|||||||
|
use strict;
|
||||||
|
|
||||||
|
use Test::Collection;
|
||||||
|
use Test::FakeData;
|
||||||
|
use Test::More;
|
||||||
|
use Data::Dumper;
|
||||||
|
|
||||||
|
#use NGCP::Panel::Utils::Subscriber;
|
||||||
|
|
||||||
|
my $test_machine = Test::Collection->new(
|
||||||
|
name => 'bannedips',
|
||||||
|
);
|
||||||
|
my $fake_data = Test::FakeData->new;
|
||||||
|
|
||||||
|
$test_machine->methods->{collection}->{allowed} = {map {$_ => 1} qw(GET HEAD OPTIONS)};
|
||||||
|
$test_machine->methods->{item}->{allowed} = {map {$_ => 1} qw(GET HEAD OPTIONS DELETE)};
|
||||||
|
|
||||||
|
$fake_data->set_data_from_script({
|
||||||
|
'bannedips' => {
|
||||||
|
'data' => {
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
$test_machine->DATA_ITEM_STORE($fake_data->process('bannedips'));
|
||||||
|
$test_machine->ALLOW_EMPTY_COLLECTION(1);
|
||||||
|
$test_machine->form_data_item();
|
||||||
|
|
||||||
|
my $time = time();
|
||||||
|
|
||||||
|
my $hal_before = $test_machine->get_item_hal(undef,undef,1);
|
||||||
|
|
||||||
|
my @ips = qw/127.0.0.1 127.0.0.2 127.0.0.3/;
|
||||||
|
foreach (@ips){
|
||||||
|
`ngcp-sercmd lb htable.sets ipban $_ 1`;
|
||||||
|
}
|
||||||
|
|
||||||
|
$test_machine->check_bundle();
|
||||||
|
|
||||||
|
if(!$test_machine->IS_EMPTY_COLLECTION){
|
||||||
|
$test_machine->clear_test_data_all([map {"/api/bannedips/$_"} @ips]);
|
||||||
|
}
|
||||||
|
if(!$hal_before || $hal_before->{content_collection}->{total_count} < 1){
|
||||||
|
my $hal_after = $test_machine->get_item_hal(undef,undef,1);
|
||||||
|
is($hal_after, undef, "Check that all added banned ips were deleted");
|
||||||
|
}
|
||||||
|
#fake data aren't registered in this test machine, so they will stay.
|
||||||
|
done_testing;
|
||||||
|
|
||||||
|
|
||||||
|
# vim: set tabstop=4 expandtab:
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
use strict;
|
||||||
|
|
||||||
|
use Test::Collection;
|
||||||
|
use Test::FakeData;
|
||||||
|
use Test::More;
|
||||||
|
use Data::Dumper;
|
||||||
|
|
||||||
|
#use NGCP::Panel::Utils::Subscriber;
|
||||||
|
|
||||||
|
my $test_machine = Test::Collection->new(
|
||||||
|
name => 'bannedusers',
|
||||||
|
);
|
||||||
|
my $fake_data = Test::FakeData->new;
|
||||||
|
|
||||||
|
$test_machine->methods->{collection}->{allowed} = {map {$_ => 1} qw(GET HEAD OPTIONS)};
|
||||||
|
$test_machine->methods->{item}->{allowed} = {map {$_ => 1} qw(GET HEAD OPTIONS DELETE)};
|
||||||
|
|
||||||
|
$fake_data->set_data_from_script({
|
||||||
|
'bannedusers' => {
|
||||||
|
'data' => {
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
$test_machine->DATA_ITEM_STORE($fake_data->process('bannedusers'));
|
||||||
|
$test_machine->ALLOW_EMPTY_COLLECTION(1);
|
||||||
|
$test_machine->form_data_item();
|
||||||
|
|
||||||
|
my $hal_before = $test_machine->get_item_hal(undef,undef,1);
|
||||||
|
|
||||||
|
my $time = time();
|
||||||
|
my @users = qw/user1 user2 user3/;
|
||||||
|
foreach (@users){
|
||||||
|
my $cmd1 = "ngcp-sercmd lb htable.sets auth $_\@domain.com::auth_count 10";
|
||||||
|
my $cmd2 = "ngcp-sercmd lb htable.sets auth $_\@domain.com::last_auth $time";
|
||||||
|
print $cmd1."\n".$cmd2."\n";
|
||||||
|
`$cmd1`;
|
||||||
|
`$cmd2`;
|
||||||
|
}
|
||||||
|
|
||||||
|
$test_machine->check_bundle();
|
||||||
|
print "is_empty:".$test_machine->IS_EMPTY_COLLECTION.";";
|
||||||
|
if(!$test_machine->IS_EMPTY_COLLECTION){
|
||||||
|
$test_machine->clear_test_data_all([map {"/api/bannedusers/$_\@domain.com"} @users]);
|
||||||
|
}
|
||||||
|
if(!$hal_before || $hal_before->{content_collection}->{total_count} < 1){
|
||||||
|
my $hal_after = $test_machine->get_item_hal(undef,undef,1);
|
||||||
|
print Dumper $hal_after;
|
||||||
|
is($hal_after, undef, "Check that all added banned users were deleted");
|
||||||
|
}
|
||||||
|
done_testing;
|
||||||
|
|
||||||
|
|
||||||
|
# vim: set tabstop=4 expandtab:
|
||||||
Loading…
Reference in new issue