mirror of
https://github.com/postgres/pgweb.git
synced 2025-08-06 09:57:57 +00:00
Add community auth v2 provider for mediawiki
This commit is contained in:
38
tools/communityauth/sample/php/mediawiki/README.rst
Normal file
38
tools/communityauth/sample/php/mediawiki/README.rst
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
Mediawiki login provider
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
This provider implements a (fairly ugly) community auth v2 provider
|
||||||
|
for mediawiki. Since the mediawiki API doesn't support external
|
||||||
|
authentication (it reqiures there to be a username and password,
|
||||||
|
which isn't always true, and can only pass those on to external
|
||||||
|
services), this has to be done by browser interception. Basically,
|
||||||
|
we intercept the mediawiki login URL and redirect it. Upon receiving
|
||||||
|
the data back from the authentication system, we inject it into the
|
||||||
|
mediawiki session and redirect back. It appears to work so far...
|
||||||
|
|
||||||
|
Installation
|
||||||
|
++++++++++++
|
||||||
|
Copy all the PHP files to `/var/lib/mediawiki/pgauth/`, and
|
||||||
|
edit as necessary to have the correct URLs and keys.
|
||||||
|
|
||||||
|
Server configuration
|
||||||
|
++++++++++++++++++++
|
||||||
|
The webserver needs to be configured to intercept and redirect
|
||||||
|
the mediawiki URLs. The following configuration is required on
|
||||||
|
lighttpd::
|
||||||
|
|
||||||
|
url.rewrite-once = (
|
||||||
|
"^/wiki/([^?]*)(?:\?(.*))?" => "/index.php?title=$1&$2",
|
||||||
|
"^/index.php\?title=Special:UserLogin&returnto=(.*)" => "/pgauth/login.php?r=$1",
|
||||||
|
"^/index.php\?title=Special:UserLogout&returnto=(.*)" => "/pgauth/logout.php",
|
||||||
|
)
|
||||||
|
|
||||||
|
It should be added after the regular mediawiki rewrites (included here
|
||||||
|
for reference on the first row).
|
||||||
|
|
||||||
|
Configuration
|
||||||
|
+++++++++++++
|
||||||
|
Edit the settings in `pgauth_conf.php` to set steid, key and URLs. The
|
||||||
|
database connectoin string configured here is for the authentication
|
||||||
|
provider to connect to the mediawiki database, not to the community auth
|
||||||
|
database.
|
201
tools/communityauth/sample/php/mediawiki/auth.php
Normal file
201
tools/communityauth/sample/php/mediawiki/auth.php
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
<?php
|
||||||
|
require 'pgauth_conf.php';
|
||||||
|
|
||||||
|
if ($_GET['s'] == "logout") {
|
||||||
|
/*
|
||||||
|
* Redirect back from the authentication system after a
|
||||||
|
* distributed logout. Just send it back to the frontpage for now.
|
||||||
|
*/
|
||||||
|
header("Location: ${pgauth_logoutsite}/");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
session_name('wikidb_session');
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
$iv = $_GET['i'];
|
||||||
|
$d = $_GET['d'];
|
||||||
|
|
||||||
|
$key = base64_decode(strtr(${pgauth_key}, '-_', '+/'), true);
|
||||||
|
$iv = base64_decode(strtr($iv, '-_', '+/'), true);
|
||||||
|
$d = base64_decode(strtr($d, '-_', '+/'), true);
|
||||||
|
if ($key == FALSE || $iv == FALSE || $d == FALSE) {
|
||||||
|
print "Invalid authentication data";
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
$td = mcrypt_module_open("rijndael-128", "", "cbc", "");
|
||||||
|
if (!$td) {
|
||||||
|
print "Unable to open mcrypt module";
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
$r = mcrypt_generic_init($td, $key, $iv);
|
||||||
|
/* Docs say FALSE or <0 is incorrect. But it returns FALSE when it works.. */
|
||||||
|
if ($r < 0) {
|
||||||
|
print "Unable to initialize encryption module: $r";
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
$decrypted = rtrim(mdecrypt_generic($td, $d));
|
||||||
|
mcrypt_generic_deinit($td);
|
||||||
|
mcrypt_module_close($td);
|
||||||
|
parse_str($decrypted, $data);
|
||||||
|
|
||||||
|
if ($data['t'] < time() - 10) {
|
||||||
|
print "Authentication token too old";
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// User found, and we read a reasonable authenticaiton time.
|
||||||
|
// Look for the user in the mediawiki database
|
||||||
|
$db = pg_connect(${pgauth_connstr});
|
||||||
|
$q = pg_query_params($db, "SELECT user_token, user_id, user_real_name, user_email FROM mwuser WHERE user_name=$1", array(ucfirst(strtolower($data['u']))));
|
||||||
|
if (pg_num_rows($q) == 0) {
|
||||||
|
/*
|
||||||
|
* Create a token the same way mediawiki does (ish).
|
||||||
|
* We cheat on some points though, but that shouldn't
|
||||||
|
* be an issue really - it's random enough.
|
||||||
|
*/
|
||||||
|
$token = md5(microtime() . mt_rand(0, 0x7fffffff));
|
||||||
|
|
||||||
|
/* Hardcoded default options.. Ugly, but it works.. */
|
||||||
|
$options=<<<EOT
|
||||||
|
quickbar=1
|
||||||
|
underline=2
|
||||||
|
cols=80
|
||||||
|
rows=25
|
||||||
|
searchlimit=20
|
||||||
|
contextlines=5
|
||||||
|
contextchars=50
|
||||||
|
skin=postgresql
|
||||||
|
math=1
|
||||||
|
rcdays=7
|
||||||
|
rclimit=50
|
||||||
|
wllimit=250
|
||||||
|
highlightbroken=1
|
||||||
|
stubthreshold=0
|
||||||
|
previewontop=1
|
||||||
|
editsection=1
|
||||||
|
editsectiononrightclick=0
|
||||||
|
showtoc=1
|
||||||
|
showtoolbar=1
|
||||||
|
date=ISO 8601
|
||||||
|
imagesize=2
|
||||||
|
thumbsize=2
|
||||||
|
rememberpassword=0
|
||||||
|
enotifwatchlistpages=1
|
||||||
|
enotifusertalkpages=1
|
||||||
|
enotifminoredits=1
|
||||||
|
enotifrevealaddr=0
|
||||||
|
shownumberswatching=0
|
||||||
|
fancysig=0
|
||||||
|
externaleditor=0
|
||||||
|
externaldiff=0
|
||||||
|
showjumplinks=1
|
||||||
|
numberheadings=0
|
||||||
|
uselivepreview=0
|
||||||
|
watchlistdays=3
|
||||||
|
variant=
|
||||||
|
language=en
|
||||||
|
searchNs0=1
|
||||||
|
nickname=
|
||||||
|
timecorrection=
|
||||||
|
ajaxsearch=
|
||||||
|
searchNs1=0
|
||||||
|
searchNs2=0
|
||||||
|
searchNs3=0
|
||||||
|
searchNs4=0
|
||||||
|
searchNs5=0
|
||||||
|
searchNs6=0
|
||||||
|
searchNs7=0
|
||||||
|
searchNs8=0
|
||||||
|
searchNs9=0
|
||||||
|
searchNs10=0
|
||||||
|
searchNs11=0
|
||||||
|
searchNs12=0
|
||||||
|
searchNs13=0
|
||||||
|
searchNs14=0
|
||||||
|
searchNs15=0
|
||||||
|
disablemail=1
|
||||||
|
justify=0
|
||||||
|
hideminor=0
|
||||||
|
extendwatchlist=0
|
||||||
|
usenewrc=0
|
||||||
|
editondblclick=0
|
||||||
|
editwidth=0
|
||||||
|
watchcreations=0
|
||||||
|
watchdefault=0
|
||||||
|
watchmoves=0
|
||||||
|
watchdeletion=0
|
||||||
|
minordefault=0
|
||||||
|
previewonfirst=0
|
||||||
|
nocache=0
|
||||||
|
forceeditsummary=0
|
||||||
|
watchlisthideown=0
|
||||||
|
watchlisthidebots=0
|
||||||
|
watchlisthideminor=0
|
||||||
|
ccmeonemails=1
|
||||||
|
diffonly=0
|
||||||
|
EOT;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Try to create a user..
|
||||||
|
*/
|
||||||
|
$q = pg_query_params($db, "INSERT INTO mwuser (user_name, user_real_name, user_password, user_newpassword, user_newpass_time, user_token, user_email, user_email_token, user_email_token_expires, user_email_authenticated, user_options, user_touched, user_registration, user_editcount, user_hidden) VALUES ($1, $2, NULL, NULL, NULL, $3, $4, NULL, '2000-01-01 00:00:00', CURRENT_TIMESTAMP, $5, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 0, 0) RETURNING user_token, user_id, user_real_name, user_email", array(ucfirst(strtolower($data['u'])), $data['f'] . ' ' . $data['l'], $token, $data['e'], $options));
|
||||||
|
if (pg_num_rows($q) != 1) {
|
||||||
|
print "Failed to add user!";
|
||||||
|
pg_close($db);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pg_num_rows($q) != 1) {
|
||||||
|
print "Invalid data returned!";
|
||||||
|
pg_close($db);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update email and real name, if they changed in the community
|
||||||
|
* auth system. Community auth always overwrites whatever is
|
||||||
|
* in the wiki.
|
||||||
|
*/
|
||||||
|
$r = pg_fetch_assoc($q);
|
||||||
|
if ($r['user_email'] != $data['e']) {
|
||||||
|
$q = pg_query_params($db, "UPDATE mwuser SET user_email=$1 WHERE user_name=$2", array($data['e'], ucfirst(strtolower($data['u']))));
|
||||||
|
if (pg_result_status($q) != PGSQL_COMMAND_OK) {
|
||||||
|
print "Failed to update email!";
|
||||||
|
pg_close($db);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($r['user_real_name'] != $data['f'] . ' ' . $data['l']) {
|
||||||
|
$q = pg_query_params($db, "UPDATE mwuser SET user_real_name=$1 WHERE user_name=$2", array($data['f'] . ' ' . $data['l'], ucfirst(strtolower($data['u']))));
|
||||||
|
print "'$q'";
|
||||||
|
if (pg_result_status($q) != PGSQL_COMMAND_OK) {
|
||||||
|
print "Failed to update real name!";
|
||||||
|
pg_close($db);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pg_close($db);
|
||||||
|
|
||||||
|
// Now inject this data into the mediawiki session
|
||||||
|
$_SESSION['wsUserID'] = $r['user_id'];
|
||||||
|
$_SESSION['wsToken'] = $r['user_token'];
|
||||||
|
$_SESSION['wsUserName'] = ucfirst(strtolower($data['u']));
|
||||||
|
session_write_close();
|
||||||
|
|
||||||
|
if ($data['su']) {
|
||||||
|
$redir = $data['su'];
|
||||||
|
} else {
|
||||||
|
$redir = '/wiki/Main_Page';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add ?nocache=... or &nocache=... to avoid mediawiki caching */
|
||||||
|
$redir .= strpos($redir, "?")==false?"?":"&";
|
||||||
|
$redir .= "nocache=" . urlencode(microtime());
|
||||||
|
header("Location: ${pgauth_rootsite}$redir");
|
||||||
|
header("Cache-control: private, must-revalidate, max-age=0");
|
||||||
|
?>
|
7
tools/communityauth/sample/php/mediawiki/login.php
Normal file
7
tools/communityauth/sample/php/mediawiki/login.php
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?
|
||||||
|
require 'pgauth_conf.php';
|
||||||
|
/* Redirect authentication request */
|
||||||
|
|
||||||
|
$su = "/wiki/" . $_GET['r'];
|
||||||
|
header("Location: https://www.postgresql.org/account/auth/${pgauth_siteid}/?su=" . urlencode($su));
|
||||||
|
?>
|
15
tools/communityauth/sample/php/mediawiki/logout.php
Normal file
15
tools/communityauth/sample/php/mediawiki/logout.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?
|
||||||
|
require 'pgauth_conf.php';
|
||||||
|
/* Log the user out locally */
|
||||||
|
|
||||||
|
session_name('wikidb_session');
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
unset($_SESSION['wsUserID']);
|
||||||
|
unset($_SESSION['wsToken']);
|
||||||
|
unset($_SESSION['wsUserName']);
|
||||||
|
setcookie('wikidbLoggedOut', time());
|
||||||
|
|
||||||
|
/* Redirect logout request too */
|
||||||
|
header("Location: https://www.postgresql.org/account/auth/${pgauth_siteid}/logout/");
|
||||||
|
?>
|
7
tools/communityauth/sample/php/mediawiki/pgauth_conf.php
Normal file
7
tools/communityauth/sample/php/mediawiki/pgauth_conf.php
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?
|
||||||
|
$pgauth_siteid=12321432432;
|
||||||
|
$pgauth_key = 'puSOAmUPWlZvVvnQtkUpwjxj7U4NT7sW0FhBqo/OkgA=';
|
||||||
|
$pgauth_rootsite = 'https://wikitest.postgresql.org';
|
||||||
|
$pgauth_logoutsite = 'http://wikitest.postgresql.org';
|
||||||
|
$pgauth_connstr = "dbname=wikidb";
|
||||||
|
?>
|
Reference in New Issue
Block a user