payprop / net-oauth2-authorizationserver

Module to implement core functions of an OAuth2 authorization server
7 stars 10 forks source link

[oauth2_server_db.pl] Can't locate object method "db" via package "response_type" (perhaps you forgot to load "response_type"?) at oauth2_server_db.pl line 85. #19

Closed muenalan closed 6 years ago

muenalan commented 6 years ago

Hi,

The simple examples work by-the-way. Seems that the callbacks don't get the controller as the first argument, to me. I suspect the MongoDB::Client new API changes are the culprit ?

80 };
81  
82 my $verify_client_sub = sub {
83 my ( $c,$client_id,$scopesref ) = @;
84  
85 if (
86 my $client = $c->db->get_collection( 'clients' )
87 ->find_one({ client_id => $client_id })
88 ) {
89 foreach my $scope ( @{ $scopes_ref // [] } ) {
90  

Mojo:

CORE Perl (v5.28.0, darwin) Mojolicious (7.85, Doughnut)

OPTIONAL EV 4.0+ (4.22) IO::Socket::Socks 0.64+ (0.74) IO::Socket::SSL 2.009+ (2.056) Net::DNS::Native 0.15+ (0.18) Role::Tiny 2.000001+ (2.000006)

leejo commented 6 years ago

I probably forgot to tweak the examples when i did some refactoring recently, I'll have a look when i gt time. Thanks!

muenalan commented 6 years ago

After further sherlocking: Net::OAuth2::AuthorizationServer is up to date. (0.18), but seems to be the root cause:

So this callback get finally called through: Entering verify_client_sub().. at /Users/muenalan/.plenv/versions/5.28.0-sitecustomize/lib/perl5/site_perl/5.28.0/Net/OAuth2/AuthorizationServer/Defaults.pm line 124.

which is:

114 sub _delegate_to_cb_or_private {
115 
116     my $method = shift;
117     my $self   = shift;
118     my %args   = @_;
119 
120     my $cb_method = "${method}_cb";
121     my $p_method  = "_$method";
122 
123     if ( my $cb = $self->$cb_method ) {
124         return $cb->( %args );
125     }
126     else {
127         return $self->$p_method( %args );
128     }
129 }

and see, the %args will be random, however your callback expects ordered args. But replacing %args with @_ did not help.

Odd enough, I don't see how your callback ends up getting the controller object in the first place.

leejo commented 6 years ago

I think the examples are just out of date w/r/t to the module.

muenalan commented 6 years ago

Okay, thanks+understood.

PS: Maybe that helps somehow to spot it quicker. The root call is at:

_delegate_to_cb_or_private() at /Users/muenalan/.plenv/versions/5.28.0-sitecustomize/lib/perl5/site_perl/5.28.0/Mojolicious/Plugin/OAuth2/Server.pm line 282.

ends here

279 $Grant = $type eq 'token' ? $ImplicitGrant : $AuthCodeGrant; 280 281 my $mojo_url = Mojo::URL->new( $uri ); 282 my ( $res,$error ) = $Grant->verify_client( 283 client_id => $client_id, 284 redirect_uri => $uri, 285 scopes => [ @scopes ], 286 mojo_controller => $self, 287 response_type => $type, 288 ); 289

where indeed there is no way this will work.

muenalan commented 6 years ago

Okay, solved. Indeed you example seems out of date, and going back to the new documentation I could copy+paste a callback that would work at that instance, however its escalating to other callbacks then.

After fixing a missing brace in the docs

my $verify_clientsub = sub { my ( %args ) = @;

my ( $obj,$client_id,$scopes_ref,$client_secret,$redirect_uri,$response_type )  = @args{ qw/ mojo_controller client_id scopes client_secret redirect_uri response_type / };

if (my $client = $obj->db->get_collection( 'clients' )->find_one({ client_id => $client_id })) { my $client_scopes = [];

  # Check scopes                                                                                                                                                                                                                          
  foreach my $scope ( @{ $scopes_ref // [] } )
  {
    if ( ! exists( $client->{scopes}{$scope} ) )
    {
      return ( 0,'invalid_scope' );
    }
    elsif ( $client->{scopes}{$scope} )
    {
      push @{$client_scopes}, $scope;
    }
  }

  # Implicit Grant Checks                                                                                                                                                                                                                 
  if ( $response_type && $response_type eq 'token' ) {
    # If 'credentials' have been assigned Implicit Grant should be prevented, so check for secret                                                                                                                                         
    return (0, 'unauthorized_grant') if $client->{'secret'};

    # Check redirect_uri                                                                                                                                                                                                                  
    return (0, 'access_denied')   if (
            $client->{'redirect_uri'} &&
           (!$redirect_uri || $redirect_uri ne $client->{'redirect_uri'}) );
  }

  # Credentials Grant Checks                                                                                                                                                                                                              
  if ($client_secret && $client_secret ne $client->{'secret'}) {
      return (0, 'access_denied');
  }

  return ( 1, undef, $client_scopes );

}

return ( 0,'unauthorized_client' ); };

leejo commented 6 years ago

Any plan to update them ?

Yep, I'll do that when i get time - it's no use having examples that don't work :)

muenalan commented 6 years ago

Thx for the quick response, this effort here is greatly appreciated 👍

leejo commented 6 years ago

Of course, feel free to fix them and raise a PR if you like ;)

muenalan commented 6 years ago

Okay, not a PR yet, but created apps as tests. Fixed some quirks along the way.

https://github.com/muenalan/net-oauth2-authorizationserver/tree/master/examples/apps/example_db

For now, example_db and example_client are working.

BTW: Test::Mojo::TxHistory you can comment out.