Misc updates with thanks to JC Wren
[catagits/Catalyst-Manual.git] / lib / Catalyst / Manual / Tutorial / Authorization.pod
index 5ba80f0..d0ca866 100644 (file)
@@ -57,44 +57,52 @@ L<Appendices|Catalyst::Manual::Tutorial::Appendices>
 =head1 DESCRIPTION
 
 This part of the tutorial adds role-based authorization to the existing
-authentication implemented in Part 4.  It provides simple examples of
+authentication implemented in Part 5.  It provides simple examples of
 how to use roles in both TT templates and controller actions.  The first
 half looks at manually configured authorization.  The second half looks
 at how the ACL authorization plugin can simplify your code.
 
 You can checkout the source code for this example from the catalyst
 subversion repository as per the instructions in
-L<Catalyst::Manual::Tutorial::Intro>
+L<Catalyst::Manual::Tutorial::Intro|Catalyst::Manual::Tutorial::Intro>.
+
 
 =head1 BASIC AUTHORIZATION
 
 In this section you learn how to manually configure authorization.
 
+
 =head2 Update Plugins to Include Support for Authorization
 
 Edit C<lib/MyApp.pm> and add C<Authorization::Roles> to the list:
 
-    use Catalyst qw/
+    __PACKAGE__->setup(qw/
             -Debug
             ConfigLoader
             Static::Simple
-            
+    
             StackTrace
-            
+    
             Authentication
             Authorization::Roles
-            
+    
             Session
             Session::Store::FastMmap
             Session::State::Cookie
-            /;
+        /;
+
+B<Note:> As discussed in MoreCatalystBasics, different versions of 
+C<Catalyst::Devel> have used a variety of methods to load the plugins. 
+You put the plugins in the C<use Catalyst> statement if you prefer.
 
 
 =head2 Add Config Information for Authorization
 
-Edit C<myapp.conf> and update it to match the following (the 
+Edit C<myapp.conf> and update it to match the following (the
 C<role_relation> and C<role_field> definitions are new):
 
+    # rename this file to MyApp.yml and put a : in front of "name" if
+    # you want to use yaml like in old versions of Catalyst
     name MyApp
     <authentication>
         default_realm dbic
@@ -103,7 +111,7 @@ C<role_relation> and C<role_field> definitions are new):
                 <credential>
                     # Note this first definition would be the same as setting
                     # __PACKAGE__->config->{authentication}->{realms}->{dbic}
-                    #     ->{credential} = 'Password' in lib/MyApp.pm 
+                    #     ->{credential} = 'Password' in lib/MyApp.pm
                     #
                     # Specify that we are going to do password-based auth
                     class Password
@@ -118,16 +126,13 @@ C<role_relation> and C<role_field> definitions are new):
                 <store>
                     # Use DBIC to retrieve username, password & role information
                     class DBIx::Class
-                    # This is the model object created by Catalyst::Model::DBIC 
+                    # This is the model object created by Catalyst::Model::DBIC
                     # from your schema (you created 'MyApp::Schema::User' but as
-                    # the Catalyst startup debug messages show, it was loaded as 
+                    # the Catalyst startup debug messages show, it was loaded as
                     # 'MyApp::Model::DB::Users').
-                    # NOTE: Omit 'MyApp::Model' here just as you would when using 
+                    # NOTE: Omit 'MyApp::Model' here just as you would when using
                     # '$c->model("DB::Users)'
                     user_class DB::Users
-                    # This is the name of the field in your 'users' table that 
-                    # contains the user's name
-                    id_field username
                     # This is the name of a many_to_many relation in the users
                     # object that points to the roles for that user
                     role_relation  roles
@@ -145,31 +150,32 @@ C<role_relation> and C<role_field> definitions are new):
 Open C<root/src/books/list.tt2> in your editor and add the following
 lines to the bottom of the file:
 
-    <p>Hello [% Catalyst.user.username %], you have the following roles:</p>
+    <p>Hello [% c.user.username %], you have the following roles:</p>
     
     <ul>
       [% # Dump list of roles -%]
-      [% FOR role = Catalyst.user.roles %]<li>[% role %]</li>[% END %]
+      [% FOR role = c.user.roles %]<li>[% role %]</li>[% END %]
     </ul>
     
     <p>
     [% # Add some simple role-specific logic to template %]
     [% # Use $c->check_user_roles() to check authz -%]
-    [% IF Catalyst.check_user_roles('user') %]
+    [% IF c.check_user_roles('user') %]
       [% # Give normal users a link for 'logout' %]
-      <a href="[% Catalyst.uri_for('/logout') %]">Logout</a>
+      <a href="[% c.uri_for('/logout') %]">Logout</a>
     [% END %]
     
     [% # Can also use $c->user->check_roles() to check authz -%]
-    [% IF Catalyst.check_user_roles('admin') %]
+    [% IF c.check_user_roles('admin') %]
       [% # Give admin users a link for 'create' %]
-      <a href="[% Catalyst.uri_for('form_create') %]">Create</a>
+      <a href="[% c.uri_for('form_create') %]">Create</a>
     [% END %]
     </p>
 
 This code displays a different combination of links depending on the
 roles assigned to the user.
 
+
 =head2 Limit C<Books::add> to C<admin> Users
 
 C<IF> statements in TT templates simply control the output that is sent
@@ -183,7 +189,7 @@ admin-level users by editing C<lib/MyApp/Controller/Books.pm> and
 updating C<url_create> to match the following code:
 
     =head2 url_create
-
+    
     Create a book with the supplied title and rating,
     with manual authorization
     
@@ -197,30 +203,30 @@ updating C<url_create> to match the following code:
     
         # Check the user's roles
         if ($c->check_user_roles('admin')) {
-            # Call create() on the book model object. Pass the table 
+            # Call create() on the book model object. Pass the table
             # columns/field values we want to set as hash values
             my $book = $c->model('DB::Books')->create({
                     title   => $title,
                     rating  => $rating
                 });
-            
-            # Add a record to the join table for this book, mapping to 
+    
+            # Add a record to the join table for this book, mapping to
             # appropriate author
             $book->add_to_book_authors({author_id => $author_id});
             # Note: Above is a shortcut for this:
             # $book->create_related('book_authors', {author_id => $author_id});
-            
+    
             # Assign the Book object to the stash for display in the view
             $c->stash->{book} = $book;
-        
+    
             # This is a hack to disable XSUB processing in Data::Dumper
             # (it's used in the view).  This is a work-around for a bug in
             # the interaction of some versions or Perl, Data::Dumper & DBIC.
             # You won't need this if you aren't using Data::Dumper (or if
-            # you are running DBIC 0.06001 or greater), but adding it doesn't 
+            # you are running DBIC 0.06001 or greater), but adding it doesn't
             # hurt anything either.
             $Data::Dumper::Useperl = 1;
-        
+    
             # Set the TT template to use
             $c->stash->{template} = 'books/create_done.tt2';
         } else {
@@ -238,13 +244,14 @@ way to demonstrate that TT templates will not be used if the response
 body has already been set.  In reality you would probably want to use a
 technique that maintains the visual continuity of your template layout
 (for example, using the "status" or "error" message feature added in
-Part 2).
+Part 3).
 
 B<TIP>: If you want to keep your existing C<url_create> method, you can
 create a new copy and comment out the original by making it look like a
 Pod comment.  For example, put something like C<=begin> before C<sub add
 : Local {> and C<=end> after the closing C<}>.
 
+
 =head2 Try Out Authentication And Authorization
 
 Press C<Ctrl-C> to kill the previous server instance (if it's still
@@ -252,13 +259,13 @@ running) and restart it:
 
     $ script/myapp_server.pl
 
-Now trying going to L<http://localhost:3000/books/list> and you should
-be taken to the login page (you might have to C<Shift+Reload> your
-browser and/or click the "Logout" link on the book list page).  Try 
-logging in with both C<test01> and C<test02> (both use a password 
-of C<mypass>) and notice how the roles information updates at the 
-bottom of the "Book List" page. Also try the C<Logout> link on the
-book list page.
+Now trying going to L<http://localhost:3000/books/list> and you should 
+be taken to the login page (you might have to C<Shift+Reload> or 
+C<Ctrl+Reload> your browser and/or click the "Logout" link on the book 
+list page).  Try logging in with both C<test01> and C<test02> (both 
+use a password of C<mypass>) and notice how the roles information 
+updates at the bottom of the "Book List" page. Also try the C<Logout> 
+link on the book list page.
 
 Now the "url_create" URL will work if you are already logged in as user
 C<test01>, but receive an authorization failure if you are logged in as
@@ -266,8 +273,8 @@ C<test02>.  Try:
 
     http://localhost:3000/books/url_create/test/1/6
 
-while logged in as each user.  Use one of the 'Logout' links (or go to
-L<http://localhost:3000/logout> in you browser directly) when you are
+while logged in as each user.  Use one of the 'Logout' links (or go to 
+L<http://localhost:3000/logout> in your browser directly) when you are 
 done.
 
 
@@ -275,23 +282,25 @@ done.
 
 This section takes a brief look at how the
 L<Catalyst::Plugin::Authorization::ACL|Catalyst::Plugin::Authorization::ACL>
-plugin can automate much of the work required to perform role-based 
+plugin can automate much of the work required to perform role-based
 authorization in a Catalyst application.
 
+
 =head2 Add the C<Catalyst::Plugin::Authorization::ACL> Plugin
 
 Open C<lib/MyApp.pm> in your editor and add the following plugin to the
-C<use Catalyst> statement:
+C<__PACKAGE__-E<gt>setup> statement:
 
     Authorization::ACL
 
 Note that the remaining C<use Catalyst> plugins from earlier sections
 are not shown here, but they should still be included.
 
+
 =head2 Add ACL Rules to the Application Class
 
 Open C<lib/MyApp.pm> in your editor and add the following B<BELOW> the
-C<__PACKAGE__-E<gt>setup;> statement:
+C<__PACKAGE__-E<gt>setup> statement:
 
     # Authorization::ACL Rules
     __PACKAGE__->deny_access_unless(
@@ -320,14 +329,14 @@ ways.  The following provides a basic overview of the capabilities:
 
 =over 4
 
-=item * 
+=item *
 
 The ACL plugin only operates on the Catalyst "private namespace".  You
 are using the private namespace when you use C<Local> actions.  C<Path>,
 C<Regex>, and C<Global> allow you to specify actions where the path and
 the namespace differ -- the ACL plugin will not work in these cases.
 
-=item * 
+=item *
 
 Each rule is expressed in a separate
 C<__PACKAGE__-E<gt>deny_access_unless()> or
@@ -337,11 +346,11 @@ portion of the
 L<Catalyst::Plugin::Authorization::ACL|Catalyst::Plugin::Authorization::ACL>
 documentation for more details).
 
-=item * 
+=item *
 
 Each rule can contain multiple roles but only a single path.
 
-=item * 
+=item *
 
 The rules are tried in order (with the "most specific" rules tested
 first), and processing stops at the first "match" where an allow or deny
@@ -350,17 +359,18 @@ is specified.  Rules "fall through" if there is not a "match" (where a
 then processing stops there and the appropriate allow/deny action is
 taken.
 
-=item * 
+=item *
 
 If none of the rules match, then access is allowed.
 
-=item * 
+=item *
 
-The rules currently need to be specific in the application class
+The rules currently need to be specified in the application class
 C<lib\MyApp.pm> B<after> the C<__PACKAGE__-E<gt>setup;> line.
 
 =back
 
+
 =head2 Add a Method to Handle Access Violations
 
 By default,
@@ -390,7 +400,7 @@ following method:
         $c->forward('list');
     }
 
-Then run the Catalyst development server script:    
+Then run the Catalyst development server script:
 
     $ script/myapp_server.pl
 
@@ -412,8 +422,8 @@ Kennedy Clark, C<hkclark@gmail.com>
 
 Please report any errors, issues or suggestions to the author.  The
 most recent version of the Catalyst Tutorial can be found at
-L<http://dev.catalyst.perl.org/repos/Catalyst/trunk/Catalyst-Manual/lib/Catalyst/Manual/Tutorial/>.
+L<http://dev.catalyst.perl.org/repos/Catalyst/Catalyst-Manual/5.70/trunk/lib/Catalyst/Manual/Tutorial/>.
 
-Copyright 2006, Kennedy Clark, under Creative Commons License
-(L<http://creativecommons.org/licenses/by-nc-sa/2.5/>).
+Copyright 2006-2008, Kennedy Clark, under Creative Commons License
+(L<http://creativecommons.org/licenses/by-sa/3.0/us/>).