package CF2022::Helpers::Auth; use base 'Mojolicious::Plugin'; use Mojo::UserAgent; use Mojo::JWT; use feature 'signatures'; no warnings qw{ experimental::signatures }; 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 ) { if ( $self->cfg->{test} && $self->cfg->{test_auth_jwt_secret}) { $jwt = Mojo::JWT->new( secret => $self->cfg->{test_auth_jwt_secret} ); return $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 => sub ( $c ) { my $claims = $c->oauth_claims // return; GROUP: foreach my $group ( sort @{ $claims->{groups} } ) { if ( $group =~ REGIONS ) { my $role = ( $2 eq 'f') ? 'member':'regp'; my $region = $c->oauth_groups->{ $group }; $region =~ s/^K[SF]\s+//i; return { region => $region, role => $role, }; } elsif ( $group =~ /cen:regp/ ) { return { region => 'Celostátní fórum', role => 'regp', }; } } }); $self->helper( user => sub ( $c ) { my $claims = $c->oauth_claims // return undef; if ( ! $c->stash->{user} ) { $c->stash->{user} = { uuid => $claims->{sub}, username => $claims->{preferred_username}, name => $claims->{name}, # groups => $claims->{groups}, main_group_name => $c->oauth_main_group_name(), }; } return $c->stash->{user}; }); } 1; __END__