Commit graph

258 commits

Author SHA1 Message Date
TehKittyCat
8728f29a32 PermissionManager: Fix missingPermissionError() not returning early when $short is true.
This regression was introduced in I6670a58fe1.

Bug: T399793
Co-Authored-By: Jonathan Lee <cookmeplox@weirdgloop.org>
Change-Id: I26b61e2a08b51aaca5d2740dcaf20b509be380eb
(cherry picked from commit fa05279424e0688a7b34f1186050dca1e2ec5f4b)
2025-07-18 20:07:08 +00:00
Bartosz Dziewoński
3aab5f1f3d RestrictionStore: Remove short-circuit mode when fetching cascading sources
Almost every call to isCascadeProtected() (which uses short-circuit
mode) is followed by a call to getCascadeProtectionSources() (which
doesn't), so this attempted optimization (skipping a loop that does
some very cheap operations) actually results in worse performance
in the common case (because the result of the database query can't
be cached in short-circuit mode, and we must query it again), and
it makes the code really annoying to read or modify.

Relevant code: https://codesearch.wmcloud.org/search/?q=getCascadeProtectionSources\(|isCascadeProtected\(&excludeFiles=RestrictionStore.php|HISTORY|tests%2F

Change-Id: Ib9eb6cab28492776d40a10cbfb28e9c1cec8c1d2
(cherry picked from commit f9180c4a36fb8874fc0211f05a1eebaceb67aa0c)
2025-04-09 13:25:44 +00:00
Dylan F
7071887383 PermissionManager: Differentiate between cascading protection of file content and file pages
This patch reworks RestrictionStore::getCascadeProtectionSourcesInternal
to return a third and fourth array:
* One for cascading restrictions originating from templatelinks
* Another for those originating from imagelinks

They are used in PermissionManager::checkCascadingSourcesRestrictions
to differentiate cascading protection of file content and file page,
but could also be used in the future by action=info and other callers.

Bug: T24521
Bug: T62109
Bug: T140010
Change-Id: Ia5863f418538106f4fd657c672298ff6ac835805
(cherry picked from commit 7a4952ef2c5d593fae9419bad39f3e9894f42adf)
2025-03-24 13:31:34 +00:00
Máté Szabó
784b9c4dc4 permissions: Avoid potential infinite loop if BlockDisablesLogin = true
Why:

- PermissionManager::getUserPermissions() checks whether the user is
  blocked if $wgBlockDisablesLogin = true, so that it can then limit
  user's permissions to the set of permissions assigned to unregistered
  users if so.
- This causes the GetUserBlock hook to run, which may itself check
  permissions on the user (e.g. in the GlobalBlocking extension),
  causing an infinite loop.
- Since the decision whether the user is blocked isn't yet final by the
  time GetUserBlock runs, any permission checks triggered by
  GetUserBlock handlers should see the user's full set of permissions.

What:

- Stash the user's permissions in PermissionManager's in-memory cache
  before running block checks if BlockDisablesLogin = true.
- Add tests.

Bug: T384197
Change-Id: I3e3804fe518627e9edc2b574cce88f533fd93fe4
(cherry picked from commit 27062b9f8752cc853a65e8a46c9d7d1a9af32c48)
2025-03-13 00:45:18 +00:00
daniel
d0bbe78b23 RateLimiter: Fix peek mode
Why:
- Setting the increment to 0 should check the limit without bumping it.
- This was apparently broken by If3e66491306f22650.

What:
- Use LimitBatch::peek if the increment amount is 0

Bug: T381033
Change-Id: Ife76a1976a2063f051f00302e5adaebd701e6367
(cherry picked from commit e09606b3dc44711571cc6cf2d0d11bd7784d0cdd)
2025-03-01 15:51:16 +00:00
Umherirrender
e662614f95 Use explicit nullable type on parameter arguments
Implicitly marking parameter $... as nullable is deprecated in php8.4,
the explicit nullable type must be used instead

Created with autofix from Ide15839e98a6229c22584d1c1c88c690982e1d7a

Break one long line in SpecialPage.php

Bug: T376276
Change-Id: I807257b2ba1ab2744ab74d9572c9c3d3ac2a968e
2024-10-16 20:58:33 +02:00
thiemowmde
b1c9ec74fa Remove meaningless @var documentation from constants
A constant is not a variable. The type is hard-coded via the value
and can never change. While the extra @var probably doesn't hurt much,
it's redundant and error-prone and can't provide any additional
information.

Change-Id: Iee1f36a1905d9b9c6b26d0684b7848571f0c1733
2024-10-09 09:33:12 +02:00
James D. Forrester
cc28acc455 Add namespace to remaining parts of Wikimedia\Mime and Wikimedia\Stats
Bug: T353458
Change-Id: If0137003ab625017d322d57870448a02569668c3
2024-09-27 16:19:10 -04:00
James D. Forrester
53b67ae0a6 Add namespace to remaining parts of Wikimedia\ObjectCache
Bug: T353458
Change-Id: I3b736346550953e3b2977c14dc3eb10edc07cf97
2024-09-27 16:19:10 -04:00
James D. Forrester
9e5c1e8ac7 Add namespace to IDBAccessObject and DBAccessObjectUtils
Bug: T353458
Change-Id: I23cf7991f8792d4d000d1780463d8ce76dc0aee0
2024-09-27 16:19:10 -04:00
Taavi Väänänen
99951eb334
Permissions: Fix typo
Change-Id: Ieb92269f1445951fb1d179a069eb4eb4839df405
2024-09-08 10:41:18 +03:00
Umherirrender
7bee34c99d Permissions: Avoid assignment in condition in PermissionManager
Change-Id: I7a9b5c89129fe4b555d03861f2c3ce3e9e2b2446
2024-09-01 00:03:29 +02:00
Matěj Suchánek
82d7b894bf Fix some typos
Change-Id: I1a41f33c65bc9edf2df248581a2c45c5c79c4f93
2024-08-18 18:59:44 +02:00
James D. Forrester
bc662aec9b Move Language and friends into Language namespace
Bug: T353458
Change-Id: Id3202c0c4f4a2043bf97b7caee081acab684155c
2024-08-10 13:36:30 +02:00
Bartosz Dziewoński
3d40cde987 Deprecate more methods dealing with legacy error arrays
* PermissionStatus::toLegacyErrorArray() (soft-deprecated)
* OutputPage::showPermissionsErrorPage() (hard-deprecated)
* OutputPage::formatPermissionsErrorMessage() (hard-deprecated)

Depends-On: I5493deb8b72f499ecd46b8093b5fffbb12e7c246
Depends-On: Iee1dd844d36037982b9927e95d7519da87251ca1
Depends-On: Ic217af5f9766ae2d7850597a4aec1a890d58766f
Depends-On: I62c324b656ab4262fd3f4e252057802a5367f8f9
Change-Id: Ia2d590779176ae060a0567a143697436230c67a9
2024-08-09 17:30:21 +02:00
Amir E. Aharoni
c14bbf4e2f Consistent spelling of "subpage"
Also:
1. Other minor fixes in comments touched by this patch.
2. Add a separate test for subpage with spaces.

Change-Id: I267f19027098e5778b1cd491826e1741fc7ee794
2024-08-06 04:01:02 -04:00
jenkins-bot
2d3c0375d1 Merge "Drop writeapi userright" 2024-08-01 21:06:33 +00:00
DannyS712
661f1ca440 PermissionManager: fix typo sitedwide from yours truly
Oops

Change-Id: I45d0e8a9c30a7b3bf0b415e88cddac283e7c2091
2024-08-01 00:29:21 +00:00
Reedy
b52a8addf5 Drop writeapi userright
Bug: T294397
Depends-On: Ib34228a18917e404517d45e539bd786419d9c401
Change-Id: Ifad2edc782b36d21c8c67fecde7f011dce02c11b
2024-07-31 11:10:50 +00:00
Bartosz Dziewoński
3781349e27 Use real type hints for services etc. in includes/Permissions/
Mostly used find-and-replace:

Find:
/\*[\*\s]+@var (I?[A-Z](\w+)(?:Interface)?)[\s\*]+/\s*(private|protected|public) (\$[a-z]\w+;\n)((?=\s*/\*[\*\s]+@var (I?[A-Z](\w+)(?:Interface)?))\n|)
Replace with:
\3 \1 \4

More could be done, but to keep this patch reasonably sized, I only
changed the most obvious and unambiguously correct cases.

In some cases, I also removed redundant doc comments on the
constructor, and re-ordered the properties to match the constructor.

Change-Id: I3f8427ae4f5d55177ae18986ef15d84d0e7bf6f4
2024-07-31 08:56:17 +00:00
Bartosz Dziewoński
c9f73efd5a Namespace MessageSpecifier under Wikimedia\Message\
In change I625a48a6ecd3fad5c2ed76b23343a0fef91e1b83 I am planning to
make Wikimedia\Message\MessageValue use it, and we try to pretend that
it is a library separate from MediaWiki, so it makes sense to move
MessageSpecifier to the same namespace under Wikimedia\.

Bug: T353458
Change-Id: I9ff4ff7beb098b60c92f564591937c7d789c6684
2024-07-28 14:21:32 +02:00
Bartosz Dziewoński
7d9ca602db UserAuthority: Fix wikitext escaping for block errors (again)
In 279fd16bab, I made what I thought
was a trivial change to UserAuthorityTest:

(diff slightly modified here for clarity)
-		$message = $permissionStatus->getErrors()[2]['message'];
+		$message = $permissionStatus->getMessages()[2];
 		$this->assertArrayEquals(
 			$this->getFakeBlockMessageParams(),
 			$message->getParams()
 		);

And in 3d92cb2f82, I made what I thought
was also a trivial change to UserAuthority:

(diff slightly modified here for clarity, likewise)
-			foreach ( $errors as $err ) {
-				$status->fatal( wfMessage( ...$err ) );
-			}
+			$status->merge( $tempStatus );

However, it turns out these two pieces of code had vital roles:

* The code in UserAuthority ensured that the final status contains
  Message objects instead of key strings + parameter arrays, and thus
  does not trigger wikitext escaping in a legacy code path (T368821).

* The code in UserAuthorityTest accessed the internals of the same
  status with (now deprecated) getErrors() to check that it indeed
  contained a Message object, rather then a key string, which would
  cause a test failure due to a fatal error in the code below.
  getMessages() returns objects regardless of what's inside the
  status, so the test never fails.

Thus I managed to disarm the regression test, and then cause exactly
the regression it was supposed to prevent: block error messages on
Special:CreateAccount have parameters shown as wikitext (T306494).

Restore a foreach loop instead of `$status->merge()` to fix that, and
document why it is there. Change the test so that it actually runs
the code whose behavior it wants to verify, instead of a related but
different method, hopefully making it more resilient against future
developers.

(I found the bug because the test started failing with the refactoring
I'm trying to do in I625a48a6ecd3fad5c2ed76b23343a0fef91e1b83.)

Bug: T306494
Change-Id: I7601fc51702cb33ef9d2b341ea555dc230d31537
2024-07-22 19:42:50 +00:00
thiemowmde
a92152360f Use narrow UserIdentity in PermissionManager where possible
Almost all of this code still needs a full User object. Still I
found a few places that can easily live with the much more narrow
UserIdentify interface.

Change-Id: I6a43f8acbb7470144a4118d86aa1b266d4e293f4
2024-07-18 15:35:24 +02:00
jenkins-bot
609cdb524b Merge "permissions: Use UserIdentityLookup in PermissionManager" 2024-07-12 14:54:58 +00:00
jenkins-bot
14229042e5 Merge "Replace some uses of deprecated PermissionManager::getPermissionErrors()" 2024-07-10 11:02:29 +00:00
Umherirrender
41439e607f permissions: Use UserIdentityLookup in PermissionManager
Replace UserCache with UserIdentityLookup
UserIdentityLookup is implemented by ActorStore and
there is already a cache

Change-Id: I8a59e77391da45d2726aab3d5432f08ad0c9a84f
2024-07-09 19:57:40 +00:00
Gergő Tisza
0b555c9509 PermissionManager: Handle empty error array from TitleQuickPermissions
PermissionManager::resultToStatus() is used for both
getUserPermissionsErrors / getUserPermissionsErrorsExpensive (which
return a single error) and TitleQuickPermissions (which returns an array
of errors). This mostly works because it processes arrays recursively,
but the array of errors can be empty if a hook returns false just to
prevent other extensions from adding errors (wich is apparently a thing
we do: Ib56f1085eea1)

Bug: T369260
Change-Id: Iaa93c04ca195718131b37289ffcbc35d5a1b8500
2024-07-04 10:22:34 +00:00
jenkins-bot
61dc3c97bf Merge "RestrictionStore: Replace usage of deprecated LinkCache::addLinkObj." 2024-06-28 11:56:14 +00:00
Bartosz Dziewoński
3d92cb2f82 Replace some uses of deprecated PermissionManager::getPermissionErrors()
getPermissionStatus() does the same thing but better.

A lot of things use the legacy error arrays though, we're nowhere near
removing it.

Change-Id: Iff60dbb0593329a584d003b2407bbf24d5b22aea
2024-06-27 18:14:28 +00:00
Bartosz Dziewoński
1fbe8b7619 PermissionManager: Add getPermissionStatus(), deprecate getPermissionErrors()
getPermissionErrors() uses a weird format for its return value that
is slightly different from the usual "legacy error array", and legacy
errors arrays are already icky. Deprecate it without changing this
format, and introduce getPermissionStatus() to replace it. Document
the return format more precisely.

Refactor PermissionManager to use PermissionStatus objects internally,
and only convert to the weird format in the deprecated method.

However, fix a scenario where the error array could directly contain
MessageSpecifier objects or strings instead of nested arrays,
as the documentation said that was not possible. Fix a test case
demonstrating this incorrect behavior.

Change-Id: I6670a58fe1fcb4e1ae87351277e5ddf29c548183
2024-06-26 01:19:37 +02:00
Thalia
93e8350d29 Remove the 'named' user group, which is no longer used
Why:

* When temporary accounts were first implemented, temporary users were
  added to the 'user' group, and named users were added to a 'named'
  user group, to differentiate them from temporary users.
* Since T340457, temporary users were no longer added to the 'user'
  group. This means that the 'named' group is no longer needed.

What:

* Stop adding users to a 'named' user group in UserGroupManager.
* Remove special handling for the 'named' group in PermissionManager
  and tests.

Bug: T355741
Change-Id: I06bd5d7150203bbcb0806868fe829a438af486ba
2024-06-20 12:24:51 +01:00
jenkins-bot
5099efb286 Merge "PermissionManager: Allow some readonly user rights bypass NSProtection" 2024-05-21 16:19:47 +00:00
anterdc99
eeaed6fee4
PermissionManager: Allow some readonly user rights bypass NSProtection
What:
* Make user rights "deletedhistory" and "deletedtext" get rid of the
  restriction of the namespace protection.

Why:
* On Special:Undelete, users who have rights to view deleted pages and
  its revisions, will get restricted if the namespace of the page have
  a namespace protection, and they don't have the right to edit pages
  in this namespace, so the two designing purposes are conflicted:
  read-only rights shouldn't be restricted by a namespace protection
  which is designed to restrict edit actions.

Bug: T362536
Follow-Up: I02e820c818e9e58e6591ec412fc3eca9384e0bb2
Change-Id: I61ec3f8e1fe84927a6c987f387cbba349ec4a357
2024-05-20 00:34:45 +08:00
Gergő Tisza
e41b66c93a
PermissionManager: Move a confusingly positioned comment block
Change-Id: I271d51f75fddb932fbde4fd79a3aba0bd233ab2d
2024-05-19 18:16:14 +02:00
thiemowmde
1f7886a6af Remove auto-generated "Class ClassName" comments
This is most certainly auto-generated by some IDEs. Unfortunately
there is nothing to learn from such comments. It's just noise.
Especially in tests.

Change-Id: Idf59332d96ca4718b6ce9d17b4da79a88641d4fd
2024-05-06 10:03:41 +02:00
Lewis Cawte
eefbbbd908 RestrictionStore: Replace usage of deprecated LinkCache::addLinkObj.
Change-Id: I499f6430bbdd048fd5bcb7ad1330f7b3aacb28e1
2024-05-05 14:01:04 +00:00
Umherirrender
0a193cacd6 Permissions: Migrate to SelectQueryBuilder in RestrictionStore
Bug: T344971
Change-Id: Ibd00246709ccfe278d0d84c85b2f4fd9b03a93b0
2024-05-04 12:28:31 +02:00
Amir Sarabadani
8e183495e1 Stop using LoadBalancer::getConnectionRef() so it can be hard-deprecated
Bug: T326274
Change-Id: I90493d7cd4c21fdc022bcc19765fc04d986a9c8f
2024-04-30 13:31:08 +01:00
Tim Starling
917f0a5996 Replace all instances of "per default" with "by default"
According to the dictionary, "per" (or more conventionally "as per")
means "according to". Refer OED "per" sense II.3.a. For example:

"No value was passed, so return null, as per default".

In this sentence, we are not specifying the default, we are referring
to the default. This correct usage of "per default" was used nowhere
in MediaWiki core as far as I can see.

Instead we have "per default" being used to mean "by default", that is,
giving the value to use when no explicit value was specified.

In OED, the phrase "by default" is blessed with its own section just
for computing usage:

"P.1.e. Computing. As an option or setting adopted automatically by a
computer program whenever an alternative is not specified by the user
or programmer. Cf. sense I.7a."

There are highly similar pre-computing usages of the same phrase,
whereas the phrase "per default" is not mentioned.

As a matter of style, I think "per default" should not be used even
when it is strictly correct, since the common incorrect usage makes it
ambiguous and misleading.

Change-Id: Ibcccc65ead864d082677b472b34ff32ff41c60ae
2024-04-29 10:47:54 +10:00
Umherirrender
8d97313f81 Fix some line indent
Change-Id: I8f82724197d20f9289d80e138d80310f1eab29f2
2024-04-20 00:25:15 +02:00
Máté Szabó
aa3b388b5b Permissions: Avoid RestrictionStore lookup for unsupported actions
When rendering Special:RecentChanges for an user with rollback rights,
the software checks whether the user has permission to perform the
rollback action on each entry via User::probablyCan(), which
delegates to PermissionManager. This in turn checks for each entry
whether the title has protections (e.g. from action=protect) against the
"rollback" action, which is unlikely to be the case since by default
wgRestrictionTypes only supports create/edit/move/upload.

This triggers noticeable memcached I/O and overhead.[1]

So, as an optimization, avoid fetching page restrictions in
RestrictionStore for action types that are known to not be restrictable
via page protection. In the unlikely event that wgRestrictionTypes is
customised to offer separate restrictions for "rollback", this will
work continue to work as expected and is covered by tests.

-
[1] acd6281072/recentchanges.speedscope.json

Bug: T341319
Change-Id: I912e4ef2fa3d48238c01631d4f35940aea93ab03
2024-04-11 21:02:53 +00:00
James D. Forrester
35b2542895 Namespace includes/cache
Bug: T353458
Change-Id: Ic3f3168ef17113f5fb3ec11e0a47f52d65eefba9
2024-02-20 10:28:03 -05:00
James D. Forrester
eeb5a740b3 Namespace Message, move to appropriate directory
Bug: T353458
Change-Id: I088cbc53fbcdb974e5b05b45a62e91709dacc024
2024-02-14 15:10:36 -05:00
James D. Forrester
4bae64d1c7 Namespace includes/context
Bug: T353458
Change-Id: I4dbef138fd0110c14c70214282519189d70c94fb
2024-02-08 11:07:01 -05:00
jenkins-bot
d023c7fb99 Merge "Move creation of BlockErrorFormatter into FormatterFactory" 2024-02-02 22:29:47 +00:00
thiemowmde
ab1e3a66e7 Make use of the [ ... ] operator instead of array_merge
The array spread operator is documented to behave identical to
array_merge. The syntax is just much shorter and easier to read in
situations like this, in my opinion.

Change-Id: I3b016e896e552af53d87d5e72436dc4e29070ce1
2024-01-31 15:47:44 +01:00
daniel
3d55397207 Move creation of BlockErrorFormatter into FormatterFactory
The idea is that all formatters that need the user language or
other request specific context should be instantiated by
FormatterFactory.

Change-Id: I8334cc89dcf0f293298b82e004116be50a90f0d1
2024-01-26 13:03:44 -05:00
Umherirrender
4dadaf0166 Permissions: Replace deprecated User::newFromIdentity
Change-Id: I19b68ecfc804b9e3d1a43ea923ed7968a03a57df
2024-01-23 20:25:24 +01:00
Amir Sarabadani
014bc61006 Remove more indirect calls to IDBAccessObject::READ_* constants
Found via (?<!IDBAccessObject)::READ_

We are planning to deprecate and remove implementing IDBAccessObject
interface just to use the constants.

Bug: T354194
Change-Id: I89d442fa493b8e5332ce118e5bf13f13b8dd3477
2024-01-23 15:42:38 +01:00
Umherirrender
9b0591448e Use UserFactory::newAnonymous
Bug: T325686
Change-Id: Ia7ce7df94c233a4534625d250229806fb21d8017
2024-01-22 20:39:05 +00:00