From 042c734a2573c5690b4ed60dcd876016ae6cc91a Mon Sep 17 00:00:00 2001 From: Francesc Guasch Date: Mon, 30 Sep 2024 12:22:39 +0200 Subject: [PATCH 01/11] wip: upload users and groups in json file --- lib/Ravada/Front.pm | 51 ++++++++++++++ t/mojo/60_upload.t | 158 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 208 insertions(+), 1 deletion(-) diff --git a/lib/Ravada/Front.pm b/lib/Ravada/Front.pm index 81388f440..e8f8f7980 100644 --- a/lib/Ravada/Front.pm +++ b/lib/Ravada/Front.pm @@ -1912,6 +1912,57 @@ sub upload_users($self, $users, $type, $create=0) { return ($found, $count, \@error); } + +sub upload_users_json($self, $data_json, $type='openid') { + + my ($found, $count, @error); + my $data; + eval { + $data= decode_json($data_json); + }; + push @error,($@) if $@; + warn $@ if $@; + + for my $u0 (@{$data->{users}}) { + $found++; + my $u = $u0; + $u = dclone($u0) if ref($u0); + if (!ref($u)) { + $u = { name => $u0 }; + } + if (!exists $u->{is_external}) { + if ($type ne 'sql') { + $u->{is_external} = 1; + $u->{external_auth} = $type ; + } + } + my $user = Ravada::Auth::SQL->new(name => $u->{name}); + if ($user && $user->id) { + push @error,("User $u->{name} already added"); + next; + } + Ravada::Auth::SQL::add_user(%$u); + $count++; + } + + for my $g0 (@{$data->{groups}}) { + my $g = $g0; + if (!ref($g)) { + $g = { name => $g0 }; + } + $found++; + my $group = Ravada::Auth::Group->new(name => $g->{name}); + if ($group && $group->id) { + push @error,("Group $g->{name} already added"); + next; + } + Ravada::Auth::Group::add_group(%$g); + $count++; + } + + return ($found, $count, \@error); +} + =head2 create_bundle Creates a new bundle diff --git a/t/mojo/60_upload.t b/t/mojo/60_upload.t index 1877a7bdd..f26eba8d5 100644 --- a/t/mojo/60_upload.t +++ b/t/mojo/60_upload.t @@ -6,7 +6,7 @@ use Data::Dumper; use Test::More; use Test::Mojo; use Mojo::File 'path'; -use Mojo::JSON qw(decode_json); +use Mojo::JSON qw(encode_json decode_json); use lib 't/lib'; use Test::Ravada; @@ -262,6 +262,160 @@ sub test_upload_group($mojo=0) { } +sub test_upload_json() { + + test_upload_json_users_groups(); + test_upload_json_users_groups2(); + test_upload_json_users_admin(); + test_upload_json_users_pass(); + test_upload_json_users(); +} + +sub _do_upload_users_json($data, $mojo=0, $type='openid') { + my $data_h = decode_json($data); + my $users = $data_h->{users}; + if ($users) { + for my $user (@$users) { + my $name = $user; + $name = $user->{name} if ref($user); + next if !$name; + remove_old_user($name); + } + } + if (!$mojo) { + rvd_front->upload_users_json($data, $type); + } + +} + +sub test_upload_json_users() { + my @users = ( new_domain_name(), new_domain_name() ); + my $data = { + users => \@users + }; + + _do_upload_users_json( encode_json( { users => \@users }) ); + + for my $name ( @users ) { + my $user = Ravada::Auth::SQL->new(name => $name); + ok($user->id, "Expecting user $name created"); + is($user->external_auth, 'openid'); + + $user = undef; + eval { + $user = Ravada::Auth->login( $name , ''); + }; + like($@,qr/login failed/i); + ok(!$user) or warn $user->name; + } +} + +sub test_upload_json_users_groups() { + my @users = ( + {name => new_domain_name() } + , {name => new_domain_name(), is_admin => 1 } + ); + my @groups = ( + new_domain_name() + ,new_domain_name() + ); + my $data = { + users => \@users + ,groups => \@groups + }; + + _do_upload_users_json( encode_json( $data ) ); + for my $u ( @users ) { + my $user = Ravada::Auth::SQL->new(name => $u->{name}); + ok($user->id, "Expecting user $u->{name} created"); + } + for my $g ( @groups) { + my $group = Ravada::Auth::Group->new(name => $g); + ok($group->id, "Expecting group $g created"); + } + +} + +sub test_upload_json_users_groups2() { + my @users = ( + {name => new_domain_name() } + , {name => new_domain_name(), is_admin => 1 } + ); + my @groups = ( + {name => new_domain_name() } + ,{name => new_domain_name() } + ); + my $data = { + users => \@users + ,groups => \@groups + }; + + _do_upload_users_json( encode_json( $data ) ); + for my $u ( @users ) { + my $user = Ravada::Auth::SQL->new(name => $u->{name}); + ok($user->id, "Expecting user $u->{name} created"); + } + for my $g ( @groups) { + my $group = Ravada::Auth::Group->new(name => $g->{name}); + ok($group->id, "Expecting group $g->{name} created"); + } + +} + + + +sub test_upload_json_users_admin() { + my @users = ( + {name => new_domain_name() } + , {name => new_domain_name(), is_admin => 0 } + , {name => new_domain_name(), is_admin => 1 } + ); + my $data = { + users => \@users + }; + + _do_upload_users_json( encode_json( $data ) ); + + for my $u ( @users ) { + my ($name, $password) = ($u->{name} , $u->{password}); + my $user = Ravada::Auth::SQL->new(name => $name); + ok($user->id, "Expecting user $name created"); + is($user->external_auth, 'openid') or exit; + $u->{is_admin}=0 if !exists $u->{is_admin}; + is($user->is_admin, $u->{is_admin}); + } + + +} + +sub test_upload_json_users_pass() { + my $p1='a'; + my $p2 = 'b'; + my @users = ( + {name => new_domain_name(), password => $p1 } + , {name => new_domain_name(), password => $p2 } + ); + my $data = { + users => \@users + }; + + _do_upload_users_json( encode_json( { users => \@users }), 0, 'sql' ); + + for my $u ( @users ) { + my ($name, $password) = ($u->{name} , $u->{password}); + my $user = Ravada::Auth::SQL->new(name => $name); + ok($user->id, "Expecting user $name created"); + is($user->external_auth, '') or exit; + + $user = undef; + eval { + $user = Ravada::Auth::login( $name , $password); + }; + is($@,''); + ok($user,"Expecting $name/$password") or exit; + } +} + ################################################################################ @@ -278,6 +432,8 @@ test_upload_no_admin($t); _login($t); +test_upload_json(); + test_upload_group(); test_upload_group(1); # mojo test_upload_group(2); # mojo post From 5e0c04eb30608031f1c9932f64c39c8ddfcd5cc6 Mon Sep 17 00:00:00 2001 From: Francesc Guasch Date: Mon, 30 Sep 2024 17:13:01 +0200 Subject: [PATCH 02/11] wip: upload users groups and members --- lib/Ravada/Auth/Group.pm | 4 + lib/Ravada/Front.pm | 59 ++++++---- t/lib/Test/Ravada.pm | 24 ++++ t/mojo/60_upload.t | 241 +++++++++++++++++++++++++++++++++++++-- 4 files changed, 298 insertions(+), 30 deletions(-) diff --git a/lib/Ravada/Auth/Group.pm b/lib/Ravada/Auth/Group.pm index 469c934d0..f2a6ec771 100644 --- a/lib/Ravada/Auth/Group.pm +++ b/lib/Ravada/Auth/Group.pm @@ -121,6 +121,10 @@ sub remove_member($self, $name) { $sth->execute($id_user); } +sub remove_all_members($self) { + $self->_remove_all_members(); +} + sub _remove_all_members($self) { my $sth = $$CON->dbh->prepare("DELETE FROM users_group " ." WHERE id_group=?" diff --git a/lib/Ravada/Front.pm b/lib/Ravada/Front.pm index e8f8f7980..dd8e74374 100644 --- a/lib/Ravada/Front.pm +++ b/lib/Ravada/Front.pm @@ -1923,8 +1923,44 @@ sub upload_users_json($self, $data_json, $type='openid') { push @error,($@) if $@; warn $@ if $@; - for my $u0 (@{$data->{users}}) { + my $result = { + users_found => 0 + ,users_added => 0 + ,groups_found => 0 + ,groups_added => 0 + }; + for my $g0 (@{$data->{groups}}) { + $result->{groups_found}++; + my $g = $g0; + if (!ref($g)) { + $g = { name => $g0 }; + } $found++; + my $group = Ravada::Auth::Group->new(name => $g->{name}); + my $members = delete $g->{members}; + if (!$group || !$group->id) { + $result->{groups_added}++; + Ravada::Auth::Group::add_group(%$g); + } + $self->_add_users($members, $type, $result, \@error); + $group->remove_all_members() if $data->{options}->{flush}; + + for my $m (@$members) { + my $user = Ravada::Auth::SQL->new(name => $m); + $user->add_to_group($g->{name}) unless $user->is_member($g->{name}); + } + $group->remove() if $data->{options}->{remove_empty} && !$group->members; + } + + $self->_add_users($data->{users}, $type, $result, \@error) + if $data->{users}; + + return ($result, \@error); +} + +sub _add_users($self,$users, $type, $result, $error) { + for my $u0 (@$users) { + $result->{users_found}++; my $u = $u0; $u = dclone($u0) if ref($u0); if (!ref($u)) { @@ -1938,29 +1974,12 @@ sub upload_users_json($self, $data_json, $type='openid') { } my $user = Ravada::Auth::SQL->new(name => $u->{name}); if ($user && $user->id) { - push @error,("User $u->{name} already added"); + push @$error,("User $u->{name} already added"); next; } Ravada::Auth::SQL::add_user(%$u); - $count++; + $result->{users_added}++; } - - for my $g0 (@{$data->{groups}}) { - my $g = $g0; - if (!ref($g)) { - $g = { name => $g0 }; - } - $found++; - my $group = Ravada::Auth::Group->new(name => $g->{name}); - if ($group && $group->id) { - push @error,("Group $g->{name} already added"); - next; - } - Ravada::Auth::Group::add_group(%$g); - $count++; - } - - return ($found, $count, \@error); } =head2 create_bundle diff --git a/t/lib/Test/Ravada.pm b/t/lib/Test/Ravada.pm index 1ab20576a..b2f87cc0f 100644 --- a/t/lib/Test/Ravada.pm +++ b/t/lib/Test/Ravada.pm @@ -599,8 +599,32 @@ sub init($config=undef, $sqlite = 1 , $flush=0) { $Ravada::VM::KVM::VERIFY_ISO = 0; $Ravada::VM::MIN_DISK_MB = 1; + _clean_old_users(); + _clean_old_groups(); } +sub _clean_old_users() { + my $sth = $CONNECTOR->dbh->prepare("SELECT id,name FROM users WHERE name like ? "); + $sth->execute(base_domain_name().'%'); + while ( my ($id,$name) = $sth->fetchrow ) { + next if $USER_ADMIN && $name eq $USER_ADMIN->name; + my $user = Ravada::Auth::SQL->search_by_id($id); + next if !$user; + $user->remove(); + } +} + +sub _clean_old_groups() { + my $sth = $CONNECTOR->dbh->prepare("SELECT id,name FROM groups_local WHERE name like ? "); + $sth->execute(base_domain_name().'%'); + while ( my ($id,$name) = $sth->fetchrow ) { + my $g = Ravada::Auth::Group->open($id); + next if !$g; + $g->remove(); + } +} + + sub _load_remote_config() { return {} if ! -e $FILE_CONFIG_REMOTE; my $conf; diff --git a/t/mojo/60_upload.t b/t/mojo/60_upload.t index f26eba8d5..c59d3ecff 100644 --- a/t/mojo/60_upload.t +++ b/t/mojo/60_upload.t @@ -264,15 +264,34 @@ sub test_upload_group($mojo=0) { sub test_upload_json() { + test_upload_json_members(); + test_upload_json_members(1); + + test_upload_json_members_flush(); + test_upload_json_members_remove_empty(); + test_upload_json_users_groups(); test_upload_json_users_groups2(); test_upload_json_users_admin(); test_upload_json_users_pass(); test_upload_json_users(); + test_upload_json_users(1); } -sub _do_upload_users_json($data, $mojo=0, $type='openid') { +sub _do_upload_users_json($data, $exp_result=undef, $mojo=0, $type='openid') { + my $data_h = decode_json($data); + if (!defined $exp_result) { + $exp_result= { groups_found => 0, groups_added => 0, users_found=>0, users_added => 0}; + if ($data_h->{groups}) { + $exp_result->{groups_found} = scalar(@{$data_h->{groups}}); + $exp_result->{groups_added} = scalar(@{$data_h->{groups}}); + } + if ($data_h->{users}) { + $exp_result->{users_found} = scalar(@{$data_h->{users}}); + $exp_result->{users_added} = scalar(@{$data_h->{users}}); + }; + } my $users = $data_h->{users}; if ($users) { for my $user (@$users) { @@ -283,18 +302,32 @@ sub _do_upload_users_json($data, $mojo=0, $type='openid') { } } if (!$mojo) { - rvd_front->upload_users_json($data, $type); + my ($result, $error)=rvd_front->upload_users_json($data, $type); + is_deeply($result, $exp_result); + is_deeply($error,[]); + } else { + $t->post_ok('/admin/users/upload.json' => form => { + type => $type + ,create => 0 + ,users => { content => $data, filename => 'data.json' + , 'Content-Type' => 'application/json' }, + })->status_is(200); + die $t->tx->res->body if $t->tx->res->code != 200; + + my $response = $t->tx->res->json(); + warn Dumper($response->{output}); + is_deeply($response->{error},[]); } } -sub test_upload_json_users() { +sub test_upload_json_users($mojo=0) { my @users = ( new_domain_name(), new_domain_name() ); my $data = { users => \@users }; - _do_upload_users_json( encode_json( { users => \@users }) ); + _do_upload_users_json( encode_json( { users => \@users }),undef,$mojo ); for my $name ( @users ) { my $user = Ravada::Auth::SQL->new(name => $name); @@ -324,7 +357,7 @@ sub test_upload_json_users_groups() { ,groups => \@groups }; - _do_upload_users_json( encode_json( $data ) ); + _do_upload_users_json( encode_json( $data ), { groups_found => 2, groups_added => 2, users_found => 2, users_added => 2} ); for my $u ( @users ) { my $user = Ravada::Auth::SQL->new(name => $u->{name}); ok($user->id, "Expecting user $u->{name} created"); @@ -362,6 +395,198 @@ sub test_upload_json_users_groups2() { } +sub test_upload_json_members() { + my @users_g0 = ( + new_domain_name() + ,new_domain_name() + ); + + my @groups = ( + {name => new_domain_name() + ,members => \@users_g0 } + ,{name => new_domain_name() } + ); + my $data = { + groups => \@groups + }; + + _do_upload_users_json( encode_json( $data ),{ groups_found => 2,groups_added => 2, users_found => 2, users_added => 2} ); + for my $u ( @users_g0 ) { + my $user = Ravada::Auth::SQL->new(name => $u ); + ok($user->id, "Expecting user $u created"); + } + for my $g ( @groups) { + my $group = Ravada::Auth::Group->new(name => $g->{name}); + ok($group->id, "Expecting group $g->{name} created"); + } + + my $g0 = Ravada::Auth::Group->new(name => $groups[0]->{name}); + ok($g0->members,"Expecting members in ".$g0->name); + + for my $m (@{$groups[0]->{members}}) { + my ($found) = grep (/^$m$/ , $g0->members); + ok($found,"Expecting $m member"); + } + + my $g1 = Ravada::Auth::Group->new(name => $groups[1]->{name}); + ok(!$g1->members,"Expecting no members in ".$g1->name); + + # add more users + my @users_g0b = ( + new_domain_name() + ,new_domain_name() + ,$users_g0[0] + ); + + $groups[0]->{members} = \@users_g0b; + + _do_upload_users_json( encode_json( {groups => \@groups}),{ groups_found => 2,groups_added => 0, users_found => 3, users_added => 2} ); + + for my $name ( @users_g0 , @users_g0b ) { + + my $user = Ravada::Auth::SQL->new(name => $name ); + ok($user->id, "Expecting user $name created"); + + my $g0 = Ravada::Auth::Group->new(name => $groups[0]->{name}); + my ($found) = grep (/^$name$/ , $g0->members); + ok($found,"Expecting $name member"); + } +} + +sub test_upload_json_members_flush() { + my @users_g0 = ( + new_domain_name() + ,new_domain_name() + ); + + my @groups = ( + {name => new_domain_name() + ,members => \@users_g0 } + ,{name => new_domain_name() } + ); + my $data = { + groups => \@groups + }; + + _do_upload_users_json( encode_json( $data ),{ groups_found => 2,groups_added => 2, users_found => 2, users_added => 2} ); + for my $u ( @users_g0 ) { + my $user = Ravada::Auth::SQL->new(name => $u ); + ok($user->id, "Expecting user $u created"); + } + for my $g ( @groups) { + my $group = Ravada::Auth::Group->new(name => $g->{name}); + ok($group->id, "Expecting group $g->{name} created"); + } + + my $g0 = Ravada::Auth::Group->new(name => $groups[0]->{name}); + ok($g0->members,"Expecting members in ".$g0->name); + + for my $m (@{$groups[0]->{members}}) { + my ($found) = grep (/^$m$/ , $g0->members); + ok($found,"Expecting $m member"); + } + + my $g1 = Ravada::Auth::Group->new(name => $groups[1]->{name}); + ok(!$g1->members,"Expecting no members in ".$g1->name); + + # add more users + my @users_g0b = ( + new_domain_name() + ,new_domain_name() + ,$users_g0[0] + ); + + $groups[0]->{members} = \@users_g0b; + + _do_upload_users_json( encode_json( {groups => \@groups, options => {'flush' => 1}}),{ groups_found => 2,groups_added => 0, users_found => 3, users_added => 2} ); + + for my $name ( $users_g0[1] ) { + + my $user = Ravada::Auth::SQL->new(name => $name ); + ok($user->id, "Expecting user $name created"); + + my $g0 = Ravada::Auth::Group->new(name => $groups[0]->{name}); + my ($found) = grep (/^$name$/ , $g0->members); + ok(!$found,"Expecting no $name member") or exit; + } + + for my $name ( @users_g0b ) { + + my $user = Ravada::Auth::SQL->new(name => $name ); + ok($user->id, "Expecting user $name created"); + + my $g0 = Ravada::Auth::Group->new(name => $groups[0]->{name}); + my ($found) = grep (/^$name$/ , $g0->members); + ok($found,"Expecting $name member"); + } + +} + +sub test_upload_json_members_remove_empty() { + my @users_g0 = ( + new_domain_name() + ,new_domain_name() + ); + + my @groups = ( + {name => new_domain_name() + ,members => \@users_g0 } + ,{name => new_domain_name() } + ); + my $data = { + groups => \@groups + }; + + _do_upload_users_json( encode_json( $data ),{ groups_found => 2,groups_added => 2, users_found => 2, users_added => 2} ); + for my $u ( @users_g0 ) { + my $user = Ravada::Auth::SQL->new(name => $u ); + ok($user->id, "Expecting user $u created"); + } + for my $g ( @groups) { + my $group = Ravada::Auth::Group->new(name => $g->{name}); + ok($group->id, "Expecting group $g->{name} created"); + } + + my $g0 = Ravada::Auth::Group->new(name => $groups[0]->{name}); + ok($g0->members,"Expecting members in ".$g0->name); + + for my $m (@{$groups[0]->{members}}) { + my ($found) = grep (/^$m$/ , $g0->members); + ok($found,"Expecting $m member"); + } + + my $g1 = Ravada::Auth::Group->new(name => $groups[1]->{name}); + ok(!$g1->members,"Expecting no members in ".$g1->name); + + # add more users + my @users_g0b = ( + new_domain_name() + ,new_domain_name() + ,$users_g0[0] + ); + + $groups[1]->{members} = \@users_g0b; + $groups[0]->{members} = []; + + _do_upload_users_json( encode_json( {groups => \@groups, options => {'flush'=>1,'remove_empty'=>1}}),{ groups_found => 2,groups_added => 0, users_found => 3, users_added => 2} ); + + for my $name ( @users_g0b ) { + + my $user = Ravada::Auth::SQL->new(name => $name ); + ok($user->id, "Expecting user $name created"); + + my $g1 = Ravada::Auth::Group->new(name => $groups[1]->{name}); + ok($g1 && $g1->id) or exit; + my ($found) = grep (/^$name$/ , $g0->members); + ok(!$found,"Expecting $name member") or exit; + } + + $g0 = Ravada::Auth::Group->new(name => $groups[0]->{name}); + ok(!$g0->id,"Expecting $groups[0]->{name} removed"); + +} + + sub test_upload_json_users_admin() { @@ -395,11 +620,8 @@ sub test_upload_json_users_pass() { {name => new_domain_name(), password => $p1 } , {name => new_domain_name(), password => $p2 } ); - my $data = { - users => \@users - }; - _do_upload_users_json( encode_json( { users => \@users }), 0, 'sql' ); + _do_upload_users_json( encode_json( { users => \@users }),undef, 0, 'sql' ); for my $u ( @users ) { my ($name, $password) = ($u->{name} , $u->{password}); @@ -416,7 +638,6 @@ sub test_upload_json_users_pass() { } } - ################################################################################ $ENV{MOJO_MODE} = 'development'; From f59a4f9300b3682fe815a24f2b526538739be978 Mon Sep 17 00:00:00 2001 From: Francesc Guasch Date: Tue, 1 Oct 2024 12:08:35 +0200 Subject: [PATCH 03/11] wip: upload json file in mojo --- lib/Ravada/Front.pm | 1 - script/rvd_front | 33 ++++++++++-- t/mojo/60_upload.t | 124 ++++++++++++++++++++++++++++++++++++-------- 3 files changed, 130 insertions(+), 28 deletions(-) diff --git a/lib/Ravada/Front.pm b/lib/Ravada/Front.pm index dd8e74374..b8fc43455 100644 --- a/lib/Ravada/Front.pm +++ b/lib/Ravada/Front.pm @@ -1921,7 +1921,6 @@ sub upload_users_json($self, $data_json, $type='openid') { $data= decode_json($data_json); }; push @error,($@) if $@; - warn $@ if $@; my $result = { users_found => 0 diff --git a/script/rvd_front b/script/rvd_front index c2b19b0e4..432bf7441 100644 --- a/script/rvd_front +++ b/script/rvd_front @@ -1852,14 +1852,37 @@ any '/admin/users/upload.#req' => sub($c) { return $c->render(json => { error => "Unknown type $type" }) if $type !~ /^(sql|ldap|sso|openid)/; - my $csv = $c->req->upload('users'); - if($csv->headers->content_type !~ m{text/(csv|plain)}) { + my $file = $c->req->upload('users'); + + if($file->headers->content_type =~ m{text/(csv|plain)}) { + _upload_users_csv($c, $file, $type, $create); + } elsif ( $file->headers->content_type =~ m{application/json}) { + _upload_users_json($c, $file, $type, $create); + } else { return $c->render(status => 400 - ,text => "Wrong content type ".$csv->headers->content_type - ." , it should be text/csv or plain" + ,text => "Wrong content type ".$file->headers->content_type + ." , it should be text/csv , application/json or plain" ); + + } +}; + +sub _upload_users_json($c, $file, $type, $create) { + + my ($result, $error)=$RAVADA->upload_users_json($file->slurp, $type); + + if ($create) { + push @$error,("Warning: create not implemented with json upload"); } + return $c->render(json => + { + output => $result + ,error => $error + } + ); +} +sub _upload_users_csv($c, $csv, $type, $create) { my ($found, $count, $error) = $RAVADA->upload_users( $csv->slurp, $type, $create ); @@ -1875,7 +1898,7 @@ any '/admin/users/upload.#req' => sub($c) { ,error => $error ,done => 1 ); -}; +} get '/admin/user/remove/#id' => sub($c) { return access_denied($c) unless $USER->is_admin; diff --git a/t/mojo/60_upload.t b/t/mojo/60_upload.t index c59d3ecff..8d8894fac 100644 --- a/t/mojo/60_upload.t +++ b/t/mojo/60_upload.t @@ -262,10 +262,36 @@ sub test_upload_group($mojo=0) { } +sub test_upload_json_fail() { + + _do_upload_users_fail(0); + _do_upload_users_fail(1); +} + +sub _do_upload_users_fail($mojo, $type='openid') { + my ($result, $error); + if (!$mojo) { + ($result, $error)=rvd_front->upload_users_json("wrong", $type); + } else { + $t->post_ok('/admin/users/upload.json' => form => { + type => $type + ,create => 0 + ,users => { content => "wrong", filename => 'data.json' + , 'Content-Type' => 'application/json' }, + })->status_is(200); + die $t->tx->res->body if $t->tx->res->code != 200; + + my $response = $t->tx->res->json(); + $result = $response->{output}; + $error = $response->{error}; + } + like($error->[0],qr/malformed JSON/); + is_deeply($result, { groups_found => 0 , groups_added => 0, users_found => 0, users_added => 0}); +} + sub test_upload_json() { test_upload_json_members(); - test_upload_json_members(1); test_upload_json_members_flush(); test_upload_json_members_remove_empty(); @@ -275,12 +301,19 @@ sub test_upload_json() { test_upload_json_users_admin(); test_upload_json_users_pass(); test_upload_json_users(); - test_upload_json_users(1); } -sub _do_upload_users_json($data, $exp_result=undef, $mojo=0, $type='openid') { +sub _do_upload_users_json($data, $mojo, $exp_result=undef, $type='openid') { - my $data_h = decode_json($data); + confess if ref($mojo); + confess if defined $exp_result && !ref($exp_result); + + my $data_h = $data; + if (ref($data)) { + $data = encode_json($data); + } else { + $data_h = decode_json($data); + } if (!defined $exp_result) { $exp_result= { groups_found => 0, groups_added => 0, users_found=>0, users_added => 0}; if ($data_h->{groups}) { @@ -301,10 +334,9 @@ sub _do_upload_users_json($data, $exp_result=undef, $mojo=0, $type='openid') { remove_old_user($name); } } + my ($result, $error); if (!$mojo) { - my ($result, $error)=rvd_front->upload_users_json($data, $type); - is_deeply($result, $exp_result); - is_deeply($error,[]); + ($result, $error)=rvd_front->upload_users_json($data, $type); } else { $t->post_ok('/admin/users/upload.json' => form => { type => $type @@ -315,19 +347,29 @@ sub _do_upload_users_json($data, $exp_result=undef, $mojo=0, $type='openid') { die $t->tx->res->body if $t->tx->res->code != 200; my $response = $t->tx->res->json(); - warn Dumper($response->{output}); - is_deeply($response->{error},[]); + $result = $response->{output}; + $error = $response->{error}; } + is_deeply($result, $exp_result) or die Dumper([$result, $exp_result]); + + for my $err (@$error) { + ok(0,$err) unless $err =~ /already added/; + } +} + +sub test_upload_json_users() { + _do_test_upload_json_users(0); + _do_test_upload_json_users(1); } -sub test_upload_json_users($mojo=0) { +sub _do_test_upload_json_users($mojo) { my @users = ( new_domain_name(), new_domain_name() ); my $data = { users => \@users }; - _do_upload_users_json( encode_json( { users => \@users }),undef,$mojo ); + _do_upload_users_json( { users => \@users },$mojo ); for my $name ( @users ) { my $user = Ravada::Auth::SQL->new(name => $name); @@ -344,6 +386,12 @@ sub test_upload_json_users($mojo=0) { } sub test_upload_json_users_groups() { + + _do_test_upload_json_users_groups(0); + _do_test_upload_json_users_groups(1); +} + +sub _do_test_upload_json_users_groups($mojo) { my @users = ( {name => new_domain_name() } , {name => new_domain_name(), is_admin => 1 } @@ -357,7 +405,7 @@ sub test_upload_json_users_groups() { ,groups => \@groups }; - _do_upload_users_json( encode_json( $data ), { groups_found => 2, groups_added => 2, users_found => 2, users_added => 2} ); + _do_upload_users_json( encode_json( $data ), $mojo, { groups_found => 2, groups_added => 2, users_found => 2, users_added => 2} ); for my $u ( @users ) { my $user = Ravada::Auth::SQL->new(name => $u->{name}); ok($user->id, "Expecting user $u->{name} created"); @@ -370,6 +418,11 @@ sub test_upload_json_users_groups() { } sub test_upload_json_users_groups2() { + _do_test_upload_json_users_groups2(0); + _do_test_upload_json_users_groups2(1); +} + +sub _do_test_upload_json_users_groups2($mojo) { my @users = ( {name => new_domain_name() } , {name => new_domain_name(), is_admin => 1 } @@ -383,7 +436,7 @@ sub test_upload_json_users_groups2() { ,groups => \@groups }; - _do_upload_users_json( encode_json( $data ) ); + _do_upload_users_json( $data, $mojo ); for my $u ( @users ) { my $user = Ravada::Auth::SQL->new(name => $u->{name}); ok($user->id, "Expecting user $u->{name} created"); @@ -396,6 +449,11 @@ sub test_upload_json_users_groups2() { } sub test_upload_json_members() { + _do_test_upload_json_members(0); + _do_test_upload_json_members(1); +} + +sub _do_test_upload_json_members($mojo=0) { my @users_g0 = ( new_domain_name() ,new_domain_name() @@ -410,7 +468,7 @@ sub test_upload_json_members() { groups => \@groups }; - _do_upload_users_json( encode_json( $data ),{ groups_found => 2,groups_added => 2, users_found => 2, users_added => 2} ); + _do_upload_users_json( encode_json( $data ),$mojo,{ groups_found => 2,groups_added => 2, users_found => 2, users_added => 2} ); for my $u ( @users_g0 ) { my $user = Ravada::Auth::SQL->new(name => $u ); ok($user->id, "Expecting user $u created"); @@ -440,12 +498,12 @@ sub test_upload_json_members() { $groups[0]->{members} = \@users_g0b; - _do_upload_users_json( encode_json( {groups => \@groups}),{ groups_found => 2,groups_added => 0, users_found => 3, users_added => 2} ); + _do_upload_users_json( encode_json( {groups => \@groups}),$mojo, { groups_found => 2,groups_added => 0, users_found => 3, users_added => 2} ); for my $name ( @users_g0 , @users_g0b ) { my $user = Ravada::Auth::SQL->new(name => $name ); - ok($user->id, "Expecting user $name created"); + ok($user->id, "Expecting user $name created mojo=$mojo") or exit; my $g0 = Ravada::Auth::Group->new(name => $groups[0]->{name}); my ($found) = grep (/^$name$/ , $g0->members); @@ -454,6 +512,11 @@ sub test_upload_json_members() { } sub test_upload_json_members_flush() { + _do_test_upload_json_members_flush(0); + _do_test_upload_json_members_flush(1); +} + +sub _do_test_upload_json_members_flush($mojo) { my @users_g0 = ( new_domain_name() ,new_domain_name() @@ -468,7 +531,7 @@ sub test_upload_json_members_flush() { groups => \@groups }; - _do_upload_users_json( encode_json( $data ),{ groups_found => 2,groups_added => 2, users_found => 2, users_added => 2} ); + _do_upload_users_json( encode_json( $data ),$mojo,{ groups_found => 2,groups_added => 2, users_found => 2, users_added => 2} ); for my $u ( @users_g0 ) { my $user = Ravada::Auth::SQL->new(name => $u ); ok($user->id, "Expecting user $u created"); @@ -498,7 +561,7 @@ sub test_upload_json_members_flush() { $groups[0]->{members} = \@users_g0b; - _do_upload_users_json( encode_json( {groups => \@groups, options => {'flush' => 1}}),{ groups_found => 2,groups_added => 0, users_found => 3, users_added => 2} ); + _do_upload_users_json( encode_json( {groups => \@groups, options => {'flush' => 1}}),$mojo, { groups_found => 2,groups_added => 0, users_found => 3, users_added => 2} ); for my $name ( $users_g0[1] ) { @@ -523,6 +586,11 @@ sub test_upload_json_members_flush() { } sub test_upload_json_members_remove_empty() { + _do_test_upload_json_members_remove_empty(0); + _do_test_upload_json_members_remove_empty(1); +} + +sub _do_test_upload_json_members_remove_empty($mojo) { my @users_g0 = ( new_domain_name() ,new_domain_name() @@ -537,7 +605,7 @@ sub test_upload_json_members_remove_empty() { groups => \@groups }; - _do_upload_users_json( encode_json( $data ),{ groups_found => 2,groups_added => 2, users_found => 2, users_added => 2} ); + _do_upload_users_json( encode_json( $data ), $mojo, { groups_found => 2,groups_added => 2, users_found => 2, users_added => 2} ); for my $u ( @users_g0 ) { my $user = Ravada::Auth::SQL->new(name => $u ); ok($user->id, "Expecting user $u created"); @@ -568,7 +636,7 @@ sub test_upload_json_members_remove_empty() { $groups[1]->{members} = \@users_g0b; $groups[0]->{members} = []; - _do_upload_users_json( encode_json( {groups => \@groups, options => {'flush'=>1,'remove_empty'=>1}}),{ groups_found => 2,groups_added => 0, users_found => 3, users_added => 2} ); + _do_upload_users_json( encode_json( {groups => \@groups, options => {'flush'=>1,'remove_empty'=>1}}), $mojo, { groups_found => 2,groups_added => 0, users_found => 3, users_added => 2} ); for my $name ( @users_g0b ) { @@ -590,6 +658,11 @@ sub test_upload_json_members_remove_empty() { sub test_upload_json_users_admin() { + _do_test_upload_json_users_admin(0); + _do_test_upload_json_users_admin(1); +} + +sub _do_test_upload_json_users_admin($mojo) { my @users = ( {name => new_domain_name() } , {name => new_domain_name(), is_admin => 0 } @@ -599,7 +672,7 @@ sub test_upload_json_users_admin() { users => \@users }; - _do_upload_users_json( encode_json( $data ) ); + _do_upload_users_json( $data, $mojo ); for my $u ( @users ) { my ($name, $password) = ($u->{name} , $u->{password}); @@ -614,6 +687,11 @@ sub test_upload_json_users_admin() { } sub test_upload_json_users_pass() { + _do_test_upload_json_users_pass(0); + _do_test_upload_json_users_pass(1); +} + +sub _do_test_upload_json_users_pass($mojo) { my $p1='a'; my $p2 = 'b'; my @users = ( @@ -621,7 +699,7 @@ sub test_upload_json_users_pass() { , {name => new_domain_name(), password => $p2 } ); - _do_upload_users_json( encode_json( { users => \@users }),undef, 0, 'sql' ); + _do_upload_users_json( encode_json( { users => \@users }), $mojo, undef, 'sql' ); for my $u ( @users ) { my ($name, $password) = ($u->{name} , $u->{password}); @@ -653,6 +731,8 @@ test_upload_no_admin($t); _login($t); +test_upload_json_fail(); + test_upload_json(); test_upload_group(); From 261b30216404a0d50f61302fe16e98445d1f75cb Mon Sep 17 00:00:00 2001 From: Francesc Guasch Date: Wed, 2 Oct 2024 11:31:55 +0200 Subject: [PATCH 04/11] wip: testing group member update --- lib/Ravada/Front.pm | 10 +++++++++- t/mojo/60_upload.t | 14 ++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/lib/Ravada/Front.pm b/lib/Ravada/Front.pm index b8fc43455..5327c398c 100644 --- a/lib/Ravada/Front.pm +++ b/lib/Ravada/Front.pm @@ -1920,7 +1920,10 @@ sub upload_users_json($self, $data_json, $type='openid') { eval { $data= decode_json($data_json); }; - push @error,($@) if $@; + if ( $@ ) { + push @error,($@); + $data={} + } my $result = { users_found => 0 @@ -1928,6 +1931,11 @@ sub upload_users_json($self, $data_json, $type='openid') { ,groups_found => 0 ,groups_added => 0 }; + if (exists $data->{groups} && + (!ref($data->{groups}) || ref($data->{groups}) ne 'ARRAY')) { + die "Expecting groups as an array , got ".ref($data->{groups}); + } + $data->{groups} = [] if !exists $data->{groups}; for my $g0 (@{$data->{groups}}) { $result->{groups_found}++; my $g = $g0; diff --git a/t/mojo/60_upload.t b/t/mojo/60_upload.t index 8d8894fac..fb9944763 100644 --- a/t/mojo/60_upload.t +++ b/t/mojo/60_upload.t @@ -319,10 +319,16 @@ sub _do_upload_users_json($data, $mojo, $exp_result=undef, $type='openid') { if ($data_h->{groups}) { $exp_result->{groups_found} = scalar(@{$data_h->{groups}}); $exp_result->{groups_added} = scalar(@{$data_h->{groups}}); + confess"not array groups\n".Dumper($data_h) if ref($data_h->{groups}) ne 'ARRAY'; + for my $g ($data_h->{groups}) { + next if !ref($g) || ref($g) ne 'HASH' || !exists $g->{members}; + $exp_result->{users_found} += scalar(@{$g->{members}}); + $exp_result->{users_added} += scalar(@{$g->{members}}); + } } if ($data_h->{users}) { - $exp_result->{users_found} = scalar(@{$data_h->{users}}); - $exp_result->{users_added} = scalar(@{$data_h->{users}}); + $exp_result->{users_found} += scalar(@{$data_h->{users}}); + $exp_result->{users_added} += scalar(@{$data_h->{users}}); }; } my $users = $data_h->{users}; @@ -351,11 +357,11 @@ sub _do_upload_users_json($data, $mojo, $exp_result=undef, $type='openid') { $error = $response->{error}; } - is_deeply($result, $exp_result) or die Dumper([$result, $exp_result]); - for my $err (@$error) { ok(0,$err) unless $err =~ /already added/; } + is_deeply($result, $exp_result) or die Dumper(["mojo=$mojo",$data,$error,$result, $exp_result]); + } sub test_upload_json_users() { From 63c36c91812f3d917777cb180c3925492130d8cd Mon Sep 17 00:00:00 2001 From: Francesc Guasch Date: Wed, 2 Oct 2024 12:16:41 +0200 Subject: [PATCH 05/11] wip: properly display output from uploading --- lib/Ravada/Front.pm | 2 ++ script/rvd_front | 15 ++++++++++++--- t/mojo/60_upload.t | 6 +++--- templates/main/upload_users.html.ep | 9 +++++++-- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/lib/Ravada/Front.pm b/lib/Ravada/Front.pm index 5327c398c..1bdf054af 100644 --- a/lib/Ravada/Front.pm +++ b/lib/Ravada/Front.pm @@ -1948,6 +1948,8 @@ sub upload_users_json($self, $data_json, $type='openid') { if (!$group || !$group->id) { $result->{groups_added}++; Ravada::Auth::Group::add_group(%$g); + } else { + push @error,("Group $g->{name} already added"); } $self->_add_users($members, $type, $result, \@error); $group->remove_all_members() if $data->{options}->{flush}; diff --git a/script/rvd_front b/script/rvd_front index 432bf7441..91fb39924 100644 --- a/script/rvd_front +++ b/script/rvd_front @@ -1879,6 +1879,12 @@ sub _upload_users_json($c, $file, $type, $create) { output => $result ,error => $error } + ) if $c->stash('req') eq 'json'; + + return $c->render(template => "/main/upload_users" + ,output => $result + ,error => $error + ,done => 1 ); } @@ -1886,15 +1892,18 @@ sub _upload_users_csv($c, $csv, $type, $create) { my ($found, $count, $error) = $RAVADA->upload_users( $csv->slurp, $type, $create ); + my $output = { + users_found => $found + ,users_added => $count + }; return $c->render(json => - { output => "$count users added" + { output => $output ,error => $error + ,done => 1 }) if $c->stash('req') eq 'json'; return $c->render(template => "/main/upload_users" - ,count => $count - ,found => $found ,error => $error ,done => 1 ); diff --git a/t/mojo/60_upload.t b/t/mojo/60_upload.t index fb9944763..391908acc 100644 --- a/t/mojo/60_upload.t +++ b/t/mojo/60_upload.t @@ -68,7 +68,7 @@ sub test_upload_users_nopassword( $type, $mojo=0 ) { die $t->tx->res->body if $t->tx->res->code != 200; my $response = $t->tx->res->json(); - like($response->{output}, qr/2 users added/); + is($response->{output}->{users_added} ,2); is_deeply($response->{error},[]); } else { rvd_front->upload_users($users, $type); @@ -99,7 +99,7 @@ sub test_upload_users( $type, $create=0, $mojo=0 ) { die $t->tx->res->body if $t->tx->res->code != 200; my $response = $t->tx->res->json(); - like($response->{output}, qr/2 users added/); + is($response->{output}->{users_added} ,2); is_deeply($response->{error},[]); } else { rvd_front->upload_users($users, $type, $create); @@ -123,7 +123,7 @@ sub test_upload_users( $type, $create=0, $mojo=0 ) { die $t->tx->res->body if $t->tx->res->code != 200; my $response = $t->tx->res->json(); - like($response->{output}, qr/0 users added/); + is($response->{output}->{users_added},0); is(scalar(@{$response->{error}}),2); test_users_added($type, $user1, $user2); diff --git a/templates/main/upload_users.html.ep b/templates/main/upload_users.html.ep index 564159b53..16b79f852 100644 --- a/templates/main/upload_users.html.ep +++ b/templates/main/upload_users.html.ep @@ -60,8 +60,13 @@ % } else { - <%= $found %> <%=l 'users found in uploaded file' %>, - <%= $count %> <%=l 'created' %>. +<%= $output->{users_found} %> <%=l 'users found in uploaded file' %>, +<%= $output->{users_added} %> <%=l 'created' %>. +% if (exists $output->{groups_found}) { +<%= $output->{groups_found} %> <%=l 'groups found in uploaded file' %>, +<%= $output->{groups_added} %> <%=l 'created' %>. +% } +
<%=l 'Errors found' %>: <%= scalar(@$error) %>
    From 4cb9f8e94aae1d4c11687f448166fa3adaade803 Mon Sep 17 00:00:00 2001 From: Francesc Guasch Date: Wed, 2 Oct 2024 12:47:54 +0200 Subject: [PATCH 06/11] wip: remove empty groups and display it --- lib/Ravada/Front.pm | 12 +++++++++--- script/rvd_front | 4 +++- t/mojo/60_upload.t | 2 +- templates/main/upload_users.html.ep | 3 +++ 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/lib/Ravada/Front.pm b/lib/Ravada/Front.pm index 1bdf054af..74733eea2 100644 --- a/lib/Ravada/Front.pm +++ b/lib/Ravada/Front.pm @@ -1946,8 +1946,10 @@ sub upload_users_json($self, $data_json, $type='openid') { my $group = Ravada::Auth::Group->new(name => $g->{name}); my $members = delete $g->{members}; if (!$group || !$group->id) { - $result->{groups_added}++; - Ravada::Auth::Group::add_group(%$g); + unless (!scalar(@$members) && $data->{options}->{flush} && $data->{options}->{remove_empty}) { + $result->{groups_added}++; + Ravada::Auth::Group::add_group(%$g); + } } else { push @error,("Group $g->{name} already added"); } @@ -1958,7 +1960,11 @@ sub upload_users_json($self, $data_json, $type='openid') { my $user = Ravada::Auth::SQL->new(name => $m); $user->add_to_group($g->{name}) unless $user->is_member($g->{name}); } - $group->remove() if $data->{options}->{remove_empty} && !$group->members; + if ( $data->{options}->{remove_empty} && $group->id && !$group->members ) { + $group->remove(); + $result->{groups_removed}++; + push @error,("Group ".$group->name." empty removed"); + } } $self->_add_users($data->{users}, $type, $result, \@error) diff --git a/script/rvd_front b/script/rvd_front index 91fb39924..134e91b92 100644 --- a/script/rvd_front +++ b/script/rvd_front @@ -1845,7 +1845,9 @@ any '/admin/users/upload.#req' => sub($c) { my $type = $c->req->param('type'); - return $c->render(template => "/main/upload_users", done => 0, count => 0, found => 0, type => 'sql') if !$type; + return $c->render(template => "/main/upload_users", done => 0, output => {} + ,error => [] + ,type => 'sql') if !$type; my $create = ( $c->req->param('create') or 0); diff --git a/t/mojo/60_upload.t b/t/mojo/60_upload.t index 391908acc..9724b86d3 100644 --- a/t/mojo/60_upload.t +++ b/t/mojo/60_upload.t @@ -642,7 +642,7 @@ sub _do_test_upload_json_members_remove_empty($mojo) { $groups[1]->{members} = \@users_g0b; $groups[0]->{members} = []; - _do_upload_users_json( encode_json( {groups => \@groups, options => {'flush'=>1,'remove_empty'=>1}}), $mojo, { groups_found => 2,groups_added => 0, users_found => 3, users_added => 2} ); + _do_upload_users_json( encode_json( {groups => \@groups, options => {'flush'=>1,'remove_empty'=>1}}), $mojo, { groups_found => 2,groups_added => 0, users_found => 3, users_added => 2, groups_removed => 1} ); for my $name ( @users_g0b ) { diff --git a/templates/main/upload_users.html.ep b/templates/main/upload_users.html.ep index 16b79f852..d278812db 100644 --- a/templates/main/upload_users.html.ep +++ b/templates/main/upload_users.html.ep @@ -65,6 +65,9 @@ % if (exists $output->{groups_found}) { <%= $output->{groups_found} %> <%=l 'groups found in uploaded file' %>, <%= $output->{groups_added} %> <%=l 'created' %>. +% } +% if (exists $output->{groups_removed}) { +<%= $output->{groups_removed} %> <%= l 'groups removed'%>. % }
    From c523b6e17d1bb3537879a4e86e68b0ee5ca0f2c5 Mon Sep 17 00:00:00 2001 From: Francesc Guasch Date: Thu, 3 Oct 2024 08:40:29 +0200 Subject: [PATCH 07/11] wip: properly flush and remove empty groups --- lib/Ravada/Front.pm | 2 +- t/mojo/60_upload.t | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/Ravada/Front.pm b/lib/Ravada/Front.pm index 74733eea2..acd0e552a 100644 --- a/lib/Ravada/Front.pm +++ b/lib/Ravada/Front.pm @@ -1946,7 +1946,7 @@ sub upload_users_json($self, $data_json, $type='openid') { my $group = Ravada::Auth::Group->new(name => $g->{name}); my $members = delete $g->{members}; if (!$group || !$group->id) { - unless (!scalar(@$members) && $data->{options}->{flush} && $data->{options}->{remove_empty}) { + unless (defined $members && !scalar(@$members) && $data->{options}->{flush} && $data->{options}->{remove_empty}) { $result->{groups_added}++; Ravada::Auth::Group::add_group(%$g); } diff --git a/t/mojo/60_upload.t b/t/mojo/60_upload.t index 9724b86d3..ffb5f4f6b 100644 --- a/t/mojo/60_upload.t +++ b/t/mojo/60_upload.t @@ -344,7 +344,8 @@ sub _do_upload_users_json($data, $mojo, $exp_result=undef, $type='openid') { if (!$mojo) { ($result, $error)=rvd_front->upload_users_json($data, $type); } else { - $t->post_ok('/admin/users/upload.json' => form => { + my $url='/admin/users/upload.json'; + $t->post_ok( $url => form => { type => $type ,create => 0 ,users => { content => $data, filename => 'data.json' @@ -358,7 +359,7 @@ sub _do_upload_users_json($data, $mojo, $exp_result=undef, $type='openid') { } for my $err (@$error) { - ok(0,$err) unless $err =~ /already added/; + ok(0,$err) unless $err =~ /already added|empty removed/; } is_deeply($result, $exp_result) or die Dumper(["mojo=$mojo",$data,$error,$result, $exp_result]); From d16a52bc5525833b0ce8513d7c8a033fdfc02236 Mon Sep 17 00:00:00 2001 From: Francesc Guasch Date: Fri, 4 Oct 2024 10:28:10 +0200 Subject: [PATCH 08/11] wip: remove other members after adding current --- lib/Ravada/Auth/Group.pm | 9 +++++++-- lib/Ravada/Front.pm | 11 ++++++----- templates/main/upload_users.html.ep | 2 +- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/lib/Ravada/Auth/Group.pm b/lib/Ravada/Auth/Group.pm index f2a6ec771..1b3c76467 100644 --- a/lib/Ravada/Auth/Group.pm +++ b/lib/Ravada/Auth/Group.pm @@ -121,8 +121,13 @@ sub remove_member($self, $name) { $sth->execute($id_user); } -sub remove_all_members($self) { - $self->_remove_all_members(); +sub remove_other_members($self, $members) { + my %members = map { $_ => 1 } @$members; + + for my $name ($self->members ) { + $self->remove_member($name) if !$members{$name}; + } + } sub _remove_all_members($self) { diff --git a/lib/Ravada/Front.pm b/lib/Ravada/Front.pm index acd0e552a..e6754ffb7 100644 --- a/lib/Ravada/Front.pm +++ b/lib/Ravada/Front.pm @@ -1953,8 +1953,8 @@ sub upload_users_json($self, $data_json, $type='openid') { } else { push @error,("Group $g->{name} already added"); } - $self->_add_users($members, $type, $result, \@error); - $group->remove_all_members() if $data->{options}->{flush}; + $self->_add_users($members, $type, $result, \@error, 1); + $group->remove_other_members($members) if $data->{options}->{flush}; for my $m (@$members) { my $user = Ravada::Auth::SQL->new(name => $m); @@ -1973,7 +1973,7 @@ sub upload_users_json($self, $data_json, $type='openid') { return ($result, \@error); } -sub _add_users($self,$users, $type, $result, $error) { +sub _add_users($self,$users, $type, $result, $error, $ignore_already=0) { for my $u0 (@$users) { $result->{users_found}++; my $u = $u0; @@ -1989,8 +1989,9 @@ sub _add_users($self,$users, $type, $result, $error) { } my $user = Ravada::Auth::SQL->new(name => $u->{name}); if ($user && $user->id) { - push @$error,("User $u->{name} already added"); - next; + push @$error,("User $u->{name} already added") + unless $ignore_already; + next; } Ravada::Auth::SQL::add_user(%$u); $result->{users_added}++; diff --git a/templates/main/upload_users.html.ep b/templates/main/upload_users.html.ep index d278812db..343d3fd1a 100644 --- a/templates/main/upload_users.html.ep +++ b/templates/main/upload_users.html.ep @@ -39,7 +39,7 @@
    - From bb7bf86e41d74b38a05dd27de046b5e77162696b Mon Sep 17 00:00:00 2001 From: Francesc Guasch Date: Fri, 4 Oct 2024 10:30:18 +0200 Subject: [PATCH 09/11] wip: properly indent --- templates/main/upload_users.html.ep | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/templates/main/upload_users.html.ep b/templates/main/upload_users.html.ep index 343d3fd1a..fbb81a09f 100644 --- a/templates/main/upload_users.html.ep +++ b/templates/main/upload_users.html.ep @@ -60,16 +60,15 @@
    % } else { -<%= $output->{users_found} %> <%=l 'users found in uploaded file' %>, -<%= $output->{users_added} %> <%=l 'created' %>. -% if (exists $output->{groups_found}) { -<%= $output->{groups_found} %> <%=l 'groups found in uploaded file' %>, -<%= $output->{groups_added} %> <%=l 'created' %>. -% } -% if (exists $output->{groups_removed}) { -<%= $output->{groups_removed} %> <%= l 'groups removed'%>. -% } - + <%= $output->{users_found} %> <%=l 'users found in uploaded file' %>, + <%= $output->{users_added} %> <%=l 'created' %>. +% if (exists $output->{groups_found}) { + <%= $output->{groups_found} %> <%=l 'groups found in uploaded file' %>, + <%= $output->{groups_added} %> <%=l 'created' %>. +% } +% if (exists $output->{groups_removed}) { + <%= $output->{groups_removed} %> <%= l 'groups removed'%>. +% }
    <%=l 'Errors found' %>: <%= scalar(@$error) %>
      From d2cf05a09ce669bddb89e3d626b0379f9d49b4ea Mon Sep 17 00:00:00 2001 From: Francesc Guasch Date: Fri, 4 Oct 2024 10:40:26 +0200 Subject: [PATCH 10/11] doc: upload users json file --- lib/Ravada/Front.pm | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/Ravada/Front.pm b/lib/Ravada/Front.pm index e6754ffb7..8f04c903b 100644 --- a/lib/Ravada/Front.pm +++ b/lib/Ravada/Front.pm @@ -1912,6 +1912,22 @@ sub upload_users($self, $users, $type, $create=0) { return ($found, $count, \@error); } +=head2 upload_users_json + +Upload a list of users to the database + +=head3 Arguments + +=over + +=item * string with users and passwords in each line + +=item * type: it can be SQL, LDAP or SSO + +=back + +=cut + sub upload_users_json($self, $data_json, $type='openid') { From a98459b6d86ecfd01258cac829e540795f02cd59 Mon Sep 17 00:00:00 2001 From: Francesc Guasch Date: Fri, 4 Oct 2024 11:04:19 +0200 Subject: [PATCH 11/11] wip: we need init now to create local_groups table --- t/40_auth_sql.t | 1 + t/lib/Test/Ravada.pm | 1 + t/user/10_domains.t | 1 + t/user/35_share.t | 1 + 4 files changed, 4 insertions(+) diff --git a/t/40_auth_sql.t b/t/40_auth_sql.t index a058340d8..24d2b7ae2 100644 --- a/t/40_auth_sql.t +++ b/t/40_auth_sql.t @@ -10,6 +10,7 @@ use Test::Ravada; use_ok('Ravada'); use_ok('Ravada::Auth::SQL'); +init(); my $RAVADA = rvd_back(); Ravada::Auth::SQL::add_user(name => 'test',password => $$); diff --git a/t/lib/Test/Ravada.pm b/t/lib/Test/Ravada.pm index b2f87cc0f..a1776d586 100644 --- a/t/lib/Test/Ravada.pm +++ b/t/lib/Test/Ravada.pm @@ -1597,6 +1597,7 @@ sub _qemu_storage_pool { sub remove_void_networks($vm=undef) { if (!defined $vm) { eval { $vm = rvd_back->search_vm('Void') }; + die $@ if $@; } my $dir_net = $vm->dir_img()."/networks"; return if ! -e $dir_net; diff --git a/t/user/10_domains.t b/t/user/10_domains.t index 2d16597e4..0490c76f7 100644 --- a/t/user/10_domains.t +++ b/t/user/10_domains.t @@ -11,6 +11,7 @@ use_ok('Ravada'); use_ok('Ravada::VM::Void'); use_ok('Ravada::Auth::SQL'); +init(); my $ravada = rvd_back(); # diff --git a/t/user/35_share.t b/t/user/35_share.t index f0948ade7..40d8a13ef 100644 --- a/t/user/35_share.t +++ b/t/user/35_share.t @@ -134,6 +134,7 @@ sub test_machine_info_shared($user, $clone) { ############################################################## +init(); clean(); for my $vm_name ( vm_names() ) {