preaction / Yancy

The Best Web Framework Deserves the Best Content Management System
http://preaction.me/yancy/
Other
54 stars 21 forks source link

Create admin superuser #81

Closed pavelsr closed 5 years ago

pavelsr commented 5 years ago

Is there any method to create admin superuser like in Django ? https://docs.djangoproject.com/en/2.2/intro/tutorial02/#creating-an-admin-user I haven't found anything in docs. If there is no such method - it would be nice to add it.

preaction commented 5 years ago

Yancy doesn't yet have a built-in mechanism for user roles (see #62). What it does have is require_user, which can be used to build simple authorization methods (like an admin boolean field).

I haven't written about this yet (I got a bit burned out from blogging), but here's a quick overview:

Once you've configured an auth plugin, you have access to two helpers: yancy.auth.current_user and yancy.auth.require_user. The current_user helper gets the current user item, with all of the fields the user schema has. The require_user helper returns a subref to be used in an under route. The require_user helper can be passed data that the user must have to be allowed in (using Yancy::Util match()).

use Mojolicious::Lite;
plugin Yancy => {
    backend => ...,
    schema => {
        users => {
            'x-id-field' => 'username',
            properties => {
                username => { type => 'string' },
                password => { type => 'string', format => 'password' },
                is_admin => { type => 'boolean', default => 0 },
            },
        },
    },
};
app->yancy->plugin( 'Auth' => {
    schema => 'users',
    username_field => 'username',
    plugins => [
        [ Password => {
            password_field => 'password',
            password_digest => { type => 'SHA-1' },
        } ],
    ],
} );

# User /user, require any logged-in user
my $user_route = app->routes->under(
    '/user',
    app->yancy->auth->require_user,
);
$user_route->get( '' )->name( 'user' );

# Under /admin, require a logged-in user with `is_admin` set to true
my $admin_route = app->routes->under(
    '/admin',
    app->yancy->auth->require_user( { is_admin => 1 } ),
);
$admin_route->get( '' )->name( 'admin' );

app->start;
__END__
@@ admin.html.ep
Hello, <%= yancy->auth->current_user->{username} %>, you're an admin!
@@ user.html.ep
Hello, <%= yancy->auth->current_user->{username} %>, you're logged-in!

So, if you create an is_admin field in your users table, you can create new admins on the command-line with the eval command:

$ ./myapp.pl eval 'app->yancy->create( users => { username => "admin", password => "admin", is_admin => 1 } )'

I'll keep this ticket open to create a guide for users authentication and authorization. Let me know if you have any questions.