jhthorsen / mojolicious-plugin-openapi

OpenAPI / Swagger plugin for Mojolicious
54 stars 44 forks source link

securityDefinitions: security callback called twice or curl Nothing has been rendered #121

Closed Veltro-pm closed 5 years ago

Veltro-pm commented 5 years ago

Hello, I tried to use securityDefinitions to adapt your example https://mojolicious.io/blog/2017/12/22/day-22-how-to-build-a-public-rest-api/

Problem description: In the case of using perl .\script\my_app openapi ... the callback is getting called twice and the morbo+curl approach shows the line "Nothing has been rendered ..."

May be related:

40

82

I've added "securityDefinitions" and "security" to my yaml:

swagger: '2.0'
info:
  version: '0.42'
  title: Dummy example
schemes: [ http ]
basePath: "/api"
securityDefinitions:
  dummy:
    type: basic
paths:
  /echo:
    post:
      x-mojo-to: "echo#index"
      security: [{"dummy": []}]
      operationId: echo
      parameters:
      - in: body
        name: body
        schema:
          type: object
      responses:
        200:
          description: Echo response
          schema:
            type: object

and adapted my code:

   my $openapi_api = $self->plugin( OpenAPI => {
         spec => $self->static->file( "api.yaml" )->path,
         security => {
            dummy => sub {
               my ($c, $definition, $scopes, $cb) = @_;
               print "dummy was called\n" ;
               $c->$cb() ;
            }
         },
      }
   ) ;

Note: In the following [datetime] removed from the debugging lines for readability:

Without security: [{"dummy": []}] (runs as expected)

perl .\script\my_app openapi /api echo -c "{\"age\":42}" [debug] GET "/api" [debug] Routing to a callback [debug] 200 OK (0.002471s, 404.694/s) [debug] POST "/api/echo" [debug] Routing to a callback [debug] Routing to controller "MyApp::Controller::Echo" and action "index" [debug] 200 OK (0.004139s, 241.604/s) {"age":42}

With security: [{"dummy": []}] (cb twice)

perl .\script\my_app openapi /api echo -c "{\"age\":42}" [debug] GET "/api" [debug] Routing to a callback [debug] 200 OK (0.00338s, 295.858/s) [debug] POST "/api/echo" [debug] Routing to a callback dummy was called [debug] Routing to a callback dummy was called [debug] Routing to controller "MyApp::Controller::Echo" and action "index" [debug] 200 OK (0.004336s, 230.627/s) {"age":42}

Then I tried to use morbo and curl:

morbo ./script/my_app + curl -d "{\"age\":42}" -H "Content-Type: application/json" -X POST http://localhost:3000/api/echo {"age":42} (<= output of command)

Without security: [{"dummy": []}] (runs as expected)

[debug] POST "/api/echo" [debug] Routing to a callback [debug] Routing to controller "MyApp::Controller::Echo" and action "index" [debug] 200 OK (0.003282s, 304.692/s)

With security: [{"dummy": []}] (Nothing has been rendered ... although the output is correct)

[debug] POST "/api/echo" [debug] Routing to a callback dummy was called [debug] Nothing has been rendered, expecting delayed response [debug] Routing to controller "MyApp::Controller::Echo" and action "index" [debug] 200 OK (0.003917s, 255.297/s)

Am I doing something wrong?

jhthorsen commented 5 years ago

Thanks for the bug report! My first instinct was that the bug had to be in OpenAPI::Client, but the issue was that Mojo::Promise inside Security.pm used a different IOLoop when called from OpenAPI::Client than the singleton. I've rewritten the code now, so it does not require an IOLoop at all.

@jberger: Not sure if you want to have a look at the diff. Unfortunately, I haven't written any new tests, but such an test would simply check that the code does not use Mojo::Promise or Mojo::IOLoop::Delay, so I'm not sure how useful it is.

Going to make a new release soon.