Skip to content
Snippets Groups Projects
Verified Commit f4501c6a authored by Andrej Ramašeuski's avatar Andrej Ramašeuski
Browse files

Pridana prace s postama

parent 4efc11e1
No related branches found
No related tags found
No related merge requests found
package CF;
use Mojo::Base 'Mojolicious';
use Mojo::Pg;
use Mojo::JWT;
use CF::Schema;
# This method will run once at server start
sub startup {
my $self = shift;
$self->plugin('CF::Helpers::Core');
my $cfg = $self->plugin('Config' => { file => 'cf.conf'} );
$self->helper( cfg => sub { return $cfg; } );
# Konfigurace z ENV ma prednost
KEY:
......@@ -25,7 +25,7 @@ sub startup {
->username($cfg->{db_username})
->password($cfg->{db_password})
;
$pg->migrations->from_file($self->home . '/sql/migrations.sql');
$pg->migrations->from_dir($self->home . '/sql');
$pg->migrations->migrate();
$self->helper( pg => sub { return $pg; } );
......@@ -37,13 +37,50 @@ sub startup {
});
$self->helper( schema => sub { return $schema; } );
$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, 404, 500, 501],
default_response_codes => [400, 401, 403, 404, 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'}
);
$c->stash->{user}{id} = $user->id;
return $c->$cb() if ! scalar @{ $scopes };
ROLE:
foreach my $role ( @{ $scopes } ) {
return $c->$cb() if $c->user_roles->{ $role };
}
return $c->$cb('Insufficient permissions');
}
}
});
$self->defaults(
......
package CF::Controller::Posts;
use Mojo::Base 'Mojolicious::Controller';
sub create {
my $c = shift->openapi->valid_input or return;
my $args = $c->req->json;
# Navrh postupu muze predlozit jenom clen
if ( $args->{type} == 0 && ! $c->user_roles->{'xember'} ) {
return $c->error(401, 'Insufficient permissions');
}
my $post = $c->schema->resultset('Post')->create({
user_id => $c->user->{id},
type => $args->{type},
content => $args->{content},
});
### TODO: Notify
$c->render(
status => 201,
openapi => { id => $post->id },
);
};
1;
package CF::Helpers::Auth;
use base 'Mojolicious::Plugin';
use feature 'signatures';
no warnings qw{ experimental::signatures };
use Mojo::UserAgent;
use Mojo::JWT;
use constant KEY_FORMAT => "-----BEGIN PUBLIC KEY-----\n%s\n-----END PUBLIC KEY-----";
use constant REGIONS => qr{^(jhc|jhm|kvk|lbk|msk|olk|pak|pha|plk|stc|ulk|vys|zlk|khk):(f|regp)$};
sub register ( $class, $self, $conf) {
my $ua = Mojo::UserAgent->new();
my ( $jwt, $groups);
$self->helper( jwt => sub {
if ( ! $jwt ) {
my $res;
eval { $res = $ua->get( $self->cfg->{oauth_url} )->result; };
if (! $@ && $res->is_success) {
$jwt = Mojo::JWT->new(
public => sprintf( KEY_FORMAT, $res->json->{public_key} )
);
}
}
return $jwt;
});
$self->helper( oauth_groups => sub ( $c ) {
if ( ! $groups ) {
my $res;
eval { $res = $ua->get( $self->cfg->{groups_url} )->result; };
if (! $@ && $res->is_success) {
my $json = $res->json;
$groups = { map { $_->{code} => $_->{name} } @{ $json } };
}
}
return $groups;
});
$self->helper( oauth_token => sub ( $c, $token='' ) {
$c->stash->{token} //= $token;
return $c->stash->{token};
});
$self->helper( oauth_claims => sub ( $c ) {
if ( ! $c->stash->{claims}) {
return undef if ! ($c->jwt && $c->oauth_token);
my $claims;
eval { $claims = $c->jwt->decode( $c->oauth_token ); };
if ( $@ ) {
$c->app->log->warn("Invalid token ($@)");
}
$c->stash->{claims} = $claims;
}
return $c->stash->{claims};
});
$self->helper( oauth_main_group_name => sub ( $c ) {
my $claims = $c->oauth_claims // return;
GROUP:
foreach my $group ( sort @{ $claims->{groups} } ) {
return $c->oauth_groups->{ $group } if $group =~ REGIONS;
}
});
$self->helper( user => sub ( $c ) {
my $claims = $c->oauth_claims // return;
if ( ! $c->stash->{user} ) {
$c->stash->{user} = {
uuid => $claims->{sub},
username => $claims->{preferred_username},
name => $claims->{name},
main_group_name => $c->oauth_main_group_name(),
};
}
return $c->stash->{user};
});
$self->helper( user_roles => sub ( $c ) {
my $claims = $c->oauth_claims // return;
$c->stash->{user_roles} //= { map { $_ => 1 } @{ $claims->{roles} // [] }};
return $c->stash->{user_roles};
});
}
1;
__END__
package CF::Schema::Result::Announcement;
use strict;
use warnings;
use base 'DBIx::Class::Core';
our $VERSION = 1;
__PACKAGE__->table('announcements');
__PACKAGE__->add_columns(
id => {
data_type => 'integer',
is_auto_increment => 1,
is_nullable => 0,
sequence => 'uid_seq'
},
qw(
datetime
is_archived
user_id
type
state
content
link
related_post_id
),
);
__PACKAGE__->set_primary_key('id');
1;
package CF::Schema::Result::Post;
use strict;
use warnings;
use base 'DBIx::Class::Core';
our $VERSION = 1;
__PACKAGE__->table('posts');
__PACKAGE__->add_columns(
id => {
data_type => 'integer',
is_auto_increment => 1,
is_nullable => 0,
sequence => 'uid_seq'
},
qw(
datetime
is_archived
user_id
type
state
content
ranking_likes
ranking_dislikes
),
);
__PACKAGE__->set_primary_key('id');
1;
package CF::Schema::Result::Post_view;
use strict;
use warnings;
use base 'CF::Schema::Result::Post';
our $VERSION = 1;
__PACKAGE__->table('posts_view');
__PACKAGE__->add_columns(
qw(
score
user_name
group_name
),
);
__PACKAGE__->set_primary_key('id');
sub format {
my $self = shift;
my $post = {
id => $self->id,
datetime => $self->datetime,
type => $self->type,
is_archive => $self->is_archived,
author => {
name => $self->user_name,
group => $self->group_name,
},
ranking => {
score => $self->score,
likes => $self->likes,
dislikes => $self->dislikes,
my_vote => 0, #TODO
}
};
return $post;
}
1;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment