http://www.mediawiki.org/wiki/Special:Code/MediaWiki/94219
Revision: 94219
Author: neilk
Date: 2011-08-11 01:50:11 +0000 (Thu, 11 Aug 2011)
Log Message:
-----------
experimental identity api, so chat server / etherpad can authenticate a user as
being logged into the wiki via MediaWiki api
Added Paths:
-----------
branches/extensions-realtime/IdentityApi/
branches/extensions-realtime/IdentityApi/IdentityApi.class.php
branches/extensions-realtime/IdentityApi/IdentityApi.i18n.php
branches/extensions-realtime/IdentityApi/IdentityApi.php
branches/extensions-realtime/IdentityApi/README
branches/extensions-realtime/IdentityApi/api/
branches/extensions-realtime/IdentityApi/api/ApiQueryIdentity.php
branches/extensions-realtime/IdentityApi/api/ApiQueryVerifyIdentity.php
Added: branches/extensions-realtime/IdentityApi/IdentityApi.class.php
===================================================================
--- branches/extensions-realtime/IdentityApi/IdentityApi.class.php
(rev 0)
+++ branches/extensions-realtime/IdentityApi/IdentityApi.class.php
2011-08-11 01:50:11 UTC (rev 94219)
@@ -0,0 +1,116 @@
+<?php
+
+/**
+ * Static class for general functions of the IdentityApi extension.
+ *
+ * @file IdentityApi.classphp
+ *
+ * @licence GNU GPL v2 or later
+ * @author Neil Kandalgaonkar <[email protected]>
+ */
+
+class IdentityApi {
+
+ /**
+ * Return authentication parameters for currently logged in user, or
null
+ * @return {Null|Array}
+ */
+ public static function getAuthParams() {
+ global $wgUser, $wgServer, $wgScriptPath, $wgMemc,
$wgIdentityApiConfig;
+
+ if ( !( $wgUser && $wgUser->isLoggedIn() ) ) {
+ return null;
+ }
+
+ $data = array(
+ 'user_id' => $wgUser->getId(),
+ 'cookie' => $_COOKIE,
+ );
+ $token = $wgUser->generateToken();
+
+ $wgMemc->set( wfMemcKey( $token ), $data,
$wgIdentityApiConfig['timeoutSeconds'] );
+
+ return array(
+ 'apiurl' => $wgServer . $wgScriptPath . '/api.php',
+ 'username' => $wgUser->getName(),
+ 'token' => $token
+ );
+ }
+
+ /**
+ * Verifies that this user is logged in -- using memcached
+ * @param User
+ * @param String token, which we created in getAuth()
+ * @param Array extra queries, array of strings that represent what
other info to return
+ * @return Array key-val, including 'verified' => boolean, and any
other properties that may have
+ * been asked for in $extra
+ */
+ public static function verifyAuthParams( $user, $token, $extras ) {
+ global $wgMemc;
+ $ret = array( 'verified' => false );
+ $data = $wgMemc->get( wfMemcKey( $token ) );
+ if ( isset( $data ) and $data !== null and $data['user_id'] ) {
+ $ret['verified'] = ( intval( $user->getId() ) ===
intval( $data['user_id'] ) );
+ }
+ if ( $ret['verified'] ) {
+ $ret = array_merge( $ret, IdentityApi::getExtraInfo(
$user, $data, $extras ) );
+ }
+ return $ret;
+ }
+
+ /**
+ * Gets additional information, as specified in $extras
+ * @param User
+ * @param Array (data as was stored)
+ * @param Array (array of strings, options for what data to return);
+ */
+ public static function getExtraInfo( $user, $data, $extras ) {
+ global $wgServer, $wgArticlePath;
+ $ret = array();
+ foreach ( $extras as $extra ) {
+ $extraInfo = array();
+ if ( preg_match( '/^avatarSrc=(\\d+)$/', $extra,
$matches ) ) {
+ if ( class_exists( 'AvatarService' ) ) {
+ $avatarSize = intval( $matches[1] );
+ $ret['avatarSrc'] =
AvatarService::getAvatarUrl( $user->getName(), $avatarSize );
+ }
+ }
+ switch ( $extra ) {
+ case 'chat':
+ if ( class_exists( 'Chat' ) ) {
+ $canChat = Chat::canChat( $user
);
+ if ( $canChat ) {
+ $ret['canChat'] =
$canChat;
+ $ret['isChatMod'] =
$user->isAllowed( 'chatmoderator' );
+ $userChangeableGroups =
$user->changeableGroups(); // php makes us use a temp variable here, sigh
+
$ret['isCanGiveChatMode'] = in_array( 'chatmoderator',
$userChangeableGroups['add'] );
+ // TODO if still
relevant, check for cross-wiki chat hack (see
https://svn.wikia-code.com/wikia/trunk/extensions/wikia/Chat/ChatAjax.class.php
)
+ // TODO get user stats
for chat (see
https://svn.wikia-code.com/wikia/trunk/extensions/wikia/Chat/ChatAjax.class.php
)
+ }
+ }
+ break;
+ case 'cookie':
+ $ret['cookie'] = $data['cookie'];
+ break;
+ case 'isLoggedIn':
+ $ret['isLoggedIn'] =
$user->isLoggedIn();
+ break;
+ case 'isStaff':
+ // Wikia-specific
+ $ret['isStaff'] = $user->isAllowed(
'staff' );
+ break;
+ case 'username':
+ $ret['username'] = $user->getName();
+ break;
+ case 'wgServer':
+ $ret['wgServer'] = $wgServer;
+ case 'wgArticlePath':
+ $ret['wgArticlePath'] = $wgArticlePath;
+ default:
+ break;
+ }
+ }
+ return $ret;
+ }
+
+}
Property changes on:
branches/extensions-realtime/IdentityApi/IdentityApi.class.php
___________________________________________________________________
Added: svn:eol-style
+ native
Added: branches/extensions-realtime/IdentityApi/IdentityApi.i18n.php
===================================================================
--- branches/extensions-realtime/IdentityApi/IdentityApi.i18n.php
(rev 0)
+++ branches/extensions-realtime/IdentityApi/IdentityApi.i18n.php
2011-08-11 01:50:11 UTC (rev 94219)
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * Internationalization file for IdentityApi extension.
+ *
+ * @file IdentityApi.i18n.php
+ *
+ * @licence GNU GPL v2 or later
+ * @author Neil Kandalgaonkar <[email protected]>
+ */
+
+$messages = array();
+
+/** English
+ * @author Neil Kandalgaonkar <[email protected]>
+ */
+$messages['en'] = array(
+ 'identityapi-desc' => 'Provides API methods that help a remote service
verify the identity of a user on this wiki'
+);
Property changes on:
branches/extensions-realtime/IdentityApi/IdentityApi.i18n.php
___________________________________________________________________
Added: svn:eol-style
+ native
Added: branches/extensions-realtime/IdentityApi/IdentityApi.php
===================================================================
--- branches/extensions-realtime/IdentityApi/IdentityApi.php
(rev 0)
+++ branches/extensions-realtime/IdentityApi/IdentityApi.php 2011-08-11
01:50:11 UTC (rev 94219)
@@ -0,0 +1,58 @@
+<?php
+
+/**
+ * Provides a means for users to verify their identity on this wiki to a
remote service.
+ *
+ * For example: imagine if you wanted to associate a chat service with your
wiki, and users should have the same names on
+ * the chat service as they do on the wiki. This isn't as complicated of a
case as OpenID or oAuth, we just want two well-known services
+ * run by the same organization to verify identity.
+ *
+ * This could also be done with a shared secret, but this way we can avoid
having to distribute that secret or keep it up to date, and there
+ * aren't any consequences if the secret is discovered.
+ *
+ * Documentation:
http://www.mediawiki.org/wiki/Extension:IdentityApi
+ * Source code:
http://svn.wikimedia.org/viewvc/mediawiki/trunk/extensions/IdentityApi
+ *
+ * @author Neil Kandalgaonkar <[email protected]>
+ * @license GPL v2 or later
+ */
+
+if ( !defined( 'MEDIAWIKI' ) ) {
+ die( 'Not an entry point.' );
+}
+
+if ( version_compare( $wgVersion, '1.17', '<' ) ) {
+ die( 'This extension requires MediaWiki 1.17 or above.' );
+}
+
+if ( ! $wgSessionsInMemcached ) {
+ die( 'This extension requires you to be storing sessions in Memcached
(for now)' );
+}
+
+
+define( 'IdentityApi_VERSION', '0.1' );
+
+$wgExtensionCredits['other'][] = array(
+ 'path' => __FILE__,
+ 'name' => 'IdentityApi',
+ 'version' => IdentityApi_VERSION,
+ 'author' => array(
+ '[http://www.mediawiki.org/wiki/User:NeilK NeilK]',
+ ),
+ 'url' => 'http://www.mediawiki.org/wiki/Extension:IdentityApi',
+ 'descriptionmsg' => 'identityapi-desc'
+);
+
+$wgExtensionMessagesFiles['IdentityApi'] = dirname( __FILE__ ) .
'/IdentityApi.i18n.php';
+
+$wgAutoloadClasses['IdentityApi'] = dirname( __FILE__ ) .
'/IdentityApi.class.php';
+
+$wgAutoloadClasses['ApiQueryVerifyIdentity'] = dirname( __FILE__ ) .
'/api/ApiQueryVerifyIdentity.php';
+$wgAPIModules['verifyidentity'] = 'ApiQueryVerifyIdentity';
+$wgAutoloadClasses['ApiQueryIdentity'] = dirname( __FILE__ ) .
'/api/ApiQueryIdentity.php';
+$wgAPIModules['identity'] = 'ApiQueryIdentity';
+
+
+$wgIdentityApiConfig = array(
+ 'timeoutSeconds' => 60 * 60 * 24 // one day
+);
Property changes on: branches/extensions-realtime/IdentityApi/IdentityApi.php
___________________________________________________________________
Added: svn:eol-style
+ native
Added: branches/extensions-realtime/IdentityApi/README
===================================================================
--- branches/extensions-realtime/IdentityApi/README
(rev 0)
+++ branches/extensions-realtime/IdentityApi/README 2011-08-11 01:50:11 UTC
(rev 94219)
@@ -0,0 +1,12 @@
+This extension is experimental. It should not be used by anyone in a
production environment.
+
+The purpose of this extension is to act as a sort of identity helper for other
non-MediaWiki services that might be
+run in the same hosting environment. An example might be a chat server, where
it is desirable that users have the same
+user name on the chat as they do on the wiki (and that users cannot
impersonate one another).
+
+This implementation is based on Wikia's Chat module AJAX functions[1], but
tries to be more general.
+
+-- Neil Kandalgaonkar <[email protected]> 10 Aug 2011
+
+
+[1] See
https://svn.wikia-code.com/wikia/trunk/extensions/wikia/Chat/ChatAjax.class.php
Added: branches/extensions-realtime/IdentityApi/api/ApiQueryIdentity.php
===================================================================
--- branches/extensions-realtime/IdentityApi/api/ApiQueryIdentity.php
(rev 0)
+++ branches/extensions-realtime/IdentityApi/api/ApiQueryIdentity.php
2011-08-11 01:50:11 UTC (rev 94219)
@@ -0,0 +1,79 @@
+<?php
+
+/**
+ * API module to allow a non-mediawiki service to know that a certain user is
who s/he claims to be on this wiki.
+ * See the README for what this extension is and isn't.
+ *
+ * @file ApiQueryIdentity.php
+ *
+ * @licence GNU GPL v2 or later
+ * @author Neil Kandalgaonkar <[email protected]>
+ */
+class ApiQueryIdentity extends ApiQueryBase {
+ public function __construct( $main, $action ) {
+ parent::__construct( $main, $action, 'vi' );
+ }
+
+ /**
+ * Obtain data we can pass for the purposes of verifying a user later
+ */
+ public function execute() {
+ $auth = IdentityApi::getAuthParams( $user );
+
+ if ( $auth === null ) {
+ $this->dieUsage( 'Could not obtain auth credentials -
are you logged in?', 'mustbeloggedin' );
+ }
+
+ // a wiki is identified by the root URL of the API --
everything else about a wiki is
+ // dependent on Apache configuration
+ foreach ( $auth as $key => $val ) {
+ $this->getResult()->addValue( 'authentication', $key,
$val );
+ }
+
+ }
+
+ /**
+ * ???? do we need this? XSRF? TODO
+ * Indicates whether this module must be called with a POST request
+ * @return bool
+ */
+ public function mustBePosted() {
+ return false;
+ }
+
+ /**
+ * Probably needed to avoid XSRF -- TODO
+ * Returns whether this module requires a Token to execute
+ * @return bool
+ */
+ public function needsToken() {
+ return false;
+ }
+
+ public function getAllowedParams() {
+ return array();
+ }
+
+ public function getParamDescription() {
+ return array();
+ }
+
+ public function getDescription() {
+ return 'API module to allow a non-mediawiki service to know
that a certain user is who s/he claims to be on this wiki';
+ }
+
+ public function getPossibleErrors() {
+ return array();
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=identity'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id: $';
+ }
+
+}
Property changes on:
branches/extensions-realtime/IdentityApi/api/ApiQueryIdentity.php
___________________________________________________________________
Added: svn:eol-style
+ native
Added: branches/extensions-realtime/IdentityApi/api/ApiQueryVerifyIdentity.php
===================================================================
--- branches/extensions-realtime/IdentityApi/api/ApiQueryVerifyIdentity.php
(rev 0)
+++ branches/extensions-realtime/IdentityApi/api/ApiQueryVerifyIdentity.php
2011-08-11 01:50:11 UTC (rev 94219)
@@ -0,0 +1,89 @@
+<?php
+
+/**
+ * API module to allow a non-mediawiki service to know that a certain user is
who s/he claims to be on this wiki.
+ * See the README for what this extension is and isn't.
+ *
+ * @file ApiQueryVerifyIdentity.php
+ *
+ * @licence GNU GPL v2 or later
+ * @author Neil Kandalgaonkar <[email protected]>
+ */
+class ApiQueryVerifyIdentity extends ApiQueryBase {
+ public function __construct( $main, $action ) {
+ parent::__construct( $main, $action, 'vi' );
+ }
+
+ /**
+ * Verify that a user has a certain active login session.
+ */
+ public function execute() {
+ $params = $this->extractRequestParams();
+ $result = array( 'verified' => false );
+
+ // check if this user is a user who can login
+ if ( User::isUsableName( $params['user'] ) ) {
+ // and even exists
+ $userId = User::idFromName( $params['user'] );
+ if ( $userId !== null ) {
+ $user = User::newFromId( $userId );
+ $token = $params['token'];
+ $extras = preg_split( '/\|/', $params['extras']
);
+ $result = IdentityApi::verifyAuthParams( $user,
$token, $extras );
+ }
+ }
+
+ foreach ( $result as $key => $val ) {
+ $this->getResult()->addValue( 'authentication', $key,
$val );
+ }
+ }
+
+ public function getAllowedParams() {
+ return array (
+ 'user' => array(
+ ApiBase::PARAM_TYPE => 'string',
+ ApiBase::PARAM_REQUIRED => true,
+ ),
+ 'token' => array(
+ ApiBase::PARAM_TYPE => 'string',
+ ApiBase::PARAM_REQUIRED => true,
+ ),
+ 'extras' => array(
+ ApiBase::PARAM_TYPE => 'string',
+ ApiBase::PARAM_REQUIRED => false,
+ ApiBase::PARAM_DFLT => '',
+ )
+ );
+ }
+
+ public function getParamDescription() {
+ return array (
+ 'token' => 'The token that the user offers as proof of
their identity; obtained through an identity API query',
+ 'user' => 'The username the user claims to have on this
wiki',
+ 'extras' => 'If verified, extra information to return
about the user or the wiki, delimited by pipe (|) characters.'
+ . ' Possible values: avatarSrc, chat, cookie,
isLoggedIn, isStaff, username, wgServer, wgArticlePath',
+ );
+ }
+
+ public function getDescription() {
+ return 'API module to allow a non-mediawiki service to know
that a certain user is who s/he claims to be on this wiki';
+ }
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'missingparam', 'token' ),
+ array( 'missingparam', 'user' )
+ ) );
+ }
+
+ protected function getExamples() {
+ return array (
+
'api.php?action=verifyidentity&viuser=NeilK&vitoken=abcdef123456&viextras=avatarSrc|chat|cookie|isStaff|username',
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id: $';
+ }
+
+}
Property changes on:
branches/extensions-realtime/IdentityApi/api/ApiQueryVerifyIdentity.php
___________________________________________________________________
Added: svn:eol-style
+ native
_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs