package CF; use Mojo::Base 'Mojolicious'; use Mojo::Pg; use Mojo::JWT; use Mojo::Redis; use CF::Schema; # This method will run once at server start sub startup { my $self = shift; my $cfg = $self->plugin('Config' => { file => 'cf.conf'} ); $self->helper( cfg => sub { return $cfg; } ); # Konfigurace z ENV ma prednost KEY: foreach my $key ( keys %ENV ) { if ( $key =~ /^CFG_(.+)/i ) { $cfg->{lc($1)} = $ENV{$key}; } } # migrace schematu my $pg = Mojo::Pg->new ->dsn($cfg->{db_dsn}) ->username($cfg->{db_username}) ->password($cfg->{db_password}) ; if ($cfg->{test}) { $pg->search_path(['test']); $pg->db->query('drop schema if exists test cascade'); $pg->db->query('create schema test'); } $pg->migrations->from_dir($self->home . '/sql'); $pg->migrations->migrate(); $self->helper( pg => sub { return $pg; } ); # DB Schema my $schema = CF::Schema->connect({ dsn => $cfg->{db_dsn}, user => $cfg->{db_username}, password => $cfg->{db_password}, }); if ( $cfg->{test} ) { $schema->storage->dbh->do("set search_path to test") ; } $self->helper( schema => sub { return $schema; } ); # Redis my $redis = Mojo::Redis->new( $cfg->{redis} ); $self->helper( redis => sub { return $redis; } ); $self->plugin('CF::Helpers::Core'); $self->plugin('CF::Helpers::Auth'); $self->plugin("OpenAPI" => { url => $self->home . '/openapi.yaml', schema => 'v3', plugins => [qw(+SpecRenderer +Cors +Security)], render_specification => 1, render_specification_for_paths => 1, default_response_codes => [400, 401, 403, 404, 429, 500, 501], security => { Bearer => sub { my ($c, $definition, $scopes, $cb ) = @_; my $key = $c->req->headers->authorization; # moznost nepovinneho bez tokenu return $c->$cb() if $scopes->[0] && $scopes->[0] eq 'optional' && ! $key; return $c->$cb('Authorization header not present') if ! $key; return $c->$cb('Unsupported authorization type') if $key !~ s/Bearer\s+//i; $c->oauth_token($key); if (! $c->user ) { return $c->$cb('Invalid user'); } my $user = $c->schema->resultset('User')->find_or_create( $c->user, { key => 'uuid'} ); $user->set_secret(); $user->update_roles($c->user_roles); $c->stash->{user}{id} = $user->id; return $c->$cb() if ! scalar @{ $scopes }; ROLE: foreach my $role ( @{ $scopes } ) { return $c->$cb() if $role eq '*'; return $c->$cb() if $c->user_roles->{ $role }; } return $c->$cb('Insufficient permissions'); } } }); $self->defaults( openapi_cors_allowed_origins => ['*'] ); # Router my $r = $self->routes; $r->get('/')->to(cb => sub { shift->redirect_to('/api.html');}); $r->websocket('/ws')->to('Websockets#main'); } 1;