From: Jess Robinson Date: Thu, 24 May 2012 15:49:53 +0000 (+0000) Subject: Add simple "admin" user support X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=7cb56251fa02e6d1f39ec90a78791118fcc5d287;p=scpubgit%2Fstemmatology.git Add simple "admin" user support Fetch all traditions when user is_admin Test the above --- diff --git a/lib/Text/Tradition/Directory.pm b/lib/Text/Tradition/Directory.pm index 1f69d94..743ab6c 100644 --- a/lib/Text/Tradition/Directory.pm +++ b/lib/Text/Tradition/Directory.pm @@ -221,12 +221,11 @@ around BUILDARGS => sub { return $class->$orig( $args ); }; +## These checks don't cover store($id, $obj) before [ qw/ store update insert delete / ] => sub { my $self = shift; my @nontrad; foreach my $obj ( @_ ) { -# if( ref( $obj ) && ref( $obj ) ne 'Text::Tradition' ) { - if( ref( $obj ) && ref( $obj ) ne 'Text::Tradition' && ref ($obj) ne 'Text::Tradition::User' ) { # Is it an id => Tradition hash? @@ -278,7 +277,10 @@ sub user_traditionlist { my ($self, $user) = @_; my @tlist; - if(ref $user) { + if(ref $user && $user->is_admin) { + ## Admin sees all + return $self->traditionlist(); + } elsif(ref $user) { ## We have a user object already, so just fetch its traditions and use tose foreach my $t (@{ $user->traditions }) { push( @tlist, { 'id' => $self->object_to_id( $t ), @@ -366,6 +368,7 @@ sub add_user { my ($self, $userinfo) = @_; my $username = $userinfo->{url} || $userinfo->{username}; my $password = $userinfo->{password}; + my $role = $userinfo->{role} || 'user'; return unless ($username =~ /^https?:/ || ($username && $self->validate_password($password))) ; @@ -373,6 +376,7 @@ sub add_user { my $user = Text::Tradition::User->new( id => $username, password => ($password ? crypt_password($password) : ''), + role => $role, ); $self->store($user->kiokudb_object_id, $user); diff --git a/lib/Text/Tradition/User.pm b/lib/Text/Tradition/User.pm index 47ab694..7e53bb4 100644 --- a/lib/Text/Tradition/User.pm +++ b/lib/Text/Tradition/User.pm @@ -10,6 +10,7 @@ with qw(KiokuX::User); has 'password' => (is => 'rw', required => 1); ## Change this default active value if you want/need to have an admin confirm a user after they self-create. has 'active' => (is => 'rw', default => sub { 1; }); +has 'role' => (is => 'rw', default => sub { 'user' }); # 'traits' => ['Array'] ? # https://metacpan.org/module/Moose::Meta::Attribute::Native::Trait::Array has 'traditions' => (is => 'rw', @@ -38,6 +39,12 @@ sub remove_tradition { $self->traditions(\@traditions); } +sub is_admin { + my ($self) = @_; + + return $self->role eq 'admin'; +} + 1; =head1 NAME diff --git a/script/admin_users.pl b/script/admin_users.pl index 9f9b72e..c492506 100644 --- a/script/admin_users.pl +++ b/script/admin_users.pl @@ -39,6 +39,8 @@ my $new_scope = $userstore->new_scope; given ($command) { when ('add') { + ## We only add local users here, OpenID etc users will get auto-added + ## when they login if(!$password || !$userstore->validate_password($password)) { print "Can't add a new user without a valid password\n\n"; usage(); diff --git a/stemmaweb/lib/stemmaweb/Controller/Root.pm b/stemmaweb/lib/stemmaweb/Controller/Root.pm index b8238dc..6e26299 100644 --- a/stemmaweb/lib/stemmaweb/Controller/Root.pm +++ b/stemmaweb/lib/stemmaweb/Controller/Root.pm @@ -48,9 +48,7 @@ Serves a snippet of HTML that lists the available texts. This returns texts bel sub directory :Local :Args(0) { my( $self, $c ) = @_; my $m = $c->model('Directory'); - # TODO not used yet, will load user texts later my $user = $c->user_exists ? $c->user->get_object : 'public'; -# my $user = $c->request->param( 'user' ) || 'ALL'; my @textlist = $m->traditionlist($user); $c->stash->{texts} = \@textlist; $c->stash->{template} = 'directory.tt'; diff --git a/t/text_tradition_user.t b/t/text_tradition_user.t index bce5cb1..5297df4 100644 --- a/t/text_tradition_user.t +++ b/t/text_tradition_user.t @@ -27,6 +27,7 @@ my $new_user = $user_store->add_user({ username => 'fred', password => 'bloggspass'}); isa_ok($new_user, 'Text::Tradition::User'); is($new_user->active, 1, 'New user created and active'); +ok(!$new_user->is_admin, 'New user is not an admin'); ## find user my $find_user = $user_store->find_user({ username => 'fred'}); @@ -100,6 +101,59 @@ ok($changed->check_password('passbloggs'), 'Modified & retrieved with correct ne my @tlist = $user_store->traditionlist($user); is($tlist[0]->{name}, $t->name, 'Traditionlist returns same named user->tradition'); is($tlist[0]->{id}, $uuid, 'Traditionlist returns actual tradition with same uuid we put in earlier'); + my $fetched_t = $user_store->tradition($tlist[0]->{id}); + is($fetched_t->user->id, $user->id, 'Traditionlist returns item belonging to this user'); + + ## add a second, not owned by this user, we shouldn't return it from + ## traditionslist + my $t2 = Text::Tradition->new( + 'name' => 'inline', + 'input' => 'Tabular', + 'file' => 't/data/simple.txt', + ); + $user_store->save($t2); + my @tlist2 = $user_store->traditionlist($user); + is(scalar @tlist2, 1, 'With 2 stored traditions, we only fetch one'); + my $fetched_t2 = $user_store->tradition($tlist[0]->{id}); + is($fetched_t2->user->id, $user->id, 'Traditionlist returns item belonging to this user'); + + +} + + +TODO: { + local $TODO = 'searching on public attr not implemented yet'; + ## Fetch public traditions, not user traditions, when not fetching with a user + use Text::Tradition; + my $t = Text::Tradition->new( + 'name' => 'inline', + 'input' => 'Tabular', + 'file' => 't/data/simple.txt', + ); + + $user_store->save($t); + my $user = $user_store->add_user({ username => 'testpublic', + password => 'testingtraditions' }); + $user->add_tradition($t); + $user_store->update($user); + + ## add a second, not owned by this user, we shouldn't return it from + ## traditionslist + my $t2 = Text::Tradition->new( + 'name' => 'inline', + 'input' => 'Tabular', + 'file' => 't/data/simple.txt', + ); + $t2->public(1); + my $uuid = $user_store->save($t2); + + my @tlist = $user_store->traditionlist('public'); + is(scalar @tlist, 1, 'Got one public tradition'); + is($tlist[0]->{name}, $t2->name, 'Traditionlist returns same named user->tradition'); + is($tlist[0]->{id}, $uuid, 'Traditionlist returns actual tradition with same uuid we put in earlier'); + my $fetched_t = $user_store->tradition($tlist[0]->{id}); + ok($fetched_t->public, 'Traditionlist returns public item'); + } { @@ -128,3 +182,28 @@ ok($changed->check_password('passbloggs'), 'Modified & retrieved with correct ne is(scalar @tlist, 0, 'Traditionlist now empty'); } +{ + ## Add admin user + my $admin = $user_store->add_user({ + username => 'adminuser', + password => 'adminpassword', + role => 'admin' }); + + ok($admin->is_admin, 'Got an admin user'); + + ## test admins get all traditions + use Text::Tradition; + my $t = Text::Tradition->new( + 'name' => 'inline', + 'input' => 'Tabular', + 'file' => 't/data/simple.txt', + ); + + $user_store->save($t); + + my @tlist = $user_store->traditionlist(); ## all traditions + my @admin_tlist = $user_store->traditionlist($admin); + + is(scalar @admin_tlist, scalar @tlist, 'Got all traditions for admin user'); + +}