Catalyst::Manual is now in the correct state.
[catagits/Catalyst-Manual.git] / lib / Catalyst / Manual / Tutorial / Tutorial / Authorization.pod
diff --git a/lib/Catalyst/Manual/Tutorial/Tutorial/Authorization.pod b/lib/Catalyst/Manual/Tutorial/Tutorial/Authorization.pod
deleted file mode 100644 (file)
index 9af1ce3..0000000
+++ /dev/null
@@ -1,413 +0,0 @@
-=head1 NAME
-
-Catalyst::Manual::Tutorial::Authorization - Catalyst Tutorial - Part 5: Authorization
-
-
-=head1 OVERVIEW
-
-This is B<Part 5 of 9> for the Catalyst tutorial.
-
-L<Tutorial Overview|Catalyst::Manual::Tutorial>
-
-=over 4
-
-=item 1
-
-L<Introduction|Catalyst::Manual::Tutorial::Intro>
-
-=item 2
-
-L<Catalyst Basics|Catalyst::Manual::Tutorial::CatalystBasics>
-
-=item 3
-
-L<Basic CRUD|Catalyst::Manual::Tutorial_BasicCRUD>
-
-=item 4
-
-L<Authentication|Catalyst::Manual::Tutorial::Authentication>
-
-=item 5
-
-B<Authorization>
-
-=item 6
-
-L<Debugging|Catalyst::Manual::Tutorial::Debugging>
-
-=item 7
-
-L<Testing|Catalyst::Manual::Tutorial::Testing>
-
-=item 8
-
-L<AdvancedCRUD|Catalyst::Manual::Tutorial::AdvancedCRUD>
-
-=item 9
-
-L<Appendices|Catalyst::Manual::Tutorial::Appendices>
-
-=back
-
-
-
-=head1 DESCRIPTION
-
-This part of the tutorial adds role-based authorization to the existing
-authentication implemented in Part 4.  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>
-
-=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/
-            -Debug
-            ConfigLoader
-            Static::Simple
-            
-            StackTrace
-            
-            Authentication
-            Authentication::Store::DBIC
-            Authentication::Credential::Password
-            Authorization::Roles
-            
-            Session
-            Session::Store::FastMmap
-            Session::State::Cookie
-            /;
-
-
-=head2 Add Config Information for Authorization
-
-Edit C<myapp.yml> and update it to match (everything from the
-"authorization:" line down is new):
-
-    ---
-    name: MyApp
-    authentication:
-        dbic:
-            # Note this first definition would be the same as setting
-            # __PACKAGE__->config->{authentication}->{dbic}->{user_class} = 'MyAppDB::User'
-            # in lib/MyApp.pm (IOW, each hash key becomes a "name:" in the YAML file).
-            #
-            # This is the model object created by Catalyst::Model::DBIC from your
-            # schema (you created 'MyAppDB::User' but as the Catalyst startup
-            # debug messages show, it was loaded as 'MyApp::Model::MyAppDB::User').
-            # NOTE: Omit 'MyApp::Model' here just as you would when using 
-            # '$c->model("MyAppDB::User)'
-            user_class: MyAppDB::User
-            # This is the name of the field in your 'users' table that contains the user's name
-            user_field: username
-            # This is the name of the field in your 'users' table that contains the password
-            password_field: password
-            # Other options can go here for hashed passwords
-            # Enabled hashed passwords
-            password_type: hashed
-            # Use the SHA-1 hashing algorithm
-            password_hash_type: SHA-1
-    authorization:
-        dbic:
-            # This is the model object created by Catalyst::Model::DBIC from your
-            # schema (you created 'MyAppDB::Role' but as the Catalyst startup
-            # debug messages show, it was loaded as 'MyApp::Model::MyAppDB::Role').
-            # NOTE: Omit 'MyApp::Model' here just as you would when using 
-            # '$c->model("MyAppDB::User)'
-            role_class: MyAppDB::Role
-            # The name of the field in the 'roles' table that contains the role name
-            role_field: role
-            # The name of the accessor used to map a role to the users who have this role
-            # See the has_many() in MyAppDB/Role.pm
-            role_rel: map_user_role
-            # The name of the field in the user_role table that references the user
-            user_role_user_field: user_id
-
-
-=head2 Add Role-Specific Logic to the "Book List" Template
-
-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>
-    
-    <ul>
-      [% # Dump list of roles -%]
-      [% FOR role = Catalyst.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') %]
-      [% # Give normal users a link for 'logout' %]
-      <a href="[% Catalyst.uri_for('/logout') %]">Logout</a>
-    [% END %]
-    
-    [% # Can also use $c->user->check_roles() to check authz -%]
-    [% IF Catalyst.check_user_roles('admin') %]
-      [% # Give admin users a link for 'create' %]
-      <a href="[% Catalyst.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
-to the user's browser; it provides no real enforcement (if users know or
-guess the appropriate URLs, they are still perfectly free to hit any
-action within your application).  We need to enhance the controller
-logic to wrap restricted actions with role-validation logic.
-
-For example, we might want to restrict the "formless create" action to
-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
-    
-    =cut
-    
-    sub url_create : Local {
-        # In addition to self & context, get the title, rating & author_id args
-        # from the URL.  Note that Catalyst automatically puts extra information
-        # after the "/<controller_name>/<action_name/" into @_
-        my ($self, $c, $title, $rating, $author_id) = @_;
-    
-        # Check the user's roles
-        if ($c->check_user_roles('admin')) {
-            # Call create() on the book model object. Pass the table 
-            # columns/field values we want to set as hash values
-            my $book = $c->model('MyAppDB::Book')->create({
-                    title   => $title,
-                    rating  => $rating
-                });
-            
-            # 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 
-            # hurt anything either.
-            $Data::Dumper::Useperl = 1;
-        
-            # Set the TT template to use
-            $c->stash->{template} = 'books/create_done.tt2';
-        } else {
-            # Provide very simple feedback to the user
-            $c->response->body('Unauthorized!');
-        }
-    }
-
-
-To add authorization, we simply wrap the main code of this method in an
-C<if> statement that calls C<check_user_roles>.  If the user does not
-have the appropriate permissions, they receive an "Unauthorized!"
-message.  Note that we intentionally chose to display the message this
-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).
-
-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
-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 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
-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
-done.
-
-
-=head1 ENABLE ACL-BASED AUTHORIZATION
-
-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 
-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:
-
-    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:
-
-    # Authorization::ACL Rules
-    __PACKAGE__->deny_access_unless(
-            "/books/form_create",
-            [qw/admin/],
-        );
-    __PACKAGE__->deny_access_unless(
-            "/books/form_create_do",
-            [qw/admin/],
-        );
-    __PACKAGE__->deny_access_unless(
-            "/books/delete",
-            [qw/user admin/],
-        );
-
-Each of the three statements above comprises an ACL plugin "rule".  The
-first two rules only allow admin-level users to create new books using
-the form (both the form itself and the data submission logic are
-protected).  The third statement allows both users and admins to delete
-books.  The C</books/url_create> action will continue to be protected by
-the "manually configured" authorization created earlier in this part of
-the tutorial.
-
-The ACL plugin permits you to apply allow/deny logic in a variety of
-ways.  The following provides a basic overview of the capabilities:
-
-=over 4
-
-=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 * 
-
-Each rule is expressed in a separate
-C<__PACKAGE__-E<gt>deny_access_unless()> or
-C<__PACKAGE__-E<gt>allow_access_if()> line (there are several other
-methods that can be used for more complex policies, see the C<METHODS>
-portion of the
-L<Catalyst::Plugin::Authorization::ACL|Catalyst::Plugin::Authorization::ACL>
-documentation for more details).
-
-=item * 
-
-Each rule can contain multiple roles but only a single path.
-
-=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
-is specified.  Rules "fall through" if there is not a "match" (where a
-"match" means the user has the specified role).  If a "match" is found,
-then processing stops there and the appropriate allow/deny action is
-taken.
-
-=item * 
-
-If none of the rules match, then access is allowed.
-
-=item * 
-
-The rules currently need to be specific 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,
-L<Catalyst::Plugin::Authorization::ACL|Catalyst::Plugin::Authorization::ACL>
-throws an exception when authorization fails.  This will take the user
-to the Catalyst debug screen, or a "Please come back later" message if
-you are not using the C<-Debug> flag. This step uses the
-C<access_denied> method in order to provide more appropriate feedback to
-the user.
-
-Open C<lib/MyApp/Controller/Books.pm> in your editor and add the
-following method:
-
-    =head2 access_denied
-    
-    Handle Catalyst::Plugin::Authorization::ACL access denied exceptions
-    
-    =cut
-    
-    sub access_denied : Private {
-        my ($self, $c) = @_;
-    
-        # Set the error message
-        $c->stash->{error_msg} = 'Unauthorized!';
-    
-        # Display the list
-        $c->forward('list');
-    }
-
-Then run the Catalyst development server script:    
-
-    $ script/myapp_server.pl
-
-Log in as C<test02>.  Once at the book list, click the "Create" link to
-try the C<form_create> action.  You should receive a red "Unauthorized!"
-error message at the top of the list.  (Note that in reality you would
-probably want to place the "Create" link code in
-C<root/src/books/list.tt2> inside an C<IF> statement that only displays
-the list to admin-level users.)  If you log in as C<test01> you should
-be able to view the C<form_create> form and add a new book.
-
-When you are done, use one of the 'Logout' links (or go to the
-L<http://localhost:3000/logout> URL directly) when you are done.
-
-
-=head1 AUTHOR
-
-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-Runtime/lib/Catalyst/Manual/Tutorial/>.
-
-Copyright 2006, Kennedy Clark, under Creative Commons License
-(L<http://creativecommons.org/licenses/by-nc-sa/2.5/>).
-