'OpenID', 'version' => '1.1.2', 'url' => 'http://phpquebec.org/', 'author' => 'PHP Quebec Community', 'authorurl' => 'http://phpquebec.org/', 'license' => 'Apache License 2.0', 'description' => 'Adds OpenID 2.0 authentification support.', 'copyright' => '2007' ); } public function filter_rewrite_rules( $db_rules ) { $db_rules[] = new RewriteRule( array( 'name' => 'openid', 'parse_regex' => '%^openid/?(?P[^/]*)/?$%i', // For Server, if previous matched, don't look. 'build_str' => 'openid/({$user})', 'handler' => 'OpenID', 'action' => 'dispatch', 'priority' => 1, 'is_active' => 1, 'rule_class' => RewriteRule::RULE_CUSTOM, 'description' => 'OpenID Authentification' ) ); return $db_rules; } public function act( $action ) { $error_reporting = error_reporting(1); if ( isset( $_GET['openid_mode'] ) ) { switch ( $_GET['openid_mode'] ) { case 'id_res': self::openid_end(); break; case 'cancel': EventLog::log( 'Authorization failed: User cancelled authorization.', 'info', 'authentication', 'OpenID' ); error_reporting($error_reporting); throw new Exception( 'Authorization failed: User cancelled authorization.' ); break; } } else if ( isset( $_POST['openid_url'] ) ) { self::openid_start(); } else { EventLog::log( 'Authorization failed: unknown error.', 'err', 'authentication', 'OpenID' ); error_reporting($error_reporting); throw new Exception( 'Authorization failed: unknown error.' ); } error_reporting($error_reporting); } public function action_plugin_activation( $file ) { if ( realpath( $file ) == __FILE__ ) { if ( !extension_loaded('curl') && !@dl('curl') ) { EventLog::log( 'Could not load CURL, which is needed for OpenID to work.', 'err', 'authentication', 'OpenID' ); throw new Exception( 'Could not load CURL, which is needed for OpenID to work.' ); } EventLog::register_type( 'authentification', 'OpenID' ); } } public function action_plugin_deactivation( $file ) { if ( realpath( $file ) == __FILE__ ) { EventLog::unregister_type( 'OpenID' ); } } public function action_init() { if ( session_id() == '' ) { session_start(); } ini_set( 'include_path', dirname( __FILE__ ) ); Stack::add( 'template_stylesheet', array( $this->get_url() . '/openid.css', 'screen' ), 'openid_style' ); } public function action_theme_loginform_before() { if ( isset( $_GET['openid_url'] ) ) { echo '
If you have an existing account, sign in so we can assign your OpenID identifer to it.
'; } } public function action_theme_loginform_after() { // @todo Remove the !isset( $_GET['openid_url'] ) once registration works in Habari. if ( ( Controller::get_action() != 'register' ) && !isset( $_GET['openid_url'] ) ) { if ( Controller::get_action() == 'login' ) { echo '

'; } else { echo '

'; } } } public function action_theme_loginform_controls() { if ( isset( $_GET['openid_url'] ) ) { echo ''; } } /* Uncomment once registration is supported by Habari. public function action_theme_registerform_controls() { if ( isset( $_GET['openid_url'] ) ) { echo ''; } } */ public function action_theme_admin_user( $user ) { $openid_url = isset( $user->info->openid_url ) ? $user->info->openid_url : ''; echo '

' . _t('OpenID') . '

'; } public function action_user_identify() { if ( ( Controller::get_action() == 'login' ) && !empty( $_POST['openid_url'] ) ) { self::openid_start(); } } // TODO: Add more security against form hijacking (for instance, check against server sent data) public function action_user_authenticate_successful( $user ) { if ( !empty( $_POST['habari_openid_url'] ) ) { $user->info->openid_url = $_POST['habari_openid_url']; } } function action_admin_header( $theme ) { // Add the css if this is the default login page if ( $theme->admin_page == 'login' ) { Stack::add( 'admin_stylesheet', array( $this->get_url() . '/openid.css', 'screen' ), 'openid_style' ); } } function getOpenIDURL() { if ( empty( $_POST['openid_url'] ) ) { EventLog::log( 'Expected an OpenID URL.', 'err', 'authentication', 'OpenID' ); throw new Exception( 'Expected an OpenID URL.' ); } return $_POST['openid_url']; } function getReturnTo() { return URL::get('openid'); } function getTrustRoot() { return Site::get_url('habari'); } function getStore() { $store_path = "/tmp/_php_consumer_test"; if ( !file_exists( $store_path ) && !mkdir( $store_path ) ) { EventLog::log( 'Could not create the FileStore directory: ' . $store_path, 'err', 'authentication', 'OpenID' ); throw new Exception( 'Could not create the FileStore directory: ' . $store_path . '. Please check the effective permissions.' ); } return new Auth_OpenID_FileStore( $store_path ); } function getConsumer() { require_once "Auth/OpenID/Consumer.php"; require_once "Auth/OpenID/FileStore.php"; require_once "Auth/OpenID/SReg.php"; $store = self::getStore(); return new Auth_OpenID_Consumer( $store ); } function openid_start() { $openid = self::getOpenIDURL(); $consumer = self::getConsumer(); $auth_request = $consumer->begin( $openid ); if ( !$auth_request ) { EventLog::log( 'Authentication error: Not a valid OpenID.', 'err', 'authentication', 'OpenID' ); throw new Exception( 'Authentication error: Not a valid OpenID.' ); } $sreg_request = Auth_OpenID_SRegRequest::build( array( 'nickname' ), array( 'fullname', 'email' ) ); if ( $sreg_request ) { $auth_request->addExtension( $sreg_request ); } if ( !$auth_request->shouldSendRedirect() ) { $redirect_url = $auth_request->redirectURL( self::getTrustRoot(), self::getReturnTo() ); if ( Auth_OpenID::isFailure( $redirect_url ) ) { EventLog::log( 'Could not redirect to server: ' . $redirect_url->message, 'err', 'authentication', 'OpenID' ); throw new Exception( 'Could not redirect to server: ' . $redirect_url->message ); } else { header( "Location: ".$redirect_url ); } } else { $form_id = 'openid_message'; $form_html = $auth_request->formMarkup( self::getTrustRoot(), self::getReturnTo(), false, array( 'id' => $form_id ) ); if ( Auth_OpenID::isFailure( $form_html ) ) { EventLog::log( 'Could not prepare redirection form: ' . $form_html->message, 'err', 'authentication', 'OpenID' ); throw new Exception( 'Could not prepare redirection form: ' . $form_html->message ); } else { echo ' OpenID transaction in progress '.$form_html.' '; } } } function openid_end() { $consumer = self::getConsumer(); $return_to = self::getReturnTo(); $response = $consumer->complete( $return_to ); switch( $response->status ) { case Auth_OpenID_CANCEL: EventLog::log( 'Verification cancelled.', 'err', 'authentication', 'OpenID' ); throw new Exception( 'Verification cancelled.' ); break; case Auth_OpenID_FAILURE: EventLog::log( 'OpenID authentication failed: ' . $response->message, 'err', 'authentication', 'OpenID' ); throw new Exception( 'OpenID authentication failed: ' . $response->message ); break; case Auth_OpenID_SUCCESS: $openid = $response->getDisplayIdentifier(); $esc_identity = htmlspecialchars( $openid, ENT_QUOTES ); $user = Users::get_by_info( 'openid_url', $openid ); if ( count( $user ) != 0 ) { if ( count( $user ) > 1 ) { EventLog::log( 'Authentication error: More than one user has this OpenID.', 'err', 'authentication', 'OpenID' ); throw new Exception( 'Authentication error: More than one user has this OpenID.' ); } $user[0]->remember(); EventLog::log( 'Successful login for ' . $user[0]->username, 'info', 'authentication', 'OpenID' ); header( "HTTP/1.1 100 Continue" ); header( "Location: " . Site::get_url( 'admin' ) ); header( "Connection: close" ); } else { Utils::redirect( URL::get( 'user', array( 'page'=>'login', 'openid_url' => $openid ), true ) ); } } } function openid_comment_end( ActionHandler $handler ) { $consumer = self::getConsumer(); $return_to = URL::get( 'submit_feedback', array('id' => $handler->handler_vars['id'])); $response = $consumer->complete( $return_to ); switch( $response->status ) { case Auth_OpenID_CANCEL: throw new Exception(_t('OpenID Verification cancelled.', 'openid')); break; case Auth_OpenID_FAILURE: throw new Exception(_t('OpenID authentication failed: %s', array($response->message), 'openid')); break; case Auth_OpenID_SUCCESS: $openid = $response->getDisplayIdentifier(); $esc_identity = htmlspecialchars( $openid, ENT_QUOTES ); $sreg_resp = Auth_OpenID_SRegResponse::fromSuccessResponse($response); $sreg = $sreg_resp->contents(); $sreg['openid'] = $openid; return $sreg; } } public function openid_comment_start( ActionHandler $handler ) { $openid = $handler->handler_vars['openid_url']; $consumer = self::getConsumer(); $auth_request = $consumer->begin( $openid ); if ( !$auth_request ) { throw new Exception(_t('Authentication error: Not a valid OpenID.', 'openid')); return; } $sreg_request = Auth_OpenID_SRegRequest::build( array( 'fullname', 'email' ), array( 'nickname' ) ); if ( $sreg_request ) { $auth_request->addExtension( $sreg_request ); } if ( !$auth_request->shouldSendRedirect() ) { $redirect_url = $auth_request->redirectURL( self::getTrustRoot(), URL::get( 'submit_feedback', array('id' => $handler->handler_vars['id'])) ); if ( Auth_OpenID::isFailure( $redirect_url ) ) { throw new Exception( 'Could not redirect to server: ' . $redirect_url->message ); } else { //die($redirect_url); header( "Location: ".$redirect_url ); exit; } } else { $form_id = 'openid_message'; $form_html = $auth_request->formMarkup( self::getTrustRoot(), URL::get( 'submit_feedback', array('id' => $handler->handler_vars['id'])), false, array( 'id' => $form_id ) ); if ( Auth_OpenID::isFailure( $form_html ) ) { throw new Exception( 'Could not prepare redirection form: ' . $form_html->message ); } else { echo ' OpenID transaction in progress '.$form_html.' '; exit; } } } public function action_comment_insert_before( Comment $comment ) { if ($this->approve_it) { $comment->status = 'ham'; } } public function action_before_act_add_comment( ActionHandler &$handler ) { $error_reporting = error_reporting(1); if ( isset($_GET['openid_mode']) ) { switch ($_GET['openid_mode']) { case 'id_res': try { $data = self::openid_comment_end($handler); $session = Session::get_set('comment'); $handler->handler_vars['content'] = $session['content']; $handler->handler_vars['url'] = $data['openid']; $handler->handler_vars['name'] = $data['fullname']; $handler->handler_vars['email'] = $data['email']; $this->approve_it = true; } catch (Exception $e) { Session::error(_t('OpenID Error: %s', array($e->getMessage()), 'openid')); } break; case 'cancel': Session::error(_t('Authorization failed: User cancelled authorization.', 'openid')); break; } } elseif ( isset($_POST['openid_url']) && $_POST['openid_url'] != null ) { try { Session::add_to_set('comment', Controller::get_var('content'), 'content'); self::openid_comment_start($handler); } catch (Exception $e) { Session::error(_t('OpenID Error: %s', array($e->getMessage()), 'openid')); } } else { Session::error(_t('Your OpenID Identifier is required.', 'openid')); } if ( Session::has_errors() ) { $post = Post::get( array( 'id'=>$handler->handler_vars['id'] ) ); Session::add_to_set('comment', Controller::get_var('content'), 'content'); Session::add_to_set('comment', '', 'name'); Session::add_to_set('comment', '', 'email'); Session::add_to_set('comment', '', 'url'); Utils::redirect( $post->permalink . '#respond' ); exit; } error_reporting($error_reporting); } } ?>