## @file # OpenID Issuer file ## @class # OpenID Issuer class package Lemonldap::NG::Portal::IssuerDBOpenID; use strict; use Lemonldap::NG::Portal::Simple; our $VERSION = '0.01'; our $initDone; ## @method void issuerDBInit() # Do nothing # @return Lemonldap::NG::Portal error code sub issuerDBInit { my $self = shift; return PE_OK if ($initDone); $self->{openIdSecret} ||= $self->{cipher}->encrypt(0); eval { require Lemonldap::NG::Portal::OpenID::Server }; $self->abort( 'Unable to load Net::OpenID::Server', $@ ) if ($@); $initDone = 1; return PE_OK; } ## @apmethod int issuerForUnAuthUser() # Do nothing # @return Lemonldap::NG::Portal error code sub issuerForUnAuthUser { my $self = shift; # Restore datas $self->restoreOpenIDprm(); my $mode = $self->param('openid.mode'); unless ($mode) { $self->lmLog( 'OpenID SP test', 'debug' ); return PE_OPENID_EMPTY; } if ( $mode eq 'associate' ) { return $self->_openIDResponse( $self->openIDServer->_mode_associate() ); } elsif ( $mode eq 'check_authentication' ) { return $self->_openIDResponse( $self->openIDServer->_mode_check_authentication() ); } else { $self->storeOpenIDprm(); return PE_OK; } } ## @apmethod int issuerForAuthUser() # Do nothing # @return Lemonldap::NG::Portal error code sub issuerForAuthUser { my $self = shift; # Restore datas $self->restoreOpenIDprm(); my $mode = $self->param('openid.mode'); unless ($mode) { $self->lmLog( 'OpenID SP test', 'debug' ); return PE_OPENID_EMPTY; } unless ( $mode =~ /^checkid_(?:immediate|setup)/ ) { $self->lmLog( "OpenID error : $mode is not known at this step (issuerForAuthUser)", 'error' ); return PE_ERROR; } return $self->_openIDResponse( $self->openIDServer->_mode_checkid() ); } ## @apmethod int issuerLogout() # Does nothing since OpenID does not provide any logout system # @return Lemonldap::NG::Portal error code sub issuerLogout { PE_OK; } ## @method private void storeOpenIDprm() # Store openid parameters in a hidden value for forms using # setHiddenFormValue() sub storeOpenIDprm { my $self = shift; delete( $self->{_prm}->{lmhidden_openidprm} ); $self->setHiddenFormValue( 'openidprm', Storable::nfreeze( $self->{_prm} ) ); } ## @method private void restoreOpenIDprm() # Restore initial openid parameters stored with storeOpenIDprm() sub restoreOpenIDprm { my $self = shift; return if ( $self->{openIDRestored} ); if ( my $tmp = $self->getHiddenFormValue('openidprm') ) { $self->lmLog( 'Restore OpenID parameters', 'debug' ); eval { $tmp = Storable::thaw($tmp); $self->{_prm}->{$_} = $tmp->{$_} foreach ( keys %$tmp ); }; } $self->{openIDRestored} = 1; } ## @method private Lemonldap::NG::Portal::OpenID::Server openIDServer() # Create if not done a new Lemonldap::NG::Portal::OpenID::Server objet # @return Lemonldap::NG::Portal::OpenID::Server object sub openIDServer { my $self = shift; return $self->{_openidserver} if ( $self->{_openidserver} ); $self->{_openidPortal} = $self->{portal} . "/openidserver/"; $self->{_openidPortal} =~ s#(?param(@_) }; $self->{_openidserver} = Lemonldap::NG::Portal::OpenID::Server->new( server_secret => sub { return $self->{openIdSecret} }, post_args => $sub, get_args => $sub, endpoint_url => $self->{_openidPortal}, setup_url => $self->{_openidPortal}, get_user => sub { return $self->{sessionInfo} ->{ $self->{OpenIdAttr} || $self->{whatToTrace} }; }, get_identity => sub { my ( $u, $identity ) = @_; return $identity unless $u; return $self->{_openidPortal} . $u; }, is_identity => sub { my ( $u, $identity ) = @_; return 0 unless ( $u and $identity ); if ( $u eq ( split '/', $identity )[-1] ) { return 1; } else { $self->{_badOpenIdentity} = 1; return 0; } }, is_trusted => sub { my ( $u, $trust_root, $is_identity ) = @_; return 0 unless ( $u and $is_identity ); if ( $self->{sessionInfo}->{"_openidTrust$trust_root"} ) { $self->lmLog( 'OpenID request already trusted', 'debug' ); return 1; } elsif ( $self->param("confirm") == 1 ) { $self->updateSession( { "_openidTrust$trust_root" => 1 } ); return 1; } elsif ( $self->param("confirm") == -1 ) { return 0; } else { $self->lmLog( 'OpenID request not trusted' . $sub->("confirm"), 'debug' ); $self->{_openIdTrustRequired} = 1; return 0; } }, extensions => { sreg => sub { require Lemonldap::NG::Portal::OpenID::SREG; return $self->Lemonldap::NG::Portal::OpenID::SREG::sregHook(@_); }, }, ); return $self->{_openidserver}; } ## @method private int _openIDResponse() # Manage Lemonldap::NG::Portal::OpenID::Server responses # @return Lemonldap::NG::Portal error code sub _openIDResponse { my ( $self, $type, $data ) = splice @_; # TODO: use autoRedirect instead if ( $type eq 'redirect' ) { $self->lmLog( 'OpenID redirection', 'debug' ); print $self->redirect($data); } elsif ( $type eq 'setup' ) { if ( $self->{_openIdTrustRequired} ) { # TODO $self->info( '