MODE=TAP,43

BEGINPERL

my $mech;

subtest 'Login' => sub {
    plan tests => 4;

    $mech = webui_login(
        username => 'user4',
        password => 'user4',
        url      => "http://$webhost",
    );
};

$mech->follow_link( text_regex => qr/View My Details/ );
$mech->form_number(1);
is($mech->value('xxxxusername'), 'user4', 'Username field correct');
is($mech->value('principal_id'), '1005', 'princial_id hidden field correct');
is($mech->value('newpass1'), '@@@@@@@@@@', 'New password field 1 correct');
is($mech->value('newpass2'), '@@@@@@@@@@', 'New password field 2 correct');
is($mech->value('fullname'), 'User 4', 'Fullname field correct');
is($mech->value('email'), 'user4@example.net', 'Email field correct');
is($mech->value('locale'), '', 'Locale field correct');
is($mech->value('date_format_type'), 'E', 'Date format type field correct');
is($mech->value('type_id'), 1, 'Type field correct');
$mech->content_lacks('is_admin', 'Is Admin field missing');
$mech->content_lacks('user_active', 'User Active field missing');

# Test invalid password change
$mech->submit_form_ok(
    {
        form_number => 1,
        button      => 'submit',
        fields      => {
            newpass1 => 'a password',
            newpass2 => 'a different password',
        },
    }, "Submit mismatching passwords"
);
#$mech->save_content('/tmp/form.html');

$mech->content_contains(
    'Password not updated. The supplied passwords do not match.',
    'Password change error displayed')
    || BAIL_OUT("Password error not returned, all hope is lost");

# Ensure we can still login with the old password.
subtest 'Login with old password' => sub {
    plan tests => 4;

    $mech = webui_login(
        username => 'user4',
        password => 'user4',
        url      => "http://$webhost",
    );
};

$mech->follow_link( text_regex => qr/View My Details/ );

# Test valid password change
$mech->submit_form_ok(
    {
        form_number => 1,
        button      => 'submit',
        fields      => {
            newpass1 => 'a new password',
            newpass2 => 'a new password',
        },
    }, "Submit matching passwords"
);

$mech->content_lacks(
    'Password not updated. The supplied passwords do not match.',
    'Password change error displayed')
    || BAIL_OUT("Password has probably not changed, all hope is lost");

# Ensure we can't login with the old password.
subtest 'Login with old password' => sub {
    plan tests => 4;

    $mech = webui_login(
        username => 'user4',
        password => 'user4',
        url      => "http://$webhost",
        failauth => 1,
    );
};

# Ensure we can login with the new password.
subtest 'Login with new password' => sub {
    plan tests => 4;

    $mech = webui_login(
        username => 'user4',
        password => 'a new password',
        url      => "http://$webhost",
    );
};

$mech->follow_link( text_regex => qr/View My Details/ );

$mech->form_number(1);

# Non-admin user shouldn't be able to change is_admin or user_active flags.
$mech->submit_form_ok(
    {
        form_number => 1,
        button      => 'submit',
        fields      => {
            xxxxusername     => 'user99',
            fullname         => 'User 99',
            email            => 'user99@example.net',
            locale           => 'en',
            date_format_type => 'I',
            type_id          => 2,
            is_admin         => 'off',
            user_active      => 'off',
        },
    }, "Submit updated fields"
);

# Ensure we can login with new username.
subtest 'Login with new username' => sub {
    plan tests => 4;

    $mech = webui_login(
        username => 'user99',
        password => 'a new password',
        url      => "http://$webhost",
    );
};

$mech->follow_link( text_regex => qr/View My Details/ );
$mech->form_number(1);
is($mech->value('xxxxusername'), 'user99', 'Username field correct');
is($mech->value('principal_id'), '1005', 'princial_id hidden field correct');
is($mech->value('fullname'), 'User 99', 'Fullname field correct');
is($mech->value('email'), 'user99@example.net', 'Email field correct');
is($mech->value('locale'), 'en', 'Locale field correct');
is($mech->value('date_format_type'), 'I', 'Date format type field correct');
is($mech->value('type_id'), 2, 'Type field correct');

my $action = $mech->form_number(1)->action;
$action =~ s/id=1005/id=1003/;
$mech->form_number(1)->action($action);

# Submit changes to another user we don't have access to.
$mech->submit_form_ok(
    {
        form_number => 1,
        button      => 'submit',
        fields      => {
            principal_id     => '1003',
            xxxxusername     => 'user98',
            newpass1         => 'another password',
            newpass2         => 'another password',
            fullname         => 'User 98',
            email            => 'user98@example.net',
            locale           => 'en',
            date_format_type => 'I',
            type_id          => 2,
            is_admin         => 'off',
            user_active      => 'off',
        },
    }, "Submit updated fields on a user we have no access to"
);

$mech->content_contains(
    'You do not have permission to modify this record.',
    'Error message denying access displayed');

# Fetch details for another user, make sure any sensitive sections are not
# visible. Also, no need to show the change password fields.
$mech->get_ok($action, "Fetch details page for principal ID 1003");

$mech->content_contains('Principal: User 2', 'Looking at principal ID 1003');

for my $missing_text ('Change Password', 'Confirm Password', 'Group Memberships',
    'Principal Grants', 'Access Tickets', 'Principal Collections',
    'Bindings to other collections',
    'Bindings to this Principal\'s Collections') {

    $mech->content_lacks($missing_text, "$missing_text missing");
}

# Invalidate the CSRF token to make sure the correct error is thrown.
$mech->follow_link( text_regex => qr/View My Details/ );
$mech->form_number(1);
$mech->submit_form_ok(
    {
        form_number => 1,
        button      => 'submit',
        fields      => {
            csrf_token  => 'bogus',
            email       => 'bogus-csrf@example.net',
        },
    }, "Submit form with bogus CSRF fields"
);

$mech->content_contains(
    'A valid CSRF token must be provided',
    'Error message rejecting CSRF displayed');

is($mech->value('email'), 'user99@example.net', 'Email field back to previous value');


ENDPERL


# Test the user we modified to ensure fields are set.
BEGINQUERY
SELECT user_active, username, password <> '**user4' AS password_changed, fullname, email,
    date_format_type, locale, type_id, displayname, dav_name
FROM dav_principal
WHERE principal_id = 1005;
ENDQUERY

# Test some other users we've not modified to ensure they've stayed the same.
BEGINQUERY
SELECT user_active, username, password = '**user1' AS password_same, fullname, email,
    date_format_type, locale, type_id, displayname, dav_name
FROM dav_principal
WHERE principal_id IN (1002, 1003)
ORDER BY principal_id;
ENDQUERY
