Index: trunk/extensions/NssMySQLAuth/NssMySQLAuthPlugin.php |
— | — | @@ -0,0 +1,149 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +/* |
| 5 | + * A plugin to authenticate against a libnss-mysql database |
| 6 | + * |
| 7 | + * Copyright 2008 - Bryan Tong Minh / Delft Aerospace Rocket Engineering |
| 8 | + * Licensed under the terms of the GNU General Public License, version 2 |
| 9 | + * or any later version. |
| 10 | + * |
| 11 | + */ |
| 12 | + |
| 13 | +class NssMySQLAuthPlugin extends AuthPlugin { |
| 14 | + static function initialize() { |
| 15 | + global $wgAuth, $wgHooks; |
| 16 | + global $wgNssMySQLAuthDB; |
| 17 | + $wgAuth = new self( $wgNssMySQLAuthDB ); |
| 18 | + |
| 19 | + $wgHooks['UserEffectiveGroups'][] = array( $wgAuth, 'onUserEffectiveGroups' ); |
| 20 | + $wgHooks['UserGetEmail'][] = array( $wgAuth, 'onUserGetEmail' ); |
| 21 | + $wgHooks['UserSetEmail'][] = array( $wgAuth, 'onUserSetEmail' ); |
| 22 | + } |
| 23 | + |
| 24 | + function __construct( $wikiName = false ) { |
| 25 | + $this->wikiName = $wikiName; |
| 26 | + $this->users = array(); |
| 27 | + } |
| 28 | + |
| 29 | + function getDB( $db = DB_LAST ) { |
| 30 | + return wfGetDB( $db, array(), $this->wikiName ); |
| 31 | + } |
| 32 | + |
| 33 | + function userExists( $username ) { |
| 34 | + if( isset( $this->users[$username] )) |
| 35 | + return $this->users[$username]; |
| 36 | + |
| 37 | + $dbr = $this->getDB( DB_READ ); |
| 38 | + return $this->users[$username] = |
| 39 | + false !== $dbr->select( |
| 40 | + 'passwd', 1, array( 'pwd_name' => $username ), |
| 41 | + __METHOD__ |
| 42 | + ); |
| 43 | + } |
| 44 | + |
| 45 | + function authenticate( $username, $password ) { |
| 46 | + $dbr = $this->getDB( DB_READ ); |
| 47 | + $res = $dbr->selectRow( |
| 48 | + 'passwd', |
| 49 | + array( 'pwd_name', 'pwd_password' ), |
| 50 | + array( 'pwd_name' => $username ), |
| 51 | + __METHOD__ |
| 52 | + ); |
| 53 | + if( $res === false ) return false; |
| 54 | + |
| 55 | + return Md5crypt::encryptPassword( $password, $res->pwd_password ) |
| 56 | + == $res->pwd_password; |
| 57 | + } |
| 58 | + |
| 59 | + function updateUser( &$user ) { |
| 60 | + $dbr = $this->getDB( DB_READ ); |
| 61 | + $res = $dbr->selectRow( |
| 62 | + 'passwd', |
| 63 | + array( 'pwd_email' ), |
| 64 | + array( 'pwd_name' => $user->getName() ), |
| 65 | + __METHOD__ |
| 66 | + ); |
| 67 | + |
| 68 | + if( $res === false ) return true; |
| 69 | + |
| 70 | + $user->setEmail( $res->pwd_email ); |
| 71 | + return true; |
| 72 | + } |
| 73 | + |
| 74 | + function autoCreate() { |
| 75 | + return true; |
| 76 | + } |
| 77 | + function setPassword( $user, $password ) { |
| 78 | + $encryptedPassword = Md5crypt::encryptPassword( $password ); |
| 79 | + $dbw = $this->getDB( DB_WRITE ); |
| 80 | + return true == $dbw->update( |
| 81 | + 'passwd', |
| 82 | + array( |
| 83 | + 'pwd_password' => $encryptedPassword, |
| 84 | + 'pwd_password_lastchange' => wfTimestamp( TS_UNIX ), |
| 85 | + ), |
| 86 | + array( 'pwd_name' => $user->getName() ), |
| 87 | + __METHOD__ |
| 88 | + ); |
| 89 | + } |
| 90 | + |
| 91 | + function updateExternalDB( $user ) { |
| 92 | + // Email updated via hook |
| 93 | + return true; |
| 94 | + } |
| 95 | + |
| 96 | + function canCreateAccounts() { |
| 97 | + return false; |
| 98 | + } |
| 99 | + |
| 100 | + function addUser( $user, $password, $email='', $realname='' ) { |
| 101 | + return false; |
| 102 | + } |
| 103 | + |
| 104 | + function strict() { |
| 105 | + return false; |
| 106 | + } |
| 107 | + |
| 108 | + function onUserEffectiveGroups( &$user, &$groups ) { |
| 109 | + if( !$this->userExists( $user->getName() ) ) |
| 110 | + return true; |
| 111 | + |
| 112 | + $dbr = $this->getDB( DB_READ ); |
| 113 | + $res = $dbr->select( |
| 114 | + array( 'passwd', 'group_membership' ), |
| 115 | + array( 'gm_group' ), |
| 116 | + array( 'pwd_uid = gm_user', 'pwd_name' => $user->getName() ), |
| 117 | + __METHOD__ |
| 118 | + ); |
| 119 | + while( $row = $res->fetchObject() ) |
| 120 | + $groups[] = $row->gm_group; |
| 121 | + |
| 122 | + return true; |
| 123 | + } |
| 124 | + |
| 125 | + function onUserGetEmail( $user, &$address ) { |
| 126 | + if( !$this->userExists( $user->getName() ) ) |
| 127 | + return true; |
| 128 | + |
| 129 | + $dbr = $this->getDB( DB_READ ); |
| 130 | + $row = $dbr->selectRow( 'passwd' , 'pwd_email', |
| 131 | + array( 'pwd_name' => $user->getName() ) ); |
| 132 | + if( $row ) $address = $row->pwd_email; |
| 133 | + return true; |
| 134 | + |
| 135 | + } |
| 136 | + |
| 137 | + function onUserSetEmail( $user, &$address ) { |
| 138 | + if( !$this->userExists( $user->getName() ) ) |
| 139 | + return true; |
| 140 | + |
| 141 | + $dbw = $this->getDB( DB_WRITE ); |
| 142 | + return true == $dbw->update( |
| 143 | + 'passwd', |
| 144 | + array( 'pwd_email' => $address ), |
| 145 | + array( 'pwd_name' => $user->getName() ), |
| 146 | + __METHOD__ |
| 147 | + ); |
| 148 | + } |
| 149 | + |
| 150 | +} |
Property changes on: trunk/extensions/NssMySQLAuth/NssMySQLAuthPlugin.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 151 | + native |
Index: trunk/extensions/NssMySQLAuth/NssMySQLAuth.php |
— | — | @@ -0,0 +1,29 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +/* |
| 5 | + * A plugin to authenticate against a libnss-mysql database |
| 6 | + * |
| 7 | + * Copyright 2008 - Bryan Tong Minh / Delft Aerospace Rocket Engineering |
| 8 | + * Licensed under the terms of the GNU General Public License, version 2 |
| 9 | + * or any later version. |
| 10 | + * |
| 11 | + */ |
| 12 | + |
| 13 | + ### READ BEFORE USING ### |
| 14 | + /* |
| 15 | + * This plugin allows authentication against an libnss-mysql database and thus |
| 16 | + * allows the use of the same login for MediaWiki as for shell. |
| 17 | + * |
| 18 | + */ |
| 19 | + |
| 20 | + |
| 21 | +$wgAutoloadClasses['NssMySQLAuthPlugin'] = dirname( __FILE__ ) . '/NssMySQLAuthPlugin.php'; |
| 22 | +$wgAutoloadClasses['Md5crypt'] = dirname( __FILE__ ) . '/Md5crypt.php'; |
| 23 | +$wgAutoloadClasses['SpecialAccountManager'] = dirname( __FILE__ ) . '/SpecialAccountManager.php'; |
| 24 | +$wgSpecialPages['AccountManager'] = 'SpecialAccountManager'; |
| 25 | + |
| 26 | +$wgNssMySQLAuthDB = false; |
| 27 | + |
| 28 | +$wgExtensionFunctions[] = array( 'NssMySQLAuthPlugin', 'initialize' ); |
| 29 | + |
| 30 | +$wgUserProperties = array( 'address', 'city' ); |
Property changes on: trunk/extensions/NssMySQLAuth/NssMySQLAuth.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 31 | + native |
Index: trunk/extensions/NssMySQLAuth/tables.sql |
— | — | @@ -0,0 +1,60 @@ |
| 2 | +CREATE DATABASE nss_auth; |
| 3 | + |
| 4 | +USE nss_auth; |
| 5 | + |
| 6 | +CREATE TABLE passwd ( |
| 7 | + pwd_uid int not null, |
| 8 | + pwd_name varchar(255), |
| 9 | + pwd_password varbinary(255), |
| 10 | + pwd_password_lastchange int not null, |
| 11 | + pwd_gid int not null, |
| 12 | + pwd_home varchar(255) default null, |
| 13 | + pwd_shell varchar(255) default '/bin/sh', |
| 14 | + pwd_active varchar(15) default 1, |
| 15 | + pwd_email varchar(255) not null, |
| 16 | + |
| 17 | + PRIMARY KEY (pwd_uid), |
| 18 | + UNIQUE INDEX (pwd_name) |
| 19 | +) character set ascii collate ascii_general_ci; |
| 20 | + |
| 21 | +CREATE TABLE groups ( |
| 22 | + grp_gid int not null, |
| 23 | + grp_name varchar(255), |
| 24 | + grp_password varchar(255) not null, |
| 25 | + |
| 26 | + PRIMARY KEY(grp_gid), |
| 27 | + INDEX (grp_name) |
| 28 | +) character set ascii collate ascii_general_ci; |
| 29 | + |
| 30 | +CREATE TABLE group_membership ( |
| 31 | + gm_user int not null, |
| 32 | + gm_group varchar(255), |
| 33 | + |
| 34 | + PRIMARY KEY (gm_user, gm_group), |
| 35 | + KEY (gm_group) |
| 36 | +) character set ascii collate ascii_general_ci; |
| 37 | + |
| 38 | +CREATE TABLE permission ( |
| 39 | + perm_user int not null, |
| 40 | + perm_action varbinary(255), |
| 41 | + perm_permission varbinary(255) |
| 42 | +) character set ascii collate ascii_general_ci; |
| 43 | + |
| 44 | +CREATE TABLE user_props ( |
| 45 | + up_user varchar(255), |
| 46 | + up_timestamp binary(14), |
| 47 | + up_name varchar(255), |
| 48 | + up_value blob, |
| 49 | + |
| 50 | + INDEX(up_name), |
| 51 | + INDEX(up_user, up_timestamp) |
| 52 | +) character set ascii collate ascii_general_ci; |
| 53 | + |
| 54 | +GRANT USAGE ON nss_auth.* TO `nss-root`@`localhost` IDENTIFIED BY 'secretpassword'; |
| 55 | +GRANT USAGE ON nss_auth.* TO `nss-user`@`localhost` IDENTIFIED BY 'publiclyviewablepassword'; |
| 56 | + |
| 57 | +GRANT SELECT ON nss_auth.* TO `nss-root`@`localhost`; |
| 58 | +GRANT SELECT (pwd_uid, pwd_name, pwd_gid, pwd_home, pwd_shell, pwd_active) ON nss_auth.passwd TO `nss-user`@`localhost`; |
| 59 | +GRANT SELECT ON nss_auth.groups TO `nss-user`@`localhost`; |
| 60 | +GRANT SELECT ON nss_auth.group_membership TO `nss-user`@`localhost`; |
| 61 | + |
Property changes on: trunk/extensions/NssMySQLAuth/tables.sql |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 62 | + native |
Index: trunk/extensions/NssMySQLAuth/libnss-mysql.cfg |
— | — | @@ -0,0 +1,16 @@ |
| 2 | +getpwnam SELECT pwd_name, 'x', pwd_uid, pwd_gid, '', pwd_home, pwd_shell FROM passwd WHERE pwd_name = '%1$s' LIMIT 1 |
| 3 | +getpwuid SELECT pwd_name, 'x', pwd_uid, pwd_gid, '', pwd_home, pwd_shell FROM passwd WHERE pwd_uid = '%1$u' LIMIT 1 |
| 4 | +getspnam SELECT pwd_name, pwd_password, pwd_password_lastchange, 0, 3650000, 7, -1, -1, 0 FROM passwd WHERE pwd_name = '%1$s' LIMIT 1 |
| 5 | +getpwent SELECT pwd_name, 'x', pwd_uid, pwd_gid, '', pwd_home, pwd_shell FROM passwd |
| 6 | +getspent SELECT pwd_name, pwd_password, pwd_password_lastchange, 0, 3650000, 7, -1, -1, 0 FROM passwd |
| 7 | +getgrnam SELECT grp_name, grp_password, grp_gid FROM groups WHERE grp_name = '%1$u' LIMIT 1 |
| 8 | +getgrgid SELECT grp_name, grp_password, grp_gid FROM groups WHERE grp_gid = '%1$u' LIMIT 1 |
| 9 | +getgrent SELECT grp_name, grp_password, grp_gid FROM groups |
| 10 | +memsbygid SELECT pwd_name FROM group_membership, groups, passwd WHERE gm_group = grp_name AND gm_user = pwd_uid AND grp_gid = '%1$u' |
| 11 | +gidsbymem SELECT grp_gid FROM group_membership, groups, passwd WHERE gm_group = grp_name AND gm_user = pwd_uid AND pwd_name = '%1$s' |
| 12 | + |
| 13 | +host localhost |
| 14 | +database nss_auth |
| 15 | +username nss-user |
| 16 | +password publiclyviewablepassword |
| 17 | +socket /var/run/mysqld/mysqld.sock |
Property changes on: trunk/extensions/NssMySQLAuth/libnss-mysql.cfg |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 18 | + native |
Index: trunk/extensions/NssMySQLAuth/Md5crypt.php |
— | — | @@ -0,0 +1,145 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +/* |
| 5 | + |
| 6 | +md5crypt.php5 |
| 7 | +-------------- |
| 8 | +Modified by |
| 9 | + - Bryan Tong Minh |
| 10 | + |
| 11 | +Written by |
| 12 | + |
| 13 | + - Dennis Riehle <selfhtml@riehle-web.com> |
| 14 | + |
| 15 | +Based on |
| 16 | + |
| 17 | + - perl's Crypt::PasswdMD5 by Luis Munoz (lem@cantv.net) |
| 18 | + - phyton's md5crypt.py by Michal Wallace http://www.sabren.com/ |
| 19 | + - /usr/src/libcrypt/crypt.c from FreeBSD 2.2.5-RELEASE |
| 20 | + |
| 21 | +Many thanks to |
| 22 | + |
| 23 | + - Fabian Steiner <info@fabis-site.net> |
| 24 | + without him this script would not work!! |
| 25 | + |
| 26 | +Version: 1.0 stable |
| 27 | +Last edit: Tue, 13 September 2005 13:49:28 GMT |
| 28 | + |
| 29 | + |
| 30 | +USAGE |
| 31 | + |
| 32 | + $cryptedpassword = md5crypt_unix ($password [, $salt [, $magicstring ]); |
| 33 | + $apachepassword = md5crypt_apache ($password [, $salt]); |
| 34 | + |
| 35 | +DESCRIPTION |
| 36 | + |
| 37 | + unix_md5_crypt() provides a crypt()-compatible interface to the |
| 38 | + rather new MD5-based crypt() function found in modern operating systems. |
| 39 | + It's based on the implementation found on FreeBSD 2.2.[56]-RELEASE and |
| 40 | + contains the following license in it: |
| 41 | + |
| 42 | + "THE BEER-WARE LICENSE" (Revision 42): |
| 43 | + <phk@login.dknet.dk> wrote this file. As long as you retain this notice you |
| 44 | + can do whatever you want with this stuff. If we meet some day, and you think |
| 45 | + this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp |
| 46 | + |
| 47 | + apache_md5_crypt() provides a function compatible with Apache's |
| 48 | + .htpasswd files. This was contributed by Bryan Hart <bryan@eai.com>. |
| 49 | + |
| 50 | +*/ |
| 51 | + |
| 52 | +class Md5crypt { |
| 53 | + private static $itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; |
| 54 | + |
| 55 | + static function to64($v, $n) { |
| 56 | + $ret = ''; |
| 57 | + |
| 58 | + while(--$n >= 0) { |
| 59 | + $ret .= self::$itoa64{$v & 0x3f}; |
| 60 | + $v = $v >> 6; |
| 61 | + } |
| 62 | + return $ret; |
| 63 | + } |
| 64 | + |
| 65 | + static function encryptPassword($pw, $salt = NULL, $Magic = '$1$') { |
| 66 | + if($salt !== NULL) { |
| 67 | + // Take care of the magic string if present |
| 68 | + if(substr($salt, 0, strlen($Magic)) == $Magic) { |
| 69 | + $salt = substr($salt, strlen($Magic), strlen($salt)); |
| 70 | + } |
| 71 | + // Salt can have up to 8 characters |
| 72 | + $parts = explode('$', $salt, 1); |
| 73 | + $salt = substr($parts[0], 0, 8); |
| 74 | + } else { |
| 75 | + $salt = ''; |
| 76 | + mt_srand((double)(microtime() * 10000000)); |
| 77 | + |
| 78 | + while(strlen($salt) < 8) { |
| 79 | + $salt .= self::$itoa64{mt_rand(0, strlen($itoa64))}; |
| 80 | + } |
| 81 | + } |
| 82 | + |
| 83 | + $ctx = $pw . $Magic . $salt; |
| 84 | + |
| 85 | + $final = pack('H*', md5($pw . $salt . $pw)); |
| 86 | + |
| 87 | + for ($pl = strlen($pw); $pl > 0; $pl -= 16) { |
| 88 | + $ctx .= substr($final, 0, ($pl > 16) ? 16 : $pl); |
| 89 | + } |
| 90 | + |
| 91 | + // Now the 'weird' xform |
| 92 | + for($i = strlen($pw); $i; $i >>= 1) { |
| 93 | + if($i & 1) { // This comes from the original version, |
| 94 | + $ctx .= pack("C", 0); // where a memset() is done to $final |
| 95 | + } else { // before this loop |
| 96 | + $ctx .= $pw{0}; |
| 97 | + } |
| 98 | + } |
| 99 | + |
| 100 | + $final = pack('H*', md5($ctx)); // The following is supposed to make |
| 101 | + // things run slower |
| 102 | + |
| 103 | + for($i = 0; $i < 1000; $i++) { |
| 104 | + $ctx1 = ''; |
| 105 | + if($i & 1) { |
| 106 | + $ctx1 .= $pw; |
| 107 | + } else { |
| 108 | + $ctx1 .= substr($final, 0, 16); |
| 109 | + } |
| 110 | + if($i % 3) { |
| 111 | + $ctx1 .= $salt; |
| 112 | + } |
| 113 | + if($i % 7) { |
| 114 | + $ctx1 .= $pw; |
| 115 | + } |
| 116 | + if($i & 1) { |
| 117 | + $ctx1 .= substr($final, 0, 16); |
| 118 | + } else { |
| 119 | + $ctx1 .= $pw; |
| 120 | + } |
| 121 | + $final = pack('H*', md5($ctx1)); |
| 122 | + } |
| 123 | + |
| 124 | + // Final xform |
| 125 | + $passwd = ''; |
| 126 | + $passwd .= self::to64((intval(ord($final{0})) << 16) |
| 127 | + |(intval(ord($final{6})) << 8) |
| 128 | + |(intval(ord($final{12}))),4); |
| 129 | + $passwd .= self::to64((intval(ord($final{1})) << 16) |
| 130 | + |(intval(ord($final{7})) << 8) |
| 131 | + |(intval(ord($final{13}))), 4); |
| 132 | + $passwd .= self::to64((intval(ord($final{2})) << 16) |
| 133 | + |(intval(ord($final{8})) << 8) |
| 134 | + |(intval(ord($final{14}))), 4); |
| 135 | + $passwd .= self::to64((intval(ord($final{3})) << 16) |
| 136 | + |(intval(ord($final{9})) << 8) |
| 137 | + |(intval(ord($final{15}))), 4); |
| 138 | + $passwd .= self::to64((intval(ord($final{4}) << 16) |
| 139 | + |(intval(ord($final{10})) << 8) |
| 140 | + |(intval(ord($final{5})))), 4); |
| 141 | + $passwd .= self::to64((intval(ord($final{11}))), 2); |
| 142 | + |
| 143 | + // Return the final string |
| 144 | + return $Magic . $salt . '$' . $passwd; |
| 145 | + } |
| 146 | +} |
Property changes on: trunk/extensions/NssMySQLAuth/Md5crypt.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 147 | + native |
Index: trunk/extensions/NssMySQLAuth/SpecialAccountManager.php |
— | — | @@ -0,0 +1,177 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +class SpecialAccountManager extends SpecialPage { |
| 5 | + function __construct() { |
| 6 | + parent::__construct( 'AccountManager', 'accountmanager', false ); |
| 7 | + } |
| 8 | + |
| 9 | + function execute() { |
| 10 | + global $wgUser; |
| 11 | + if( !$this->userCanExecute( $wgUser ) ) |
| 12 | + return $this->displayRestrictionError(); |
| 13 | + |
| 14 | + $this->users = UserProps::fetchAllUsers(); |
| 15 | + if( $this->processData() === true) |
| 16 | + $this->showSuccess(); |
| 17 | + $this->constructForm(); |
| 18 | + } |
| 19 | + |
| 20 | + function showSuccess() { |
| 21 | + global $wgOut; |
| 22 | + $wgOut->addHTML( Xml::element('p', array(), 'Your changes have been successfully updated' ) ); |
| 23 | + } |
| 24 | + |
| 25 | + function constructForm() { |
| 26 | + global $wgOut, $wgScript; |
| 27 | + global $wgUserProperties; |
| 28 | + |
| 29 | + // TODO: wfMsg etc. |
| 30 | + $wgOut->addHTML( Xml::openElement( 'form', array( |
| 31 | + 'action' => $wgScript, |
| 32 | + 'method' => 'post' ) |
| 33 | + ) ); |
| 34 | + |
| 35 | + $wgOut->addHTML("<table id=\"userprops\" border=\"1\" width=\"100%\">\n\t<tr>". |
| 36 | + "<th>Username</th><th>Email</th>"); |
| 37 | + foreach( $wgUserProperties as $i ) |
| 38 | + $wgOut->addHTML( Xml::element( 'th', null, $i ) ); |
| 39 | + $wgOut->addHTML("</tr>\n\n"); |
| 40 | + |
| 41 | + foreach( $this->users as $user ) { |
| 42 | + $name = $user->getName(); |
| 43 | + $row = "\t<tr>"; |
| 44 | + $row .= Xml::element( 'td', null, $name ); |
| 45 | + $row .= Xml::element( 'td', null, $user->getEmail() ); |
| 46 | + |
| 47 | + $props = $user->getProps(); |
| 48 | + foreach( $wgUserProperties as $key ) { |
| 49 | + $value = isset( $wgUserProperties[$key] ) ? |
| 50 | + $wgUserProperties[$key] : ''; |
| 51 | + $row .= "<td>".Xml::input( |
| 52 | + "am-{$name}-{$key}", |
| 53 | + false, $value |
| 54 | + )."</td>"; |
| 55 | + } |
| 56 | + $row .= "</tr>\n"; |
| 57 | + $wgOut->addHTML( $row ); |
| 58 | + } |
| 59 | + |
| 60 | + $wgOut->addHTML( "</table>\n" ); |
| 61 | + $wgOut->addHTML( "<div id=\"userprops-submit\">\n". |
| 62 | + Xml::hidden( 'title', 'Special:AccountManager' ). |
| 63 | + Xml::hidden( 'action', 'submit' ). |
| 64 | + Xml::element( 'input', array( |
| 65 | + 'type' => 'submit', |
| 66 | + 'value' => 'Save changes' |
| 67 | + ) ). |
| 68 | + "</div>\n</form>" |
| 69 | + ); |
| 70 | + } |
| 71 | + |
| 72 | + function processData() { |
| 73 | + global $wgRequest, $wgUserProperties; |
| 74 | + if( !$wgRequest->wasPosted() || $wgRequest->getVal('action') != 'submit' ) |
| 75 | + return; |
| 76 | + |
| 77 | + $post = $wgRequest->getValues(); |
| 78 | + foreach( $post as $key => $value ) { |
| 79 | + if( substr( $key, 0, 3 ) != 'am-' ) |
| 80 | + continue; |
| 81 | + $parts = explode( '-', $key, 3 ); |
| 82 | + if( count( $parts ) != 3 ) |
| 83 | + continue; |
| 84 | + |
| 85 | + $username = $parts[1]; |
| 86 | + $keyname = $parts[2]; |
| 87 | + |
| 88 | + if( !isset( $this->users[$username] ) ) |
| 89 | + continue; |
| 90 | + if( !isset( $wgUserProperties[$key] ) ) |
| 91 | + continue; |
| 92 | + |
| 93 | + $this->users[$username]->set( $keyname, $value ); |
| 94 | + } |
| 95 | + |
| 96 | + foreach( $this->users as $user ) |
| 97 | + $user->update(); |
| 98 | + return true; |
| 99 | + } |
| 100 | +} |
| 101 | + |
| 102 | +class UserProps { |
| 103 | + static function fetchAllUsers() { |
| 104 | + $users = array(); |
| 105 | + $res = self::select(); |
| 106 | + while( $row = $res->fetchObject() ) { |
| 107 | + if( !isset( $users[$row->pwd_name] ) ) |
| 108 | + $users[$row->pwd_name] = new self( $row->pwd_name, $row->pwd_email ); |
| 109 | + $users[$row->pwd_name]->setInternal($row->up_name, $row->up_value); |
| 110 | + } |
| 111 | + $res->free(); |
| 112 | + return $users; |
| 113 | + } |
| 114 | + function __construct( $username, $email = null ) { |
| 115 | + $this->username = $username; |
| 116 | + $this->props = null; |
| 117 | + $this->email = $email; |
| 118 | + } |
| 119 | + function getProps() { |
| 120 | + return $this->props; |
| 121 | + } |
| 122 | + function getName() { |
| 123 | + return $this->username; |
| 124 | + } |
| 125 | + function getEmail() { |
| 126 | + return $this->email; |
| 127 | + } |
| 128 | + function setEmail( $email ) { |
| 129 | + $this->email = $email; |
| 130 | + } |
| 131 | + |
| 132 | + static function select($username = null) { |
| 133 | + global $wgAuth; |
| 134 | + $dbr = $wgAuth->getDB( DB_READ ); |
| 135 | + $join = is_null( $username ) ? 'RIGHT JOIN' : 'JOIN'; |
| 136 | + $where = is_null( $username ) ? array() : array( 'up_user' => $username ); |
| 137 | + |
| 138 | + return $dbr->select( |
| 139 | + array( 'user_props', 'passwd' ), |
| 140 | + array( 'up_name', 'up_value', 'pwd_name', 'pwd_email' ), |
| 141 | + $where, |
| 142 | + __METHOD__, |
| 143 | + array( 'ORDER BY' => 'up_timestamp DESC', 'DISTINCT' ), |
| 144 | + array( 'passwd' => array( $join, 'pwd_name = up_user' ) ) |
| 145 | + ); |
| 146 | + } |
| 147 | + |
| 148 | + function set($name, $value) { |
| 149 | + $this->props[$name] = $value; |
| 150 | + } |
| 151 | + function setInternal($name, $value) { |
| 152 | + if( is_null( $this->props ) ) { |
| 153 | + $this->props = array(); |
| 154 | + $this->old_props = array(); |
| 155 | + } |
| 156 | + $this->old_props[$name] = $this->props[$name] = $value; |
| 157 | + } |
| 158 | + |
| 159 | + function update() { |
| 160 | + $diff = array_diff_assoc($this->props, $this->old_props); |
| 161 | + if( !count( $diff ) ) return; |
| 162 | + |
| 163 | + global $wgAuth; |
| 164 | + $dbw = $wgAuth->getDB( DB_WRITE ); |
| 165 | + $timestamp = $dbw->timestamp(); |
| 166 | + |
| 167 | + $insert = array(); |
| 168 | + foreach( $diff as $key => $value ) |
| 169 | + $insert[] = array( |
| 170 | + 'up_timestamp' => $timestamp, |
| 171 | + 'up_user' => $this->username, |
| 172 | + 'up_name' => $key, |
| 173 | + 'up_value' => $value, |
| 174 | + ); |
| 175 | + |
| 176 | + $dbw->insert( 'user_props', $insert, __METHOD__ ); |
| 177 | + } |
| 178 | +} |
Property changes on: trunk/extensions/NssMySQLAuth/SpecialAccountManager.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 179 | + native |