Mozilla-Persona
view release on metacpan or search on metacpan
lib/Mozilla/Persona/Server.pm view on Meta::CPAN
{ my ($self, $args) = @_;
$self->{MP_pem_fn} = $args->{private_pem} or panic;
$self->{MP_cookie} = $args->{cookie_name} or panic;
$self->{MP_domain} = $args->{domain} or panic;
$self->{MP_aliparms} = $args->{aliases}
|| { class => 'Mozilla::Persona::Aliases' };
$self->{MP_valparms} = $args->{validator}
|| { class => 'Mozilla::Persona::Validate::Table'
, pwfile => '/etc/persona/passwords'
};
$self;
}
sub fromConfig($)
{ my ($class, $fn) = (shift, shift);
my $config = decode_json read_file $fn;
$class->new(%$config, @_);
}
#-----------------
sub cookie() {shift->{MP_cookie}}
sub domain() {shift->{MP_domain}}
sub aliases()
{ my $self = shift;
return $self->{MP_aliases}
if $self->{MP_aliases};
my $config = $self->{MP_aliparms} || {};
# load alias expansion plugin
my $class = delete $config->{class} or panic;
eval "require $class"; panic $@ if $@;
$self->{MP_aliases} = $class->new(%$config);
}
sub validator()
{ my $self = shift;
return $self->{MP_validator}
if $self->{MP_validator};
my $config = $self->{MP_valparms} || {};
# load username/password validator
my $class = delete $config->{class} or panic;
eval "require $class"; panic $@ if $@;
$self->{MP_validator} = $class->new(%$config);
}
sub privatePEM()
{ my $self = shift;
my $pem = read_file $self->{MP_pem_fn};
my $key = Crypt::OpenSSL::RSA->new_private_key($pem);
$key->use_pkcs1_padding;
$key->use_sha256_hash;
$key;
}
#------------------------
sub getSession($)
{ my ($self, $cgi) = @_;
my $cookie = $cgi->cookie($self->cookie)
or error __x"no session cookie";
my $session = CGI::Session->new('driver:File', $cookie)
or error __x"invalid session cookie";
$session;
}
sub _sign($$$)
{ my ($self, $client_pubkey, $email, $duration) = @_;
# NB. Treating the jwcrypto code as the spec here.
my $issued_at = int(1000*time);
my %cert =
( iss => $self->domain
, exp => $issued_at + 1000*$duration
, iat => $issued_at
, "public-key" => $client_pubkey
, principal => { email => $email }
);
my %header =
( typ => 'JWT'
, alg => 'RS256'
);
my $header_enc = encode_base64url encode_json \%header;
my $cert_enc = encode_base64url encode_json \%cert;
my $key = $self->privatePEM or return;
my $sig_enc = encode_base64url $key->sign("$header_enc.$cert_enc");
"$header_enc.$cert_enc.$sig_enc";
}
sub actionSign($)
{ my ($self, $cgi) = @_;
my $session = $self->getSession($cgi);
my $user = $session->param('user');
print $cgi->header(-content_type => MIME_JSON);
my $user_pubkey = $cgi->param('pubkey')
or error __x"nothing to sign for {user}", user => $user;
my $duration = $cgi->param('duration') || 24*3600;
( run in 0.881 second using v1.01-cache-2.11-cpan-0bb4e1dffa6 )