use strict; use warnings; use Test::Collection; use Test::FakeData; use Test::More; use Data::Dumper; use Clone qw/clone/; use feature 'state'; #use NGCP::Panel::Utils::Subscriber; #use Data::Compare qw//; my $test_machine = Test::Collection->new( name => 'subscribers', QUIET_DELETION => 1, ); my $fake_data = Test::FakeData->new; $test_machine->methods->{collection}->{allowed} = {map {$_ => 1} qw(GET HEAD OPTIONS POST)}; $test_machine->methods->{item}->{allowed} = {map {$_ => 1} qw(GET HEAD OPTIONS PUT PATCH DELETE)}; $fake_data->set_data_from_script({ 'subscribers' => { 'data' => { administrative => 0, customer_id => sub { return shift->get_id('customers',@_); }, primary_number => { ac => 12, cc=> 12, sn => 12 }, alias_numbers => [ { ac => 112, cc=> 112, sn => 112 } ], username => 'api_test_username', password => 'api_test_password', webusername => 'api_test_webusername', webpassword => 'web_password_1', domain_id => sub { return shift->get_id('domains',@_); }, #domain_id => email => undef, external_id => undef, is_pbx_group => 1, is_pbx_pilot => 1, #sub { # my($self) = @_; # my $pilot = $self->test_machine->get_item_hal('subscribers','/api/subscribers/?customer_id='.$self->data->{$collection_name}->{data}->{customer_id}.'&'.'is_pbx_pilot=1'); # if($pilot->{content}->{total_count} > 0){ # return 0; # } # return 1; #}, pbx_extension => '111', pbx_group_ids => [], pbx_groupmember_ids => [], profile_id => sub { return shift->get_id('subscriberprofiles',@_); }, profile_set_id => sub { return shift->get_id('subscriberprofilesets',@_); }, status => 'active', pbx_hunt_policy => 'parallel', pbx_hunt_timeout => '15', pbx_hunt_cancel_mode => 'cancel', }, 'query' => [['username',{'query_type'=> 'string_like'}]], 'create_special'=> sub { state $num; $num //= 0; $num++; my ($self,$collection_name,$test_machine) = @_; my $pilot = $test_machine->get_item_hal('subscribers','/api/subscribers/?customer_id='.$self->data->{$collection_name}->{data}->{customer_id}.'&'.'is_pbx_pilot=1'); if(!$pilot->{total_count} || $pilot->{total_count} <= 0){ undef $pilot; } return $test_machine->check_create_correct(1, sub{ my $time = time; $_[0]->{is_pbx_pilot} = ($pilot || $_[1]->{i} > 1)? 0 : 1; $_[0]->{pbx_extension} = $time.$num.Test::FakeData::seq; $_[0]->{webusername} .= $time.$num.Test::FakeData::seq; $_[0]->{username} .= $time.$num.Test::FakeData::seq; delete $_[0]->{alias_numbers}; $_[0]->{primary_number}->{sn} = $time.$num; }, $self->data->{$collection_name}->{data} ); }, 'update_change_fields' => [qw/modify_timestamp create_timestamp primary_number_id webpassword/], }, }); my $fake_data_processed = $fake_data->process('subscribers'); my $pilot = $test_machine->get_item_hal('subscribers','/api/subscribers/?customer_id='.$fake_data_processed->{customer_id}.'&'.'is_pbx_pilot=1'); if((exists $pilot->{total_count} && $pilot->{total_count}) || (exists $pilot->{content}->{total_count} && $pilot->{content}->{total_count} > 0) ){ $fake_data_processed->{is_pbx_pilot} = 0; #remove pilot aliases to don't intersect with them. On subscriber termination admin adopt numbers, see ticket#4967 $test_machine->request_patch( [ { op => 'replace', path => '/alias_numbers', value => [] } ], $pilot->{location} ); }else{ undef $pilot; } $test_machine->DATA_ITEM_STORE($fake_data_processed); $test_machine->form_data_item(); my $remote_config = $test_machine->init_catalyst_config; #modify time changes on every data change, and primary_number_id on every primary number change my $put2get_check_params = { ignore_fields => $fake_data->data->{subscribers}->{update_change_fields} }; { #20369 diag("20369: informative error for the PUT method on subscriber with duplicated number;\n\n"); my $members = $test_machine->check_create_correct( 2, sub{ my $num = $_[1]->{i}; $_[0]->{username} .= time().'_20369_'.$num ; $_[0]->{webusername} .= time().'_'.$num; $_[0]->{pbx_extension} .= '20369'.$num.Test::FakeData::seq; $_[0]->{primary_number}->{ac} .= $num; $_[0]->{is_pbx_group} = 0; $_[0]->{is_pbx_pilot} = ($pilot || $_[1]->{i} > 1)? 0 : 1; $_[0]->{alias_numbers} = [{ ac => '111'.$num, cc=> 11, sn => 11 },{ ac => '112'.$num, cc=> 11, sn => 11 }]; } ); #$members->[1]->{content}->{primary_number} = $members->[0]->{content}->{primary_number}; #$members->[1]->{content}->{primary_number} = $members->[0]->{content}->{alias_numbers}->[0]; $members->[1]->{content}->{alias_numbers}->[0] = $members->[0]->{content}->{alias_numbers}->[0]; my ($res,$content,$request) = $test_machine->request_put(@{$members->[1]}{qw/content location/}); $test_machine->http_code_msg(422, "Check that PUT existing number will return nice error", $res, $content); #Number '11-1111-11' already exists ok($content->{message} =~ /Number ['\-\d]+ already exists/, "check error message in body"); #commit 581f1386b restricted deletion of PBX pilot before deleting all other subscribers $test_machine->request_delete($members->[1]->{location}); $test_machine->request_delete($members->[0]->{location}); $test_machine->clear_data_created();#fake data aren't registered in this test machine, so they will stay. } { # create new subscribers from DATA_ITEM. Item is not created in the fake_data->process. $test_machine->check_create_correct( 1, sub{ $_[0]->{username} .= time().'_'.$_[1]->{i} ; $_[0]->{pbx_extension} .= Test::FakeData::seq; } ); $test_machine->check_bundle(); $test_machine->check_get2put(undef,{},$put2get_check_params); $test_machine->clear_test_data_all();#fake data aren't registered in this test machine, so they will stay. #remove pilot aliases to don't intersect with them. On subscriber termination admin adopt numbers, see ticket#4967 $pilot and $test_machine->request_patch( [ { op => 'replace', path => '/alias_numbers', value => [] } ], $pilot->{location} ); } #------- MT#15441 { diag("15441"); my $intentional_cli = '111'.time(); my $intentional_primary_number = { 'cc' => '111', 'ac' => '222', 'sn' => '1234'.time(), }; #prepare preconditions: cli should differ from primary_nuber #my $subscriber = ($test_machine->get_created_first() || $fake_data->get_existent_item($test_machine->name) || $test_machine->get_item_hal()); my $subscriber = $test_machine->check_create_correct(1, sub{ my $num = $_[1]->{i}; $_[0]->{username} .= time().'_15441' ; $_[0]->{webusername} .= time().'_15441'; $_[0]->{pbx_extension} .= '15441'.Test::FakeData::seq; $_[0]->{primary_number}->{ac} .= $num; $_[0]->{customer_id} = $fake_data->get_id('customer_sipaccount'); } )->[0]; #print Dumper $subscriber; #die(); $subscriber->{uri} = $subscriber->{location}; my ($preferences, $preferences_put) = ({'uri' => '/api/subscriberpreferences/'.$test_machine->get_id_from_created($subscriber)}) x 2; (undef, $preferences->{content}) = $test_machine->check_item_get($preferences->{uri}); $preferences->{content}->{cli} = $intentional_cli; (undef, $preferences_put->{content}) = $test_machine->request_put($preferences->{content},$preferences->{uri}); is($preferences_put->{content}->{cli}, $intentional_cli, "check that cli was updated on subscriberpreferences put: $preferences_put->{content}->{cli} == $intentional_cli"); my ($subscriber_put, $subscriber_get, $preferences_get); #1 $subscriber->{content}->{primary_number} = $intentional_primary_number; $put2get_check_params->{compare_cb} = sub{ #$put_in->{content}, $put_get_out->{content}; my($put_in_content,$put_get_out_content) = @_; delete $put_get_out_content->{primary_number}->{number_id} if exists $put_get_out_content->{primary_number}; }; ($subscriber_put,$subscriber_get,$preferences_get) = $test_machine->put_and_get($subscriber, $preferences_put, $put2get_check_params); is($preferences_get->{content}->{cli}, $intentional_cli, "1. check that cli was preserved on subscriber phones update: $preferences_get->{content}->{cli} == $intentional_cli"); #/1 #2 delete $subscriber->{content}->{primary_number}; ($subscriber_put,$subscriber_get,$preferences_get) = $test_machine->put_and_get($subscriber, $preferences_put, $put2get_check_params); is($preferences_get->{content}->{cli}, $intentional_cli, "2. check that cli was preserved on subscriber phones update: $preferences_get->{content}->{cli} == $intentional_cli"); #/2 #now prepare preferences for zero situation, when synchronization will be restarted again delete $preferences->{content}->{cli}; (undef, $preferences_put->{content}) = $test_machine->request_put($preferences->{content},$preferences->{uri}); is($preferences_put->{content}->{cli}, undef, "check that cli was deleted on subscriberpreferences put with empty cli"); if($remote_config->{config}->{numbermanagement}->{auto_sync_cli}){ #3 $subscriber->{content}->{primary_number} = $intentional_primary_number; ($subscriber_put,$subscriber_get,$preferences_get) = $test_machine->put_and_get($subscriber, $preferences_put, $put2get_check_params); is($preferences_get->{content}->{cli}, number_as_string($intentional_primary_number), "check that cli was created on subscriber phones update: $preferences_get->{content}->{cli} == ".number_as_string($intentional_primary_number) ); #/3 $intentional_primary_number = { 'cc' => '222', 'ac' => '333', 'sn' => '444'.time(), }; #4 $subscriber->{content}->{primary_number} = $intentional_primary_number; ($subscriber_put,$subscriber_get,$preferences_get) = $test_machine->put_and_get($subscriber, $preferences_put, $put2get_check_params ); is($preferences_get->{content}->{cli}, number_as_string($intentional_primary_number), "check that cli was updated on subscriber phones update: $preferences_get->{content}->{cli} == ".number_as_string($intentional_primary_number) ); #/4 #5 delete $subscriber->{content}->{primary_number}; ($subscriber_put,$subscriber_get,$preferences_get) = $test_machine->put_and_get($subscriber, $preferences_put, $put2get_check_params); is($preferences_get->{content}->{cli}, undef, "check that cli was deleted on subscriber phones update"); #/5 } $test_machine->clear_test_data_all();#fake data aren't registered in this test machine, so they will stay. #remove pilot aliases to don't intersect with them. On subscriber termination admin adopt numbers, see ticket#4967 $pilot and $test_machine->request_patch( [ { op => 'replace', path => '/alias_numbers', value => [] } ], $pilot->{location} ); } if($remote_config->{config}->{features}->{cloudpbx}){ { #TT#50802 my $member_to_terminate; my $member_to_get_number; my $pilot_local; my $alias_numbers = [ { ac => '115', cc=> 15, sn => '50802' }, { ac => '116', cc=> 16, sn => '50802' }, { ac => '117', cc=> 17, sn => '50802' }, { ac => '118', cc=> 18, sn => '50802' }, ]; if(!$pilot) { diag("50802: create pilot"); $pilot = $test_machine->check_create_correct( 1, sub{ my $num = $_[1]->{i}.Test::FakeData::seq; $_[0]->{username} .= time().'_50802_'.$num ; $_[0]->{webusername} .= time().'_'.$num; $_[0]->{pbx_extension} .= '50802'.$num; $_[0]->{primary_number}->{ac} .= $num; $_[0]->{is_pbx_group} = 0; $_[0]->{is_pbx_pilot} = 1; $_[0]->{alias_numbers} = $alias_numbers; } )->[0]; $pilot_local = $pilot; } else { $pilot_local = $pilot; $test_machine->request_patch( [ { op => 'replace', path => '/alias_numbers', value => $alias_numbers } ], $pilot_local->{location} ); } diag("50802: create member_to_terminate"); $member_to_terminate = $test_machine->check_create_correct( 1, sub{ my $num = $_[1]->{i}.Test::FakeData::seq; $_[0]->{username} .= time().'_50802_'.$num ; $_[0]->{webusername} .= time().'_'.$num; $_[0]->{pbx_extension} = '50802'.'1'; $_[0]->{primary_number}->{sn} .= '50802'; $_[0]->{is_pbx_group} = 0; $_[0]->{is_pbx_pilot} = 0; $_[0]->{alias_numbers} = [];#@{$alias_numbers}[0,1] } )->[0]; #print Dumper $member_to_terminate; diag("50802: create member_to_get_number"); $member_to_get_number = $test_machine->check_create_correct( 1, sub{ my $num = $_[1]->{i}.Test::FakeData::seq; $_[0]->{username} .= time().'_50802_'.$num ; $_[0]->{webusername} .= time().'_'.$num; $_[0]->{pbx_extension} .= '50802'.$num; $_[0]->{primary_number}->{ac} .= $num; $_[0]->{is_pbx_group} = 0; $_[0]->{is_pbx_pilot} = 0; $_[0]->{alias_numbers} = [];#@{$alias_numbers}[2,3] } )->[0]; my ($aliases) = $test_machine->get_collection_hal('numbers', '/api/numbers/?type=alias&subscriber_id='.$pilot_local->{content}->{id}, 1)->{collection}; ok(((scalar @$aliases) == 4),"50802: aliases of ".$pilot_local->{content}->{id}." are not empty:".(scalar @$aliases )); diag("50802: assign all aliases to member_to_terminate"); foreach my $alias (@$aliases) { !$alias->{location} && next; diag("50802: check 'before' ownership, subscriber_id should be a pilot id:".$pilot_local->{content}->{id}); is($pilot_local->{content}->{id},$alias->{content}->{subscriber_id},"50802: check ownership: prev owner id: ".$pilot_local->{content}->{id}."; alias subscriber_id:".$alias->{content}->{subscriber_id}); $test_machine->check_patch2get([ { op => 'replace', path => '/subscriber_id', value => $member_to_terminate->{content}->{id} } ] , $alias->{location}); } $aliases = $test_machine->get_collection_hal('numbers', '/api/numbers/?type=alias&subscriber_id='.$member_to_terminate->{content}->{id}, 1)->{collection}; ok(((scalar @$aliases) == 4),"50802: aliases of ".$member_to_terminate->{content}->{id}." are not empty:".(scalar @$aliases)); diag("50802: assign all aliases to member_to_get_number"); foreach my $alias (@$aliases) { !$alias->{location} && next; diag("50802: check 'before' ownership, subscriber_id should be a member_to_terminate id:".$member_to_terminate->{content}->{id}); is($member_to_terminate->{content}->{id},$alias->{content}->{subscriber_id},"50802: check ownership: prev owner id: ".$member_to_terminate->{content}->{id}."; alias subscriber_id:".$alias->{content}->{subscriber_id}); $test_machine->check_patch2get([ { op => 'replace', path => '/subscriber_id', value => $member_to_get_number->{content}->{id} } ] , $alias->{location}); } $aliases = $test_machine->get_collection_hal('numbers', '/api/numbers/?type=alias&subscriber_id='.$member_to_get_number->{content}->{id}, 1)->{collection}; ok(((scalar @$aliases) == 4),"50802: aliases of ".$member_to_get_number->{content}->{id}." are not empty:".(scalar @$aliases )); diag("50802: assign all aliases to member_to_terminate again"); foreach my $alias (@$aliases) { diag("50802: check 'before' ownership, subscriber_id should be a member_to_get_number id:".$member_to_get_number->{content}->{id}); is($member_to_get_number->{content}->{id},$alias->{content}->{subscriber_id},"50802: check ownership: prev owner id: ".$member_to_get_number->{content}->{id}."; alias subscriber_id:".$alias->{content}->{subscriber_id}); $test_machine->check_patch2get([ { op => 'replace', path => '/subscriber_id', value => $member_to_terminate->{content}->{id} } ] , $alias->{location}); } my $terminated_primary_number = $member_to_terminate->{content}->{primary_number}; diag("50802: primary_number of member_to_terminate"); diag(Dumper($terminated_primary_number)); diag("50802: terminate member_to_terminate"); $test_machine->request_delete($member_to_terminate->{location}); $aliases = $test_machine->get_collection_hal('numbers', '/api/numbers/?type=alias&subscriber_id='.$pilot_local->{content}->{id}, 1)->{collection}; #print Dumper $aliases; ok(((scalar @$aliases) == 4),"50802: aliases of ".$pilot_local->{content}->{id}." are not empty:".(scalar @$aliases ).". We returned aliases to pilot."); $pilot_local = $test_machine->get_item_hal('subscribers', '/api/subscribers/'.$pilot_local->{content}->{id}, 1); $terminated_primary_number->{is_devid} = json_true; $test_machine->check_patch2get([ { op => 'replace', path => '/alias_numbers', value => [@{$pilot_local->{content}->{alias_numbers}}, $terminated_primary_number] } ] , $pilot_local->{location},$put2get_check_params); $aliases = $test_machine->get_collection_hal('numbers', '/api/numbers/?type=alias&subscriber_id='.$pilot_local->{content}->{id}, 1)->{collection}; #print Dumper $aliases; ok(((scalar @$aliases) == 5),"50802: aliases of ".$pilot_local->{content}->{id}." are not empty:".(scalar @$aliases ).". We added ex-primary number as an alias."); diag("50802: steal numbers of terminated subscriber"); foreach my $alias (@$aliases) { diag("50802: check ownership, subscriber_id should be a pilot id:".$pilot_local->{content}->{id}); is($pilot_local->{content}->{id},$alias->{content}->{subscriber_id},"50802: check ownership: prev owner id: ".$pilot_local->{content}->{id}."; alias subscriber_id:".$alias->{content}->{subscriber_id}); $test_machine->check_patch2get([ { op => 'replace', path => '/subscriber_id', value => $member_to_get_number->{content}->{id} } ] , $alias->{location}); } $aliases = $test_machine->get_collection_hal('numbers', '/api/numbers/?type=alias&subscriber_id='.$member_to_get_number->{content}->{id}, 1)->{collection}; #print Dumper $aliases; ok(((scalar @$aliases) == 5),"50802: aliases of ".$member_to_get_number->{content}->{id}." are not empty:".(scalar @$aliases ).". We added ex-primary number as an alias."); $test_machine->request_patch( [ { op => 'replace', path => '/alias_numbers', value => [] } ], $pilot->{location} ); $test_machine->request_delete($member_to_get_number->{location}); #die; } {#18601 diag("18601: config->features->cloudpbx: ".$remote_config->{config}->{features}->{cloudpbx}.";\n"); my $groups = $test_machine->check_create_correct( 3, sub{ my $num = $_[1]->{i}; $_[0]->{username} .= time().'_18601_'.$num ; $_[0]->{webusername} .= time().'_'.$num; $_[0]->{pbx_extension} .= '18601'.$num; $_[0]->{primary_number}->{ac} .= $num; $_[0]->{is_pbx_group} = 1; $_[0]->{is_pbx_pilot} = ($pilot || $_[1]->{i} > 1)? 0 : 1; delete $_[0]->{alias_numbers}; } ); my $members = $test_machine->check_create_correct( 3, sub{ my $num = 3 + $_[1]->{i}; $_[0]->{username} .= time().'_18601_'.$num ; $_[0]->{webusername} .= time().'_'.$num; $_[0]->{pbx_extension} .= '18601'.$num.Test::FakeData::seq; $_[0]->{primary_number}->{ac} .= $num; $_[0]->{is_pbx_pilot} = 0; $_[0]->{is_pbx_group} = 0; delete $_[0]->{alias_numbers}; }); $members->[1]->{content}->{pbx_group_ids} = []; diag("1. Check that member will return empty groups after put groups empty"); my($member_put,$member_get) = $test_machine->check_put2get($members->[1],undef, $put2get_check_params); is_deeply( $members->[1]->{content}->{pbx_group_ids}, [], "Check that member will return empty groups after put groups empty"); $members->[1]->{content}->{pbx_group_ids} = [map { $groups->[$_]->{content}->{id} } (2,1)]; diag("2. Check that member will return groups as they were specified"); #fix for the 5415 prevents changing members order in the group, this is why resulting groups order for the member may differ from the input #($member_put,$member_get) = $test_machine->check_put2get($members->[1], undef, $put2get_check_params); my($res,$content) = $test_machine->request_put(@{$members->[1]}{qw/content location/}); $test_machine->http_code_msg(200, "PUT for members[1] was successful", $res, $content); my(undef, $members_1_after_touch) = $test_machine->check_item_get($members->[1]->{location}); #print Dumper [$members->[1]->{content}, $members_1_after_touch]; is_deeply( [sort @{$members->[1]->{content}->{pbx_group_ids}}], [sort @{$members_1_after_touch->{pbx_group_ids}}], "Check member groups after touch - the same cortege"); $groups->[1]->{content}->{pbx_groupmember_ids} = [map { $members->[$_]->{content}->{id} } (2,1,0)]; diag("3. Check that group will return members as they were specified"); my($group_put,$group_get) = $test_machine->check_put2get($groups->[1], undef, $put2get_check_params); $groups->[1]->{content}->{pbx_groupmember_ids} = []; diag("4. Check that group will return empty members after put members empty"); ($group_put,$group_get) = $test_machine->check_put2get($groups->[1], undef, $put2get_check_params); #5415 WF diag("5415: check that groups management doesn't change members order;\n"); diag("5415:Set members order for the group;\n"); $groups->[1]->{content}->{pbx_groupmember_ids} = [ map { $members->[$_]->{content}->{id} } ( 0, 2, 1 ) ]; ($group_put,$group_get)= $test_machine->check_put2get($groups->[1], undef, $put2get_check_params); diag("5415:Touch one of the members;\n"); $members->[2]->{content}->{pbx_group_ids} = [ map { $groups->[$_]->{content}->{id} } (2,1)]; #my($res,$content) = $test_machine->check_put2get($members->[2]); #fix for the 5415 prevents changing members order in the group, this is why resulting groups order for the member may differ from the input ($res,$content) = $test_machine->request_put(@{$members->[2]}{qw/content location/}); $test_machine->http_code_msg(200, "PUT for groups was successful", $res, $content); my(undef, $members_2_after_touch) = $test_machine->check_item_get($members->[2]->{location}); is_deeply( [sort @{$members->[2]->{content}->{pbx_group_ids}}], [sort @{$members_2_after_touch->{pbx_group_ids}}], "Check member groups after touch - the same cortege"); diag("5415:Check members order in the group;\n"); my(undef, $group_get_after) = $test_machine->check_item_get($groups->[1]->{location}); is_deeply($groups->[1]->{content}->{pbx_groupmember_ids}, $group_get_after->{pbx_groupmember_ids}, "Check group members order after touching it's member"); #7453 - we have modifications, so we can check modify_timestamp ok(length($members_2_after_touch->{create_timestamp}) > 8 , "check create_timestamp not empty ".$members_2_after_touch->{create_timestamp}); ok(length($members_2_after_touch->{modify_timestamp}) > 8 , "check modify_timestamp not empty ".$members_2_after_touch->{modify_timestamp}); $test_machine->clear_test_data_all();#fake data aren't registered in this test machine, so they will stay. } {#TT#28510 diag("28510: check subscriberadmin POST. Possible only for pbx subscriberadmin. ;\n"); my $data = clone $test_machine->DATA_ITEM; $data->{administrative} = 1; my $pbxsubscriberadmin = $test_machine->check_create_correct(1, sub { my $num = $_[1]->{i}; $_[0]->{administrative} = 1; $_[0]->{webusername} .= time().'_28510'; $_[0]->{webpassword} = 'api_test_webpassword'; $_[0]->{username} .= time().'_28510' ; $_[0]->{pbx_extension} .= '28510'.Test::FakeData::seq; $_[0]->{primary_number}->{ac} .= '28510'; $_[0]->{is_pbx_group} = 0; $_[0]->{is_pbx_pilot} = ($pilot || $_[1]->{i} > 1)? 0 : 1; } )->[0]; $test_machine->set_subscriber_credentials($pbxsubscriberadmin->{content}); $test_machine->runas('subscriber'); my $subscriber = $test_machine->check_create_correct(1, sub { my $num = $_[1]->{i}; $_[0]->{webusername} .= time().'_28510_1'; $_[0]->{webpassword} = 'api_test_webpassword'; $_[0]->{username} .= time().'_28510_1' ; $_[0]->{pbx_extension} .= '285101'.Test::FakeData::seq; $_[0]->{primary_number}->{ac} .= '28510'; $_[0]->{is_pbx_group} = 1; $_[0]->{is_pbx_pilot} = 0; delete $_[0]->{profile_id}; delete $_[0]->{profile_set_id}; delete $_[0]->{alias_numbers}; } )->[0]; if (check_password_validation_config()) { my $subscriber_pwd = $test_machine->check_create_correct(1, sub { my $num = $_[1]->{i}; $_[0]->{administrative} = 0; $_[0]->{webusername} = 'api_test_'.time().'_21818'; $_[0]->{webpassword} = 'api_test_WEBpassword'; $_[0]->{username} = 'api_test_'.time().'_21818' ; $_[0]->{password} = 'api_test_PWD'.time().'_21818' ; $_[0]->{pbx_extension} = '21818'.Test::FakeData::seq; $_[0]->{primary_number}->{ac} = '21818'; $_[0]->{is_pbx_group} = 0; delete $_[0]->{profile_id}; delete $_[0]->{profile_set_id}; #sometimes we have pbx customer with disabled pbx feature in test data. $_[0]->{is_pbx_pilot} = 0; delete $_[0]->{alias_numbers}; } )->[0]; diag("21818: check password validation: run as \"subscriberadmin\" role;\n"); test_password_validation($subscriber_pwd, {POST => 1}); $test_machine->runas('admin'); diag("21818: check password validation: run as \"admin\" role;\n"); test_password_validation($subscriber_pwd); $test_machine->runas('reseller'); diag("21818: check password validation: run as \"resellers\" role;\n"); test_password_validation($subscriber_pwd); } $test_machine->runas('admin'); } {#TT#34021 my ($res,$content,$req); diag("34021: check subscriberadmin PUT and PATCH. Possible only for pbx subscriberadmin. Access privileges:".Dumper($remote_config->{config}->{acl}).";\n"); $test_machine->runas('admin'); my $resellers = $test_machine->get_collection_hal('resellers','/api/resellers/'); my $wrong_reseller; foreach my $reseller (@{$resellers->{collection}}) { if ($reseller->{content}->{id} ne $fake_data->data->{customers}->{reseller_id}) { $wrong_reseller = $reseller; last; } } my $wrong_profile_sets = $fake_data->create( 'subscriberprofilesets', undef, { data => { 'subscriberprofilesets' => { reseller_id => $wrong_reseller->{content}->{id}}}} ); my $wrong_profiles = $fake_data->create( 'subscriberprofiles', undef, { data => { 'subscriberprofiles' => { profile_set_id => $wrong_profile_sets->[0]->{content}->{id}, name => 'api_test_wrong_reseller_'.time() }}} ); my $data = clone $test_machine->DATA_ITEM; $data->{administrative} = 1; $pilot = $test_machine->get_item_hal('subscribers','/api/subscribers/?customer_id='.$data->{customer_id}.'&'.'is_pbx_pilot=1'); if(!$pilot->{total_count} || $pilot->{total_count} <= 0){ undef $pilot; } my $pbxsubscriberadmin = $test_machine->check_create_correct(1, sub { my $num = $_[1]->{i}; $_[0]->{administrative} = 1; $_[0]->{webusername} .= time().'_34021'; $_[0]->{webpassword} = 'api_test_webpassword'; $_[0]->{username} .= time().'_34021' ; $_[0]->{pbx_extension} .= '34021'.Test::FakeData::seq; $_[0]->{primary_number}->{ac} .= '34021'; $_[0]->{is_pbx_group} = 0; $_[0]->{is_pbx_pilot} = ($pilot || $_[1]->{i} > 1)? 0 : 1; delete $_[0]->{alias_numbers}; } )->[0]; $test_machine->set_subscriber_credentials($pbxsubscriberadmin->{content}); $test_machine->runas('subscriber'); my $subscriber = $test_machine->check_create_correct(1, sub { my $num = $_[1]->{i}; $_[0]->{webusername} .= time().'_34021_1'; $_[0]->{webpassword} = 'api_test_webpassword'; $_[0]->{username} .= time().'_34021_1' ; $_[0]->{pbx_extension} .= '340211'.Test::FakeData::seq; $_[0]->{primary_number}->{ac} .= '34021'; $_[0]->{is_pbx_group} = 0; $_[0]->{is_pbx_pilot} = 0; delete $_[0]->{profile_id}; delete $_[0]->{profile_set_id}; delete $_[0]->{alias_numbers}; } )->[0]; #if ($remote_config->{config}->{privileges}->{subscriberadmin}->{subscribers} =~/write/) { if ($remote_config->{config}->{features}->{cloudpbx}) { $test_machine->check_get2put($subscriber,{},$put2get_check_params); ($res,$content,$req) = $test_machine->request_patch( [ { op => 'replace', path => '/display_name', value => 'patched 34021' } ], $subscriber->{location} ); $test_machine->http_code_msg(200, "Check display_name patch for subscriberadmin", $res, $content); my $pilot_34021 = $test_machine->get_item_hal('subscribers','/api/subscribers/?customer_id='.$subscriber->{content}->{customer_id}.'&'.'is_pbx_pilot=1'); my($res, $mod_34021_pilot) = $test_machine->request_patch([ #to don't intersect with manual testing on the web { op => 'replace', path => '/profile_set_id', value => $fake_data->get_id('subscriberprofilesets') }, { op => 'replace', path => '/profile_id', value => undef },#we will take default profile for profile_set ], $pilot_34021->{location} ); #print Dumper [$wrong_reseller->{content},$wrong_profile_sets->[0]->{content},$wrong_profiles->[0]->{content}]; #print Dumper [$subscriber->{content}]; #subscriberadmin is not supposed to changed profile and profile_set. Subscriberadmin even don't contain these fields. ($res,$content,$req) = $test_machine->request_patch( [ { op => 'replace', path => '/profile_set_id', value => $wrong_profile_sets->[0]->{content}->{id} } ], $subscriber->{location} ); $test_machine->http_code_msg(422, "Check profile_set_id patch for subscriberadmin", $res, $content); ($res,$content,$req) = $test_machine->request_patch( [ { op => 'replace', path => '/profile_id', value => $wrong_profiles->[0]->{content}->{id} } ], $subscriber->{location} ); $test_machine->http_code_msg(422, "Check profile_id patch for subscriberadmin", $res, $content); #($res,$content,$req) = $test_machine->request_patch( [ { op => 'replace', path => '/alias_numbers', value => [{'cc' => '111','ac' => '222','sn' => '444'.time(),}] } ], $subscriber->{location} ); #$test_machine->http_code_msg(200, "Check patch alias_numbers not belonging to the pilot for subscriberadmin", $res, $content); $test_machine->runas('admin'); ($res,$content,$req) = $test_machine->request_patch( [ { op => 'replace', path => '/profile_set_id', value => $wrong_profile_sets->[0]->{content}->{id} } ], $subscriber->{location} ); $test_machine->http_code_msg(422, "Check incorrect profile_set_id patch for administrator", $res, $content); ($res,$content,$req) = $test_machine->request_patch( [ { op => 'replace', path => '/profile_id', value => undef }, { op => 'replace', path => '/profile_set_id', value => undef } ], $subscriber->{location} ); $test_machine->http_code_msg(200, "Check unset profile_id and profile_set_id patch for administrator", $res, $content); ($res,$content,$req) = $test_machine->request_patch( [ { op => 'replace', path => '/profile_id', value => $wrong_profiles->[0]->{content}->{id} } ], $subscriber->{location} ); $test_machine->http_code_msg(422, "Check incorrect profile_id patch for administrator", $res, $content); ($res,$content,$req) = $test_machine->request_patch( [ { op => 'replace', path => '/profile_set_id', value => $wrong_profile_sets->[0]->{content}->{id} } ], $subscriber->{location} ); $test_machine->http_code_msg(422, "Check profile_set_id patch for administrator", $res, $content); ($res,$content,$req) = $test_machine->request_patch( [ { op => 'replace', path => '/profile_id', value => $wrong_profiles->[0]->{content}->{id} } ], $subscriber->{location} ); $test_machine->http_code_msg(422, "Check profile_id patch for administrator", $res, $content); $test_machine->check_patch2get( [ { op => 'replace', path => '/profile_id', value => $mod_34021_pilot->{content}->{profile_id} } ], $subscriber->{location}, $put2get_check_params ); $test_machine->check_patch2get( [ { op => 'replace', path => '/profile_set_id', value => $mod_34021_pilot->{content}->{profile_set_id} } ], $subscriber->{location}, $put2get_check_params ); } else { my($res,$content,$req) = $test_machine->request_patch( [ { op => 'replace', path => '/display_name', value => 'patched 34021' } ], $subscriber->{location} ); $test_machine->http_code_msg(403, "Check display_name patch for subscriberadmin", $res, $content, "Read-only resource for authenticated role"); } } {#TT#43350 diag("TT#43350 Test subscriberadmin access"); diag("#------------------------ create subscribers of other customer of other reseller\n"); my $test_machine_other_reseller = Test::Collection->new( name => 'subscribers', QUIET_DELETION => 1, ); my $fake_data_other_reseller = Test::FakeData->new( keep_db_data => 1, test_machine => $test_machine_other_reseller, ); $fake_data_other_reseller->load_collection_data('subscribers'); $fake_data_other_reseller->apply_data({ 'customers' => { 'external_id' => 'other_reseller', 'type' => 'pbxaccount', }, 'customercontacts' => { 'email' => 'other_reseller@email.com', }, 'contracts' => { 'external_id' => 'other_reseller', }, 'resellers' => { 'name' => 'other_reseller', }, 'subscribers' => { 'is_pbx_pilot' => 0, 'is_pbx_group' => 0, 'webpassword' => 'api_test_webpassword', }, 'subscriberprofilesets' => { 'name' => 'other_reseller_subscriberprofileset', }, 'subscriberprofiles' => { 'name' => 'other_reseller_subscriberprofile', }, }); my($subscribers_other_reseller, $subscriberadmins_other_reseller) = create_subs_and_subadmin($fake_data_other_reseller, $test_machine_other_reseller); diag("#------------------------ create subscriber of other customer\n"); my $test_machine_other_customer = Test::Collection->new( name => 'subscribers', QUIET_DELETION => 1, ); my $fake_data_other_customer = Test::FakeData->new( keep_db_data => 1, test_machine => $test_machine_other_customer, ); $fake_data_other_customer->load_collection_data('subscribers'); $fake_data_other_customer->apply_data({ 'customers' => { 'external_id' => 'other_customer', 'type' => 'pbxaccount', }, 'customercontacts' => { 'email' => 'other_customer@email.com', }, 'contracts' => { 'external_id' => 'other_customer', }, 'subscribers' => { 'is_pbx_pilot' => 0, 'is_pbx_group' => 0, 'webpassword' => 'api_test_webpassword', }, 'subscriberprofilesets' => { 'name' => 'other_customer_subscriberprofileset', }, 'subscriberprofiles' => { 'name' => 'other_customer_subscriberprofile', }, }); my($subscribers_other_customer, $subscriberadmins_other_customer) = create_subs_and_subadmin($fake_data_other_customer, $test_machine_other_customer); diag("#------------------------ create usual subscriber of default test customer and reseller\n"); my $fake_data_processed_old = $test_machine->DATA_ITEM_STORE; $fake_data->apply_data({ 'subscribers' => { 'is_pbx_pilot' => 0, 'is_pbx_group' => 0, 'webpassword' => 'api_test_webpassword', }, }); $fake_data_processed = $fake_data->process('subscribers'); $test_machine->DATA_ITEM($fake_data_processed); #print Dumper $test_machine->DATA_ITEM; my($subscribers, $subscriberadmins) = create_subs_and_subadmin($fake_data, $test_machine); $test_machine->set_subscriber_credentials($subscriberadmins->[0]->{content}); $test_machine->runas('subscriber'); diag("\n\n\nSUBSCRIBERADMIN ".$subscriberadmins->[0]->{content}->{id}.":"); diag("#------------------------ subscriberadmin: attempt to create subscriber using other customer-reseller:\n"); my($res,$content,$sub_create_attempt); $sub_create_attempt = $test_machine->check_create_correct(1,sub { my $num = $_[1]->{i}; my $uniq = Test::FakeData::seq; $_[0]->{webusername} = '43350_'.$uniq; $_[0]->{username} = '43350_'.$uniq; $_[0]->{pbx_extension} = '43350'.$uniq; $_[0]->{primary_number}->{ac} = '43350'.$uniq; $_[0]->{is_pbx_pilot} = 0; $_[0]->{administrative} = 1; delete $_[0]->{profile_id}; delete $_[0]->{profile_set_id}; delete $_[0]->{alias_numbers}; #$_[0]->{profile_id} = $subscribers->[0]->{content}->{profile_id}; #print Dumper $_[0]; }, $subscribers_other_reseller->[0]->{content})->[0]; #print Dumper [ # $sub_create_attempt->{content}, # $subscribers_other_reseller->[0]->{content}->{customer_id}, # $subscriberadmins->[0]->{content}->{customer_id}]; #print Dumper [$sub_create_attempt->{content}, $sub_create_attempt->{content_post}]; ok(($sub_create_attempt->{content}->{customer_id} != $subscribers_other_reseller->[0]->{content}->{customer_id}) && ($sub_create_attempt->{content}->{customer_id} == $subscriberadmins->[0]->{content}->{customer_id}) && ($sub_create_attempt->{content_post}->{customer_id} == $subscribers_other_reseller->[0]->{content}->{customer_id}), "check that subscriberadminadmin customer_id ".$subscriberadmins->[0]->{content}->{customer_id} ." was applied instead of ".$sub_create_attempt->{content_post}->{customer_id}); ok( ($sub_create_attempt->{content}->{administrative} == 0) && ($sub_create_attempt->{content_post}->{administrative} == 1), "check that subscriberadminadmin can't create subscriberadmin: " .$sub_create_attempt->{content_post}->{administrative} ."=>".$sub_create_attempt->{content}->{administrative}.";"); #here we have unexpected error: #Sep 9 22:37:02 sp1 ngcp-panel: DEBUG: username:43350_8_; resource.domain_id:101;item.domain_id:535; #Sep 9 22:37:02 sp1 ngcp-panel: ERROR: error 422 - Subscriber with this username does not exist in the domain. diag("#-------------------------- 1. Check customer_id management ----------"); my ($content_get,$content_put, $content_patch); $test_machine->request_patch( [ { op => 'replace', path => '/customer_id', value => $subscribers_other_customer->[0]->{content}->{customer_id} } ], $subscribers->[0]->{location}); (undef,$content_get) = $test_machine->check_item_get($subscribers->[0]->{location}); ok($content_get->{customer_id} == $fake_data->get_id('customers') && $content_get->{customer_id} != $subscribers_other_customer->[0]->{content}->{customer_id}, "check that subscribersadmin can't apply foreign customer_id to own subscribers: " .$subscribers_other_customer->[0]->{content}->{customer_id}."=>".$content_get->{customer_id}); $content_get->{customer_id} = $subscribers_other_customer->[0]->{content}->{customer_id}; $test_machine->request_put( $content_get, $subscribers->[0]->{location}); (undef,$content_get) = $test_machine->check_item_get($subscribers->[0]->{location}); ok($content_get->{customer_id} == $fake_data->get_id('customers') && $content_get->{customer_id} != $subscribers_other_customer->[0]->{content}->{customer_id}, "check that subscribersadmin can't apply foreign customer_id to own subscribers: " .$subscribers_other_customer->[0]->{content}->{customer_id}."=>".$content_get->{customer_id}); diag("#-------------------------- 2. Check NUMBER management ----------"); diag("#-------------------------- 2. 1. NUMBER: use other customer's primary number for create ----------"); ($res,$sub_create_attempt) = $test_machine->check_item_post(sub { my $num = $_[1]->{i}; my $uniq = Test::FakeData::seq; $_[0]->{webusername} = '43350_'.$uniq; $_[0]->{username} = '43350_'.$uniq; $_[0]->{pbx_extension} = '43350'.$uniq; $_[0]->{primary_number}->{ac} = '43350'.$uniq; my $foreign_number = clone $subscribers_other_customer->[0]->{content}->{primary_number}; delete $foreign_number->{number_id}; delete $_[0]->{profile_id}; $_[0]->{alias_numbers} = [$foreign_number]; #print Dumper $_[0]->{alias_numbers}; }, $subscribers_other_reseller->[0]->{content}); $test_machine->http_code_msg(422, "Check subscriberadmin create subscriber using foreign primary_number", $res, $sub_create_attempt); #print Dumper $res; diag("#-------------------------- 2. 2. NUMBER: use other customer's primary number for edit (PUT) ----------"); $content_put = clone $content_get; $content_put->{alias_numbers} = [clone $subscribers_other_customer->[0]->{content}->{primary_number}]; delete $content_put->{_links}; delete $content_put->{alias_numbers}->[0]->{number_id}; #print Dumper $content_put; ($res,$content_put) = $test_machine->request_put( $content_put, $subscribers->[0]->{location}); $test_machine->http_code_msg(422, "check that subscribersadmin can't manage others customers numbers", $res, $content_put); (undef,$content_get) = $test_machine->check_item_get($subscribers->[0]->{location}); delete $content_get->{alias_numbers}->[0]->{number_id}; delete $subscribers_other_customer->[0]->{content}->{primary_number}->{number_id}; # 0 if different, 1 if equal #k(!Data::Compare::Compare($content_get->{alias_numbers}->[0], $subscribers_other_customer->[0]->{content}->{primary_number}), # "check that subscribersadmin can't manage others customers numbers. Other subscriber primary_number:\n" # .Dumper($subscribers_other_customer->[0]->{content}->{primary_number})."\n=>\n".Dumper($content_get->{alias_numbers}->[0]) # ); diag("#--------------------------3. Check PROFILE management "); diag("#--------------------------3. 1. PROFILE: Check attempt to apply other cutsomer's profile_id ------------ "); $content_put = clone $subscribers->[0]->{content}; delete $content_put->{_links}; $content_put->{profile_id} = $subscribers_other_customer->[0]->{content}->{profile_id}; ($res, $content_put) = $test_machine->request_put( $content_put, $subscribers->[0]->{location}); $test_machine->http_code_msg(422, "check that subscribersadmin can't manage others customers profile_id", $res, $content_put); ($res,$content_get) = $test_machine->check_item_get($subscribers->[0]->{location}); $content_get->{profile_id} //= ''; ok($content_get->{profile_id} != $subscribers_other_customer->[0]->{content}->{profile_id}, "check that subscribersadmin can't apply others customers profile_id. " .$subscribers_other_customer->[0]->{content}->{profile_id}." => ".$content_get->{profile_id}); diag("#--------------------------3. 2. PROFILE: Check attempt to apply other profile_set profile_id ------------ "); my $test_machine_other_profile_set = Test::Collection->new( name => 'subscriberprofiles', QUIET_DELETION => 1, ); my $fake_data_other_profile_set = Test::FakeData->new( keep_db_data => 1, test_machine => $test_machine_other_profile_set, ); $fake_data_other_profile_set->load_collection_data('subscriberprofiles'); $fake_data_other_profile_set->apply_data({ 'subscriberprofilesets' => { 'name' => 'other_subscriberprofileset'.Test::FakeData::seq, }, 'subscriberprofiles' => { 'name' => 'other_subscriberprofile'.Test::FakeData::seq, }, }); my $fake_data_other_profile_set_processed = $fake_data_other_profile_set->process('subscriberprofiles'); #print Dumper ['create_subs_and_subadmin','fake_data_l_processed',$fake_data_l_processed]; $test_machine_other_profile_set->DATA_ITEM($fake_data_other_profile_set_processed); $test_machine_other_profile_set->DATA_ITEM_STORE($fake_data_other_profile_set_processed); #just note - test_machine_other_profile_set is logged in as administrator, so we can create profileset and profile my $subscriberprofile_other_profile_set = $test_machine_other_profile_set->check_create_correct(1)->[0]; $content_put = clone $subscribers->[0]->{content}; delete $content_put->{_links}; $content_put->{profile_id} = $subscriberprofile_other_profile_set->{content}->{id}; $content_put->{display_name} = 'test_other_profileset_profile'; ($res, $content_put) = $test_machine->request_put( $content_put, $subscribers->[0]->{location}); $test_machine->http_code_msg(422, "check that subscribersadmin can't assign other profileset profile_id", $res, $content_put); ($res,$content_get) = $test_machine->check_item_get($subscribers->[0]->{location}); $content_get->{profile_id} //= ''; ok($content_get->{profile_id} != $subscriberprofile_other_profile_set->{content}->{id}, "check that subscribersadmin can't apply other profileset profile_id. " .$subscriberprofile_other_profile_set->{content}->{id}." => ".$content_get->{profile_id}); diag("#--------------------------3. 3. PROFILE: Check attempt to apply correct profile_id ------------ "); my $test_machine_other_profile = Test::Collection->new( name => 'subscriberprofiles', QUIET_DELETION => 1, ); my $fake_data_other_profile = Test::FakeData->new( keep_db_data => 1, test_machine => $test_machine_other_profile, ); $fake_data_other_profile->load_collection_data('subscriberprofiles'); $fake_data_other_profile->apply_data({ 'subscriberprofiles' => { 'name' => 'other_subscriberprofile'.Test::FakeData::seq, }, }); my $fake_data_other_profile_processed = $fake_data_other_profile->process('subscriberprofiles'); #print Dumper ['create_subs_and_subadmin','fake_data_l_processed',$fake_data_l_processed]; $test_machine_other_profile->DATA_ITEM($fake_data_other_profile_processed); $test_machine_other_profile->DATA_ITEM_STORE($fake_data_other_profile_processed); #just note - test_machine_other_profile is logged in as administrator, so we can create profileset and profile my $subscriberprofile_other = $test_machine_other_profile->check_create_correct(1)->[0]; $content_put = clone $subscribers->[0]->{content}; delete $content_put->{_links}; $content_put->{profile_id} = $subscriberprofile_other->{content}->{id}; $content_put->{display_name} = 'test_other_profileset_profile'; ($res, $content_put) = $test_machine->request_put( $content_put, $subscribers->[0]->{location}); $test_machine->http_code_msg(200, "check that subscribersadmin can assign other profile from correct profile_set", $res, $content_put); ($res,$content_get) = $test_machine->check_item_get($subscribers->[0]->{location}); $content_get->{profile_id} //= ''; ok($content_get->{profile_id} eq $subscriberprofile_other->{content}->{id}, "check that subscribersadmin can't apply other profileset profile_id. " .$subscriberprofile_other->{content}->{id}." => ".$content_get->{profile_id}); diag("#--------------------------4. MISC: Check that subscriberadmin can manage something ------------ "); ($res,$content_patch) = $test_machine->request_patch( [ { op => 'replace', path => '/display_name', value => 'patched_43350' } ], $subscribers->[0]->{location}); $test_machine->http_code_msg(200, "check that subscribersadmin can manage available fields", $res, $content_patch); ($res,$content_get) = $test_machine->check_item_get($subscribers->[0]->{location}); ok($content_get->{display_name} eq 'patched_43350', "check that subscribersadmin can manage display_name"); diag("#-------------------------- 5. ACCESS other's customer subscribers ----------"); foreach my $restricted_subscriber ($subscribers_other_reseller, $subscribers_other_customer) { my $location = $restricted_subscriber->[0]->{location}; ($res,$content) = $test_machine->request_get($location); $test_machine->http_code_msg(404, "subscriberadmin: view subscriber of other customer:",$res,$content, "Entity 'subscriber' not found"); ($res,$content) = $test_machine->request_put($sub_create_attempt->{content}, $location); $test_machine->http_code_msg(404, "subscriberadmin: put subscriber of other customer:",$res,$content, "Entity 'subscriber' not found"); ($res,$content) = $test_machine->request_patch( [ { op => 'replace', path => '/display_name', value => 'patched 433050' } ], $location); $test_machine->http_code_msg(404, "subscriberadmin: patch subscriber of other customer:",$res,$content, "Entity 'subscriber' not found"); } #$test_machine_other->set_subscriber_credentials($subscriber_other->{content}); #$test_machine_other->runas('subscriber'); #diag("\n\n\nSUBSCRIBER ".$subscriber_other->{content}->{id}.":"); $test_machine->DATA_ITEM($fake_data_processed_old); $test_machine->clear_test_data_all(); #if we failed with create checking (we s) #$test_machine->check_item_delete(); } } #TT#21818 variant 2 - pbx feature off, subscriberadmin is read-only. No subscriber exists if (!$remote_config->{config}->{features}->{cloudpbx}) { diag("21818: check password validation: subscriber and subscriberadmin are read-only roles;\n"); $test_machine->runas('admin'); my $subscriber = $test_machine->check_create_correct(1, sub { my $num = $_[1]->{i}; $_[0]->{administrative} = 0; $_[0]->{webusername} = 'api_test_'.time().'_21818'; $_[0]->{webpassword} = 'api_test_WEBpassword'; $_[0]->{username} = 'api_test_'.time().'_21818' ; $_[0]->{password} = 'api_test_PWD_21818' ; $_[0]->{pbx_extension} = '21818'.Test::FakeData::seq; $_[0]->{primary_number}->{ac} = '21818'; $_[0]->{is_pbx_group} = 0; #sometimes we have pbx customer with disabled pbx feature in test data. $_[0]->{is_pbx_pilot} = ($pilot || $_[1]->{i} > 1)? 0 : 1; delete $_[0]->{alias_numbers}; } )->[0]; if (check_password_validation_config()) { diag("21818: check password validation: run as \"admin\" role;\n"); test_password_validation($subscriber); $test_machine->runas('reseller'); diag("21818: check password validation: run as \"resellers\" role;\n"); test_password_validation($subscriber); $test_machine->runas('admin'); } } $test_machine->runas('admin'); #TT#8680 { diag("8680: check E164 fields format;\n"); my $data = clone $test_machine->DATA_ITEM; #TT#9066 $data->{primary_number} = ["12123132"]; my($res,$content) = $test_machine->request_post( $data); $test_machine->http_code_msg(422, "Pimary number should be a hash", $res, $content); #MT#22853 $data = clone $test_machine->DATA_ITEM; $data->{alias_numbers} = ["49221222899813", "49221222899814", "49221222899814"]; ($res,$content) = $test_machine->request_post( $data); $test_machine->http_code_msg(422, "Alias numbers should be the hashes", $res, $content); } $test_machine->init_ssl_cert(); $fake_data->clear_test_data_all(); $test_machine->clear_test_data_all();#fake data aren't registered in this test machine, so they will stay. $fake_data->clear_test_data_all(); undef $test_machine; undef $fake_data; done_testing; #--------- aux sub check_password_validation_config{ if( $remote_config->{config}->{security}->{password_sip_validate} && $remote_config->{config}->{security}->{password_web_validate} && ok($remote_config->{config}->{security}->{password_sip_validate},"check www_admin.security.password_sip_validate should be true.") && ok($remote_config->{config}->{security}->{password_web_validate},"check www_admin.security.password_web_validate should be true.")) { return 1; } return 0; } sub test_password_validation { my ($subscriber_put, $actions) = @_; my %fields = ('web' => 'web%s','' => '%s'); my $data_pre = clone $subscriber_put->{content}; my $uri = $subscriber_put->{location}; $data_pre->{password} = 'not empty 1';#to don't raise error for empty pass when checking webpass #print Dumper $data_pre; foreach my $type ('','web'){ my $fieldformat = $fields{$type}; my $usernamefield = sprintf($fieldformat,'username'); my $passwordfield = sprintf($fieldformat,'password'); my $message_start = ($type ? ucfirst($type)." password" : "Password"); #test POST if(!$actions || $actions->{POST}){ my $data = clone $data_pre; $data->{$usernamefield} .= '_post_lc'; $data->{$passwordfield} = ' '.ucfirst($data->{$usernamefield}).' '; my($res,$content) = $test_machine->request_post($data); $test_machine->http_code_msg(422, $message_start." must not contain username", $res, $content, 1); $data = clone $data_pre; $data->{$usernamefield} .= '_post1'; $data->{$passwordfield} = '123456'; ($res,$content) = $test_machine->request_post($data); $test_machine->http_code_msg(422, $message_start." is too weak", $res, $content, 1); $data = clone $data_pre; $data->{$usernamefield} .= '_post2'; $data->{$passwordfield} = 'qwerty'; ($res,$content) = $test_machine->request_post($data); $test_machine->http_code_msg(422, $message_start." is too weak", $res, $content, 1); $data = clone $data_pre; $data->{$usernamefield} .= '_post3'; $data->{$passwordfield} = 'passwd'; ($res,$content) = $test_machine->request_post($data); $test_machine->http_code_msg(422, $message_start." is too weak", $res, $content, 1); } if(!$actions || $actions->{PUT}){ #test PUT my $data = clone $data_pre; $data = $subscriber_put->{content}; $data->{$usernamefield} .= '_put_lc'; $data->{$passwordfield} = ' '.ucfirst($data->{$usernamefield}).' '; my($res,$content) = $test_machine->request_put($data,$uri); $test_machine->http_code_msg(422, $message_start." must not contain username", $res, $content, 1); $data = clone $data_pre; $data->{$usernamefield} .= '_put1'; $data->{$passwordfield} = '123abc'; ($res,$content) = $test_machine->request_put($data,$uri); $test_machine->http_code_msg(422, $message_start." is too weak", $res, $content, 1); $data = clone $data_pre; $data->{$usernamefield} .= '_put2'; $data->{$passwordfield} = 'something'; ($res,$content) = $test_machine->request_put($data,$uri); $test_machine->http_code_msg(422, $message_start." is too weak", $res, $content, 1); $data = clone $data_pre; $data->{$usernamefield} .= '_put3'; $data->{$passwordfield} = 'password'; ($res,$content) = $test_machine->request_put($data,$uri); $test_machine->http_code_msg(422, $message_start." is too weak", $res, $content, 1); } if(!$actions || $actions->{PATCH}){ #test PATCH my $data = clone $data_pre; my $username = $data->{$usernamefield}.= '_patch_lc'; my $password = ' '.ucfirst($username).' '; my($res,$content) = $test_machine->request_patch( [ { op => 'replace', path => '/'.$usernamefield, value => $username}, { op => 'replace', path => '/'.$passwordfield, value => $password}, ], $uri); $test_machine->http_code_msg(422, $message_start." must not contain username", $res, $content, 1); $data = clone $data_pre; $username = $data->{$usernamefield}.= '_patch1'; $password = '12345678'; ($res,$content) = $test_machine->request_patch( [ { op => 'replace', path => '/'.$usernamefield, value => $username}, { op => 'replace', path => '/'.$passwordfield, value => $password}, ], $uri); $test_machine->http_code_msg(422, $message_start." is too weak", $res, $content, 1); $data = clone $data_pre; $username = $data->{$usernamefield}.= '_patch2'; $password = '111aaa'; ($res,$content) = $test_machine->request_patch( [ { op => 'replace', path => '/'.$usernamefield, value => $username}, { op => 'replace', path => '/'.$passwordfield, value => $password}, ], $uri); $test_machine->http_code_msg(422, $message_start." is too weak", $res, $content, 1); $data = clone $data_pre; $username = $data->{$usernamefield}.= '_patch3'; $password = 'mypassword'; ($res,$content) = $test_machine->request_patch( [ { op => 'replace', path => '/'.$usernamefield, value => $username}, { op => 'replace', path => '/'.$passwordfield, value => $password}, ], $uri); $test_machine->http_code_msg(422, $message_start." is too weak", $res, $content, 1); } } } sub create_subs_and_subadmin { my ($fake_data_l, $test_machine_l, $prefix, $no_pilot) = @_; $prefix //= ''; my $fake_data_l_processed = $fake_data_l->process('subscribers'); #print Dumper ['create_subs_and_subadmin','fake_data_l_processed',$fake_data_l_processed]; $test_machine_l->DATA_ITEM($fake_data_l_processed); $test_machine_l->DATA_ITEM_STORE($fake_data_l_processed); my $pilot_l = $test_machine_l->get_item_hal('subscribers','/api/subscribers/?customer_id='.$fake_data_l_processed->{customer_id}.'&'.'is_pbx_pilot=1'); if((exists $pilot_l->{total_count} && $pilot_l->{total_count}) || (exists $pilot_l->{content}->{total_count} && $pilot_l->{content}->{total_count} > 0)){ #remove existing pilot aliases to don't intersect with them. On subscriber termination admin adopt numbers, see ticket#4967 my($res, $mod_pilot) = $test_machine_l->request_patch([ { op => 'replace', path => '/alias_numbers', value => [] }, #to don't intersect with manual testing on the web { op => 'replace', path => '/profile_set_id', value => $fake_data_l->get_id('subscriberprofilesets') }, { op => 'replace', path => '/profile_id', value => undef },#we will take default profile for profile_set #we can't change domain #and we can create subscriber in domain out of reseller #{ op => 'replace', path => '/domain_id', value => $fake_data_l->get_id('domains') }, ], $pilot_l->{location} ); #print Dumper $pilot_l->{content}; #print Dumper $res; }else{ undef $pilot_l; } my $subscribers = $test_machine_l->check_create_correct(3, sub { my $num = $_[1]->{i}; my $uniq = Test::FakeData::seq; $_[0]->{webusername} = '43350_'.$uniq.'_'.$prefix; $_[0]->{username} = '43350_'.$uniq.'_'.$prefix ; $_[0]->{pbx_extension} = '43350'.$uniq; $_[0]->{primary_number}->{ac} = '43350'.$uniq; $_[0]->{is_pbx_pilot} = ($pilot_l || $num > 1 )? 0 : 1; $_[0]->{administrative} = 0; $_[0]->{alias_numbers} = [{ ac => '43350'.$uniq, cc => $uniq, sn => '43350'.$uniq, }]; #$_[0]->{domain} = $pilot_l->{domain}; $pilot_l and $_[0]->{domain_id} = $pilot_l->{content}->{domain_id}; }); #$fake_data_l->get_id('resellers',@_); diag("#------------------------ create subscriberadmin\n"); my $subscriberadmins = $test_machine_l->check_create_correct(1, sub { my $num = $_[1]->{i}; my $uniq = Test::FakeData::seq; $_[0]->{webusername} = '43350_'.$uniq.'_'.$prefix.'_adm'; $_[0]->{username} = '43350_'.$uniq.'_'.$prefix.'_adm'; $_[0]->{pbx_extension} = '43350'.$uniq; $_[0]->{primary_number}->{ac} = '43350'.$uniq; $_[0]->{administrative} = 1; $_[0]->{is_pbx_pilot} = 0; delete $_[0]->{alias_numbers}; }); diag("#------------------------ /create subscriberadmin\n"); return $subscribers, $subscriberadmins; } sub number_as_string{ my ($number_row, %params) = @_; return 'HASH' eq ref $number_row ? $number_row->{cc} . ($number_row->{ac} // '') . $number_row->{sn} : $number_row->cc . ($number_row->ac // '') . $number_row->sn; } # vim: set tabstop=4 expandtab: