Apache-SWIT-Security

 view release on metacpan or  search on metacpan

lib/Apache/SWIT/Security/DB/Schema.pm  view on Meta::CPAN

use Apache::SWIT::Security qw(Hash);

__PACKAGE__->Name('apache_swit_security');

__PACKAGE__->add_version(sub {
	my $dbh = shift;
	local $ENV{AS_SECURITY_SALT} = 'ajweqwe';
	$dbh->do(q{ create table users (
			id serial primary key, 
			name text unique not null,
			password text not null) without oids });
	$dbh->do(q{ insert into users (name, password) 
			values ('admin', '} . Hash('password') . q{') });

	$dbh->do(q{ create table user_roles (
			user_id integer not null references users(id)
				on delete cascade,
			role_id smallint not null,
			constraint user_roles_pk 
				primary key (user_id, role_id),
			constraint valid_role_id_chk check (
				role_id in (1, 2)))
		without oids });

lib/Apache/SWIT/Security/UI/Login.pm  view on Meta::CPAN

use strict;
use warnings FATAL => 'all';

package Apache::SWIT::Security::UI::Login;
use base qw(Apache::SWIT::HTPage);
use Apache::SWIT::Security qw(Hash);

sub swit_startup {
	my $rc = shift()->ht_make_root_class;
	$rc->ht_add_widget(::HTV."::EditBox", 'username');
	$rc->ht_add_widget(::HTV."::PasswordBox", 'password');
	$rc->ht_add_widget(::HTV."::Hidden", 'redirect'
		, default_value => '../result/r');
	$rc->ht_add_widget(::HTV, $_) for qw(failed logout);
}

sub ht_swit_render {
	my ($class, $r, $root) = @_;
	$r->pnotes('SWITSession')->delete_user if $root->logout;
	return $root;
}

sub ht_swit_update {
	my ($class, $r, $root) = @_;
	my ($u) = $ENV{AS_SECURITY_USER_CLASS}->search(
			name => $root->username,
			password => Hash($root->password // ""));
	my $res = $u ? $root->redirect
			: "r?failed=f&username=" . ($root->username // "");
	$r->pnotes('SWITSession')->set_user($u) if ($u);
	return $res;
}

1;

lib/Apache/SWIT/Security/UI/UserForm.pm  view on Meta::CPAN

use warnings FATAL => 'all';

package Apache::SWIT::Security::UI::UserForm;
use Apache::SWIT::HTPage;
use base qw(Apache::SWIT::HTPage::Safe);
use Apache::SWIT::Security qw(Hash);

sub swit_startup {
	my $rc = shift()->ht_make_root_class('HTML::Tested::ClassDBI');
	$rc->ht_add_widget(::HTV."::EditBox", 'username', cdbi_bind => 'name');
	$rc->ht_add_widget(::HTV."::PasswordBox", 'password', cdbi_bind => '');
	$rc->ht_add_widget(::HTV."::PasswordBox", 'password2'
		, check_mismatch => 'password'
		, constraints => [ [ 'defined' ] ]);
	$rc->bind_to_class_dbi(
		$ENV{AS_SECURITY_USER_CLASS}, { PrimaryKey => [] });
}

sub ht_swit_render {
	my ($class, $r, $root) = @_;
	return $root;
}

sub ht_swit_update {
	my ($class, $r, $root) = @_;
	$root->password(Hash($root->password));
	$root->cdbi_create_or_update;
	return "../userlist/r";
}

1;

lib/Apache/SWIT/Security/UI/UserProfile.pm  view on Meta::CPAN

use base qw(Apache::SWIT::HTPage::Safe);
use Apache::SWIT::Security qw(Hash);
use Apache::SWIT::Security qw(Sealed_Params);

sub swit_startup {
	my $rc = shift()->ht_make_root_class('HTML::Tested::ClassDBI');
	$rc->ht_add_widget(::HTV."::EditBox", 'name', cdbi_bind => '');
	$rc->ht_add_widget(::HTV."::Hidden", 'user_id', cdbi_bind => 'Primary');
	$rc->ht_add_widget(::HTV."::PasswordBox", $_
			, constraints => [ [ "defined"] ])
		for qw(new_password_confirm old_password);
	$rc->ht_add_widget(::HTV."::PasswordBox"
		, new_password => check_mismatch => 'new_password_confirm'
		, constraints => [ [ "defined"] ]);
	$rc->ht_add_widget(::HTV."::Form", form => default_value => 'u');
	$rc->bind_to_class_dbi($ENV{AS_SECURITY_USER_CLASS});
}

sub ht_swit_render {
	my ($class, $r, $root) = @_;
	$root->cdbi_load;
	return $root;
}

sub ht_swit_update_die {
	my ($class, $err, $r, $tested) = @_;
	my $em = ($err =~ /WRONG/) ? [ old_password => 'wrong' ] : undef;
	$class->SUPER::ht_swit_update_die(@_) unless $em;
	return $class->swit_encode_errors([ $em ]);
}

sub ht_swit_update {
	my ($class, $r, $root) = @_;
	my $u = $root->cdbi_retrieve;
	die "WRONG" if $u->password ne Hash($root->old_password);
	$u->password(Hash($root->new_password));
	$root->cdbi_update;
	return $root->ht_make_query_string("r", "user_id");
}

sub check_profile_user {
	my ($class, $r) = @_;
	my $s = $r->pnotes('SWITSession') or return;
	my $u = $s->get_user or return;
	my ($ruid) = Sealed_Params(Apache2::Request->new($r), 'user_id');
	return $ruid ? ($ruid eq $u->id) : undef;

t/010_db.t  view on Meta::CPAN

use Test::More tests => 22;
use T::TempDB;
use Apache::SWIT::Security qw(Hash);

BEGIN { use_ok('T::Test'); }

my @users = Apache::SWIT::Security::DB::User->retrieve_all;
is(scalar(@users), 1);
is($users[0]->name, 'admin');
local $ENV{AS_SECURITY_SALT} = 'ajweqwe';
is($users[0]->password, Hash('password'));
is_deeply([ $users[0]->role_ids ], [ 1 ]);

my $u = Apache::SWIT::Security::DB::User->create({
		name => 'another',
		password => 'p' });
ok($u);
is_deeply([ $u->role_ids ], []);

$u->add_role_id(2);
is_deeply([ $u->role_ids ], [ 2 ]);

$u->add_role_id(1);
is_deeply([ sort $u->role_ids ], [ 1, 2 ]);

eval { $u->add_role_id(3) };

t/950_install.t  view on Meta::CPAN


$t->with_or_without_mech_do(4, sub {
	is(ASTU_Read_Error_Log(), $ef);
	my $al = ASTU_Read_Access_Log();
	like($al, qr/ffff/);
	like($al, qr/moo=/);
	unlike($al, qr/qqqq/);
});

$t->ok_ht_thesub_login_r(make_url => 1);
$t->ht_thesub_login_u(ht => { username => 'admin', password => 'password' });
$t->ok_ht_index_r(make_url => 1);
$t->with_or_without_mech_do(2, sub {
	like($t->mech->content, qr/a_cap is ok/);
	unlike($t->mech->content, qr/b_cap is ok/);
});
my @u2 = Find_Open_URLs($t);
cmp_ok(@u2, '>', @urls);
ENDS

my $ou = 't/dual/thesub/500_open_urls.t';

t/dual/001_load.t  view on Meta::CPAN

};

my $t = T::Test->new;
$t->reset_db;

$t->with_or_without_mech_do(1, sub {
	$t->ht_userform_r(make_url => 1);
	is($t->mech->status, 403);
});

$t->ok_ht_login_r(make_url => 1, ht => { username => '', password => '' });
$t->ht_login_u(ht => { username => 'stranger', password => '1234' });
$t->ok_ht_login_r(ht => { username => 'stranger', password => '', 
				failed => 'f' });

$t->ht_login_u(ht => { username => undef });
$t->ok_ht_login_r(ht => { username => '', password => '', failed => 'f' });

$t->ht_login_u(ht => { username => 'admin', password => 'password' });
$t->ok_ht_result_r(ht => { username => 'admin' });
$t->ok_ht_result_r(make_url => 1, ht => { username => 'admin' });

$t->ok_ht_userlist_r(make_url => 1, ht => { 
		user_list => [ { HT_SEALED_ht_id => 1, name => 'admin' } ] });

$t->ok_ht_userform_r(make_url => 1, ht => { 
		username => '', password => '', password2 => '' });

$t->with_or_without_mech_do(2, sub {
	$t->ht_userform_u(ht => { username => 'user', password => 'p'
			, password2 => 'd' });
	$t->ok_ht_userform_r(ht => { 
		username => 'user', password => 'p', password2 => 'd' });
	like($t->mech->content, qr/passwords do not match/);
});

$t->ht_userform_u(ht => { username => 'user', password => 'p'
		, password2 => 'p' });

$t->ok_ht_userlist_r(ht => { user_list => [ 
		{ HT_SEALED_ht_id => 1, check => [ 1 ], name => 'admin' }, 
		{ HT_SEALED_ht_id => 2, check => [ 1 ], name => 'user' } 
] });

$t->ht_userlist_u(ht => { user_list => [ { HT_SEALED_ht_id => 1 }, {
				HT_SEALED_ht_id => 2, check => 1, } ] });
$t->ok_ht_userlist_r(ht => { user_list => [ 
		{ HT_SEALED_ht_id => 1, check => [ 1 ], name => 'admin' }, 

t/dual/001_load.t  view on Meta::CPAN

	{ HT_SEALED_ht_id => 1, HT_SEALED_role_id => 1 }
	, { HT_SEALED_ht_id => 1, HT_SEALED_role_id => 2, check => [ 1 ] }
] });

$t->ok_ht_userrolelist_r(ht => { user_list => [
	{ HT_SEALED_ht_id => 1, name => 'admin', role_name => 'admin'
		, HT_SEALED_role_id => 1, check => [ 1 ] },
] });

$t->ok_ht_login_r(make_url => 1, param => { redirect => "../userrolelist/r" }
		, ht => { username => '', password => '' });
$t->ht_login_u(ht => { username => 'admin', password => 'password' });
$t->ok_ht_userrolelist_r(ht => { user_list => [
	{ HT_SEALED_ht_id => 1, name => 'admin', role_name => 'admin'
		, HT_SEALED_role_id => 1, check => [ 1 ] },
] });

t/dual/010_user.t  view on Meta::CPAN


use Test::More tests => 55;
use Apache::SWIT::Security::Test qw(Is_URL_Secure);
use Apache::SWIT::Test::Utils;

BEGIN { use_ok('T::Test'); }

my $t = T::Test->new;
$t->reset_db;

$t->ok_ht_login_r(make_url => 1, ht => { username => '', password => '' });
$t->ht_login_u(ht => { username => 'admin', password => 'password' });
$t->ok_ht_result_r(ht => { username => 'admin' });

$t->ok_follow_link(text => 'Add more users');
$t->ok_ht_userform_r(ht => { username => '', password => '', });
$t->with_or_without_mech_do(9, sub {
	unlike($t->mech->content, qr/The name cannot be empty/);
	$t->ht_userform_u(ht => { username => '', password => 'p'
			, password2 => 'p' });
	$t->ok_ht_userform_r(ht => { username => '', password => 'p', });
	like($t->mech->content, qr/The name cannot be empty/);

	unlike($t->mech->content, qr/The password cannot be empty/);
	unlike($t->mech->content, qr/The confirmation password/);
	$t->ht_userform_u(ht => { username => 'fooo', password => ''
			, password2 => '' });
	like($t->mech->content, qr/The password cannot be empty/);
	like($t->mech->content, qr/The confirmation password cannot be empty/);

	unlike($t->mech->content, qr/The passwords do not match/);
	$t->ht_userform_u(ht => { username => 'fooo', password => 'p'
			, password2 => 'x' });
	like($t->mech->content, qr/The passwords do not match/);
});

$t->ht_userform_u(ht => { username => 'user', password => 'p'
		, password2 => 'p' });

$t->ok_ht_login_r(make_url => 1, ht => { username => '', password => '' });
$t->ht_login_u(ht => { username => 'user', password => 'p' });
$t->ok_ht_result_r(ht => { username => 'user' });

$t->with_or_without_mech_do(8, sub {
	is($t->mech->follow_link(text => 'Add more users'), undef);
	is($t->mech->follow_link(text => 'User Role List'), undef);
	ok(Is_URL_Secure($t, $_)) for map { ("$_/r", "$_/u") }
		qw(userform userlist userrolelist);
});

$t->ok_ht_login_r(make_url => 1, ht => { username => '', password => '' });
$t->ht_login_u(ht => { username => 'admin', password => 'password' });
$t->ok_ht_result_r(ht => { username => 'admin' });

$t->ok_follow_link(text => 'User Role List');
$t->ok_ht_userrolelist_r(ht => { user_list => [
	{ HT_SEALED_ht_id => '1', name => 'admin', role_name => 'admin'
		, HT_SEALED_role_id => 1 }
	, { HT_SEALED_ht_id => '2', name => 'user', role_name => ''
		, HT_SEALED_role_id => '' }
] });

$t->ok_ht_result_r(make_url => 1, ht => { username => 'admin' });
$t->ok_follow_link(text => 'Logout');
$t->ok_ht_login_r(param => { logout => 'admin' }
		, ht => { username => '', password => '', logout => 'admin' });

$t->with_or_without_mech_do(2, sub {
	like($t->mech->content, qr/admin.*logged out/);
	$t->ht_userform_r(make_url => 1);
	is($t->mech->status, 403);
});

$t->ok_ht_login_r(make_url => 1, ht => { username => '', password => '' });
$t->ht_login_u(ht => { username => 'admin', password => 'password' });
$t->ok_ht_result_r(ht => { username => 'admin' });

$t->ok_ht_userprofile_r(make_url => 1, param => { HT_SEALED_user_id => 1 }
	, ht => { name => 'admin', old_password => '', new_password => ''
		, new_password_confirm => '' });
$t->with_or_without_mech_do(4, sub {
	$t->ht_userprofile_u(ht => {
		HT_SEALED_user_id => 1, old_password => 'p', new_password => 'h'
		, new_password_confirm => 'h'
	});

	$t->ok_ht_userprofile_r(param => { HT_SEALED_user_id => 1 }
		, ht => { name => 'admin', old_password => 'p'
			, new_password => 'h'
			, new_password_confirm => 'h' });
	like($t->mech->content, qr/Wrong password/);

	$t->ht_userprofile_u(ht => {
		HT_SEALED_user_id => 1, old_password => 'password'
		, new_password => 'h2'
		, new_password_confirm => 'h'
	});

	$t->ok_ht_userprofile_r(param => { HT_SEALED_user_id => 1 }
		, ht => { name => 'admin', old_password => 'password'
			, new_password => 'h2'
			, new_password_confirm => 'h' });
	like($t->mech->content, qr/Passwords do not match/);
});

$t->ht_userprofile_u(ht => {
	HT_SEALED_user_id => 1, old_password => 'password'
	, new_password => 'h2', name => ''
	, new_password_confirm => 'h2'
}, $t->mech ? () : (error_ok => 1));

$t->with_or_without_mech_do(7, sub {
	$t->ok_ht_userprofile_r(param => { HT_SEALED_user_id => 1 }
		, ht => { name => '', old_password => 'password'
			, new_password => 'h2'
			, new_password_confirm => 'h2' });
	like($t->mech->content, qr/The name cannot be empty/);
	unlike($t->mech->content, qr/The password cannot be empty/);

	$t->ht_userprofile_u(ht => {
		HT_SEALED_user_id => 1, old_password => ''
		, new_password => '', name => 'fooo'
		, new_password_confirm => ''
	});

	$t->ok_ht_userprofile_r(param => { HT_SEALED_user_id => 1 }
		, ht => { name => 'fooo', old_password => ''
			, new_password => '', new_password_confirm => '' });
	like($t->mech->content, qr/The password cannot be empty/);
	like($t->mech->content, qr/New password cannot be empty/);
	like($t->mech->content, qr/Confirmation password cannot be empty/);
});

$t->ht_userprofile_u(ht => {
	HT_SEALED_user_id => 1, old_password => 'password'
	, new_password => 'h2', name => 'admin2'
	, new_password_confirm => 'h2'
});

$t->ok_ht_userprofile_r(param => { HT_SEALED_user_id => 1 }
	, ht => { name => 'admin2', old_password => ''
		, new_password => ''
		, new_password_confirm => '' });

$t = T::Test->new;
$t->ok_ht_login_r(make_url => 1, ht => { username => '', password => '' });
$t->ht_login_u(ht => { username => 'admin2', password => 'h2' });
$t->ok_ht_result_r(ht => { username => 'admin2' });

$t = T::Test->new;
$t->ok_ht_login_r(make_url => 1, ht => { username => '', password => '' });
$t->ht_login_u(ht => { username => 'user', password => 'p' });
$t->ok_ht_result_r(ht => { username => 'user' });

$t->ok_ht_userprofile_r(make_url => 1, param => { HT_SEALED_user_id => 2 }
	, ht => { name => 'user', old_password => '', new_password => ''
		, new_password_confirm => '' });

$t->ok_ht_userprofile_r(make_url => 1
	, param => { HT_SEALED_user_id => 1 }
	, ht => { HT_NO_name => 'admin2' });
$t->with_or_without_mech_do(1, sub { is($t->mech->status, 403); });

templates/login.tt  view on Meta::CPAN

<title>Login</title>
<body>
[% IF logout %]
<p>
[% logout %], you've been logged out successfully.
</p>
[% END %]
<h2>Please login</h2>
<form action="u" method="post">
Username: [% username %] <br />
Password: [% password %] <br />
[% redirect %]
<input type="submit" value="Login" />
</form>
</body>
</html>

templates/userform.tt  view on Meta::CPAN

<html>
<body>
<form action="u" method="post">
Username: [% username %] <br />
[% IF swit_errors.username == 'defined' %]
The name cannot be empty
[% END %]
Password: [% password %] <br />
[% IF swit_errors.password == 'defined' %]
The password cannot be empty
[% END %]
Confirm password: [% password2 %] <br />
[% IF swit_errors.password2 == 'defined' %]
The confirmation password cannot be empty
[% ELSIF swit_errors.password2 == 'mismatch' %]
The passwords do not match
[% END %]
<input type="submit" />
</form>
</body>
</html>

templates/userprofile.tt  view on Meta::CPAN

[% form %]
[% user_id %]
[% IF error %]
<h2>[% error %]</h2>
[% END %]
User name: [% name %] <br />
[% IF swit_errors.name == 'defined' %]
The name cannot be empty
[% END %]

Old password: [% old_password %] <br />
[% IF swit_errors.old_password == 'defined' %]
The password cannot be empty
[% ELSIF swit_errors.old_password == 'wrong' %]
Wrong password
[% END %]

New password: [% new_password %] <br />
[% IF swit_errors.new_password == 'defined' %]
New password cannot be empty
[% ELSIF swit_errors.new_password == 'mismatch' %]
Passwords do not match
[% END %]
New password confirm: [% new_password_confirm %] <br />
[% IF swit_errors.new_password_confirm == 'defined' %]
Confirmation password cannot be empty
[% END %]
<input type="submit" />
</form>
</body>
</html>



( run in 1.206 second using v1.01-cache-2.11-cpan-49f99fa48dc )