package Web::ID; use 5.010; use utf8; BEGIN { $Web::ID::AUTHORITY = 'cpan:TOBYINK'; $Web::ID::VERSION = '1.921'; } use Any::Moose 'X::Types::Moose' => [':all']; use Web::ID::Types ':all'; use Web::ID::Certificate; use Web::ID::Util qw(:default uniq); use Any::Moose; use namespace::clean -except => 'meta'; has certificate => ( is => read_only, isa => Certificate, required => true, coerce => true, ); has uri => ( is => read_only, isa => Uri, lazy_build => true, coerce => true, ); has profile => ( is => read_only, isa => Model, lazy_build => true, ); has valid => ( is => read_only, isa => Bool, lazy_build => true, ); has first_valid_san => ( is => read_only, isa => San | Undef, lazy_build => true, ); sub _build_valid { my ($self) = @_; return false unless $self->certificate->timely; return true if defined $self->first_valid_san; return false; } sub _build_uri { my ($self) = @_; $self->first_valid_san->uri_object; } sub _build_profile { my ($self) = @_; $self->first_valid_san->model; } sub _build_first_valid_san { my ($self) = @_; my $cert = $self->certificate; my @sans = @{ $cert->subject_alt_names }; foreach my $san (@sans) { foreach my $key ( $san->associated_keys ) { return $san if $key->rsa_equal($cert); } } return undef; } sub node { my ($self) = @_; RDF::Trine::Node::Resource->new($self->uri.''); } sub get { my $self = shift; my @pred = map { if (blessed $_ and $_->isa('RDF::Trine::Node')) { $_ } else { u $_ } } @_; my @results = uniq map { $_->is_resource ? $_->uri : $_->literal_value } grep { $_->is_literal or $_->is_resource } $self->profile->objects_for_predicate_list($self->node, @pred); wantarray ? @results : $results[0]; } __PACKAGE__ __END__ =head1 NAME Web::ID - implementation of WebID (a.k.a. FOAF+SSL) =head1 SYNOPSIS my $webid = Web::ID->new(certificate => $pem_encoded_x509); if ($webid->valid) { say "Authenticated as: ", $webid->uri; } =head1 DESCRIPTION WebID is a simple authentication protocol based on TLS (Transaction Layer Security, better known as Secure Socket Layer, SSL) and the Semantic Web. This module provides a Perl implementation for authenticating clients using WebID. For more information see the L document. Bundled with this module are L, a plugin for L to perform WebID authentication on HTTPS connections; and L, a module that allows you to generate WebID-enabled certificates that can be installed into web browsers. =head2 Constructor =over =item C<< new >> Standard Moose-style constructor. (This class uses L.) =back =head2 Attributes =over =item C<< certificate >> A L object representing and x509 certificate, though a PEM-encoded string will be coerced. This is usually the only attribute you want to pass to the constructor. Allow the others to be built automatically. =item C<< first_valid_san >> Probably fairly uninteresting. This is the first subjectAltName value found in the certificate that could be successfully authenticated using Web::ID. An L object. =item C<< uri >> The URI associated with the first valid SAN. A L object. This is a URI you can use to identify the person, organisation or robotic poodle holding the certificate. =item C<< profile >> Data about the certificate holder. An L object. Their FOAF file (probably). =item C<< valid >> Boolean. =back =head2 Methods =over =item C<< node >> Returns the same as C, but as an L object. =item C<< get(@predicates) >> Queries the C for triples of the form: $self->node $predicate $x . And returns literal and URI values for $x, as strings. C<< $predicate >> should be an L, or a string. If a string, it will be expanded using L, so you can do stuff like: my $name = $webid->get('foaf:name', 'rdfs:label'); my @mboxes = $webid->get('foaf:mbox'); =back =head1 BUGS AND LIMITATIONS =head2 Any::Moose This module uses L which means that if it detects that you're using the rather heavyweight L toolkit, then this module will use it too. But if you're not using it, then this module will use the lighter-weight L toolkit. Similarly, this module will use either L or L. As the decision to use Moose or Mouse is made at runtime, this makes expressing Web::ID's dependencies rather challenging. Web::ID requires B: =over =item * Any::Moose, =item * Mouse, and =item * MouseX::Types =back B: =over =item * Any::Moose, =item * Moose, and =item * MooseX::Types =back The installation script for Web-ID checks the first set of dependencies, but if you only ever plan on using Moose, and never Mouse, then you don't need them - you need the second set. Yes, it's possible to have the installation script figure out a list of dependencies dynamically when you install Web-ID, but that's not especially helpful, as Any::Moose makes its decision about what module to use at run time, not at install time. The long and the short of it is: if you use Web::ID as part of a Moose application, then make sure you have MooseX::Types installed. =head2 Other Please report any other bugs to L. =head1 SEE ALSO L. L, L. L provides an access control system that complements WebID. L is the spiritual ancestor of this module though they share very little code, and have quite different APIs. General WebID information: L, L, L, L. Mailing list for general Perl RDF/SemWeb discussion and support: L. =head1 AUTHOR Toby Inkster Etobyink@cpan.orgE. =head1 THANKS Thanks to Kjetil Kjernsmo (cpan:KJETILK) for persuading me to port my old CGI-specific implementaton of this to Plack. Thanks Kjetil Kjernsmo (again), Florian Ragwitz (cpan:FLORA), and Jonas Smedegaard for help with testing and advice on dependencies. Thanks to Henry Story, Melvin Carvalho, Simon Reinhardt, Bruno Harbulot, Ian Jacobi and many others for developing WebID from a poorly thought out idea to a clever, yet simple and practical authentication protocol. Thanks to Gregory Williams (cpan:GWILLIAMS), Tatsuhiko Miyagawa (cpan:MIYAGAWA) and the Moose Cabal for providing really good platforms (RDF::Trine, Plack and Moose respectively) to build this on. =head1 COPYRIGHT AND LICENCE This software is copyright (c) 2012 by Toby Inkster. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =head1 DISCLAIMER OF WARRANTIES THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.