package Jifty::Plugin::OpenID::Mixin::Model::User; use strict; use warnings; use Jifty::DBI::Schema; use base 'Jifty::DBI::Record::Plugin'; use URI; =head1 NAME Jifty::Plugin::OpenID::Mixin::Model::User =head1 DESCRIPTION L mixin for the User model. Provides an 'openid' column. =cut use Jifty::Plugin::OpenID::Record schema { our @EXPORT = qw(has_alternative_auth link_to_openid); column openid => type is 'text', label is 'OpenID', hints is q{You can use your OpenID to log in quickly and easily.}, is distinct, is immutable; }; =head2 has_alternative_auth =cut sub has_alternative_auth { 1 } =head2 register_triggers =cut sub register_triggers { my $self = shift; $self->add_trigger(name => 'validate_openid', callback => \&validate_openid, abortable => 1); $self->add_trigger(name => 'canonicalize_openid', callback => \&canonicalize_openid); } =head2 validate_openid =cut sub validate_openid { my $self = shift; my $openid = shift; my $uri = URI->new( $openid ); return ( 0, q{That doesn't look like an OpenID URL.} ) if not defined $uri; my $temp_user = Jifty->app_class("Model", "User")->new; $temp_user->load_by_cols( openid => $uri->canonical ); # It's ok if *we* have the openid we're looking for return ( 0, q{It looks like somebody else has claimed that OpenID.} ) if $temp_user->id and ( not $self->id or $temp_user->id != $self->id ); return 1; } =head2 canonicalize_openid =cut sub canonicalize_openid { my $self = shift; my $openid = shift; return '' if not defined $openid or not length $openid; $openid = 'http://' . $openid if $openid !~ m{^http://}; my $uri = URI->new( $openid ); return $uri->canonical; } =head2 link_to_openid Links User's account to the specified OpenID (bypassing ACLs) =cut sub link_to_openid { my $self = shift; my $openid = shift; $self->__set( column => 'openid', value => $openid ); } 1;