[Jifty-commit] r4014 - in apps/CASPlus/trunk: etc lib lib/CASPlus lib/CASPlus/View lib/CASPlus/View/Admin lib/CASPlus/View/Admin/Profile lib/CASPlus/View/Admin/Session lib/CASPlus/View/Admin/User share/web/static/css

jifty-commit at lists.jifty.org jifty-commit at lists.jifty.org
Thu Aug 30 18:14:08 EDT 2007


Author: sterling
Date: Thu Aug 30 18:14:07 2007
New Revision: 4014

Added:
   apps/CASPlus/trunk/lib/CASPlus/Menu.pm
   apps/CASPlus/trunk/lib/CASPlus/View/
   apps/CASPlus/trunk/lib/CASPlus/View/Admin/
   apps/CASPlus/trunk/lib/CASPlus/View/Admin/Profile/
   apps/CASPlus/trunk/lib/CASPlus/View/Admin/Session/
   apps/CASPlus/trunk/lib/CASPlus/View/Admin/User/
   apps/CASPlus/trunk/lib/CASPlus/View/Error.pm
   apps/CASPlus/trunk/share/web/static/css/
   apps/CASPlus/trunk/share/web/static/css/app.css
Modified:
   apps/CASPlus/trunk/   (props changed)
   apps/CASPlus/trunk/etc/config.yml
   apps/CASPlus/trunk/lib/CASPlus.pm
   apps/CASPlus/trunk/lib/CASPlus/CurrentUser.pm
   apps/CASPlus/trunk/lib/CASPlus/Dispatcher.pm
   apps/CASPlus/trunk/lib/CASPlus/View.pm

Log:
 r11074 at riddle:  andrew | 2007-08-30 11:17:57 -0500
 Expanding the user interface.


Modified: apps/CASPlus/trunk/etc/config.yml
==============================================================================
--- apps/CASPlus/trunk/etc/config.yml	(original)
+++ apps/CASPlus/trunk/etc/config.yml	Thu Aug 30 18:14:07 2007
@@ -1,6 +1,6 @@
 --- 
 framework: 
-  AdminMode: 1
+  AdminMode: 0
   ApplicationClass: CASPlus
   ApplicationName: CASPlus
   ApplicationUUID: EC7095D2-B700-11DB-9310-01BD470BAD47

Modified: apps/CASPlus/trunk/lib/CASPlus.pm
==============================================================================
--- apps/CASPlus/trunk/lib/CASPlus.pm	(original)
+++ apps/CASPlus/trunk/lib/CASPlus.pm	Thu Aug 30 18:14:07 2007
@@ -2,9 +2,14 @@
 use warnings;
 
 package CASPlus;
+use base qw/ Class::Data::Inheritable /;
 
 our $VERSION = '0.0.1';
 
+use CASPlus::Menu;
+
+__PACKAGE__->mk_classdata(qw/ _admin_menu /);
+
 =head1 NAME
 
 CASPlus - An alternative Central Authentication Service server
@@ -187,6 +192,18 @@
     return $profile_obj;
 }
 
+=head2 admin_menu
+
+This returns a L<CASPlus::AdminMenu> object that can be used to register menu items to show on the administration screen.
+
+=cut
+
+sub admin_menu {
+    my $class = shift;
+    return $class->_admin_menu if $class->_admin_menu;
+    return $class->_admin_menu( CASPlus::Menu->new );
+}
+
 =head1 IMPLEMENTED FEATURES
 
 This is a list of features that CAS+ supports. CAS+ provides the same functionality as the original CAS implementation with these additional features.

Modified: apps/CASPlus/trunk/lib/CASPlus/CurrentUser.pm
==============================================================================
--- apps/CASPlus/trunk/lib/CASPlus/CurrentUser.pm	(original)
+++ apps/CASPlus/trunk/lib/CASPlus/CurrentUser.pm	Thu Aug 30 18:14:07 2007
@@ -270,18 +270,55 @@
 }
 
 sub _may_i {
-    my $self        = shift;
-    my $may_i_do_it = 'may_'.shift;
+    my $self      = shift;
+    my $may_do_it = 'may_'.shift;
     
     # Check all the roles for the requested permissions
     for my $role ($self->roles(1)) {
-        return 1 if $role->$may_i_do_it;
+        return 1 if $role->$may_do_it;
     }
 
     # Fallback upon superuser/bootstrap user which are also granted these
     return $self->is_superuser || $self->is_bootstrap_user;
 }
 
+=head2 may_administrate
+
+This method checks to see if the current user has any role with at least one of the following set to a true value:
+
+=over
+
+=item *
+
+C<may_manage_profiles>
+
+=item *
+
+C<may_manage_roles>
+
+=item *
+
+C<may_manager_users>
+
+=back
+
+It returns true if it does. It returns false otherwise.
+
+=cut
+
+my @admin_perms = qw( may_manage_profiles may_manage_roles may_manage_users );
+sub may_administrate {
+    my $self = shift;
+
+    for my $role ($self->roles(1)) {
+        for my $may_do_it (@admin_perms) {
+            return 1 if $role->may_do_it;
+        }
+    }
+
+    return $self->is_superuser || $self->is_bootstrap_user;
+}
+
 =head1 AUTHOR
 
 Andrew Sterling Hanenkamp, C<<hanenkamp at cpan.org>>>

Modified: apps/CASPlus/trunk/lib/CASPlus/Dispatcher.pm
==============================================================================
--- apps/CASPlus/trunk/lib/CASPlus/Dispatcher.pm	(original)
+++ apps/CASPlus/trunk/lib/CASPlus/Dispatcher.pm	Thu Aug 30 18:14:07 2007
@@ -21,6 +21,88 @@
 
 The following dispatcher rules are related to the CAS 2.0 protocol.
 
+=head2 before **
+
+This rule configures the menu items for the Administration page.
+
+=cut
+
+before '**' => run {
+    my $menu = CASPlus->admin_menu;
+    my $current_user = Jifty->web->current_user;
+
+    # Stop now if they ain't an admin
+    return unless $current_user->may_administrate;
+
+    # Top-level items
+    my $profiles = 
+        $menu->child( Profiles => label => 'Profiles', side => 'left' );
+    my $users    =
+        $menu->child( Users    => label => 'Users',    side => 'left' );
+    my $sessions =
+        $menu->child( Sessions => label => 'Sessions', side => 'right' );
+
+    # Profile menu items
+    if ($current_user->may_manage_profiles) {
+        $profiles->child( Profile => 
+            label       => _('Profile Definitions'), 
+            url         => '/admin/profile/definitions',
+            description => _('Configure the profile definitions for storing additional user, group, and other information in your authentication database.'),
+        );
+        $profiles->child( ProfileProperty =>
+            label       => _('Profile Properties'),
+            url         => '/admin/profile/properties',
+            description => _('Add properties to your profile definitions for holding additional information like name, email address, street address, phone numbers, etc.'),
+        );
+        $profiles->child( ProfileRelationship =>
+            label       => _('Profile Relationships'),
+            url         => '/admin/profile/relationships',
+            description => _('Link profiles together in relationships to provide memberships, partnerships, and other profile connections.'),
+        );
+    }
+
+    # User menu
+    if ($current_user->may_manage_users) {
+        $users->child( User =>
+            label       => _('Users'),
+            url         => '/admin/user/users',
+            description => _('Manage the user accounts that may authenticate against the CAS server.'),
+        );
+    }
+    if ($current_user->may_manage_roles) {
+        $users->child( Role =>
+            label       => _('Roles'),
+            url         => '/admin/user/roles',
+            description => _('Manage the roles that may be granted to user accounts to grant special privileges within the CAS server and in client services.'),
+        );
+    }
+
+    # Sessions menu
+    $sessions->child( AccessLog =>
+        label       => _('Access Log'),
+        url         => '/admin/session/access',
+        description => _('See a log of authentication activity that has been performed on the CAS server.'),
+    );
+    $sessions->child( ErrorLog =>
+        label       => _('Error Log'),
+        url         => '/admin/session/errors',
+        description => _('Check the error log to see if there have been any problems with the CAS application.'),
+    );
+    $sessions->child( Status =>
+        label       => _('Status'),
+        url         => '/admin/session/status',
+        description => _('The status screen is a dashboard showing basic usage statistics and reports about the CAS server.'),
+    );
+
+    # Add the Administer item to main navigation
+    my $nav = Jifty->web->navigation;
+    $nav->child( Administer =>
+        label      => _('Administer'),
+        url        => '/admin',
+        sort_order => 50,
+    );
+};
+
 =head2 ROOT
 
 Automatically redirects to L</login>.
@@ -322,6 +404,29 @@
 
 ];
 
+=head2 /admin, /admin/**
+
+Only an administrator may see any of these pages. Sends the user an access denied message if they don't that access level.
+
+=cut
+
+on [ 'admin', 'admin/**' ] => run {
+    show '/error/access_denied' 
+        unless Jifty->web->current_user->may_administrate;
+};
+
+=head2 /error, /error/**
+
+Handle any direct hits to the unknown errors page.
+
+=cut
+
+on [ 'error', 'error/**' ] => run {
+    my $url = $1 || '<unknown>';
+    Jifty->log->error('An unknown error occurred: '.$url);
+    show '/error/unknown';
+};
+
 =head1 CAS+ BACK-END RULES
 
 The following dispatcher rules are related to CAS+ customizations seen by services and not, generally, but end-users or administrators.

Added: apps/CASPlus/trunk/lib/CASPlus/Menu.pm
==============================================================================
--- (empty file)
+++ apps/CASPlus/trunk/lib/CASPlus/Menu.pm	Thu Aug 30 18:14:07 2007
@@ -0,0 +1,113 @@
+use strict;
+use warnings;
+
+package CASPlus::Menu;
+use base qw/ Jifty::Web::Menu /;
+
+__PACKAGE__->mk_accessors( qw/ description side / );
+
+sub render_as_admin_page {
+    my $self = shift;
+    my @kids = $self->children;
+
+    Jifty->web->out(qq{<div class="administration-page">});
+    Jifty->web->out(qq{<div class="administer left">});
+    for my $kid (@kids) {
+        $kid->render_as_menu_group if $kid->side eq 'left';
+    }
+    Jifty->web->out(qq{</div>});
+
+    Jifty->web->out(qq{<div class="administer right">});
+    for my $kid (@kids) {
+        $kid->render_as_menu_group if $kid->side eq 'right';
+    }
+    Jifty->web->out(qq{</div>});
+    Jifty->web->out(qq{</div>});
+}
+
+sub child {
+    my $self = shift;
+    my $key = shift;
+    if (@_) {
+        $self->{children}{$key} = CASPlus::Menu->new({parent => $self,
+                                                        sort_order => ($self->{children}{$key}{sort_order}
+                                                                       || scalar values %{$self->{children}}),
+                                                        label => $key,
+                                                        escape_label => 1,
+                                                        @_
+                                                       });
+        Scalar::Util::weaken($self->{children}{$key}{parent});
+        # Activate it
+        if (my $url = $self->{children}{$key}->url and Jifty->web->request) {
+            # XXX TODO cleanup for mod_perl
+            my $base_path = Jifty->web->request->path;
+            chomp($base_path);
+        
+            $base_path =~ s/index\.html$//g;
+            $base_path =~ s/\/+$//g;
+            $url =~ s/\/+$//i;
+    
+            if ($url eq $base_path) {
+                $self->{children}{$key}->active(1); 
+            }
+        }
+    }
+
+    return $self->{children}{$key}
+}
+
+sub render_as_menu_group {
+    my $self = shift;
+
+    Jifty->web->out(qq{<div class="menu-group">});
+    Jifty->web->out(qq{<h2>});
+    Jifty->web->out($self->label);
+    Jifty->web->out(qq{</h2>});
+    $self->render_as_menu;
+    Jifty->web->out(qq{</div>});
+}
+
+sub render_as_hierarchical_menu_item {
+    my $self = shift;
+    my %args = (
+        class => '',
+        @_
+    );
+    my @kids = $self->children;
+    my $id   = Jifty->web->serial;
+    Jifty->web->out( qq{<li class="toplevel }
+            . ( $self->active ? 'active' : 'closed' ) . qq{">}
+            . qq{<span class="title">} );
+    Jifty->web->out( $self->as_link );
+    Jifty->web->out(qq{</span>});
+    Jifty->web->out(qq{ <span class="description">});
+    Jifty->web->out( $self->description );
+    Jifty->web->out(qq{</span>});
+    if (@kids) {
+        Jifty->web->out(
+            qq{<span class="expand"><a href="#" onclick="Jifty.ContextMenu.hideshow('}
+                . $id
+                . qq{'); return false;">&nbsp;</a></span>}
+                . qq{<ul id="}
+                . $id
+                . qq{">} );
+        for (@kids) {
+            Jifty->web->out(qq{<li class="submenu }.($_->active ? 'active' : '' ).qq{">});
+
+            # We should be able to get this as a string.
+            # Either stringify the link object or output the label
+            # This is really icky. XXX TODO
+            Jifty->web->out( $_->as_link );
+            Jifty->web->out(qq{ <span class="description">});
+            Jifty->web->out( $_->description );
+            Jifty->web->out(qq{</span>});
+            Jifty->web->out("</li>");
+        }
+        Jifty->web->out(qq{</ul>});
+    }
+    Jifty->web->out(qq{</li>});
+    '';
+
+}
+
+1;

Modified: apps/CASPlus/trunk/lib/CASPlus/View.pm
==============================================================================
--- apps/CASPlus/trunk/lib/CASPlus/View.pm	(original)
+++ apps/CASPlus/trunk/lib/CASPlus/View.pm	Thu Aug 30 18:14:07 2007
@@ -219,6 +219,15 @@
     }
 };
 
+template 'admin' => page {
+    { title is 'Administer' };
+
+    CASPlus->admin_menu->render_as_admin_page;
+};
+
+use CASPlus::View::Error;
+alias CASPlus::View::Error under '/error';
+
 #use Template::Declare::XML;
 #use Jifty::View::Declare schema {
 #    namespace cas => 'http://www.yale.edu/tp/cas';

Added: apps/CASPlus/trunk/lib/CASPlus/View/Error.pm
==============================================================================
--- (empty file)
+++ apps/CASPlus/trunk/lib/CASPlus/View/Error.pm	Thu Aug 30 18:14:07 2007
@@ -0,0 +1,35 @@
+use strict;
+use warnings;
+
+package CASPlus::View::Error;
+use Jifty::View::Declare -base;
+
+template 'access_denied' => page {
+    { title is 'Access Denied' };
+
+    p { _('Sorry, but you do not have permission to access this page.') };
+
+    if (Jifty->web->current_user->id) {
+        p { 
+            outs _('You may wish to ');
+            hyperlink label => _('logout'), url => '/logout';
+            outs _(' and login as a privileged user.'),
+        };
+    }
+
+    else {
+        p {
+            outs _('You probably need to ');
+            hyperlink label => _('login'), url => '/login';
+            outs '.';
+        };
+    }
+};
+
+template 'unknown' => page {
+    { title is 'Unknown Error' };
+
+    p { _('An unknown error occurred. This error has been loggged.'); };
+};
+
+1;

Added: apps/CASPlus/trunk/share/web/static/css/app.css
==============================================================================
--- (empty file)
+++ apps/CASPlus/trunk/share/web/static/css/app.css	Thu Aug 30 18:14:07 2007
@@ -0,0 +1,38 @@
+div.administration-page div.left {
+    width: 45%;
+    float: left;
+    clear: left;
+    margin-left: 3%;
+}
+
+div.administration-page div.right {
+    width: 45%;
+    float: right;
+    clear: right;
+    margin-right: 3%;
+}
+
+div.administration-page ul.menu {
+    background-color: inherit;
+    border-bottom: inherit;
+    margin: inherit;
+    padding: inherit;
+    display: inherit;
+}
+
+div.administration-page ul.menu li {
+    display: list-item;
+    list-style-type: disc;
+    margin: 0.5em 1em;
+    padding: inherit;
+}
+
+div.administration-page ul.menu li span.title,
+div.administration-page ul.menu li span.description {
+    display: block;
+}
+
+div.administration-page ul.menu li span.title {
+    font-size: 1.2em;
+    margin-bottom: 0.2em;
+}


More information about the Jifty-commit mailing list