view release on metacpan or search on metacpan
lib/Catalyst/ActionRole/OAuth2/AuthToken/ViaAuthGrant.pm view on Meta::CPAN
package Catalyst::ActionRole::OAuth2::AuthToken::ViaAuthGrant;
use Moose::Role;
use Try::Tiny;
use CatalystX::OAuth2::Request::AuthToken;
# ABSTRACT: Authorization token provider endpoint for OAuth2 authentication flows
with 'CatalystX::OAuth2::ActionRole::Token';
sub build_oauth2_request {
my ( $self, $controller, $c ) = @_;
my $store = $controller->store;
my $req;
lib/Catalyst/ActionRole/OAuth2/AuthToken/ViaAuthGrant.pm view on Meta::CPAN
}
1;
__END__
=pod
=head1 NAME
Catalyst::ActionRole::OAuth2::AuthToken::ViaAuthGrant - Authorization token provider endpoint for OAuth2 authentication flows
=head1 VERSION
version 0.001009
=head1 SYNOPSIS
package AuthServer::Controller::OAuth2::Provider;
use Moose;
lib/Catalyst/ActionRole/OAuth2/AuthToken/ViaAuthGrant.pm view on Meta::CPAN
client_model => 'DB::Client'
}
);
sub token : Chained('/') Args(0) Does('OAuth2::AuthToken::ViaAuthGrant') {}
1;
=head1 DESCRIPTION
This action role implements an endpoint that exchanges an authorization code
for an access token.
=head1 AUTHOR
Eden Cardim <edencardim@gmail.com>
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2017 by Suretec Systems Ltd.
lib/Catalyst/ActionRole/OAuth2/AuthToken/ViaRefreshToken.pm view on Meta::CPAN
package Catalyst::ActionRole::OAuth2::AuthToken::ViaRefreshToken;
use Moose::Role;
use Try::Tiny;
use CatalystX::OAuth2::Request::RefreshToken;
# ABSTRACT: Authorization token refresh provider endpoint for OAuth2 authentication flows
with 'CatalystX::OAuth2::ActionRole::Token';
sub build_oauth2_request {
my ( $self, $controller, $c ) = @_;
my $store = $controller->store;
my $req;
lib/Catalyst/ActionRole/OAuth2/AuthToken/ViaRefreshToken.pm view on Meta::CPAN
}
1;
__END__
=pod
=head1 NAME
Catalyst::ActionRole::OAuth2::AuthToken::ViaRefreshToken - Authorization token refresh provider endpoint for OAuth2 authentication flows
=head1 VERSION
version 0.001009
=head1 SYNOPSIS
package AuthServer::Controller::OAuth2::Provider;
use Moose;
lib/Catalyst/ActionRole/OAuth2/AuthToken/ViaRefreshToken.pm view on Meta::CPAN
client_model => 'DB::Client'
}
);
sub refresh : Chained('/') Args(0) Does('OAuth2::AuthToken::ViaRefreshToken') {}
1;
=head1 DESCRIPTION
This action role implements an endpoint that exchanges a refresh token for an
access token.
=head1 AUTHOR
Eden Cardim <edencardim@gmail.com>
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2017 by Suretec Systems Ltd.
lib/Catalyst/ActionRole/OAuth2/GrantAuth.pm view on Meta::CPAN
package Catalyst::ActionRole::OAuth2::GrantAuth;
use Moose::Role;
use Try::Tiny;
use CatalystX::OAuth2::Request::GrantAuth;
# ABSTRACT: Authorization grant endpoint for OAuth2 authentication flows
with 'CatalystX::OAuth2::ActionRole::Grant';
sub build_oauth2_request {
my ( $self, $controller, $c ) = @_;
my $store = $controller->store;
my $req;
try {
lib/Catalyst/ActionRole/OAuth2/GrantAuth.pm view on Meta::CPAN
}
1;
__END__
=pod
=head1 NAME
Catalyst::ActionRole::OAuth2::GrantAuth - Authorization grant endpoint for OAuth2 authentication flows
=head1 VERSION
version 0.001009
=head1 SYNOPSIS
package AuthServer::Controller::OAuth2::Provider;
use Moose;
BEGIN { extends 'Catalyst::Controller::ActionRole' }
lib/Catalyst/ActionRole/OAuth2/GrantAuth.pm view on Meta::CPAN
my ( $self, $c ) = @_;
my $oauth2 = $c->req->oauth2;
$c->user_exists and $oauth2->user_is_valid(1)
or $c->detach('/passthrulogin');
}
=head1 DESCRIPTION
This action role implements the authorization confirmation endpoint that asks
the user if he wishes to grant resource access to the client. This is
generally done by presenting a form to the user. Regardless of the mechanism
used for this confirmation, the C<$c->req->oauth2> object must be informed of
the user's decision via the C<user_is_valid> attribute, which must be true by
the end of the request, in order for the authorization flow to be continued.
=head1 AUTHOR
Eden Cardim <edencardim@gmail.com>
lib/Catalyst/ActionRole/OAuth2/ProtectedResource.pm view on Meta::CPAN
package Catalyst::ActionRole::OAuth2::ProtectedResource;
use Moose::Role;
use CatalystX::OAuth2::Request::ProtectedResource;
# ABSTRACT: Resource endpoint for OAuth2 authentication flows
with 'CatalystX::OAuth2::ActionRole::RequestInjector';
sub build_oauth2_request {
my ( $self, $controller, $c ) = @_;
my $auth = $c->req->header('Authorization')
or $c->res->status(401), $c->detach;
my ( $type, $token ) = split ' ', $auth;
lib/Catalyst/ActionRole/OAuth2/ProtectedResource.pm view on Meta::CPAN
}
1;
__END__
=pod
=head1 NAME
Catalyst::ActionRole::OAuth2::ProtectedResource - Resource endpoint for OAuth2 authentication flows
=head1 VERSION
version 0.001009
=head1 SYNOPSIS
package AuthServer::Controller::OAuth2::Resource;
use Moose;
lib/Catalyst/ActionRole/OAuth2/ProtectedResource.pm view on Meta::CPAN
}
);
sub resource : Chained('/') Args(0) Does('OAuth2::ProtectedResource') {
my ( $self, $c ) = @_;
$c->res->body( 'my protected resource' );
}
=head1 DESCRIPTION
This action role implements an arbitrary resource endpoint to be protected by
the authorization flow. Clients will only be able to access this resource if
they provide a valid access token. The action body should be customized like a
regular action.
=head1 AUTHOR
Eden Cardim <edencardim@gmail.com>
=head1 COPYRIGHT AND LICENSE
lib/Catalyst/ActionRole/OAuth2/RequestAuth.pm view on Meta::CPAN
package Catalyst::ActionRole::OAuth2::RequestAuth;
use Moose::Role;
use Try::Tiny;
use URI;
use CatalystX::OAuth2::Request::RequestAuth;
# ABSTRACT: Authorization grant endpoint for OAuth2 authentication flows
with 'CatalystX::OAuth2::ActionRole::Grant';
has enable_client_secret => ( isa => 'Bool', is => 'ro', default => 0 );
sub build_oauth2_request {
my ( $self, $controller, $c ) = @_;
my $store = $controller->store;
lib/Catalyst/ActionRole/OAuth2/RequestAuth.pm view on Meta::CPAN
}
1;
__END__
=pod
=head1 NAME
Catalyst::ActionRole::OAuth2::RequestAuth - Authorization grant endpoint for OAuth2 authentication flows
=head1 VERSION
version 0.001009
=head1 SYNOPSIS
package AuthServer::Controller::OAuth2::Provider;
use Moose;
BEGIN { extends 'Catalyst::Controller::ActionRole' }
lib/Catalyst/ActionRole/OAuth2/RequestAuth.pm view on Meta::CPAN
store => {
class => 'DBIC',
client_model => 'DB::Client'
}
);
sub request : Chained('/') Args(0) Does('OAuth2::RequestAuth') {}
=head1 DESCRIPTION
This action role implements the initial endpoint that triggers the
authorization grant flow. It generates an inactive authorization code
redirects to the next action in the workflow if all parameters are valid. The
authorization code is used to verify the validity of the arguments in the
subsequent request of the flow and prevent users of this library from creating
potentially unsafe front-end forms for user confirmation of the authorization.
=head1 AUTHOR
Eden Cardim <edencardim@gmail.com>
lib/CatalystX/OAuth2.pm view on Meta::CPAN
package CatalystX::OAuth2;
use Moose::Role;
# ABSTRACT: OAuth2 services for Catalyst
requires '_build_query_parameters';
# spec isn't clear re missing endpoint uris
has redirect_uri => ( is => 'ro', required => 0 );
has store => (
is => 'rw',
does => 'CatalystX::OAuth2::Store',
init_arg => undef,
predicate => 'has_store'
);
has query_parameters => ( is => 'rw', init_arg => undef, lazy_build => 1 );
lib/CatalystX/OAuth2.pm view on Meta::CPAN
sub token : Chained('/') Args(0) Does('OAuth2::AuthToken::ViaAuthGrant') {}
sub refresh : Chained('/') Args(0) Does('OAuth2::AuthToken::ViaRefreshToken') {}
1;
=head1 DESCRIPTION
This module implements the authorization grant subset of the L<oauth 2 ietf
spec draft|http://tools.ietf.org/html/draft-ietf-oauth-v2-23>. Action roles
containing an implementation of each required endpoint in the specification
are provided and should be applied to a L<Catalyst::Controller::ActionRole>.
The authorization grant flow is defined by the specification as follows:
+--------+ +---------------+
| |--(A)------- Authorization Grant --------->| |
| | | |
| |<-(B)----------- Access Token -------------| |
| | & Refresh Token | |
| | | |
| | +----------+ | |
lib/CatalystX/OAuth2.pm view on Meta::CPAN
request parameters if a valid authorization code is presented.
=item B - L<Catalyst::ActionRole::OAuth2::GrantAuth>
Required
This action checks the request parameters for a valid authorization code,
which should have been generated by a previous request to a RequestAuth
action. This action should be customized to somehow confirm with the end-user
if he wishes to effectively grant the authorization to the requesting
client/app. The user-agent is redirected automatically to the correct endpoint
if the authorization is granted.
=item C and D - L<Catalyst::ActionRole::OAuth2::AuthToken::ViaAuthGrant>
Required
This action exchanges a valid authorization grant code and responds with an
authorization token.
=item G and H - L<Catalyst::ActionRole::OAuth2::AuthToken::ViaRefreshToken>
lib/CatalystX/OAuth2/Request/RequestAuth.pm view on Meta::CPAN
or return {
error => 'unauthorized_client',
error_description => 'the client identified by '
. $self->client_id
. ' is not authorized to access this resource'
}
if $self->enable_client_secret;
$q{client_id} = $self->client_id;
$client->endpoint eq $self->redirect_uri
or return {
error => 'invalid_request',
error_description =>
'redirection_uri does not match the registered client endpoint'
};
$q{redirect_uri} = $self->redirect_uri;
my $code = $store->create_client_code( $self->client_id );
$q{code} = $code->as_string;
return \%q;
}
lib/CatalystX/OAuth2/Schema/Result/Client.pm view on Meta::CPAN
package CatalystX::OAuth2::Schema::Result::Client;
use parent 'DBIx::Class';
# ABSTRACT: A table for registering clients
__PACKAGE__->load_components(qw(Core));
__PACKAGE__->table('client');
__PACKAGE__->add_columns(
id => { data_type => 'int', is_auto_increment => 1 },
endpoint => { data_type => 'text', is_nullable => 0 },
client_secret => { data_type => 'text', is_nullable => 1 }
);
__PACKAGE__->set_primary_key('id');
__PACKAGE__->has_many( codes => 'CatalystX::OAuth2::Schema::Result::Code' =>
{ 'foreign.client_id' => 'self.id' } );
sub find_refresh {
shift->codes->search( { is_active => 1 } )
->related_resultset('refresh_tokens')->find(@_);
}
lib/CatalystX/OAuth2/Store.pm view on Meta::CPAN
package CatalystX::OAuth2::Store;
use Moose::Role;
# ABSTRACT: The API for oauth2 stores
requires qw(
find_client
client_endpoint
create_client_code
client_code_is_active
activate_client_code
deactivate_client_code
create_access_token
find_client_code
verify_client_secret
verify_client_token
);
lib/CatalystX/OAuth2/Store/DBIC.pm view on Meta::CPAN
has client_model => (
isa => 'Str',
is => 'ro',
required => 1
);
has _client_model => (
isa => 'DBIx::Class::ResultSet',
is => 'ro',
lazy_build => 1
);
has endpoint_field => ( isa => 'Str', is => 'ro', default => 'endpoint' );
has refresh_relation =>
( isa => 'Str', is => 'ro', default => 'refresh_tokens' );
has token_relation => ( isa => 'Str', is => 'ro', default => 'tokens' );
has code_relation => ( isa => 'Str', is => 'ro', default => 'codes' );
has code_activation_field =>
( isa => 'Str', is => 'ro', default => 'is_active' );
sub _build__client_model {
my ($self) = @_;
return $self->app->model( $self->client_model );
}
sub find_client {
my ( $self, $id ) = @_;
$self->_client_model->find($id);
}
sub client_endpoint {
my ( $self, $id ) = @_;
my $client = $self->find_client($id)
or return;
return $client->get_column( $self->endpoint_field );
}
sub _code_rs {
my ( $self, $id ) = @_;
return $self->_client_model->related_resultset( $self->code_relation )
unless defined($id);
my $client = $self->find_client($id)
or return;
return $client->related_resultset( $self->code_relation );
}
t/lib/AuthServer/Model/DB.pm view on Meta::CPAN
package AuthServer::Model::DB;
use Moose;
BEGIN { extends 'Catalyst::Model::DBIC::Schema' }
has user_endpoint =>
( isa => 'Str', is => 'ro', default => sub {'http://localhost/auth'} );
__PACKAGE__->config(
schema_class => 'CatalystX::OAuth2::Schema',
connect_info => [ 'dbi:SQLite:dbname=:memory:', '', '' ]
);
around COMPONENT => sub {
my $orig = shift;
my $class = shift;
my $self = $class->$orig(@_);
$self->schema->deploy;
$self->schema->resultset('Client')
->create(
{ endpoint => $self->user_endpoint, client_secret => 'foosecret' } );
return $self;
};
1;
t/unit/300-actionrole-grant-auth.t view on Meta::CPAN
use strictures 1;
use Test::More;
use HTTP::Request::Common;
use lib 't/lib';
use Catalyst::Test 'AuthServer';
my $code =
AuthServer->model('DB::Code')
->create( { client => { endpoint => '/client/foo' } } );
# try grant with invalid code and no approval param
# should display form
{
my $uri = URI->new('/grant');
$uri->query_form(
{ response_type => 'code',
client_id => 1,
state => 'bar',
code => 999999,
t/unit/400-actionrole-auth-token-via-auth-grant.t view on Meta::CPAN
use Test::More;
use JSON::Any;
use HTTP::Request::Common;
use lib 't/lib';
use Catalyst::Test 'AuthServer';
my $json = JSON::Any->new;
my $code = AuthServer->model('DB::Code')
->create( { client => { endpoint => '/client/foo' } } );
{
my $uri = URI->new('/token');
$uri->query_form(
{ grant_type => 'authorization_code',
redirect_uri => '/client/foo',
code => $code->as_string
}
);
my ($res2, $c) = ctx_request($uri);
t/unit/500-actionrole-auth-token-via-refresh-token.t view on Meta::CPAN
use Test::More;
use JSON::Any;
use HTTP::Request::Common;
use lib 't/lib';
use Catalyst::Test 'AuthServer';
my $json = JSON::Any->new;
my $code = AuthServer->model('DB::Code')->create(
{ client => { endpoint => '/client/foo' },
is_active => 1
}
);
my $refresh;
{
my $uri = URI->new('/withrefresh/token');
$uri->query_form(
{ grant_type => 'authorization_code',