mediawiki-extensions-RNRSHook/src/PermissionsHook.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;
}
}