package Amon2::Plugin::Web::Auth; use strict; use warnings; use 5.008001; our $VERSION = '0.01'; use Plack::Util; use URI::WithBase; sub init { my ($class, $c, $code_conf) = @_; my $module = $code_conf->{module} or die "Missing mandatory parameter: module"; my $klass = Plack::Util::load_class($code_conf->{module}, 'Amon2::Auth::Site'); my $moniker = $klass->moniker; my $authenticate_path = $code_conf->{authenticate_path} || "/auth/${moniker}/authenticate"; my $callback_path = $code_conf->{callback_path} || "/auth/${moniker}/callback"; # handlers my $on_finished = $code_conf->{on_finished} or die "Missing mandatory parameter: on_finished"; my $on_error = $code_conf->{on_error} || sub { my ($c, $err) = @_; die "Authentication error in $module: $err"; }; # auth object my $conf = $c->config->{'Auth'}->{$module} || die "Missing configuration for Auth.${module}"; my $auth = $klass->new($conf); if (exists $code_conf->{user_info}) { $auth->user_info($code_conf->{user_info}); } $c->add_trigger(BEFORE_DISPATCH => sub { my $c = shift; my $path_info = $c->req->path_info; if ($path_info eq $authenticate_path) { my $callback = URI::WithBase->new($callback_path, $c->req->base); return $c->redirect($auth->auth_uri($c, $callback->abs->as_string)); } elsif ($path_info eq $callback_path) { return $auth->callback($c, { on_finished => sub { $on_finished->($c, @_); }, on_error => sub { $on_error->($c, @_); }, }); } else { return undef; # DECLINED } }); } 1; __END__ =encoding utf8 =head1 NAME Amon2::Plugin::Web::Auth - auth with SNS =head1 SYNOPSIS package MyApp::Web; # simple usage # more configurable... __PACKAGE__->load_plugin( 'Web::Auth' => { module => 'Facebook', on_finished => sub { my ($c, $token, $user) = @_; ... } } ); =head1 DESCRIPTION Amon2::Plugin::Web::Auth is authentication engine for Amon2. B. =head1 CONFIGURATION IN CODE =over 4 =item module This is a module name for authentication plugins. You can write 'Amon2::Auth::Site::Facebook' as 'Facebook' in this part. If you want to use your own authentication module, you can write it as '+My::Own::Auth::Module' like DBIx::Class. __PACKAGE__->load_plugin( 'Web::Auth' => { module => 'Twitter', ... } ); # or __PACKAGE__->load_plugin( 'Web::Auth' => { module => '+My::Own::Auth::Module', ... } ); =item on_finished This is a callback when authentication flow was finished. You MUST return a response object in this callback function. You MAY return the response of C<< $c->redirect() >>. __PACKAGE__->load_plugin('Web::Auth', { module => 'Github', on_finished => sub { my ($c, $token, $user) = @_; my $gihtub_id = $user->{id} || die; my $github_name = $user->{name} || die; $c->session->set('name' => $github_name); $c->session->set('site' => 'github'); return $c->redirect('/'); } }); The arguments of this callback function is a auth module specific. =item user_info In auth module that uses OAuth2, is not required to fetch user information, just get a access_token. If you don't need a user information, you can set false value on this attribute. This attribute is true by default on most modules for your laziness. =item on_error Auth module calls this callback function when error occurred. Arguments are following format. my ($c, $err) = @_; The default value is following. sub { my ($c, $err) = @_; die "Authentication error in $module: $err"; } =back =head1 AUTHOR Tokuhiro Matsuno Etokuhirom AAJKLFJEF GMAIL COME =head1 SEE ALSO =head1 LICENSE Copyright (C) Tokuhiro Matsuno This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut