| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  |  | 
| 2 |  |  |  |  |  |  | package Mojolicious::Plugin::MozPersona; | 
| 3 |  |  |  |  |  |  | $Mojolicious::Plugin::MozPersona::VERSION = '0.05'; | 
| 4 |  |  |  |  |  |  | # ABSTRACT: Minimalistic integration of Mozillas "Persona" authentication system in Mojolicious apps | 
| 5 |  |  |  |  |  |  |  | 
| 6 | 1 |  |  | 1 |  | 37508 | use strict; | 
|  | 1 |  |  |  |  | 3 |  | 
|  | 1 |  |  |  |  | 54 |  | 
| 7 | 1 |  |  | 1 |  | 7 | use warnings; | 
|  | 1 |  |  |  |  | 3 |  | 
|  | 1 |  |  |  |  | 47 |  | 
| 8 |  |  |  |  |  |  |  | 
| 9 |  |  |  |  |  |  |  | 
| 10 | 1 |  |  | 1 |  | 3409 | use Mojo::Base 'Mojolicious::Plugin'; | 
|  | 1 |  |  |  |  | 15073 |  | 
|  | 1 |  |  |  |  | 11 |  | 
| 11 |  |  |  |  |  |  |  | 
| 12 | 1 |  |  | 1 |  | 2082 | use File::Basename 'dirname'; | 
|  | 1 |  |  |  |  | 3 |  | 
|  | 1 |  |  |  |  | 127 |  | 
| 13 | 1 |  |  | 1 |  | 1024 | use File::Spec::Functions 'catdir'; | 
|  | 1 |  |  |  |  | 1829 |  | 
|  | 1 |  |  |  |  | 918 |  | 
| 14 |  |  |  |  |  |  |  | 
| 15 | 1 |  |  | 1 |  | 695 | use Mojolicious::Plugin::MozPersona::Controller; | 
|  | 1 |  |  |  |  | 3 |  | 
|  | 1 |  |  |  |  | 18 |  | 
| 16 |  |  |  |  |  |  |  | 
| 17 |  |  |  |  |  |  |  | 
| 18 |  |  |  |  |  |  | my %defaults = ( | 
| 19 |  |  |  |  |  |  | audience      => '', | 
| 20 |  |  |  |  |  |  | siteName      => '', | 
| 21 |  |  |  |  |  |  | service       => 'https://verifier.login.persona.org/verify', | 
| 22 |  |  |  |  |  |  | namespace     => 'Mojolicious::Plugin::MozPersona::Controller', | 
| 23 |  |  |  |  |  |  | signinId      => 'personaSignin', | 
| 24 |  |  |  |  |  |  | signinPath    => '/_persona/signin', | 
| 25 |  |  |  |  |  |  | signoutId     => 'personaSignout', | 
| 26 |  |  |  |  |  |  | signoutPath   => '/_persona/signout', | 
| 27 |  |  |  |  |  |  | autoHook      => { css => 0, jquery => 'bundled', persona => 1, local => 1, uid => 1 }, | 
| 28 |  |  |  |  |  |  | localJsPath   => '/_persona/localjs', | 
| 29 |  |  |  |  |  |  | localJsTpl    => '_persona/local_js.txt.ep', | 
| 30 |  |  |  |  |  |  | personaJsPath => 'https://login.persona.org/include.js', | 
| 31 |  |  |  |  |  |  | ); | 
| 32 |  |  |  |  |  |  |  | 
| 33 |  |  |  |  |  |  |  | 
| 34 |  |  |  |  |  |  | sub register { | 
| 35 | 0 |  |  | 0 | 1 |  | my ( $self, $app ) = @_; | 
| 36 |  |  |  |  |  |  |  | 
| 37 | 0 |  |  |  |  |  | my $defaultHooks = delete $defaults{'autoHook'}; | 
| 38 | 0 | 0 |  |  |  |  | my (%conf) = ( %defaults, %{ $_[2] || {} } ); | 
|  | 0 |  |  |  |  |  |  | 
| 39 |  |  |  |  |  |  |  | 
| 40 | 0 | 0 |  |  |  |  | $conf{'autoHook'} = {} unless exists $conf{'autoHook'}; | 
| 41 | 0 |  |  |  |  |  | foreach my $h ( keys %{$defaultHooks} ) { | 
|  | 0 |  |  |  |  |  |  | 
| 42 | 0 | 0 | 0 |  |  |  | if ( ref $conf{'autoHook'} && !exists $conf{'autoHook'}->{$h} ) { | 
| 43 | 0 |  |  |  |  |  | $conf{'autoHook'}->{$h} = $defaultHooks->{$h}; | 
| 44 |  |  |  |  |  |  | } | 
| 45 |  |  |  |  |  |  | } | 
| 46 |  |  |  |  |  |  |  | 
| 47 | 0 |  |  |  |  |  | $conf{'siteName'} =~ tr/"'//d; | 
| 48 | 0 |  |  |  |  |  | $conf{'signinPath'} =~ tr/"'//d; | 
| 49 | 0 |  |  |  |  |  | $conf{'signoutPath'} =~ tr/"'//d; | 
| 50 | 0 |  |  |  |  |  | $conf{'signinId'} =~ tr/"'#//d; | 
| 51 | 0 |  |  |  |  |  | $conf{'signoutId'} =~ tr/"'#//d; | 
| 52 |  |  |  |  |  |  |  | 
| 53 | 0 | 0 |  |  |  |  | die "Missing required configuration parameter: 'audience'!" unless $conf{'audience'}; | 
| 54 | 0 | 0 |  |  |  |  | die "Missing required configuration parameter: 'siteName'!" unless $conf{'siteName'}; | 
| 55 |  |  |  |  |  |  |  | 
| 56 |  |  |  |  |  |  | # Append "templates" and "public" directories | 
| 57 | 0 |  |  |  |  |  | my $base = catdir( dirname(__FILE__), 'MozPersona' ); | 
| 58 | 0 |  |  |  |  |  | push @{ $app->renderer->paths }, catdir( $base, 'templates' ); | 
|  | 0 |  |  |  |  |  |  | 
| 59 | 0 |  |  |  |  |  | push @{ $app->static->paths },   catdir( $base, 'public' ); | 
|  | 0 |  |  |  |  |  |  | 
| 60 |  |  |  |  |  |  |  | 
| 61 | 0 |  |  |  |  |  | push @{ $app->renderer->classes }, __PACKAGE__; | 
|  | 0 |  |  |  |  |  |  | 
| 62 | 0 |  |  |  |  |  | push @{ $app->static->classes },   __PACKAGE__; | 
|  | 0 |  |  |  |  |  |  | 
| 63 |  |  |  |  |  |  |  | 
| 64 | 0 |  |  |  |  |  | $app->routes->route( $conf{signinPath} )->via('POST')->to( | 
| 65 |  |  |  |  |  |  | namespace         => $conf{namespace}, | 
| 66 |  |  |  |  |  |  | action            => 'signin', | 
| 67 |  |  |  |  |  |  | _persona_audience => $conf{audience}, | 
| 68 |  |  |  |  |  |  | _persona_service  => $conf{service}, | 
| 69 |  |  |  |  |  |  | ); | 
| 70 | 0 |  |  |  |  |  | $app->routes->route( $conf{signoutPath} )->via('POST')->to( | 
| 71 |  |  |  |  |  |  | namespace         => $conf{namespace}, | 
| 72 |  |  |  |  |  |  | action            => 'signout', | 
| 73 |  |  |  |  |  |  | _persona_audience => $conf{audience}, | 
| 74 |  |  |  |  |  |  | _persona_service  => $conf{service}, | 
| 75 |  |  |  |  |  |  | ); | 
| 76 | 0 |  |  |  |  |  | $app->routes->route( $conf{localJsPath} )->via('GET') | 
| 77 |  |  |  |  |  |  | ->to( namespace => $conf{namespace}, action => 'js', _persona_conf => \%conf, ); | 
| 78 |  |  |  |  |  |  |  | 
| 79 | 0 | 0 |  |  |  |  | if ( $conf{'autoHook'} ) { | 
| 80 |  |  |  |  |  |  |  | 
| 81 | 0 |  |  |  |  |  | my $head_block = ''; | 
| 82 | 0 | 0 |  |  |  |  | if ( $conf{'autoHook'}->{'css'} ) { | 
| 83 | 0 |  |  |  |  |  | $head_block | 
| 84 |  |  |  |  |  |  | .= ''; | 
| 85 |  |  |  |  |  |  | } | 
| 86 | 0 | 0 |  |  |  |  | if ( my $jq = $conf{'autoHook'}->{'jquery'} ) { | 
| 87 | 0 | 0 | 0 |  |  |  | if ( $jq eq 'cdn' ) { | 
|  |  | 0 |  |  |  |  |  | 
| 88 | 0 |  |  |  |  |  | $head_block | 
| 89 |  |  |  |  |  |  | .= ''; | 
| 90 |  |  |  |  |  |  | } | 
| 91 |  |  |  |  |  |  | elsif ( $jq eq 'bundled' or $jq ) { | 
| 92 | 0 |  |  |  |  |  | $head_block | 
| 93 |  |  |  |  |  |  | .= ''; | 
| 94 |  |  |  |  |  |  | } | 
| 95 |  |  |  |  |  |  | } | 
| 96 |  |  |  |  |  |  |  | 
| 97 | 0 |  |  |  |  |  | my $end_block = ''; | 
| 98 | 0 | 0 |  |  |  |  | if ( $conf{'autoHook'}->{'persona'} ) { | 
| 99 | 0 |  |  |  |  |  | $end_block .= qq||; | 
| 100 |  |  |  |  |  |  | } | 
| 101 | 0 | 0 |  |  |  |  | if ( $conf{'autoHook'}->{'local'} ) { | 
| 102 | 0 |  |  |  |  |  | $end_block .= qq||; | 
| 103 |  |  |  |  |  |  | } | 
| 104 |  |  |  |  |  |  |  | 
| 105 |  |  |  |  |  |  | $app->hook( | 
| 106 |  |  |  |  |  |  | after_dispatch => sub { | 
| 107 | 0 |  |  | 0 |  |  | my ($c) = @_; | 
| 108 | 0 | 0 |  |  |  |  | return unless index( $c->res->headers->content_type, 'html' ) >= 0; | 
| 109 |  |  |  |  |  |  |  | 
| 110 | 0 |  |  |  |  |  | my $body = $c->res->body; | 
| 111 |  |  |  |  |  |  |  | 
| 112 | 0 | 0 |  |  |  |  | if ( $conf{'autoHook'}->{'uid'} ) { | 
|  |  | 0 |  |  |  |  |  | 
| 113 | 0 | 0 | 0 |  |  |  | if ( defined( $c->session('_persona') ) | 
| 114 |  |  |  |  |  |  | && $c->session('_persona')->{'status'} eq 'okay' ) | 
| 115 |  |  |  |  |  |  | { | 
| 116 | 0 |  |  |  |  |  | my $email = $c->session('_persona')->{'email'}; | 
| 117 | 0 |  |  |  |  |  | $body | 
| 118 |  |  |  |  |  |  | =~ s!!$head_block!o; | 
| 119 |  |  |  |  |  |  | } | 
| 120 |  |  |  |  |  |  | else { | 
| 121 | 0 |  |  |  |  |  | $body | 
| 122 |  |  |  |  |  |  | =~ s!!$head_block!o; | 
| 123 |  |  |  |  |  |  | } | 
| 124 |  |  |  |  |  |  | } | 
| 125 |  |  |  |  |  |  | elsif ($head_block) { | 
| 126 | 0 |  |  |  |  |  | $body =~ s!!$head_block!o; | 
| 127 |  |  |  |  |  |  | } | 
| 128 |  |  |  |  |  |  |  | 
| 129 | 0 | 0 |  |  |  |  | if ($end_block) { | 
| 130 | 0 |  |  |  |  |  | $body =~ s!!$end_block!o; | 
| 131 |  |  |  |  |  |  | } | 
| 132 | 0 |  |  |  |  |  | $c->res->body($body); | 
| 133 |  |  |  |  |  |  | } | 
| 134 | 0 |  |  |  |  |  | ); | 
| 135 |  |  |  |  |  |  | } ## end if ( $conf{'autoHook'}) | 
| 136 |  |  |  |  |  |  |  | 
| 137 | 0 |  |  |  |  |  | return; | 
| 138 |  |  |  |  |  |  | } ## end sub register | 
| 139 |  |  |  |  |  |  |  | 
| 140 |  |  |  |  |  |  |  | 
| 141 |  |  |  |  |  |  | 1; | 
| 142 |  |  |  |  |  |  |  | 
| 143 |  |  |  |  |  |  | __END__ |