329 行
12 KiB
PHP
329 行
12 KiB
PHP
<?php
|
|
|
|
namespace MediaWiki\Extension\RNRSHook;
|
|
|
|
use MediaWiki\Permissions\PermissionManager;
|
|
use MediaWiki\Permissions\Hook\GetUserPermissionsErrorsHook;
|
|
use MediaWiki\User\UserOptionsLookup;
|
|
use MediaWiki\User\UserIdentity;
|
|
use MediaWiki\User\Registration\UserRegistrationLookup;
|
|
use MediaWiki\User\UserGroupManager;
|
|
use MediaWiki\Hook\SpecialContributionsBeforeMainOutputHook;
|
|
use MediaWiki\MediaWikiServices;
|
|
use MediaWiki\SpecialPage;
|
|
// use ManualLogEntry;
|
|
use RequestContext;
|
|
use Config;
|
|
use Title;
|
|
use User;
|
|
|
|
class PermissionsHook implements
|
|
getUserPermissionsErrorsHook,
|
|
SpecialContributionsBeforeMainOutputHook
|
|
{
|
|
/** @var permissionManager */
|
|
private $permissionManager;
|
|
|
|
/** @var config */
|
|
private $config;
|
|
|
|
/** @var userGroupManager */
|
|
private $userGroupManager;
|
|
|
|
/**
|
|
* @param PermissionManager $permissionManager
|
|
* @param UserGroupManager $userGroupManager
|
|
* @param Config $config
|
|
* @param UserOptionsLookup $userOptionsLookup
|
|
* @param UserRegistrationLookup $userRegistrationLookup
|
|
*/
|
|
public function __construct(
|
|
PermissionManager $permissionManager,
|
|
Config $config,
|
|
UserGroupManager $userGroupManager,
|
|
UserOptionsLookup $userOptionsLookup,
|
|
UserRegistrationLookup $userRegistrationLookup
|
|
) {
|
|
$this->permissionManager = $permissionManager;
|
|
$this->config = $config;
|
|
$this->userOptionsLookup = $userOptionsLookup;
|
|
$this->userRegistrationLookup = $userRegistrationLookup;
|
|
$this->userGroupManager = $userGroupManager;
|
|
}
|
|
|
|
/**
|
|
* @param UserIdentity $user
|
|
*
|
|
* @return bool
|
|
*/
|
|
private function checkUserVerifyHash(UserIdentity $user)
|
|
{
|
|
$rnrssalt = $this->config->get('RNRSSalt');
|
|
$lookup = MediaWikiServices::getInstance()->getCentralIdLookup();
|
|
$rnrsverifyhash = $this->userOptionsLookup->getOption($user, 'rnrsverifyhash');
|
|
$localuserid = (string)RequestContext::getMain()->getUser()->getID();
|
|
$centralid = (string)$lookup->centralIdFromLocalUser($user);
|
|
$rnrsverifytime = $this->userOptionsLookup->getOption($user, 'rnrsverifytime');
|
|
|
|
// Mode 1: user ID + verify time + salt
|
|
$rnrsHashVerified = (
|
|
$rnrsverifyhash === hash('sha3-256', $localuserid . $rnrsverifytime . hash('sha3-256', $rnrssalt)) ||
|
|
$rnrsverifyhash === hash('sha3-256', $centralid . $rnrsverifytime . hash('sha3-256', $rnrssalt))
|
|
);
|
|
|
|
if ($rnrsHashVerified) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param UserIdentity $user
|
|
*
|
|
* @return bool
|
|
*/
|
|
private function checkConfirmedGroup(UserIdentity $user)
|
|
{
|
|
// Mode2: confirmed by verification
|
|
$rnrsInConfirmedGroup = in_array($this->config->get('RNRSConfirmedGroup'), $this->userGroupManager->getUserGroups($user));
|
|
|
|
if ($rnrsInConfirmedGroup) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param UserIdentity $user
|
|
*
|
|
* @return bool
|
|
*/
|
|
private function checkExemptedGroup(UserIdentity $user)
|
|
{
|
|
// Mode3: in group(s) that exempted from verification
|
|
$rnrsInExemptGroup = (
|
|
in_array($this->config->get('RNRSExemptGroup'), $this->userGroupManager->getUserGroups($user)) ||
|
|
in_array('rnrsverify-exempt', $this->permissionManager->getUserPermissions($user)) ||
|
|
in_array('bot', $this->permissionManager->getUserPermissions($user))
|
|
);
|
|
|
|
if ($rnrsInExemptGroup) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param UserIdentity $user
|
|
*
|
|
* @return bool
|
|
*/
|
|
private function checkOtherExemptedGroups(UserIdentity $user)
|
|
{
|
|
// Mode4: in group(s) that exempted from verification
|
|
$rnrsInExemptGroup = (
|
|
in_array('rnrsverify-exempt', $this->permissionManager->getUserPermissions($user)) ||
|
|
in_array('bot', $this->permissionManager->getUserPermissions($user))
|
|
) && !(in_array($this->config->get('RNRSExemptGroup'), $this->userGroupManager->getUserGroups($user)));
|
|
|
|
if ($rnrsInExemptGroup) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param UserIdentity $user
|
|
* @param $added_group
|
|
*
|
|
* @return void
|
|
*/
|
|
private function addGroup($user, $added_group)
|
|
{
|
|
// Add Group
|
|
$this->userGroupManager->addUserToGroup($user, $added_group);
|
|
|
|
// // Add Add Log
|
|
// $oldGroups = $this->userGroupManager->getUserGroups($user); // previous groups
|
|
// $newGroups = array_merge($oldGroups, [$added_group]); // new groups
|
|
// $logEntry = new ManualLogEntry('rights', 'autopromote');
|
|
// $logEntry->setPerformer($user);
|
|
// $logEntry->setTarget($user->getUserPage());
|
|
// $logEntry->setParameters([
|
|
// '4::oldgroups' => $oldGroups,
|
|
// '5::newgroups' => $newGroups,
|
|
// ]);
|
|
// $logid = $logEntry->insert();
|
|
// $logEntry->publish($logid);
|
|
}
|
|
|
|
/**
|
|
* @param UserIdentity $user
|
|
* @param $removed_group
|
|
*
|
|
* @return void
|
|
*/
|
|
private function removeGroup($user, $removed_group)
|
|
{
|
|
// Remove Group
|
|
$this->userGroupManager->removeUserFromGroup($user, $removed_group);
|
|
|
|
// // Add Remove Log
|
|
// $oldGroups = $this->userGroupManager->getUserGroups($user); // previous groups
|
|
// $newGroups = array_intersect($oldGroups, [$removed_group]); // new groups
|
|
// If ($oldGroups !== $newGroups) {
|
|
// $logEntry = new ManualLogEntry('rights', 'autopromote');
|
|
// $logEntry->setPerformer($user);
|
|
// $logEntry->setTarget($user->getUserPage());
|
|
// $logEntry->setParameters([
|
|
// '4::oldgroups' => $oldGroups,
|
|
// '5::newgroups' => $newGroups,
|
|
// ]);
|
|
// $logid = $logEntry->insert();
|
|
// $logEntry->publish($logid);
|
|
// }
|
|
}
|
|
|
|
/**
|
|
* @param Title $title
|
|
* @param User $user
|
|
* @param string $action
|
|
* @param string &$result
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function onGetUserPermissionsErrors($title, $user, $action, &$result)
|
|
{
|
|
$rnrsEnabledConfirmedGroup = in_array(
|
|
$this->config->get('RNRSConfirmedGroup'),
|
|
array_merge(
|
|
$this->userGroupManager->listAllImplicitGroups(),
|
|
$this->userGroupManager->listAllGroups()
|
|
)
|
|
);
|
|
$rnrsEnabledExemptGroup = in_array(
|
|
$this->config->get('RNRSExemptGroup'),
|
|
array_merge(
|
|
$this->userGroupManager->listAllImplicitGroups(),
|
|
$this->userGroupManager->listAllGroups()
|
|
)
|
|
);
|
|
$rnrsHashVerified = $this->checkUserVerifyHash($user);
|
|
$rnrsInConfirmedGroup = $this->checkConfirmedGroup($user);
|
|
$rnrsInExemptGroup = $this->checkExemptedGroup($user);
|
|
$rnrsInOtherExemptedGroups = $this->checkOtherExemptedGroups($user);
|
|
|
|
// Adjust user groups
|
|
if ($rnrsHashVerified) {
|
|
// If hash verified, and not in the confirmed group,
|
|
// add to confirmed group
|
|
if (!$rnrsInConfirmedGroup) {
|
|
if ($rnrsEnabledConfirmedGroup) {
|
|
$this->addGroup($user, $this->config->get('RNRSConfirmedGroup'));
|
|
$rnrsInConfirmedGroup = true;
|
|
} else if ($rnrsEnabledExemptGroup) {
|
|
$this->addGroup($user, $this->config->get('RNRSConfirmedGroup'));
|
|
$rnrsInConfirmedGroup = true;
|
|
}
|
|
}
|
|
} else if ($rnrsInExemptGroup || $rnrsInOtherExemptedGroups) {
|
|
// If verify exempted, hash not verified, but in the confirmed group,
|
|
// remove from confirmed group
|
|
if ($rnrsInConfirmedGroup) {
|
|
if ($rnrsEnabledConfirmedGroup) {
|
|
$this->removeGroup($user, $this->config->get('RNRSConfirmedGroup'));
|
|
$rnrsInConfirmedGroup = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (
|
|
!$this->config->has('RNRSExclusiveRights') ||
|
|
!$this->config->has('RNRSSalt')
|
|
) {
|
|
// Case 1: not enabled
|
|
// return true
|
|
return true;
|
|
} else if ($rnrsInConfirmedGroup) {
|
|
// Case 2: in confirmed group
|
|
return true;
|
|
} else if ($rnrsHashVerified) {
|
|
// Case 3: hash verified
|
|
return true;
|
|
} else if ($rnrsInExemptGroup) {
|
|
// Case 4: in exempted groups
|
|
return true;
|
|
} else if ($rnrsInOtherExemptedGroups) {
|
|
// Case 5: with exempt permissions
|
|
return true;
|
|
} else if (
|
|
!$rnrsHashVerified && !$rnrsInConfirmedGroup && !$rnrsInExemptGroup && !$rnrsInOtherExemptedGroups &&
|
|
in_array($action, $this->config->get('RNRSExclusiveRights'))
|
|
) {
|
|
// Case 0: not verified, not in confirmed group, not in exempted groups, actions in restrict list
|
|
// return false
|
|
$result = 'rnrshook-action-restricted';
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param int $userId
|
|
* @param User $user
|
|
* @param SpecialPage $special
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function onSpecialContributionsBeforeMainOutput($userId, $user, $special)
|
|
{
|
|
$rnrsEnabledConfirmedGroup = in_array(
|
|
$this->config->get('RNRSConfirmedGroup'),
|
|
array_merge(
|
|
$this->userGroupManager->listAllImplicitGroups(),
|
|
$this->userGroupManager->listAllGroups()
|
|
)
|
|
);
|
|
$rnrsEnabledExemptGroup = in_array(
|
|
$this->config->get('RNRSExemptGroup'),
|
|
array_merge(
|
|
$this->userGroupManager->listAllImplicitGroups(),
|
|
$this->userGroupManager->listAllGroups()
|
|
)
|
|
);
|
|
$rnrsHashVerified = $this->checkUserVerifyHash($user);
|
|
$rnrsInConfirmedGroup = $this->checkConfirmedGroup($user);
|
|
$rnrsInExemptGroup = $this->checkExemptedGroup($user);
|
|
$rnrsInOtherExemptedGroups = $this->checkOtherExemptedGroups($user);
|
|
|
|
// Adjust user groups
|
|
if ($rnrsHashVerified) {
|
|
// If hash verified, and not in the confirmed group,
|
|
// add to confirmed group
|
|
if (!$rnrsInConfirmedGroup) {
|
|
if ($rnrsEnabledConfirmedGroup) {
|
|
$this->addGroup($user, $this->config->get('RNRSConfirmedGroup'));
|
|
$rnrsInConfirmedGroup = true;
|
|
} else if ($rnrsEnabledExemptGroup) {
|
|
$this->addGroup($user, $this->config->get('RNRSConfirmedGroup'));
|
|
$rnrsInConfirmedGroup = true;
|
|
}
|
|
}
|
|
} else if ($rnrsInExemptGroup || $rnrsInOtherExemptedGroups) {
|
|
// If verify exempted, hash not verified, but in the confirmed group,
|
|
// remove from confirmed group
|
|
if ($rnrsInConfirmedGroup) {
|
|
if ($rnrsEnabledConfirmedGroup) {
|
|
$this->removeGroup($user, $this->config->get('RNRSConfirmedGroup'));
|
|
$rnrsInConfirmedGroup = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|