37 Commits
dev ... mw_33

Author SHA1 Message Date
469c64490c add missing comment id fields (that were probably supposed to be added by a migration we skipped)
These fields exist in the live database so migration should still work there.
2019-07-06 00:49:32 -05:00
5c0a6dfd6d Merge branch 'master' into mw_33 2019-07-06 00:17:54 -05:00
ade6a6d415 update database dump with 1.32 dump 2019-07-06 00:17:38 -05:00
e020b4cc3f add wait-for-it 2019-07-02 20:11:42 -05:00
b2a5879743 update to mediawiki 1.33.0 2019-07-02 19:09:17 -05:00
026b2947d4 enable WikiEditor and CodeEditor for source editing 2019-06-16 21:01:23 -05:00
ec397feed6 add VisualEditor/Parsoid info to readme 2019-06-15 18:29:24 -05:00
829a51384b Add parsoid image & configuration 2019-06-15 18:24:40 -05:00
d8dd54dc9f add VisualEditor extension 2019-06-15 17:43:28 -05:00
f97da260d8 add ca- ids to content action links, this is required for VisualEditor 2019-06-15 17:43:03 -05:00
72dced4c8d change add_extension.sh to init submodules, in case the extension requires submodules (like visualeditor) 2019-06-15 17:41:07 -05:00
c20d8d4f6e remove deprecated calls to wfRunHooks 2019-06-15 16:12:22 -05:00
935997cc75 it is an error to use a boolean here, so don't 2019-06-15 15:57:14 -05:00
07094ab956 update mediawiki to 1.32.1 (finally) 2019-06-09 15:01:59 -05:00
b6c96f9d3c Merge branch 'master' of ssh://forge.monarch-pass.net/glitch-city-laboratories/glitch-city-laboratories 2019-02-15 21:07:52 -06:00
5f68d09c72 gate phpinfo.php behind an environment variable so it doesn't get shown to the public 2019-02-15 21:07:26 -06:00
9c9baee367 gate phpinfo.php behind an environment variable so it doesn't accidentally leak to the public 2019-02-16 03:07:10 +00:00
f747f18acd fix msmtprc syntax 2018-09-04 01:42:04 -05:00
abee89b732 Load CheckUser with wfLoadExtension.
This seems to be the preferred way to load extensions but FlaggedRevs doesn't support it for some reason, so we need to include it directly.
2018-09-03 23:01:48 -05:00
a866d8dd74 exit 0 from setup.sh 2018-09-03 22:53:18 -05:00
6dd7961ebd Implement printable mode. 2018-09-03 22:41:34 -05:00
53447ad8ef Remove UserRightsList extension; it's currently not maintained 2018-09-03 22:03:30 -05:00
d2c68efe43 Remove install.php 2018-09-03 22:00:56 -05:00
2d417f433d Add a script to install SMF packages into the image. 2018-09-03 21:53:41 -05:00
dcdb8ea4db Set $$wgPHPSessionHandling to false to disable mediawiki using php sessions.
This seems to resolve the issue of mediawiki and smf sessions colliding, as mediawiki will no longer touch smf's session. The "loss of session data" error seems to still not be present.
2018-08-27 03:32:14 -05:00
72b7638d11 remove print_r 2018-08-13 02:00:12 -05:00
83f36080e3 Destroy SMF session to work around MW/SMF collision issue. Coincidentally, this also seems to actually resolve "loss of session data" errors. 2018-08-13 01:35:39 -05:00
2c0e67e675 initial implementation of Auth remoteuser, of course it doesn't work 2018-08-13 00:39:19 -05:00
e038483e69 Add support for email with msmtp 2018-08-12 06:30:19 -05:00
5ee52eb5a1 messy hack around "loss of session data"
Should go away if/when we switch to Auth remoteuser extension
2018-08-12 05:30:18 -05:00
b365cfa58e create links to mediawiki maintenance scripts 2018-08-12 03:39:44 -05:00
b8c8bc331e Install nuke extension, since it's not included with MediaWiki 1.31 2018-08-12 02:54:33 -05:00
2da5e9837d move responsibility for creating the initial database to the database container 2018-08-12 02:50:11 -05:00
91b0cecf74 actually update to mw 31 2018-08-11 13:10:42 -05:00
c1bf04fbd2 Update mediawiki to 1.31 2018-08-08 20:54:57 -05:00
baa50b5ded Merge branch 'master' of gitlab.monarch-pass.net:glitch-city-laboratories/glitch-city-laboratories 2018-02-07 19:20:01 -06:00
1ae67657bb disable Prof Glitch's extension, so I don't keep having to enter the container and do it each time it starts 2018-01-06 01:28:17 +00:00
19 changed files with 581 additions and 920 deletions

View File

@ -1,11 +1,11 @@
FROM debian:stable
RUN apt-get -y update && apt-get -y install nginx php-fpm php-mysql php-apcu php-mbstring php-xml supervisor python-pip \
mysql-client imagemagick curl wget zip unzip php-pclzip git
mysql-client imagemagick curl wget zip unzip php-pclzip git msmtp msmtp-mta
RUN pip install supervisor-stdout
ENV MW_VERSION REL1_30
ENV MW_SOURCE https://releases.wikimedia.org/mediawiki/1.30/mediawiki-1.30.0.tar.gz
ENV MW_VERSION REL1_33
ENV MW_SOURCE https://releases.wikimedia.org/mediawiki/1.33/mediawiki-1.33.0.tar.gz
ENV SMF_VERSION 2.0.15
ENV SMF_SOURCE https://download.simplemachines.org/index.php/smf_2-0-15_install.tar.gz
@ -27,13 +27,25 @@ RUN cd /tmp && wget $MW_SOURCE && tar -xvf mediawiki-*.tar.gz && \
RUN chown -R www-data:www-data $SOURCE_ROOT
RUN cd "$WIKI_SOURCE/maintenance" && \
sh -c 'for TOOL in *.php; do LINK="/usr/bin/$(basename $TOOL .php)"; echo "#!/bin/sh\nphp $WIKI_SOURCE/maintenance/$TOOL \$@" > $LINK; chmod +x $LINK; done'
# Add our scripts
ADD scripts scripts
# Install additional extensions
# 12 August 2018: Nuke extension is not bundled with MediaWiki 1.31 by mistake.
# It will be added back in the next release.
RUN /scripts/add_extension.sh FlaggedRevs $MW_VERSION && \
/scripts/add_extension.sh CheckUser $MW_VERSION && \
/scripts/add_extension.sh Contributors $MW_VERSION
/scripts/add_extension.sh Contributors $MW_VERSION && \
/scripts/add_extension.sh Nuke $MW_VERSION && \
/scripts/add_extension.sh Auth_remoteuser $MW_VERSION && \
/scripts/add_extension.sh VisualEditor $MW_VERSION
# Install SMF mods
# 3 September 2018: These would also need to be installed in the database.
RUN /scripts/add_mod.php "http://custom.simplemachines.org/mods/index.php?action=download;mod=3067;id=179832"
# Add our stuff
ADD --chown=www-data:www-data application application
@ -47,6 +59,9 @@ RUN ln -sf /configuration/supervisord.conf /etc/supervisor/supervisord.conf && \
ln -sf /configuration/php-fpm-pool.conf /etc/php/7.0/fpm/pool.d/www.conf && \
ln -sf /configuration/php.ini /etc/php/7.0/fpm/php.ini
ADD https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh /usr/bin/wait-for-it
RUN chmod +x /usr/bin/wait-for-it
EXPOSE 80
CMD /usr/bin/supervisord -n

View File

@ -6,6 +6,9 @@ As of **9 August 2016** this version of GCL is live on the Monarch Pass server.
## Info about the test database
The test database is a small collection of wiki pages, boards, and posts. There is an admin user (username `Abwayax`, password `testadmin`).
## VisualEditor
As of **15 June 2019** (MediaWiki 1.32) the VisualEditor extension is included. This requires a Parsoid service, which is *not* included. See the `docker-compose.yml` for details.
## Commands
### Build development environment
`docker-compose build`

View File

@ -1 +1,8 @@
<?php phpinfo(); ?>
<?php
if (empty(getenv("GCL_DEV")))
{
die();
}
phpinfo();
?>

View File

@ -1,337 +1,50 @@
<?php
/**********************************************************************************
* Auth_SMF.php
***********************************************************************************
* Connection between SMF and MediaWiki.
* =================================================================================
* Software Version: 1.0.0
* Software by: Snakehit (snakehit (at) gmail.com)
***********************************************************************************/
//Necessary for MediaWiki.com
$wgExtensionCredits['validextensionclass'][] = array(
'name' => 'SMF_Authentication',
'author' => 'Snakehit (snakehit@gmail.com)',
'url' => 'http://www.mediawiki.org/wiki/User:Snakehit',
'description' => 'This Extension is a connection between SMF and MediaWiki. It automatic logins and logouts on both platforms'
);
// 7 August 2016: Since this is an auth plugin we only need it when we are working with a session.
// load.php sets $context in the global scope which conflicts with SMF's $context, so doing this
// is a hacky way to make load.php work again.
if (!defined("MW_NO_SESSION")) {
error_reporting(E_ALL); // Debug
// Fix for SMF's sanitization breaking mediawiki page titles.
// Let mediawiki do its own security
$tempGet = $_GET;
// 5 August 2016: This variable is used by Mediawiki's updater.
// Store it in a temp variable so we can restore it if we need to.
$oldMaintenance = null;
if (!empty($maintenance)) {
$oldMaintenance = $maintenance;
}
//Load the SMF files ;-)
if(!require_once($wgSMFPathSSI))
die('Could not load the SMF SSI');
if(!require_once($wgSMFPathAPI))
die('Could not load the SMF API');
$_GET = $tempGet;
if (!empty($oldMaintenance)) {
$maintenance = $oldMaintenance;
}
//Hooks!
//$wgHooks['AutoAuthenticate'][] = 'AutoAuthenticateSMF';
$wgHooks['UserLoadFromSession'][] = 'AutoAuthenticateSMF';
$wgHooks['UserLogout'][] = 'AutoLogoutSMF';
}
/**
* AutoAuthenticateSMF is the function that creates an automatic login if you are logged in to SMF.
*
* @param User $user
* @return bool
* @access public
*/
function AutoAuthenticateSMF($user,&$result) {
global $user_info;
//Is user a guest?
if ($user_info['is_guest'])
{
return true;
}
//User isn't a guest
if (!$user_info['is_guest'])
{
$user->setName($user_info['username']);
$user->setId($user->idForName());
if ($user->getID() == 0)
{
//User doesn't exist :'(
$user->setName($user_info['username']); // Set memberName
$user->setEmail($user_info['email']); // Set Email Address.
$user->setRealName($user_info['real_name']); // Set Real Name.
$user->addToDatabase();
//if user is_admin add him to the SysOp group! Wii ;-)
if ($user_info['is_admin'])
{
$user->addGroup("sysop");
}
}
else
{
//User exists
$user->loadFromDatabase();
}
// Go ahead and log 'em in
$user->setToken();
$user->saveSettings();
}
$result = true;
return true;
}
/**
* AutoLogoutSMF is the function that logout on MediaWiki and on SMF
*
* @param User $user
* @return bool
* @access public
*/
function AutoLogoutSMF(&$user) {
//logout
$user->logout();
//In this relocation we need the session_id that is stored in $smf_user_info
smf_loadSession();
global $smf_user_info,$wgSMFPath;
header("Location: ".$wgSMFPath."/index.php?action=logout;sesc=".$smf_user_info['session_id']."");
exit();
}
// First check if class has already been defined, isn't it require it
//if (!class_exists('AuthPlugin'))
// require_once 'c:/wamp/www/epic/w/w/includes/AuthPlugin.php';
/**
* Handles the authentication with the SMF database.
*
*/
class Auth_SMF extends AuthPlugin {
/**
* Check whether there exists a user account with the given name.
*
* @param string $username
* @return bool
* @access public
*/
function userExists($username) {
return !!smfapi_getUserByUsername($username);
}
/**
* Check if a username and password pair is a valid login.
*
* @param string $username
* @param string $password
* @return bool
* @access public
*/
function authenticate($username, $password) {
if(smfapi_authenticate($username, $password)) {
return smfapi_login(3600, $username);
}
return false;
}
/**
* Modify options in the login template.
*
* @param UserLoginTemplate $template
* @access public
*/
function modifyUITemplate(&$template) {
$template->set('domain', false); // Don't get in touch with domain
$template->set('usedomain', false); // We do not want a domain name.
$template->set('create', false); // Remove option to create new accounts from the wiki.
$template->set('useemail', false); // Disable the mail new password box.
$template->set('remember', false); // Disable 'remember me' box
}
/**
* Set the domain this plugin is supposed to use when authenticating.
*
* @param string $domain
* @access public
*/
function setDomain($domain) {
$this->domain = $domain;
}
/**
* Check to see if the specific domain is a valid domain.
*
* @param string $domain
* @return bool
* @access public
*/
function validDomain($domain) {
return true;
}
/**
* When a user logs in, optionally fill in preferences and such.
* For instance, you might pull the email address or real name from the
* external user database.
*
* The User object is passed by reference so it can be modified; don't
* forget the & on your function declaration.
*
* @param User $user
* @access public
*/
function updateUser( &$user ) {
global $smf_user_info;
$user->mEmail = $smf_user_info['email']; // Set Email Address.
$user->mRealName = $smf_user_info['real_name']; // Set Real Name.
return true;
}
/**
* Return true if the wiki should create a new local account automatically
* when asked to login a user who doesn't exist locally but does in the
* external auth database.
*
* If you don't automatically create accounts, you must still create
* accounts in some way. It's not possible to authenticate without
* a local account.
*
* This is just a question, and shouldn't perform any actions.
*
* @return bool
* @access public
*/
function autoCreate() {
return true;
}
/**
* Set the given password in the authentication database.
* Return true if successful.
*
* @param string $password
* @return bool
* @access public
*/
function setPassword($password) {
return false;
}
/**
* Update user information in the external authentication database.
* Return true if successful.
*
* @param User $user
* @return bool
* @access public
*/
function updateExternalDB($user) {
return true;
}
/**
* Check to see if external accounts can be created.
* Return true if external accounts can be created.
*
* @return bool
* @access public
*/
function canCreateAccounts() {
return false;
}
/**
* Add a user to the external authentication database.
* Return true if successful.
*
* @param User $user
* @param string $password
* @return bool
* @access public
*/
function addUser($user, $password) {
return false;
}
/**
* Return true to prevent logins that don't authenticate here from being checked against the local database's password fields.
*
* This is just a question, and shouldn't perform any actions.
*
* @return bool
* @access public
*/
function strict() {
return true;
}
/**
* Can users change their passwords?
*
* @return bool
*/
function allowPasswordChange() {
return false;
}
/**
* When creating a user account, optionally fill in preferences and such.
* For instance, you might pull the email address or real name from the external user database.
*
* The User object is passed by reference so it can be modified; don't forget the & on your function declaration.
*
* @param User $user
* @access public
*/
function initUser(&$user) {
global $user_info;
$user->mEmail = $user_info['email']; // Set Email Address.
$user->mRealName = $user_info['real_name']; // Set Real Name.
$user->mEmailAuthenticated = wfTimestampNow(); // Add TimeStamp
$user->setToken();
$user->saveSettings();
return true;
}
/**
* If you want to munge the case of an account name before the final check, now is your chance.
*
* @param Username $username
* @return username
* @access public
*/
function getCanonicalName($username) {
global $user_info;
if(empty($user_info['username']))
return $username;
return ucfirst($username);
}
}
?>
<?php
function loadSMFAPI ()
{
global $maintenance, $wgSMFPathSSI, $wgSMFPathAPI;
// Fix for SMF's sanitization breaking mediawiki page titles.
// Let mediawiki do its own security
$tempGet = $_GET;
// 5 August 2016: This variable is used by Mediawiki's updater.
// Store it in a temp variable so we can restore it if we need to.
$oldMaintenance = null;
if (!empty($maintenance)) {
$oldMaintenance = $maintenance;
}
if(!require_once($wgSMFPathSSI)) {
die("Could not load the SMF SSI");
}
if(!require_once($wgSMFPathAPI)) {
die("Could not load the SMF API");
}
$_GET = $tempGet;
if (!empty($oldMaintenance)) {
$maintenance = $oldMaintenance;
}
}
if (!defined("MW_NO_SESSION")) {
loadSMFAPI();
}
if(!empty($user_info)) {
$wgAuthRemoteuserUserName = $user_info['username'];
$wgAuthRemoteuserUserPrefs = [
'realname' => $user_info['name'],
'email' => $user_info['email']
];
$wgAuthRemoteuserUserUrls = [
'logout' => $wgSMFURL . "/index.php?action=logout;" . $_SESSION['session_var'] . '=' . $_SESSION['session_value']
];
}

View File

@ -1,320 +0,0 @@
<?php
# version 0.41
class UserRightsList extends UserrightsPage {
function __construct(){
SpecialPage::__construct('UserRightsList');
# SpecialPage::SpecialPage("UserRightsList", 'createaccount');
self::loadMessages();
$this->offset=0;
$this->limit=50;
list ($this->user_table,$this->user_groups_table) = wfGetDB(DB_MASTER)->tableNamesN('user','user_groups');
return true;
}
public function userCanExecute( $user ) {
global $egUserRightsListChGrp, $wgAddGroups, $wgRemoveGroups;
if (!isset($egUserRightsListChGrp)) return true;
foreach ($egUserRightsListChGrp as $group=>$chgrps){
foreach ($chgrps as $grp) $wgAddGroups[$group][] = $grp;
foreach ($chgrps as $grp) $wgRemoveGroups[$group][] = $grp;
}
return parent::userCanExecute( $user );
}
function execute( $par ) {
global $wgRequest, $wgOut, $wgUser;
$this->setHeaders();
if( !$this->userCanExecute( $wgUser ) ) {
// fixme... there may be intermediate groups we can mention.
global $wgOut;
$wgOut->showPermissionsErrorPage( array(
$wgUser->isAnon()
? 'userrights-nologin'
: 'userrights-notallowed' ) );
return true;
}
# Get request data from, e.g.
$fields = array('yearfrom','yearto','monthfrom','monthto','username','offset','limit','group');
foreach($fields as $field){
if (!is_null($wgRequest->getVal($field))) $this->$field = $wgRequest->getVal($field);
}
if ($wgRequest->getText('act') == 'save') $this->save_rights();
$output = $this->make_form($this->findMyUsers());
$wgOut->addHTML( $output );
return true;
}
function save_rights(){
global $wgRequest;
$users = $this->findMyUsers();
foreach ($users as $user){
$u = User::newFromId($user['user_id']);
if(is_object($u)) {
$oldGroups = $u->getGroups();
$newGroups = $wgRequest->getArray('user_'.$user['user_id']);
if(is_null($wgRequest->getArray('user_'.$user['user_id']))) $newGroups = array();;
// remove then add groups
$removegroup = array_diff($oldGroups, $newGroups);
$addgroup = array_diff($newGroups, $oldGroups);
if (count(array_merge($removegroup, $addgroup)) == 0) continue;
# for 1.13
$wgRequest->data['user'] = $u->getName();
$wgRequest->data['wpEditToken'] = $u->editToken();
foreach ($newGroups as $group) $wgRequest->data['wpGroup-'.$group] = 1;
UserrightsPage::saveUserGroups( $u->getName(), $removegroup, $addgroup);
}
}
return true;
}
/*
# functions from Special::Userrights
function fetchUser( $username ) {
$user = UserrightsPage::fetchUser( $username );
return $user;
}
function getAllGroups() {
return User::getAllGroups();
}
function addLogEntry( $user, $oldGroups, $newGroups ) {
return UserrightsPage::addLogEntry( $user, $oldGroups, $newGroups ) ;
}
function changeableByGroup( $group ) {
global $wgAddGroups, $wgRemoveGroups;
return UserrightsPage::changeableByGroup($group);
}
function changeableGroups( ) {
return UserrightsPage::changeableGroups();
}
function makeGroupNameList( $ids ) {
return implode( ', ', $ids );
}
*/
# takes an array of users where each user is a hash
# user_id, user_name, log_timestamp
function make_form($users){
global $wgUser;
$form = $this->pageTop();
if (count($users) == 0) return $form.wfMsg('nousersfound');
$form .= $this->navLinks();
$form .= "<br/><form method='post'><table>\n";
$row = 1; $style = array('',"bgcolor = '#dddddd'");
$changeable = UserrightsPage::changeableGroups();
$changeable_groups = array_unique($changeable['add']+$changeable['remove']+$changeable['add-self']+$changeable['remove-self']);
foreach ($users as $user){
$mwUser = User::newFromId($user['user_id']);
$mwUser->loadFromId();
$form .= "<tr valign='bottom' ".$style[$row]."><td>".$user['user_name'].":</td>";
foreach ($changeable_groups as $group){
if (in_array($group, User::getAllGroups())){
$checked = '';
if (in_array($group, $mwUser->getGroups())) $checked = 'checked';
$form .= "<td><input name='user.".$user['user_id']."[]' id='".$user['user_id']."' type='checkbox' value = '$group' $checked>$group</input></td>";
}
}
$form .= "</tr>\n";
$row++;
$row = $row%2;
}
$form .= "</table>";
# Preserve params
if( isset($this->offset) )
$form .= wfElement( 'input', array( 'type' => 'hidden', 'name' => 'offset', 'value' => $this->offset ) );
if( isset($this->limit) )
$form .= wfElement( 'input', array( 'type' => 'hidden', 'name' => 'limit', 'value' => $this->limit ) );
if( isset($this->yearfrom) )
$form .= wfElement( 'input', array( 'type' => 'hidden', 'name' => 'yearfrom', 'value' => $this->yearfrom ) );
if( isset($this->monthfrom) )
$form .= wfElement( 'input', array( 'type' => 'hidden', 'name' => 'monthfrom', 'value' => $this->monthfrom ) );
if( isset($this->yearto) )
$form .= wfElement( 'input', array( 'type' => 'hidden', 'name' => 'yearto', 'value' => $this->yearto ) );
if( isset($this->monthto) )
$form .= wfElement( 'input', array( 'type' => 'hidden', 'name' => 'monthto', 'value' => $this->monthto ) );
if( isset($this->username) )
$form .= wfElement( 'input', array( 'type' => 'hidden', 'name' => 'username', 'value' => $this->username ) );
if( isset($this->group) )
$form .= wfElement( 'input', array( 'type' => 'hidden', 'name' => 'group', 'value' => $this->group ) );
$form .="
<input name='act' type='submit' value='save'>
</form>\n";
$form .= $this->navLinks();
return $form;
}
function pageTop(){
$self = $this->getTitle();
$out = '<p>';
# Form tag
$out .= wfOpenElement( 'form', array( 'method' => 'post', 'action' => $self->getLocalUrl() ) );
# Group drop-down list
$out .= wfElement( 'label', array( 'for' => 'group' ), wfMsg( 'group' ) ) . ' ';
$out .= wfOpenElement( 'select', array( 'name' => 'group' ) );
$out .= wfElement( 'option', array( 'value' => '' ), wfMsg( 'group-all' ) ); # Item for "all groups"
$groups = User::getAllGroups();
foreach( $groups as $group ) {
$attribs = array( 'value' => $group );
if( isset($this->group) && $group == $this->group ) $attribs['selected'] = 'selected';
$out .= wfElement( 'option', $attribs, User::getGroupName( $group ) );
}
$out .= wfCloseElement( 'select' ) . ' ';# . wfElement( 'br' );
# Username field
$out .= wfElement( 'label', array( 'for' => 'username' ), wfMsg( 'usernamelike' ) ) . '</td><td>';
$out .= wfElement( 'input', array( 'type' => 'text', 'id' => 'username', 'name' => 'username',
'value' => @$this->username ) ) . ' ';
$out .= wfElement( 'label', array( 'for' => 'year' ), wfMsg( 'regafter' ) ) . ' ';
$years = $this->getYears();
$out .= $this->yearMenu($years, 'yearfrom');
$out .= $this->monthMenu('monthfrom').' ';
$out .= wfElement( 'label', array( 'for' => 'year' ), wfMsg( 'regbefore' ) ) . ' ';
$out .= $this->yearMenu($years, 'yearto');
$out .= $this->monthMenu('monthto');
# Submit button and form bottom
$out .= wfElement( 'input', array( 'type' => 'submit', 'value' => wfMsg( 'allpagessubmit' ) ) );
$out .= wfCloseElement( 'form' );
$out .= '</p>';
$out .= "<hr>";
return $out;
}
function getYears(){
$dbr =& wfGetDB( DB_SLAVE );
$years = array();
$result = $dbr->selectRow(
$this->user_table,
'user_registration',
'user_registration IS NOT NULL',
__METHOD__,
array('ORDER BY' => 'user_registration')
);
$y = 2000;
$thisyear = date("Y");
if (is_object($result)) $y = substr(wfTimeStamp(TS_MW, $result->user_registration),0,4);
for ($year = $y; $year <= $thisyear; $year++) $years[] = $year;
return $years;
}
# Year drop-down list
function yearMenu($years, $item = 'yearfrom'){
$out = wfOpenElement( 'select', array( 'name' => $item ) );
$out .= wfElement( 'option', array( 'value' => '' ), wfMsg( 'group-all' ) ); # Item for "all years"
foreach( $years as $year ) {
$attribs = array( 'value' => $year );
if( isset ($this->$item) && $year == $this->$item )
$attribs['selected'] = 'selected';
$out .= wfElement( 'option', $attribs, $year );
}
$out .= wfCloseElement( 'select' ) . ' ';# . wfElement( 'br' );
return $out;
}
function monthMenu($item){
global $wgContLang;
$out = wfOpenElement( 'select', array( 'name' => $item ) );
$out .= wfElement( 'option', array( 'value' => '' ), wfMsg( 'group-all' ) ); # Item for "all months"
for( $i = 1; $i <= 12; $i++ ) {
$month = str_pad($i,2,'0',STR_PAD_LEFT);
$monthName = $wgContLang->getMonthAbbreviation( $i );
$attribs = array( 'value' => $month );
if( isset ($this->$item) && $month == $this->$item )
$attribs['selected'] = 'selected';
$out .= wfElement( 'option', $attribs, $monthName );
}
$out .= wfCloseElement( 'select' ) . ' ';# . wfElement( 'br' );
return $out;
}
function navLinks(){
global $wgContLang;
$atend = $this->num < $this->limit;
$params = array();
if( isset($this->yearfrom) ) $params['yearfrom'] = $this->yearfrom;
if( isset($this->monthfrom) ) $params['monthfrom'] = $this->monthfrom;
if( isset($this->yearto) ) $params['yearto'] = $this->yearto;
if( isset($this->monthto) ) $params['monthto'] = $this->monthto;
if( isset($this->username) ) $params['username'] = $this->username;
if( isset($this->group) ) $params['group'] = $this->group;
return wfViewPrevNext(
$this->offset,
$this->limit ,
$wgContLang->specialPage( $this->getName() ),
wfArrayToCGI( $params ),
$atend );
}
function findMyUsers(){
global $wgUser, $wgDBprefix;
$dbr =& wfGetDB( DB_SLAVE );
$vars = array('user_id', 'user_name', 'user_registration');
if($wgUser->isAllowed('userrights')){
$table = array($this->user_table);
$conds = array();
}else{
$table = array($this->user_table,'logging');
$conds = array('log_title = user_name',
"log_type = 'newusers'",
"log_user = '".$wgUser->getID()."'");
}
if (isset($this->group) && $this->group !=''){
$table[] = $this->user_groups_table;
$conds = array_merge($conds, array(" ug_user = user_id", "ug_group = '".$this->group."'"));
}
if (isset($this->username) && !is_null($this->username) && $this->username != ''){
$conds = array_merge($conds, array("user_name LIKE'".mysql_real_escape_string($this->username)."' "));
}
if (isset($this->yearfrom) && !is_null($this->yearfrom) && $this->yearfrom != ''){
$month = '00';
if (!is_null($this->monthfrom )) $month = $this->monthfrom;
$fromdate = $dbr->timestamp(str_pad($this->yearfrom.$month, 14, '0', STR_PAD_RIGHT));
$conds = array_merge($conds, array("user_registration >='$fromdate' "));
}
if (isset($this->yearto) && !is_null($this->yearto) && $this->yearto != ''){
$year = $this->yearto;
$month = '99';
if (!is_null($this->monthto ) ) $month = $this->monthto;
$todate = $dbr->timestamp(str_pad($year.$month, 14, '9', STR_PAD_RIGHT));
$conds = array_merge($conds, array("user_registration <= '$todate'"));
}
$options["ORDER BY"] = "user_name";
$options["LIMIT"] = $this->limit;
$options["OFFSET"] = $this->offset;
$results = $dbr->select($table, $vars, $conds, __METHOD__, $options);
$this->num = $dbr->numRows($results);
if (!$results) return array();
while( $x = $dbr->fetchObject ( $results ) ) {
$arr[] = get_object_vars($x);
}
#echo "<pre>";print_r($conds);print_r($dbr->lastQuery());echo "</pre>";
return $arr;
}
function loadMessages() {
static $messagesLoaded = false;
global $wgMessageCache;
if ( $messagesLoaded ) return true;
$messagesLoaded = true;
require( dirname( __FILE__ ) . '/SpecialUserRightsList.i18n.php' );
foreach ( $allMessages as $lang => $langMessages ) {
// $wgMessageCache->addMessages( $langMessages, $lang );
}
return true;
}
}
?>

View File

@ -1,31 +0,0 @@
<?php
$allMessages = array(
'en' => array(
'userrightslist' => 'User rights list',
'nousersfound' => 'No users found that you can manage',
'regbefore' => 'Registered before',
'regafter' => 'Registered after',
'usernamelike' => 'User names like'
),
'de' => array(
'userrightslist' => 'User rights list',
'nousersfound' => 'No users found that you can manage',
'regbefore' => 'Registered before',
'regafter' => 'Registered after',
'usernamelike' => 'User names like'),
'ru' => array(
'userrightslist' => 'Список прав пользователей',
'nousersfound' => 'Не найдено пользователей, правами которых вы можете управлять',
'regbefore' => 'Зарегестрированы до',
'regafter' => 'Зарегестрированы после',
'usernamelike' => 'Имена пользователей (SQL "LIKE" синтаксис)'
),
'zh-tw' => array(
'userrightslist' => '用戶權限清單',
'nousersfound' => '查無可供管理的用戶名稱',
'regbefore' => '註冊時間早於',
'regafter' => '註冊時間晚於',
'usernamelike' => '用戶名稱包含'
)
);
?>

View File

@ -1,69 +0,0 @@
<?php
/*
The MIT License
Copyright (c) <2006-208> <Jim Hu>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Versions
0.51 patch for 1.13
0.5 release for 1.12
0.41 add db tablename lookup for better compatibility with installations not using MySQL
0.4 change base class and fix injection vulnerability
more bug fixes
0.3 change database calls to more standard MW usage
add russian translation
0.22 shading alternate rows
0.21 added return true to fix MW1.11 problems
0.2 fixed some unset variable problems
*/
# Not a valid entry point, skip unless MEDIAWIKI is defined
if (!defined('MEDIAWIKI')) {
echo <<<EOT
To install this extension, put the following line in LocalSettings.php:
require_once( "$IP/extensions/UserRightsList/UserRightsList.php" );
EOT;
exit( 1 );
}
$wgExtensionCredits['specialpage'][] = array(
'name' => 'UserRightsList',
'author' => 'Jim Hu',
'version'=>'0.51',
'description' => 'list-based user rights management',
'url' => 'http://www.mediawiki.org/wiki/Extension:UserRightsList'
);
$wgAutoloadClasses['UserRightsList'] = dirname(__FILE__) . '/SpecialUserRightsList.body.php';
$wgSpecialPages['UserRightsList'] = 'UserRightsList';
$wgHooks['LoadAllMessages'][] = 'UserRightsList::loadMessages';
$wgHooks['LangugeGetSpecialPageAliases'][] = 'UserRightsListLocalizedPageName';
function UserRightsListLocalizedPageName(&$specialPageArray, $code) {
# The localized title of the special page is among the messages of the
# extension:
UserRightsList::loadMessages();
$text = wfMsg('userrightslist');
# Convert from title in text form to DBKey and put it into the alias array:
$title = Title::newFromText($text);
$specialPageArray['UserRightsList'][] = $title->getDBKey();
return true;
}
?>

View File

@ -21,6 +21,7 @@ class SkinGCL3 extends SkinTemplate {
// Append to the default screen common & print styles...
$out->addStyle( 'GCL3/main.css', 'screen' );
$out->addStyle( 'GCL3/resources/print.css', 'print' );
if( $wgHandheldStyle ) {
// Currently in testing... try 'chick/main.css'
$out->addStyle( $wgHandheldStyle, 'handheld' );
@ -140,7 +141,7 @@ class GCL3Template extends QuickTemplate {
}
foreach($this->data['content_actions'] as $key => $tab) {
$linx[] = '<a href="'.htmlspecialchars($tab['href']).'"'.Linker::tooltipAndAccesskeyAttribs('ca-'.$key).'>'.htmlspecialchars($tab['text']).'</a>';
$linx[] = '<a id="ca-'.$key.'" href="'.htmlspecialchars($tab['href']).'"'.Linker::tooltipAndAccesskeyAttribs('ca-'.$key).'>'.htmlspecialchars($tab['text']).'</a>';
}
?>
<?php begin_box3($this,$new_title,implode($linx," | ")); ?>
@ -351,8 +352,8 @@ if($this->data['copyrightico']) { ?>
<li id="t-ispermalink"<?php echo Linker::tooltip('t-ispermalink') ?>><?php $this->msg('permalink') ?></li><?php
}
wfRunHooks( 'GCL3TemplateToolboxEnd', array( &$this ) );
wfRunHooks( 'SkinTemplateToolboxEnd', array( &$this ) );
Hooks::run( 'GCL3TemplateToolboxEnd', array( &$this ) );
Hooks::run( 'SkinTemplateToolboxEnd', array( &$this ) );
?>
</ul>
</div>

View File

@ -0,0 +1,29 @@
body {
background: #FFFFFF !important;
}
#metapod-menu, #header, .navigate_section {
display: none;
}
#metapod-table {
width: 100%;
}
#metapod-content .catbg:first-child {
font-size: 24px;
padding: 9px;
}
#metapod-content .titlebg:first-child {
display: none;
}
#content_section {
padding-left: 5px !important;
padding-top: 5px;
}
#content_section .frame {
padding: 0px !important;
}

View File

@ -17,5 +17,12 @@
"AutoloadClasses": {
"SkinGCL3": "SkinGCL3.php"
},
"ResourceModules": {
"skins.GCL3": {
"styles": {
"resources/print.css": { "media": "print" }
}
}
},
"manifest_version": 1
}

View File

@ -1,4 +1,5 @@
<?php
error_reporting(E_ALL); // Debug
# This file was automatically generated by the MediaWiki installer.
# If you make manual changes, please keep track in case you need to
@ -26,6 +27,8 @@ set_include_path( implode( PATH_SEPARATOR, $path ) . PATH_SEPARATOR . get_includ
require_once( "$IP/includes/DefaultSettings.php" );
$wgDebugLogFile = "/tmp/mwdebug.log";
if ( $wgCommandLineMode ) {
if ( isset( $_SERVER ) && array_key_exists( 'REQUEST_METHOD', $_SERVER ) ) {
die( "This script must be run from the command line\n" );
@ -144,16 +147,6 @@ $wgDiff3 = "/usr/bin/diff3";
# sure that cached pages are cleared.
$wgCacheEpoch = max( $wgCacheEpoch, gmdate( 'YmdHis', @filemtime( __FILE__ ) ) );
# This requires the link to SMF API.
$wgSMFPathAPI= "/application/forums/smf_api.php"; # The smf_api.php file can be download from SMF website and must be placed in rootdir of your forum)
$wgSMFPathSSI= "/application/forums/SSI.php"; # The SSI.php file (watch capitals!) (normally in your rootdir of your forum)
$wgSMFPath = "/application/forums";
// require the Auth_SMF.php
require_once "{$IP}/extensions/Auth_SMF.php";
$wgAuth = new Auth_SMF();
include_once('extensions/FlaggedRevs/FlaggedRevs.php');
$wgGroupPermissions['*']['edit'] = false;
@ -175,8 +168,6 @@ $wgFlaggedRevsExceptions = array( 'sysop', 'QC' );
$wgFlaggedRevsAutoReviewNew = true;
$wgUseStableTemplates = true;
require_once("$IP/extensions/UserRightsList/UserRightsList.php");
require_once("$IP/extensions/BBCodeSyntax/BBCodeSyntax.php");
// 5 August 2016: This extension is causing issues with certain characters in
@ -204,7 +195,7 @@ $wgRemoveGroups['bureaucrat'] = array( 'bureaucrat', 'sysop', 'QC' );
$wgAddGroups['oversight'] = array( 'oversight', 'bureaucrat', 'sysop', 'QC' );
$wgRemoveGroups['oversight'] = array( 'oversight', 'bureaucrat', 'sysop', 'QC' );
include_once('extensions/CheckUser/CheckUser.php');
wfLoadExtension("CheckUser");
$wgGroupPermissions['sysop']['checkuser'] = true;
$wgGroupPermissions['sysop']['checkuser-log'] = true;
@ -227,3 +218,29 @@ wfLoadSkin("MonoBook");
wfLoadSkin("GCL3");
$wgCachePages = false;
wfLoadExtension("Auth_remoteuser");
$wgGroupPermissions['*']['autocreateaccount'] = true;
# Disable MediaWiki's PHP session handling since it conflicts with SMF's
$wgPHPSessionHandling = "disable";
# This requires the link to SMF API.
$wgSMFPathAPI= "/application/forums/smf_api.php"; # The smf_api.php file can be download from SMF website and must be placed in rootdir of your forum)
$wgSMFPathSSI= "/application/forums/SSI.php"; # The SSI.php file (watch capitals!) (normally in your rootdir of your forum)
$wgSMFPath = "/application/forums";
$wgSMFURL = getenv("GCL_FORUMS_URL") ?: "https://forums.glitchcity.info";
require_once("{$IP}/extensions/Auth_SMF.php");
//$wgAuthRemoteuserUserName = "Abwayax";
wfLoadExtension("VisualEditor");
$wgDefaultUserOptions['visualeditor-enable'] = 1;
$wgVirtualRestConfig['modules']['parsoid'] = array(
'url' => getenv('GCL_PARSOID_URL') ?: 'http://parsoid:8000',
'domain' => getenv('GCL_PARSOID_DOMAIN') ?: 'glitchcity',
//'prefix' => getenv('GCL_PARSOID_PREFIX') ?: 'glitchcity'
);
wfLoadExtension("WikiEditor");
wfLoadExtension("CodeEditor");

File diff suppressed because one or more lines are too long

15
configuration/msmtprc Normal file
View File

@ -0,0 +1,15 @@
defaults
auth on
tls on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
logfile /var/log/msmtp.log
account email
host @GCL_SMTP_HOST@
port @GCL_SMTP_PORT@
from @GCL_SMTP_FROM@
user @GCL_SMTP_USER@
password @GCL_SMTP_PASSWORD@
# Set a default account
account default : email

View File

@ -227,6 +227,13 @@ env[GCL_WIKI_URL] = $GCL_WIKI_URL
; caching
env[GCL_MEMCACHED_HOST] = $GCL_MEMCACHED_HOST
; dev mode
env[GCL_DEV] = $GCL_DEV
; VisualEditor
env[GCL_PARSOID_URL] = $GCL_PARSOID_URL
env[GCL_PARSOID_DOMAIN] = $GCL_PARSOID_DOMAIN
; Additional php.ini defines, specific to this pool of workers. These settings
; overwrite the values previously defined in the php.ini. The directives are the
; same as the PHP SAPI:

View File

@ -26,6 +26,12 @@ stdout_events_enabled=true
stderr_events_enabled=true
autorestart=unexpected
[program:mwdebug-log]
command=tail -f /tmp/mwdebug.log
stdout_events_enabled=true
stderr_events_enabled=true
autorestart=unexpected
[program:nginx]
command=/usr/sbin/nginx
stdout_events_enabled=true

View File

@ -4,6 +4,8 @@ services:
image: memcached
db:
image: mariadb
volumes:
- ./configuration:/docker-entrypoint-initdb.d
environment:
MYSQL_ROOT_PASSWORD: toor
MYSQL_DATABASE: glitchcity
@ -18,12 +20,21 @@ services:
links:
- db
- cache
- parsoid
environment:
GCL_DB_HOST: db
GCL_DB_NAME: glitchcity
GCL_DB_USER: root
GCL_DB_PASSWORD: toor
GCL_DB_DUMP: /configuration/glitchcity.sql
GCL_FORUMS_URL: http://localhost:8001/forums
GCL_WIKI_URL: http://localhost:8001/wiki
GCL_MEMCACHED_HOST: cache
GCL_SMTP_HOST: mail.gandi.net
GCL_SMTP_USER: no-reply@monarch-pass.net
#GCL_SMTP_PASSWORD: smtp-password-here
GCL_DEV: "true"
GCL_PARSOID_DOMAIN: web
parsoid:
image: thenets/parsoid:0.10
environment:
PARSOID_DOMAIN_web: http://web/w/api.php

View File

@ -17,6 +17,10 @@ if [[ "${EXT_VERSION}" ]]; then
git checkout -b "${EXT_VERSION}" "origin/${EXT_VERSION}"
fi
if [[ -e ".git" ]]; then
git submodule update --init
fi
if [[ -e "composer.json" ]]; then
composer install --no-dev
fi

52
scripts/add_mod.php Executable file
View File

@ -0,0 +1,52 @@
#!/usr/bin/env php
<?php
define("SMF", true);
$boarddir = getenv("FORUMS_SOURCE");
$sourcedir = "$boarddir/Sources";
$forum_version = "SMF " . getenv("SMF_VERSION");
$temp_dir = "$boarddir/Packages/temp";
require_once("$sourcedir/Errors.php");
require_once("$sourcedir/QueryString.php");
require_once("$sourcedir/Subs.php");
require_once("$sourcedir/Subs-Package.php");
function loadLanguage($language) {}
function download($uri) {
$entries = scandir(".");
passthru("wget --content-disposition \"$uri\"");
return array_values(array_diff(scandir("."), $entries))[0];
}
function downloadPackage($packageUrl) {
global $boarddir;
$packageFile = download($packageUrl);
$fullPackageName = "$boarddir/Packages/$packageFile";
rename($packageFile, $fullPackageName);
return $packageFile;
}
function unpackPackage($packageFile) {
global $boarddir, $temp_dir;
$fullPackageName = "$boarddir/Packages/$packageFile";
mktree($temp_dir, 0777);
read_tgz_file($fullPackageName, $temp_dir);
}
function installPackage($packageFile) {
$packageInfo = getPackageInfo($packageFile);
return parsePackageInfo($packageInfo['xml'], false);
}
function cleanup() {
global $temp_dir;
deltree($temp_dir);
}
$packageUrl = $argv[1];
$packageFile = downloadPackage($packageUrl);
unpackPackage($packageFile);
installPackage($packageFile);
cleanup();

View File

@ -1,34 +1,44 @@
#!/bin/bash -e
# Create initial database if we need to
if [ $GCL_DB_DUMP ] && [ -f $GCL_DB_DUMP ]; then
mysql -h"$GCL_DB_HOST" -u"$GCL_DB_USER" -p"$GCL_DB_PASSWORD" -e "CREATE DATABASE $GCL_DB_NAME"
mysql -D"$GCL_DB_NAME" -h"$GCL_DB_HOST" -u"$GCL_DB_USER" -p"$GCL_DB_PASSWORD" < $GCL_DB_DUMP
rm $GCL_DB_DUMP
fi
# Create symlinks between application, userdata, and configuration
rm /application/w/LocalSettings.php
ln -sf /configuration/MWSettings.php /application/w/LocalSettings.php
rm $WIKI_SOURCE/LocalSettings.php
ln -sf /configuration/MWSettings.php $WIKI_SOURCE/LocalSettings.php
rm /application/forums/Settings.php
ln -sf /configuration/SMFSettings.php /application/forums/Settings.php
rm $FORUMS_SOURCE/Settings.php
ln -sf /configuration/SMFSettings.php $FORUMS_SOURCE/Settings.php
rm -rf /application/w/images
ln -sf /userdata/images /application/w/images
rm -rf $WIKI_SOURCE/images
ln -sf /userdata/images $WIKI_SOURCE/images
rm -rf /application/forums/downloads
ln -sf /userdata/downloads /application/forums/downloads
rm -rf $FORUMS_SOURCE/downloads
ln -sf /userdata/downloads $FORUMS_SOURCE/downloads
rm -rf /application/forums/attachments
ln -sf /userdata/attachments /application/forums/attachments
rm -rf $FORUMS_SOURCE/attachments
ln -sf /userdata/attachments $FORUMS_SOURCE/attachments
rm -rf /application/forums/profile_pictures
ln -sf /userdata/profile_pictures /application/forums/profile_pictures
rm -rf $FORUMS_SOURCE/profile_pictures
ln -sf /userdata/profile_pictures $FORUMS_SOURCE/profile_pictures
rm -rf /application/forums/pm_attachments
ln -sf /userdata/pm_attachments /application/forums/pm_attachments
rm -rf $FORUMS_SOURCE/pm_attachments
ln -sf /userdata/pm_attachments $FORUMS_SOURCE/pm_attachments
# Configure email
cp /configuration/msmtprc /etc/msmtprc
sed -i "s/@GCL_SMTP_HOST@/$GCL_SMTP_HOST/g" /etc/msmtprc
SMTP_PORT=${GCL_SMTP_PORT:-587}
sed -i "s/@GCL_SMTP_PORT@/$SMTP_PORT/g" /etc/msmtprc
SMTP_FROM=${GCL_SMTP_FROM:-no-reply@glitchcity.info}
sed -i "s/@GCL_SMTP_FROM@/$SMTP_FROM/g" /etc/msmtprc
sed -i "s/@GCL_SMTP_USER@/$GCL_SMTP_USER/g" /etc/msmtprc
sed -i "s/@GCL_SMTP_PASSWORD@/$GCL_SMTP_PASSWORD/g" /etc/msmtprc
# Run maintenance scripts
cd /application/w/maintenance
wait-for-it "$GCL_DB_HOST:3306" --timeout=60
cd $WIKI_SOURCE/maintenance
php update.php
cd $FORUMS_SOURCE
rm install.php
exit 0;