CatalystX-OAuth2

 view release on metacpan or  search on metacpan

lib/Catalyst/ActionRole/OAuth2/AuthToken/ViaAuthGrant.pm  view on Meta::CPAN

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
# ABSTRACT: Authorization token provider endpoint for OAuth2 authentication flows
 
 
with 'https://metacpan.org/pod/CatalystX::OAuth2::ActionRole::Token">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

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
}
 
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

63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
        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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
# ABSTRACT: Authorization token refresh provider endpoint for OAuth2 authentication flows
 
 
with 'https://metacpan.org/pod/CatalystX::OAuth2::ActionRole::Token">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

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
}
 
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

61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
        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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
# ABSTRACT: Authorization grant endpoint for OAuth2 authentication flows
 
 
with 'https://metacpan.org/pod/CatalystX::OAuth2::ActionRole::Grant">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

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
}
 
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

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
      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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
# ABSTRACT: Resource endpoint for OAuth2 authentication flows
 
 
with 'https://metacpan.org/pod/CatalystX::OAuth2::ActionRole::RequestInjector">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

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
}
 
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

57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
      }
    );
 
    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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
use URI;
 
# ABSTRACT: Authorization grant endpoint for OAuth2 authentication flows
 
 
with 'https://metacpan.org/pod/CatalystX::OAuth2::ActionRole::Grant">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

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
}
 
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

58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
      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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
# 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

77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
    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
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

128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
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

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
    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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
# 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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 
# 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

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
use Moose;
 
BEGIN { extends 'https://metacpan.org/pod/Catalyst::Model::DBIC::Schema">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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
use strictures 1;
 
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

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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',



( run in 0.712 second using v1.01-cache-2.11-cpan-a9ef4e587e4 )