Add user rights 'viewmywatchlist', 'editmywatchlist'
These are needed for OAuth grants. Note that, even if 'editmywatchlist' is not granted, various actions will still allow for adding but not removing of pages. Change-Id: Ie33446a228dd6ed0114730935c1bf65667f5ce01
This commit is contained in:
parent
3d14c52a47
commit
18062eb3b0
26 changed files with 196 additions and 78 deletions
|
|
@ -28,9 +28,9 @@ production.
|
|||
* $wgLogAutopatrol added to allow disabling logging of autopatrol edits in the logging table.
|
||||
default for $wgLogAutopatrol is true.
|
||||
* The 'edit' right no longer allows for editing a user's own CSS and JS.
|
||||
* New rights 'editmyusercss' and 'editmyuserjs' restrict actions that were
|
||||
formerly allowed by default. They have been added to the default for
|
||||
$wgGroupPermissions['*'].
|
||||
* New rights 'editmyusercss', 'editmyuserjs', 'viewmywatchlist',
|
||||
and 'editmywatchlist' restrict actions that were formerly allowed by default.
|
||||
They have been added to the default for $wgGroupPermissions['*'].
|
||||
|
||||
=== New features in 1.22 ===
|
||||
* (bug 44525) mediawiki.jqueryMsg can now parse (whitelisted) HTML elements and attributes.
|
||||
|
|
@ -108,6 +108,8 @@ production.
|
|||
for extensions such as OAuth:
|
||||
** editmyusercss controls whether a user may edit their own CSS subpages.
|
||||
** editmyuserjs controls whether a user may edit their own JS subpages.
|
||||
** viewmywatchlist controls whether a user may view their watchlist.
|
||||
** editmywatchlist controls whether a user may edit their watchlist.
|
||||
* Add new hook AbortTalkPageEmailNotification, this will be used to determine
|
||||
whether to send the regular talk page email notification
|
||||
* (bug 46513) Vector: Add the collapsibleTabs script from the Vector extension.
|
||||
|
|
|
|||
|
|
@ -1546,13 +1546,7 @@ class Article implements Page {
|
|||
|
||||
$this->doDelete( $reason, $suppress );
|
||||
|
||||
if ( $user->isLoggedIn() && $request->getCheck( 'wpWatch' ) != $user->isWatched( $title ) ) {
|
||||
if ( $request->getCheck( 'wpWatch' ) ) {
|
||||
WatchAction::doWatch( $title, $user );
|
||||
} else {
|
||||
WatchAction::doUnwatch( $title, $user );
|
||||
}
|
||||
}
|
||||
WatchAction::doWatchOrUnwatch( $request->getCheck( 'wpWatch' ), $title, $user );
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3873,6 +3873,8 @@ $wgGroupPermissions['*']['createtalk'] = true;
|
|||
$wgGroupPermissions['*']['writeapi'] = true;
|
||||
$wgGroupPermissions['*']['editmyusercss'] = true;
|
||||
$wgGroupPermissions['*']['editmyuserjs'] = true;
|
||||
$wgGroupPermissions['*']['viewmywatchlist'] = true;
|
||||
$wgGroupPermissions['*']['editmywatchlist'] = true;
|
||||
#$wgGroupPermissions['*']['patrolmarks'] = false; // let anons see what was patrolled
|
||||
|
||||
// Implicit group for all logged-in accounts
|
||||
|
|
|
|||
|
|
@ -1743,7 +1743,9 @@ class EditPage {
|
|||
protected function updateWatchlist() {
|
||||
global $wgUser;
|
||||
|
||||
if ( $wgUser->isLoggedIn() && $this->watchthis != $wgUser->isWatched( $this->mTitle ) ) {
|
||||
if ( $wgUser->isLoggedIn()
|
||||
&& $this->watchthis != $wgUser->isWatched( $this->mTitle, WatchedItem::IGNORE_USER_RIGHTS )
|
||||
) {
|
||||
$fname = __METHOD__;
|
||||
$title = $this->mTitle;
|
||||
$watch = $this->watchthis;
|
||||
|
|
@ -1752,11 +1754,7 @@ class EditPage {
|
|||
$dbw = wfGetDB( DB_MASTER );
|
||||
$dbw->onTransactionIdle( function() use ( $dbw, $title, $watch, $wgUser, $fname ) {
|
||||
$dbw->begin( $fname );
|
||||
if ( $watch ) {
|
||||
WatchAction::doWatch( $title, $wgUser );
|
||||
} else {
|
||||
WatchAction::doUnwatch( $title, $wgUser );
|
||||
}
|
||||
WatchAction::doWatchOrUnwatch( $watch, $title, $wgUser );
|
||||
$dbw->commit( $fname );
|
||||
} );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,13 +120,7 @@ class FileDeleteForm {
|
|||
// file, otherwise go back to the description page
|
||||
$wgOut->addReturnTo( $this->oldimage ? $this->title : Title::newMainPage() );
|
||||
|
||||
if ( $wgUser->isLoggedIn() && $wgRequest->getCheck( 'wpWatch' ) != $wgUser->isWatched( $this->title ) ) {
|
||||
if ( $wgRequest->getCheck( 'wpWatch' ) ) {
|
||||
WatchAction::doWatch( $this->title, $wgUser );
|
||||
} else {
|
||||
WatchAction::doUnwatch( $this->title, $wgUser );
|
||||
}
|
||||
}
|
||||
WatchAction::doWatchOrUnwatch( $wgRequest->getCheck( 'wpWatch' ), $this->title, $wgUser );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -330,13 +330,8 @@ class ProtectionForm {
|
|||
return false;
|
||||
}
|
||||
|
||||
if ( $wgUser->isLoggedIn() && $wgRequest->getCheck( 'mwProtectWatch' ) != $wgUser->isWatched( $this->mTitle ) ) {
|
||||
if ( $wgRequest->getCheck( 'mwProtectWatch' ) ) {
|
||||
WatchAction::doWatch( $this->mTitle, $wgUser );
|
||||
} else {
|
||||
WatchAction::doUnwatch( $this->mTitle, $wgUser );
|
||||
}
|
||||
}
|
||||
WatchAction::doWatchOrUnwatch( $wgRequest->getCheck( 'mwProtectWatch' ), $this->mTitle, $wgUser );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -613,12 +613,15 @@ class SkinTemplate extends Skin {
|
|||
'href' => $href,
|
||||
'active' => ( $href == $pageurl )
|
||||
);
|
||||
$href = self::makeSpecialUrl( 'Watchlist' );
|
||||
$personal_urls['watchlist'] = array(
|
||||
'text' => $this->msg( 'mywatchlist' )->text(),
|
||||
'href' => $href,
|
||||
'active' => ( $href == $pageurl )
|
||||
);
|
||||
|
||||
if ( $this->getUser()->isAllowed( 'viewmywatchlist' ) ) {
|
||||
$href = self::makeSpecialUrl( 'Watchlist' );
|
||||
$personal_urls['watchlist'] = array(
|
||||
'text' => $this->msg( 'mywatchlist' )->text(),
|
||||
'href' => $href,
|
||||
'active' => ( $href == $pageurl )
|
||||
);
|
||||
}
|
||||
|
||||
# We need to do an explicit check for Special:Contributions, as we
|
||||
# have to match both the title, and the target, which could come
|
||||
|
|
@ -992,7 +995,7 @@ class SkinTemplate extends Skin {
|
|||
wfProfileOut( __METHOD__ . '-live' );
|
||||
|
||||
// Checks if the user is logged in
|
||||
if ( $this->loggedin ) {
|
||||
if ( $this->loggedin && $user->isAllowedAll( 'viewmywatchlist', 'editmywatchlist' ) ) {
|
||||
/**
|
||||
* The following actions use messages which, if made particular to
|
||||
* the any specific skins, would break the Ajax code which makes this
|
||||
|
|
|
|||
|
|
@ -4531,7 +4531,7 @@ class Title {
|
|||
if ( array_key_exists( $uid, $this->mNotificationTimestamp ) ) {
|
||||
return $this->mNotificationTimestamp[$uid];
|
||||
}
|
||||
if ( !$uid || !$wgShowUpdatedMarker ) {
|
||||
if ( !$uid || !$wgShowUpdatedMarker || !$user->isAllowed( 'viewmywatchlist' ) ) {
|
||||
return $this->mNotificationTimestamp[$uid] = false;
|
||||
}
|
||||
// Don't cache too much!
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@ class User {
|
|||
'editprotected',
|
||||
'editmyusercss',
|
||||
'editmyuserjs',
|
||||
'editmywatchlist',
|
||||
'editusercssjs', #deprecated
|
||||
'editusercss',
|
||||
'edituserjs',
|
||||
|
|
@ -166,6 +167,7 @@ class User {
|
|||
'upload_by_url',
|
||||
'userrights',
|
||||
'userrights-interwiki',
|
||||
'viewmywatchlist',
|
||||
'writeapi',
|
||||
);
|
||||
/**
|
||||
|
|
@ -2860,11 +2862,14 @@ class User {
|
|||
/**
|
||||
* Get a WatchedItem for this user and $title.
|
||||
*
|
||||
* @since 1.22 $checkRights parameter added
|
||||
* @param $title Title
|
||||
* @param $checkRights int Whether to check 'viewmywatchlist'/'editmywatchlist' rights.
|
||||
* Pass WatchedItem::CHECK_USER_RIGHTS or WatchedItem::IGNORE_USER_RIGHTS.
|
||||
* @return WatchedItem
|
||||
*/
|
||||
public function getWatchedItem( $title ) {
|
||||
$key = $title->getNamespace() . ':' . $title->getDBkey();
|
||||
public function getWatchedItem( $title, $checkRights = WatchedItem::CHECK_USER_RIGHTS ) {
|
||||
$key = $checkRights . ':' . $title->getNamespace() . ':' . $title->getDBkey();
|
||||
|
||||
if ( isset( $this->mWatchedItems[$key] ) ) {
|
||||
return $this->mWatchedItems[$key];
|
||||
|
|
@ -2874,34 +2879,43 @@ class User {
|
|||
$this->mWatchedItems = array();
|
||||
}
|
||||
|
||||
$this->mWatchedItems[$key] = WatchedItem::fromUserTitle( $this, $title );
|
||||
$this->mWatchedItems[$key] = WatchedItem::fromUserTitle( $this, $title, $checkRights );
|
||||
return $this->mWatchedItems[$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the watched status of an article.
|
||||
* @since 1.22 $checkRights parameter added
|
||||
* @param $title Title of the article to look at
|
||||
* @param $checkRights int Whether to check 'viewmywatchlist'/'editmywatchlist' rights.
|
||||
* Pass WatchedItem::CHECK_USER_RIGHTS or WatchedItem::IGNORE_USER_RIGHTS.
|
||||
* @return bool
|
||||
*/
|
||||
public function isWatched( $title ) {
|
||||
return $this->getWatchedItem( $title )->isWatched();
|
||||
public function isWatched( $title, $checkRights = WatchedItem::CHECK_USER_RIGHTS ) {
|
||||
return $this->getWatchedItem( $title, $checkRights )->isWatched();
|
||||
}
|
||||
|
||||
/**
|
||||
* Watch an article.
|
||||
* @since 1.22 $checkRights parameter added
|
||||
* @param $title Title of the article to look at
|
||||
* @param $checkRights int Whether to check 'viewmywatchlist'/'editmywatchlist' rights.
|
||||
* Pass WatchedItem::CHECK_USER_RIGHTS or WatchedItem::IGNORE_USER_RIGHTS.
|
||||
*/
|
||||
public function addWatch( $title ) {
|
||||
$this->getWatchedItem( $title )->addWatch();
|
||||
public function addWatch( $title, $checkRights = WatchedItem::CHECK_USER_RIGHTS ) {
|
||||
$this->getWatchedItem( $title, $checkRights )->addWatch();
|
||||
$this->invalidateCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop watching an article.
|
||||
* @since 1.22 $checkRights parameter added
|
||||
* @param $title Title of the article to look at
|
||||
* @param $checkRights int Whether to check 'viewmywatchlist'/'editmywatchlist' rights.
|
||||
* Pass WatchedItem::CHECK_USER_RIGHTS or WatchedItem::IGNORE_USER_RIGHTS.
|
||||
*/
|
||||
public function removeWatch( $title ) {
|
||||
$this->getWatchedItem( $title )->removeWatch();
|
||||
public function removeWatch( $title, $checkRights = WatchedItem::CHECK_USER_RIGHTS ) {
|
||||
$this->getWatchedItem( $title, $checkRights )->removeWatch();
|
||||
$this->invalidateCache();
|
||||
}
|
||||
|
||||
|
|
@ -2909,6 +2923,7 @@ class User {
|
|||
* Clear the user's notification timestamp for the given title.
|
||||
* If e-notif e-mails are on, they will receive notification mails on
|
||||
* the next change of the page if it's watched etc.
|
||||
* @note If the user doesn't have 'editmywatchlist', this will do nothing.
|
||||
* @param $title Title of the article to look at
|
||||
*/
|
||||
public function clearNotification( &$title ) {
|
||||
|
|
@ -2919,6 +2934,11 @@ class User {
|
|||
return;
|
||||
}
|
||||
|
||||
// Do nothing if not allowed to edit the watchlist
|
||||
if ( !$this->isAllowed( 'editmywatchlist' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( $title->getNamespace() == NS_USER_TALK &&
|
||||
$title->getText() == $this->getName() ) {
|
||||
if ( !wfRunHooks( 'UserClearNewTalkNotification', array( &$this ) ) ) {
|
||||
|
|
@ -2954,12 +2974,18 @@ class User {
|
|||
* Resets all of the given user's page-change notification timestamps.
|
||||
* If e-notif e-mails are on, they will receive notification mails on
|
||||
* the next change of any watched page.
|
||||
* @note If the user doesn't have 'editmywatchlist', this will do nothing.
|
||||
*/
|
||||
public function clearAllNotifications() {
|
||||
if ( wfReadOnly() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Do nothing if not allowed to edit the watchlist
|
||||
if ( !$this->isAllowed( 'editmywatchlist' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
global $wgUseEnotif, $wgShowUpdatedMarker;
|
||||
if ( !$wgUseEnotif && !$wgShowUpdatedMarker ) {
|
||||
$this->setNewtalk( false );
|
||||
|
|
@ -4587,4 +4613,26 @@ class User {
|
|||
'user_editcount',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory function for fatal permission-denied errors
|
||||
*
|
||||
* @since 1.22
|
||||
* @param string $permission User right required
|
||||
* @return Status
|
||||
*/
|
||||
static function newFatalPermissionDeniedStatus( $permission ) {
|
||||
global $wgLang;
|
||||
|
||||
$groups = array_map(
|
||||
array( 'User', 'makeGroupLinkWiki' ),
|
||||
User::getGroupsWithPermission( $permission )
|
||||
);
|
||||
|
||||
if ( $groups ) {
|
||||
return Status::newFatal( 'badaccess-groups', $wgLang->commaList( $groups ), count( $groups ) );
|
||||
} else {
|
||||
return Status::newFatal( 'badaccess-group0' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,19 +27,37 @@
|
|||
* @ingroup Watchlist
|
||||
*/
|
||||
class WatchedItem {
|
||||
var $mTitle, $mUser;
|
||||
/**
|
||||
* Constant to specify that user rights 'editmywatchlist' and
|
||||
* 'viewmywatchlist' should not be checked.
|
||||
* @since 1.22
|
||||
*/
|
||||
const IGNORE_USER_RIGHTS = 0;
|
||||
|
||||
/**
|
||||
* Constant to specify that user rights 'editmywatchlist' and
|
||||
* 'viewmywatchlist' should be checked.
|
||||
* @since 1.22
|
||||
*/
|
||||
const CHECK_USER_RIGHTS = 1;
|
||||
|
||||
var $mTitle, $mUser, $mCheckRights;
|
||||
private $loaded = false, $watched, $timestamp;
|
||||
|
||||
/**
|
||||
* Create a WatchedItem object with the given user and title
|
||||
* @since 1.22 $checkRights parameter added
|
||||
* @param $user User: the user to use for (un)watching
|
||||
* @param $title Title: the title we're going to (un)watch
|
||||
* @param $checkRights int: Whether to check the 'viewmywatchlist' and 'editmywatchlist' rights.
|
||||
* Pass either WatchedItem::IGNORE_USER_RIGHTS or WatchedItem::CHECK_USER_RIGHTS.
|
||||
* @return WatchedItem object
|
||||
*/
|
||||
public static function fromUserTitle( $user, $title ) {
|
||||
public static function fromUserTitle( $user, $title, $checkRights = WatchedItem::CHECK_USER_RIGHTS ) {
|
||||
$wl = new WatchedItem;
|
||||
$wl->mUser = $user;
|
||||
$wl->mTitle = $title;
|
||||
$wl->mCheckRights = $checkRights;
|
||||
|
||||
return $wl;
|
||||
}
|
||||
|
|
@ -110,11 +128,23 @@ class WatchedItem {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check permissions
|
||||
* @param $what string: 'viewmywatchlist' or 'editmywatchlist'
|
||||
*/
|
||||
private function isAllowed( $what ) {
|
||||
return !$this->mCheckRights || $this->mUser->isAllowed( $what );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is mTitle being watched by mUser?
|
||||
* @return bool
|
||||
*/
|
||||
public function isWatched() {
|
||||
if ( !$this->isAllowed( 'viewmywatchlist' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->load();
|
||||
return $this->watched;
|
||||
}
|
||||
|
|
@ -126,6 +156,10 @@ class WatchedItem {
|
|||
* the wl_notificationtimestamp field otherwise
|
||||
*/
|
||||
public function getNotificationTimestamp() {
|
||||
if ( !$this->isAllowed( 'viewmywatchlist' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->load();
|
||||
if ( $this->watched ) {
|
||||
return $this->timestamp;
|
||||
|
|
@ -142,7 +176,7 @@ class WatchedItem {
|
|||
*/
|
||||
public function resetNotificationTimestamp( $force = '' ) {
|
||||
// Only loggedin user can have a watchlist
|
||||
if ( wfReadOnly() || $this->mUser->isAnon() ) {
|
||||
if ( wfReadOnly() || $this->mUser->isAnon() || !$this->isAllowed( 'editmywatchlist' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -170,7 +204,7 @@ class WatchedItem {
|
|||
wfProfileIn( __METHOD__ );
|
||||
|
||||
// Only loggedin user can have a watchlist
|
||||
if ( wfReadOnly() || $this->mUser->isAnon() ) {
|
||||
if ( wfReadOnly() || $this->mUser->isAnon() || !$this->isAllowed( 'editmywatchlist' ) ) {
|
||||
wfProfileOut( __METHOD__ );
|
||||
return false;
|
||||
}
|
||||
|
|
@ -210,7 +244,7 @@ class WatchedItem {
|
|||
wfProfileIn( __METHOD__ );
|
||||
|
||||
// Only loggedin user can have a watchlist
|
||||
if ( wfReadOnly() || $this->mUser->isAnon() ) {
|
||||
if ( wfReadOnly() || $this->mUser->isAnon() || !$this->isAllowed( 'editmywatchlist' ) ) {
|
||||
wfProfileOut( __METHOD__ );
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,19 +88,45 @@ class WatchAction extends FormAction {
|
|||
}
|
||||
|
||||
/**
|
||||
* Watch a page
|
||||
* @since 1.22 Returns Status object
|
||||
* Watch or unwatch a page
|
||||
* @since 1.22
|
||||
* @param bool $watch Whether to watch or unwatch the page
|
||||
* @param Title $title Page to watch/unwatch
|
||||
* @param User $user User who is watching/unwatching
|
||||
* @return Status
|
||||
*/
|
||||
public static function doWatch( Title $title, User $user ) {
|
||||
public static function doWatchOrUnwatch( $watch, Title $title, User $user ) {
|
||||
if ( $user->isLoggedIn() && $user->isWatched( $title, WatchedItem::IGNORE_USER_RIGHTS ) != $watch ) {
|
||||
// If the user doesn't have 'editmywatchlist', we still want to
|
||||
// allow them to add but not remove items via edits and such.
|
||||
if ( $watch ) {
|
||||
return self::doWatch( $title, $user, WatchedItem::IGNORE_USER_RIGHTS );
|
||||
} else {
|
||||
return self::doUnwatch( $title, $user );
|
||||
}
|
||||
}
|
||||
return Status::newGood();
|
||||
}
|
||||
|
||||
/**
|
||||
* Watch a page
|
||||
* @since 1.22 Returns Status, $checkRights parameter added
|
||||
* @param Title $title Page to watch/unwatch
|
||||
* @param User $user User who is watching/unwatching
|
||||
* @param int $checkRights Passed through to $user->addWatch()
|
||||
* @return Status
|
||||
*/
|
||||
public static function doWatch( Title $title, User $user, $checkRights = WatchedItem::CHECK_USER_RIGHTS ) {
|
||||
if ( $checkRights !== WatchedItem::IGNORE_USER_RIGHTS && !$user->isAllowed( 'editmywatchlist' ) ) {
|
||||
return User::newFatalPermissionDeniedStatus( 'editmywatchlist' );
|
||||
}
|
||||
|
||||
$page = WikiPage::factory( $title );
|
||||
|
||||
$status = Status::newFatal( 'hookaborted' );
|
||||
if ( wfRunHooks( 'WatchArticle', array( &$user, &$page, &$status ) ) ) {
|
||||
$status = Status::newGood();
|
||||
$user->addWatch( $title );
|
||||
$user->addWatch( $title, $checkRights );
|
||||
wfRunHooks( 'WatchArticleComplete', array( &$user, &$page ) );
|
||||
}
|
||||
return $status;
|
||||
|
|
@ -114,6 +140,10 @@ class WatchAction extends FormAction {
|
|||
* @return Status
|
||||
*/
|
||||
public static function doUnwatch( Title $title, User $user ) {
|
||||
if ( !$user->isAllowed( 'editmywatchlist' ) ) {
|
||||
return User::newFatalPermissionDeniedStatus( 'editmywatchlist' );
|
||||
}
|
||||
|
||||
$page = WikiPage::factory( $title );
|
||||
|
||||
$status = Status::newFatal( 'hookaborted' );
|
||||
|
|
|
|||
|
|
@ -823,7 +823,7 @@ abstract class ApiBase extends ContextSource {
|
|||
*/
|
||||
protected function getWatchlistValue( $watchlist, $titleObj, $userOption = null ) {
|
||||
|
||||
$userWatching = $this->getUser()->isWatched( $titleObj );
|
||||
$userWatching = $this->getUser()->isWatched( $titleObj, WatchedItem::IGNORE_USER_RIGHTS );
|
||||
|
||||
switch ( $watchlist ) {
|
||||
case 'watch':
|
||||
|
|
@ -865,12 +865,7 @@ abstract class ApiBase extends ContextSource {
|
|||
return;
|
||||
}
|
||||
|
||||
$user = $this->getUser();
|
||||
if ( $value ) {
|
||||
WatchAction::doWatch( $titleObj, $user );
|
||||
} else {
|
||||
WatchAction::doUnwatch( $titleObj, $user );
|
||||
}
|
||||
WatchAction::doWatchOrUnwatch( $value, $titleObj, $this->getUser() );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1583,6 +1578,9 @@ abstract class ApiBase extends ContextSource {
|
|||
if ( !$this->getUser()->isLoggedIn() ) {
|
||||
$this->dieUsage( 'You must be logged-in to have a watchlist', 'notloggedin' );
|
||||
}
|
||||
if ( !$this->getUser()->isAllowed( 'viewmywatchlist' ) ) {
|
||||
$this->dieUsage( 'You don\'t have permission to view your watchlist', 'permissiondenied' );
|
||||
}
|
||||
$user = $this->getUser();
|
||||
}
|
||||
return $user;
|
||||
|
|
|
|||
|
|
@ -669,7 +669,9 @@ class ApiQueryInfo extends ApiQueryBase {
|
|||
private function getWatchedInfo() {
|
||||
$user = $this->getUser();
|
||||
|
||||
if ( $user->isAnon() || count( $this->everything ) == 0 ) {
|
||||
if ( $user->isAnon() || count( $this->everything ) == 0
|
||||
|| !$user->isAllowed( 'viewmywatchlist' )
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,9 @@ class ApiSetNotificationTimestamp extends ApiBase {
|
|||
if ( $user->isAnon() ) {
|
||||
$this->dieUsage( 'Anonymous users cannot use watchlist change notifications', 'notloggedin' );
|
||||
}
|
||||
if ( !$user->isAllowed( 'editmywatchlist' ) ) {
|
||||
$this->dieUsage( 'You don\'t have permission to edit your watchlist', 'permissiondenied' );
|
||||
}
|
||||
|
||||
$params = $this->extractRequestParams();
|
||||
$this->requireMaxOneParameter( $params, 'timestamp', 'torevid', 'newerthanrevid' );
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@ class ApiWatch extends ApiBase {
|
|||
if ( !$user->isLoggedIn() ) {
|
||||
$this->dieUsage( 'You must be logged-in to have a watchlist', 'notloggedin' );
|
||||
}
|
||||
if ( !$user->isAllowed( 'editmywatchlist' ) ) {
|
||||
$this->dieUsage( 'You don\'t have permission to edit your watchlist', 'permissiondenied' );
|
||||
}
|
||||
|
||||
$params = $this->extractRequestParams();
|
||||
$title = Title::newFromText( $params['title'] );
|
||||
|
|
|
|||
|
|
@ -753,7 +753,7 @@ class SpecialBlock extends FormSpecialPage {
|
|||
|
||||
# Can't watch a rangeblock
|
||||
if ( $type != Block::TYPE_RANGE && $data['Watch'] ) {
|
||||
$performer->addWatch( Title::makeTitle( NS_USER, $target ) );
|
||||
WatchAction::doWatch( Title::makeTitle( NS_USER, $target ), $performer, WatchedItem::IGNORE_USER_RIGHTS );
|
||||
}
|
||||
|
||||
# Block constructor sanitizes certain block options on insert
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
|
|||
private $badItems = array();
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct( 'EditWatchlist' );
|
||||
parent::__construct( 'EditWatchlist', 'editmywatchlist' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -690,13 +690,8 @@ class MovePageForm extends UnlistedSpecialPage {
|
|||
}
|
||||
|
||||
# Deal with watches (we don't watch subpages)
|
||||
if ( $this->watch && $user->isLoggedIn() ) {
|
||||
$user->addWatch( $ot );
|
||||
$user->addWatch( $nt );
|
||||
} else {
|
||||
$user->removeWatch( $ot );
|
||||
$user->removeWatch( $nt );
|
||||
}
|
||||
WatchAction::doWatchOrUnwatch( $this->watch, $ot, $user );
|
||||
WatchAction::doWatchOrUnwatch( $this->watch, $nt, $user );
|
||||
|
||||
# Re-clear the file redirect cache, which may have been polluted by
|
||||
# parsing in messages above. See CR r56745.
|
||||
|
|
|
|||
|
|
@ -393,7 +393,7 @@ class SpecialRecentChanges extends IncludableSpecialPage {
|
|||
|
||||
$fields = RecentChange::selectFields();
|
||||
// JOIN on watchlist for users
|
||||
if ( $uid ) {
|
||||
if ( $uid && $this->getUser()->isAllowed( 'viewmywatchlist' ) ) {
|
||||
$tables[] = 'watchlist';
|
||||
$fields[] = 'wl_user';
|
||||
$fields[] = 'wl_notificationtimestamp';
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ class SpecialRecentchangeslinked extends SpecialRecentChanges {
|
|||
|
||||
// left join with watchlist table to highlight watched rows
|
||||
$uid = $this->getUser()->getId();
|
||||
if ( $uid ) {
|
||||
if ( $uid && $this->getUser()->isAllowed( 'viewmywatchlist' ) ) {
|
||||
$tables[] = 'watchlist';
|
||||
$select[] = 'wl_user';
|
||||
$join_conds['watchlist'] = array( 'LEFT JOIN', array(
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ class SpecialWatchlist extends SpecialPage {
|
|||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct( $page = 'Watchlist' ) {
|
||||
parent::__construct( $page );
|
||||
public function __construct( $page = 'Watchlist', $restriction = 'viewmywatchlist' ) {
|
||||
parent::__construct( $page, $restriction );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -54,6 +54,9 @@ class SpecialWatchlist extends SpecialPage {
|
|||
return;
|
||||
}
|
||||
|
||||
// Check permissions
|
||||
$this->checkPermissions();
|
||||
|
||||
// Add feed links
|
||||
$wlToken = $user->getOption( 'watchlisttoken' );
|
||||
if ( !$wlToken ) {
|
||||
|
|
|
|||
|
|
@ -688,7 +688,7 @@ abstract class UploadBase {
|
|||
|
||||
if ( $status->isGood() ) {
|
||||
if ( $watch ) {
|
||||
$user->addWatch( $this->getLocalFile()->getTitle() );
|
||||
WatchAction::doWatch( $this->getLocalFile()->getTitle(), $user, WatchedItem::IGNORE_USER_RIGHTS );
|
||||
}
|
||||
wfRunHooks( 'UploadComplete', array( &$this ) );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2095,6 +2095,8 @@ Your email address is not revealed when other users contact you.',
|
|||
'right-edituserjs' => "Edit other users' JavaScript files",
|
||||
'right-editmyusercss' => 'Edit your own user CSS files',
|
||||
'right-editmyuserjs' => 'Edit your own user JavaScript files',
|
||||
'right-viewmywatchlist' => 'View your own watchlist',
|
||||
'right-editmywatchlist' => 'Edit your own watchlist. Note some actions will still add pages even without this right.',
|
||||
'right-rollback' => 'Quickly rollback the edits of the last user who edited a particular page',
|
||||
'right-markbotedits' => 'Mark rolled-back edits as bot edits',
|
||||
'right-noratelimit' => 'Not be affected by rate limits',
|
||||
|
|
@ -2156,6 +2158,8 @@ Your email address is not revealed when other users contact you.',
|
|||
'action-userrights-interwiki' => 'edit user rights of users on other wikis',
|
||||
'action-siteadmin' => 'lock or unlock the database',
|
||||
'action-sendemail' => 'send emails',
|
||||
'action-viewmywatchlist' => 'view your watchlist',
|
||||
'action-editmywatchlist' => 'edit your watchlist',
|
||||
|
||||
# Recent changes
|
||||
'nchanges' => '$1 {{PLURAL:$1|change|changes}}',
|
||||
|
|
|
|||
|
|
@ -2914,6 +2914,8 @@ See also {{msg-mw|Right-editusercss}}',
|
|||
'right-editmyuserjs' => '{{doc-right|editmyuserjs}}
|
||||
|
||||
See also {{msg-mw|Right-edituserjs}}',
|
||||
'right-viewmywatchlist' => '{{doc-right|viewmywatchlist}}',
|
||||
'right-editmywatchlist' => '{{doc-right|editmywatchlist}}',
|
||||
'right-rollback' => '{{doc-right|rollback}}
|
||||
{{Identical|Rollback}}',
|
||||
'right-markbotedits' => '{{doc-right|markbotedits}}
|
||||
|
|
@ -2986,6 +2988,8 @@ This action allows editing of all of the "user rights", not just the rights of t
|
|||
'action-userrights-interwiki' => '{{Doc-action|userrights-interwiki}}',
|
||||
'action-siteadmin' => '{{Doc-action|siteadmin}}',
|
||||
'action-sendemail' => '{{doc-action|sendemail}}',
|
||||
'action-editmywatchlist' => '{{doc-action|editmywatchlist}}',
|
||||
'action-viewmywatchlist' => '{{doc-action|viewmywatchlist}}',
|
||||
|
||||
# Recent changes
|
||||
'nchanges' => 'Appears on the [[Special:RecentChanges]] special page in brackets after pages having more than one change on that date. $1 is the number of changes on that day.',
|
||||
|
|
|
|||
|
|
@ -1286,6 +1286,7 @@ edititis
|
|||
editlink
|
||||
editmyusercss
|
||||
editmyuserjs
|
||||
editmywatchlist
|
||||
editnotice
|
||||
editnotsupported
|
||||
editondblclick
|
||||
|
|
@ -4342,6 +4343,7 @@ view
|
|||
viewcount
|
||||
viewdeleted
|
||||
viewhelppage
|
||||
viewmywatchlist
|
||||
viewprevnext
|
||||
viewsource
|
||||
viewsourcelink
|
||||
|
|
|
|||
|
|
@ -1222,6 +1222,8 @@ $wgMessageStructure = array(
|
|||
'right-edituserjs',
|
||||
'right-editmyusercss',
|
||||
'right-editmyuserjs',
|
||||
'right-viewmywatchlist',
|
||||
'right-editmywatchlist',
|
||||
'right-rollback',
|
||||
'right-markbotedits',
|
||||
'right-noratelimit',
|
||||
|
|
@ -1283,6 +1285,8 @@ $wgMessageStructure = array(
|
|||
'action-userrights-interwiki',
|
||||
'action-siteadmin',
|
||||
'action-sendemail',
|
||||
'action-editmywatchlist',
|
||||
'action-viewmywatchlist',
|
||||
),
|
||||
'recentchanges' => array(
|
||||
'nchanges',
|
||||
|
|
|
|||
Loading…
Reference in a new issue