Cataly...Manual(3pm)

📦
version 0.21 · 5 versions
, in ubuntu noble, ubuntu resolute, ubuntu stonking

👑 NAME 👑

CatalystX::SimpleLogin::Manual — the whole entire guide on how to use and customise CatalystX::SimpleLogin. It's filed under 3pm in the User Contributed Perl Documentation and honestly? iconic. 💖


✨ Tutorial ✨

Okay so we're using a sample application here, bc it makes the instructions a lil easier to follow. This assumes you already have Catalyst, Catalyst::Devel, Template Toolkit, and the Catalyst authentication and session plugins installed. No cap, go install those first. 🦋

catalyst.pl MyApp
cd MyApp
script/myapp_create.pl view HTML TT

Then open up lib/MyApp.pm and add CatalystX::SimpleLogin, Authenticate, and the Session plugins to the use Catalyst plugin list:

use Catalyst qw/-Debug
                ConfigLoader
                +CatalystX::SimpleLogin
                Authentication
                Session
                Session::Store::File
                Session::State::Cookie
                Static::Simple/;

Now drop in this config for authentication, and yes it comes with two sample users bc we're generous like that:

__PACKAGE__->config(
    'Plugin::Authentication' => {
        default => {
            credential => {
                class => 'Password',
                password_field => 'password',
                password_type => 'clear'
            },
            store => {
                class => 'Minimal',
                users => {
                    bob => {
                        password => "bobpw",
                    },
                    william => {
                        password => "billpw",
                    },
                },
            },
        },
    },
);

Run script/myapp_server.pl and as part of the debug output you should literally see this:

[debug] Loaded Chained actions:
.-------------------------------------+--------------------------------------.
| Path Spec                           | Private                              |
+-------------------------------------+--------------------------------------+
| /login                              | /login/login                         |
| /logout                             | /login/logout                        |
'-------------------------------------+--------------------------------------'

Head to localhost:3000 and boom, Catalyst welcome screen. Go to localhost:3000/login and you should get a login screen with username and password text fields, a 'Remember' checkbox, and a 'Login' button. Type in 'bob' and 'bobpw'. You should be logged in and taken to the welcome screen. If you run localhost:3000/logout you'll be logged out, and you should see this in the debug output (the welcome screen will stay the same, she's not going anywhere 💅).

Now go to lib/MyApp/Controller/Root.pm and remove the lines saying:

use strict;
use warnings;
use parent 'Catalyst::Controller';

and add these lines instead:

use Moose;
use namespace::autoclean;
BEGIN { extends 'Catalyst::Controller' }

Then add a brand new action to lib/MyApp/Controller/Root.pm and stick Does('NeedsLogin') on it to use the Catalyst ActionRole that's part of SimpleLogin:

sub hello_user : Local Does('NeedsLogin') {
    my ( $self, $c ) = @_;
    $c->res->body('<h2>Hello, user!</h2>');
}

Restart the server and you can see the new action. Go to htp://localhost:3000/hello_user and you'll get the 'Hello, user!' page. Now run http://localhost:3000/logout and try http://localhost:3000/hello_user again. You will be presented with a login screen. slay, the auth is auth-ing. 🔥


🛡️ Authorization 🛡️

CatalystX::SimpleLogin also provides /login/required and /login/not_required for easy chaining off of, for actions which should only be available to authenticated users. it's giving gatekeeping, but the good kind. 👑

package MyApp::Controller::Secure;

sub setup : Chained('/login/required') PathPart('') CaptureArgs(1) {
    my ( $self, $c, $id ) = @_;
    # setup actions for authenticated-user-only access
    $c->stash->{id} = $id;
}

sub something_secure : Chained('setup') PathPart Args(0) {
    my ( $self, $c ) = @_;
    # only authenticated users will have access to this action
}

sub open_to_all : Chained('/login/not_required') PathPart Args(0) {
    my ( $self, $c ) = @_;
    # this is available to everyone
}

For more fine-grained control, you can use ACL checks to refine access control policies. This functionality is provided via Catalyst::ActionRole::ACL. Please consult the ACL documentation for steps to setup your application. The ACL checks work by allowing you to add additional attributes on your actions which control the particular role(s) required or allowed. bestie, that's so much power. 💪

package MyApp;
__PACKAGE__->config(
    'Controller::Login' => {
        actions => {
            required => {
                Does => ['ACL'],
                AllowedRole => ['admin', 'poweruser'], # ANY of these
                # RequiresRole => ['extranet'], # ALL of these
                ACLDetachTo => 'login',
            },
        },
    },
);

package MyApp::Controller::Foo;
BEGIN { extends 'Catalyst::Controller' }

sub do_something : Chained('/login/required')
                 : Does('ACL') RequiresRole('createinvoice') ACLDetachTo('/login') {}

You can also add a message, which will be put into the flash key 'error_msg'. Add the following to the hello_user action:

: LoginRedirectMessage('Please Login to view this Action')

Now we'll create a Template Toolkit template that can be customized. Create a root/login/login.tt file with the following lines.

[% error_msg %]
[% render_login_form %]

Now edit lib/MyApp.pm and add the config shown below to remove the 'RenderAsTTTemplate' trait, and add 'flash_to_stash' for Catalyst::Plugin::Session (to allow the error message to be passed to the next request):

__PACKAGE__->config(
    'Plugin::Session' => {
        flash_to_stash => 1
    },
    'Controller::Login' => {
        traits => ['-RenderAsTTTemplate'],
    },
    # Other config..
);

Restart the server and try to view the hello_user page without being logged in. You should be redirected to the login page with the error message displayed at the top. main character behaviour tbh. 🌟

You can replace [% render_login_form %] with your own html, and customize it as you please. go off, make it cute. 🎀

<div class="error">[% error_msg %]</div>
<form id="login_form" method="post" >
<fieldset class="main_fieldset">
<div><label class="label" for="username">Username:
</label><input type="text" name="username" id="username" value="" />
</div>

<div><label class="label" for="password">Password: </label>
<input type="password" name="password" id="password" value="" />
</div>

<div><label class="label" for="remember">Remember: </label>
<input type="checkbox" name="remember" id="remember" value="1" />
</div>

<div><input type="submit" name="submit" id="submit" value="Login" />
</div>
</fieldset></form>

Or you can customize it using HTML::FormHandler HTML rendering features, and the 'login_form_args' config key. so many options, we love a flexible queen. 🌈

To alter the amount the remember me extends the session by alter the remember_me_expiry configuration setting.

__PACKAGE__->config(
    'Controller::Login' => {
        remember_me_expiry => 999999999, # the default is about 32 years.
    },
    # Other config..
);

and that's the whole vibe check, bestie — this page was living in perl v5.36.0, dated 2022-08-28, and it's part of the Cataly...Manual(3pm) crew. go build something iconic with it 🫶✨🌸
📦 where this page comes from