Add simple "admin" user support
Jess Robinson [Thu, 24 May 2012 15:49:53 +0000 (15:49 +0000)]
Fetch all traditions when user is_admin
Test the above

lib/Text/Tradition/Directory.pm
lib/Text/Tradition/User.pm
script/admin_users.pl
stemmaweb/lib/stemmaweb/Controller/Root.pm
t/text_tradition_user.t

index 1f69d94..743ab6c 100644 (file)
@@ -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);
index 47ab694..7e53bb4 100644 (file)
@@ -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
index 9f9b72e..c492506 100644 (file)
@@ -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();
index b8238dc..6e26299 100644 (file)
@@ -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';
index bce5cb1..5297df4 100644 (file)
@@ -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');
+
+}