#! /usr/bin/perl -Idebian/tests/lib

# tests for adduser --add-authorized-key

use diagnostics;
use strict;
use warnings;

use AdduserTestsCommon;
use Test::More;

my $key_one = 'ssh-ed25519 AAAAoneoneone one@example.org';
my $key_two = 'ssh-rsa AAAAtwotwotwo two@example.org';
my $key_three = 'ssh-ed25519 AAAAthreethree three@example.org';
my $keyfile = '/tmp/adduser-test-keys.pub';

my @users = qw(ausakliteral ausakfile ausakrepeat ausaknohome ausaknonexist
               ausakexisting ausaksystem);

END {
    cleanup_user($_) foreach (@users);
    unlink($keyfile);
    done_testing();
}

sub keyfile_lines {
    my ($path) = @_;
    open(my $fh, '<', $path) or return ();
    my @lines = <$fh>;
    close($fh);
    chomp(@lines);
    return @lines;
}

sub add_user_with_keys {
    my ($name, @args) = @_;
    assert_command_success(
        '/usr/sbin/adduser',
        '--stdoutmsglevel=error', '--stderrmsglevel=error',
        '--comment', '""',
        '--disabled-password',
        @args,
        $name
    );
    assert_user_exists($name);
}

# a literal key is installed with the expected ownership and modes
my $name = 'ausakliteral';
assert_user_does_not_exist($name);
add_user_with_keys($name, '--add-authorized-key', $key_one);
assert_path_is_a_directory("/home/$name/.ssh");
assert_path_is_a_file("/home/$name/.ssh/authorized_keys");
assert_path_has_ownership("/home/$name/.ssh", "$name:$name");
assert_path_has_ownership("/home/$name/.ssh/authorized_keys", "$name:$name");
assert_path_has_mode("/home/$name/.ssh/authorized_keys", "600");
is_deeply([keyfile_lines("/home/$name/.ssh/authorized_keys")], [$key_one],
    "the literal key has been installed");

# a file argument installs all keys it contains, empty lines are skipped
open(my $fh, '>', $keyfile) or die "cannot write $keyfile: $!";
print {$fh} "$key_one\n\n$key_two\n";
close($fh);

$name = 'ausakfile';
assert_user_does_not_exist($name);
add_user_with_keys($name, '--add-authorized-key', $keyfile);
is_deeply([keyfile_lines("/home/$name/.ssh/authorized_keys")],
    [$key_one, $key_two],
    "both keys of the file have been installed, empty line skipped");

# the option can be given more than once
$name = 'ausakrepeat';
assert_user_does_not_exist($name);
add_user_with_keys($name,
    '--add-authorized-key', $key_three,
    '--add-authorized-key', $keyfile);
is_deeply([keyfile_lines("/home/$name/.ssh/authorized_keys")],
    [$key_three, $key_one, $key_two],
    "keys of all occurrences of the option have been installed");

# keys are appended, an authorized_keys from /etc/skel is kept
my $skeldir = '/etc/skel/.ssh';
my $skelfile = "$skeldir/authorized_keys";
my $skel_created = 0;
if (! -e $skeldir) {
    mkdir($skeldir, 0700) or die "cannot create $skeldir: $!";
    $skel_created = 1;
}
if (! -e $skelfile) {
    open(my $sfh, '>', $skelfile) or die "cannot write $skelfile: $!";
    print {$sfh} "$key_two\n";
    close($sfh);

    $name = 'ausakexisting';
    assert_user_does_not_exist($name);
    add_user_with_keys($name, '--add-authorized-key', $key_one);
    is_deeply([keyfile_lines("/home/$name/.ssh/authorized_keys")],
        [$key_two, $key_one],
        "the authorized_keys from /etc/skel has been kept");

    unlink($skelfile);
}
rmdir($skeldir) if ($skel_created);

# no home directory, no keys, but the user is still created
$name = 'ausaknohome';
assert_user_does_not_exist($name);
add_user_with_keys($name, '--no-create-home', '--add-authorized-key', $key_one);
assert_path_does_not_exist("/home/$name/.ssh");

$name = 'ausaknonexist';
assert_user_does_not_exist($name);
add_user_with_keys($name, '--home', '/nonexistent',
    '--add-authorized-key', $key_one);
assert_path_does_not_exist("/nonexistent/.ssh");

# the option is not supported for system users
$name = 'ausaksystem';
assert_user_does_not_exist($name);
assert_command_success(
    '/usr/sbin/adduser',
    '--stdoutmsglevel=error', '--stderrmsglevel=error',
    '--comment', '""',
    '--system',
    '--add-authorized-key', $key_one,
    $name
);
assert_user_exists($name);
assert_path_does_not_exist("/home/$name/.ssh");

# done_testing(); done in END

# vim: tabstop=4 shiftwidth=4 expandtab
