r27037 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r27036‎ | r27037 | r27038 >
Date:02:02, 30 October 2007
Author:river
Status:old
Tags:
Comment:
AuthPlugin for Atlassian Crowd SSO system
Modified paths:
  • /trunk/extensions/CrowdAuthentication (added) (history)
  • /trunk/extensions/CrowdAuthentication/CrowdAuthentication.php (added) (history)

Diff [purge]

Index: trunk/extensions/CrowdAuthentication/CrowdAuthentication.php
@@ -0,0 +1,205 @@
 2+<?php
 3+/* Copyright (c) 2007 River Tarnell <river@wikimedia.org>. */
 4+/*
 5+ * Permission is granted to anyone to use this software for any purpose,
 6+ * including commercial applications, and to alter it and redistribute it
 7+ * freely. This software is provided 'as-is', without any express or implied
 8+ * warranty.
 9+ */
 10+/* $Id$ */
 11+/*
 12+ * AuthPlugin that authenticates users against Atlassian Crowd.
 13+ *
 14+ * To use it, add something like this to LocalSettings.php:
 15+ *
 16+ * require_once("$IP/extensions/CrowdAuthentication/CrowdAuthentication.php");
 17+ * $caApplicationName = 'mediawiki';
 18+ * $caApplicationPassword = 'whatever';
 19+ * $caCrowdServerUrl = 'http://localhost:8095/crowd/services';
 20+ * $wgAuth = new CrowdAuthenticator();
 21+ *
 22+ */
 23+
 24+
 25+require_once("AuthPlugin.php");
 26+
 27+class caPasswordCredential {
 28+ public /*string*/ $credential;
 29+};
 30+
 31+class caAuthenticatedToken {
 32+};
 33+
 34+class caPrincipal {
 35+};
 36+
 37+class caSOAPAttribute {
 38+ public /*string*/ $name;
 39+ public /*string[]*/ $values;
 40+
 41+ public function __construct(/*string*/ $name, /*string*/ $value) {
 42+ $this->name = $name;
 43+ $this->values = array($value);
 44+ }
 45+};
 46+
 47+class caApplicationAuthenticationContext {
 48+ public /*PasswordCredential*/ $credential;
 49+ public /*string*/ $name;
 50+ public /*ValidationFactor[]*/ $validationFactors = null;
 51+};
 52+
 53+class caPrincipalAuthenticationContext {
 54+ public /*string*/ $application;
 55+ public /*PasswordCredential*/ $credential;
 56+ public /*string*/ $name;
 57+ public /*ValidationFactor[]*/ $validationFactors = null;
 58+};
 59+
 60+class CrowdAuthenticator extends AuthPlugin {
 61+ private $crowd = null;
 62+ private $token = null;
 63+
 64+ private function /*SoapClient*/ getCrowd() {
 65+ global $caCrowdServerUrl, $caApplicationName, $caApplicationPassword;
 66+
 67+ if (is_null($this->crowd)) {
 68+ $this->crowd = new SoapClient($caCrowdServerUrl . '/SecurityServer?wsdl',
 69+ array('classmap' =>
 70+ array(
 71+ 'ApplicationAuthenticationContext' => 'caApplicationAuthenticationContext',
 72+ 'PrincipalAuthenticationContext' => 'caPrincipalAuthenticationContext',
 73+ 'PasswordCredential' => 'caPasswordCredential',
 74+ 'AuthenticatedToken' => 'caAuthenticatedToken',
 75+ 'SOAPPrincipal' => 'caPrincipal',
 76+ 'SOAPAttribute' => 'caSOAPAttribute',
 77+ ),
 78+ )
 79+ );
 80+ $cred = new caPasswordCredential();
 81+ $cred->credential = $caApplicationPassword;
 82+ $authctx = new caApplicationAuthenticationContext();
 83+ $authctx->credential = $cred;
 84+ $authctx->name = $caApplicationName;
 85+ $t = $this->crowd->authenticateApplication(array("in0" => $authctx));
 86+ $this->token = $t->out;
 87+ }
 88+
 89+ return $this->crowd;
 90+ }
 91+
 92+ private function /*bool*/ findUsername(/*string*/ $name) {
 93+ /*
 94+ * Need to check several variations, e.g. lowercase initial letter,
 95+ * _ instead of ' ', etc.
 96+ */
 97+ $variations = array(
 98+ $name,
 99+ strtolower($name[0]) . substr($name, 1),
 100+ str_replace(" ", "_", $name),
 101+ );
 102+
 103+ $crowd = $this->getCrowd();
 104+ foreach ($variations as $v) {
 105+ try {
 106+ $crowd->findPrincipalByName(array("in0" => $this->token, "in1" => $v));
 107+ return $v;
 108+ } catch (Exception $e) {
 109+ continue;
 110+ }
 111+ }
 112+
 113+ return null;
 114+ }
 115+
 116+ public function /*bool*/ userExists(/*string*/ $name) {
 117+ return !is_null($this->findUsername($name));
 118+ }
 119+
 120+ public function /*bool*/ authenticate(/*string*/ $username, /*string*/ $password) {
 121+ global $caApplicationName;
 122+
 123+ $crowd = $this->getCrowd();
 124+ $cred = new caPasswordCredential();
 125+ $cred->credential = $password;
 126+ $authctx = new caPrincipalAuthenticationContext();
 127+ $authctx->name = $this->findUsername($username);
 128+ $authctx->credential = $cred;
 129+ $authctx->application = $caApplicationName;
 130+
 131+ try {
 132+ $crowd->authenticatePrincipal(array("in0" => $this->token, "in1" => $authctx));
 133+ return true;
 134+ } catch (Exception $e) {
 135+ return false;
 136+ }
 137+ }
 138+
 139+ public function /*bool*/ autoCreate(/*void*/) {
 140+ return true;
 141+ }
 142+
 143+ public function /*bool*/ strict(/*void*/) {
 144+ return true;
 145+ }
 146+
 147+ public function /*bool*/ allowPasswordChange(/*void*/) {
 148+ return true;
 149+ }
 150+
 151+ public function /*bool*/ setPassword(/*User*/ $user, /*string*/ $password) {
 152+ $newcred = new caPasswordCredential;
 153+ $newcred->credential = $password;
 154+ $username = $this->findUsername($user->getName());
 155+ $crowd = $this->getCrowd();
 156+ try {
 157+ $crowd->updatePrincipalCredential(array(
 158+ "in0" => $this->token,
 159+ "in1" => $username,
 160+ "in2" => $newcred));
 161+ return true;
 162+ } catch (Exception $e) {
 163+ return false;
 164+ }
 165+ }
 166+
 167+ public function /*bool*/ canCreateAccounts(/*void*/) {
 168+ return true;
 169+ }
 170+
 171+ public function /*bool*/ addUser(/*User*/ $user, /*string*/ $password,
 172+ /*string*/ $email = '', /*string*/ $realname = '') {
 173+ $crowd = $this->getCrowd();
 174+ $nameparts = split(" ", $realname, 2);
 175+ $firstname = $lastname = "";
 176+ if (count($nameparts) > 0)
 177+ $firstname = $nameparts[0];
 178+ if (count($nameparts) > 1)
 179+ $lastname = $nameparts[1];
 180+ $cred = new caPasswordCredential();
 181+ $cred->credential = $password;
 182+ $principal = new caPrincipal();
 183+ $principal->name = $user->getName();
 184+ $principal->attributes = array(
 185+ new caSOAPAttribute("mail", $email),
 186+ new caSOAPAttribute("givenName", $firstname),
 187+ new caSOAPAttribute("sn", $lastname),
 188+ new caSOAPAttribute("invalidPasswordAttempts", 0),
 189+ new caSOAPAttribute("lastAuthenticated", 0),
 190+ new caSOAPAttribute("passwordLastChanged", 0),
 191+ new caSOAPAttribute("requiresPasswordChange", 0),
 192+ );
 193+ $principal->active = true;
 194+ $principal->conception = 0;
 195+ $principal->lastModified = 0;
 196+
 197+ try {
 198+ $crowd->addPrincipal(array("in0" => $this->token,
 199+ "in1" => $principal,
 200+ "in2" => $cred));
 201+ return true;
 202+ } catch (Exception $e) {
 203+ return false;
 204+ }
 205+ }
 206+};

Status & tagging log