Skip to content
Permalink
Browse files

move API/OAuth2 code into its own namespace

separate from the Web, means we can mount it as its own standalone
server should we need to - currently mounted by the existing app_2017
psgi script
  • Loading branch information...
leejo committed Apr 27, 2019
1 parent 0fdb10a commit 59b7a70f4e8923f75ada0958b3d7d3b9798b69ac
@@ -17,6 +17,7 @@ use PAUSE::Web::Context;
use PAUSE::Web;
use PAUSE::Web::App::Index;
use PAUSE::Web::App::Disabled;
use PAUSE::API;

my $context = PAUSE::Web::Context->new(root => $AppRoot);
$context->init;
@@ -30,6 +31,7 @@ BSD::Resource::setrlimit(BSD::Resource::RLIMIT_CORE(),
40*1024*1024, 40*1024*1024);

my $pause_app = PAUSE::Web->new(pause => $context);
my $pause_api = PAUSE::API->new(pause => $context);
my $index_app = PAUSE::Web::App::Index->new->to_app;
my $disabled_app = PAUSE::Web::App::Disabled->new->to_app;

@@ -61,6 +63,11 @@ builder {
$pause_app->start('psgi');
};

mount '/api' => builder {
enable_if {$_[0]->{PATH_INFO} =~ /authorize/ ? 1 : 0} '+PAUSE::Web::Middleware::Auth::Basic', context => $context;
$pause_api->start('psgi');
};

mount '/' => builder { $index_app };
}
};
@@ -0,0 +1,69 @@
package PAUSE::API;

use Mojo::Base "Mojolicious";
use MojoX::Log::Dispatch::Simple;
use HTTP::Status qw/:constants status_message/;

has pause => sub { Carp::confess "requires PAUSE::Web::Context" };

sub startup {
my $app = shift;

$app->moniker("pause-web");

$app->max_request_size(0); # indefinite upload size

# Set the same logger as the one Plack uses
# (initialized in app.psgi)
$app->log(MojoX::Log::Dispatch::Simple->new(
dispatch => $app->pause->logger,
level => "debug",
));

$app->hook(around_dispatch => \&_log);

# Load plugins to modify path/set stash values/provide helper methods
$app->plugin("PAUSE::Web::Plugin::ConfigPerRequest");
$app->plugin("PAUSE::Web::Plugin::GetActiveUserRecord");

# Check HTTP headers and set stash
my $r = $app->routes->under("/")->to("root#check");

# API routing

# note that we define the /oauth/authorize route before we install
# the plugin to avoid it defining it first (FIFO) - we use the same
# route in the plugin setup to avoid it defining an alternate route
$app->routes->get("/oauth/authorize")->to("user#oauth_authorize");
$app->plugin("PAUSE::API::Plugin::OAuth2Server");

# API/OAuth2
my $api = $app->routes->under("/")->to(
cb => sub {
my ( $c ) = @_;
return 1 if $c->oauth;
$c->render(
status => HTTP_UNAUTHORIZED,
json => { error => 'Bad credentials' },
);
return;
}
);

$api->get("/me")->to("user#me");
}

sub _log {
my ($next, $c) = @_;
local $SIG{__WARN__} = sub {
my $message = shift;
chomp $message;
Log::Dispatch::Config->instance->log(
level => 'warn',
message => $message,
);
};
$c->helpers->reply->exception($@) unless eval { $next->(); 1 };
}

1;
@@ -1,4 +1,4 @@
package PAUSE::Web::Controller::Api::User;
package PAUSE::API::Controller::User;

use Mojo::Base "Mojolicious::Controller";
use HTTP::Status qw/:constants status_message/;
@@ -1,4 +1,4 @@
package PAUSE::Web::Plugin::OAuth2Server;
package PAUSE::API::Plugin::OAuth2Server;

use Mojo::Base "Mojolicious::Plugin";
use YAML::Syck;
@@ -11,7 +11,7 @@ sub register {
'OAuth2::Server' => {
# authorize route falls under /authenquery to make sure user
# is logged in or is asked to log in
authorize_route => '/authenquery/oauth/authorize',
authorize_route => '/oauth/authorize',

# access token route doesn't fall under /authenquery as it will
# use the oauth2 auth code and client secret for authentication
@@ -87,26 +87,6 @@ sub startup {
}
}

# note that we define the /oauth/authorize route before we install
# the plugin to avoid it defining it first (FIFO) - we use the same
# route in the plugin setup to avoid it defining an alternate route
$private->get("/oauth/authorize")->to("api-user#oauth_authorize");
$app->plugin("PAUSE::Web::Plugin::OAuth2Server");

# API/OAuth2
my $api = $app->routes->under("/api")->to(
cb => sub {
my ( $c ) = @_;
return 1 if $c->oauth;
$c->render(
status => HTTP_UNAUTHORIZED,
json => { error => 'Bad credentials' },
);
return;
}
);

$api->get("/me")->to("api-user#me");
}

sub _log {
@@ -21,7 +21,7 @@ $t->{mech}->requests_redirectable( [] );
subtest 'unknown client' => sub {

my $res = $t->get(
"/pause/authenquery/oauth/authorize"
"/api/oauth/authorize"
. "?client_id=bad_client_id"
. "&$common_qparams"
);
@@ -38,7 +38,7 @@ my $access_token;
subtest 'known client' => sub {

my $res = $t->get(
"/pause/authenquery/oauth/authorize"
"/api/oauth/authorize"
. "?client_id=ACT"
. "&$common_qparams"
);
@@ -52,7 +52,7 @@ subtest 'known client' => sub {
my $auth_code = ( split( 'code=',$res->header( 'location' ) ) )[1];

$res = $t->post_ok(
"/pause/oauth/access_token",
"/api/oauth/access_token",
{
code => $auth_code,
client_id => 'ACT',
@@ -80,7 +80,7 @@ subtest 'get user info' => sub {

$t->{mech}->requests_redirectable( [] );
my $res = $t->get(
"/pause/api/me",
"/api/me",
Authorization => "Bearer $access_token",
);

0 comments on commit 59b7a70

Please sign in to comment.
You can’t perform that action at this time.