This also removes assumptions that when a page
in one Namespace should be watched / removed
that the page in the talk / subject ns for the
page should have the same action applied
This should maintain all backward compatability
for the WatchedItem class
This also includes tests written by:
- WMDE-leszek
- Addshore
Bug: T127956
Change-Id: Iad9abafe4417bb479151a3bfbee6e1c78a3afe3c
If there is an existing session for a given ID but loading it fails,
there is no point in trying to create a new empty session with that
ID. Just fail silently (the reason for not loading the session
should be logged elsewhere), don't spam the logs and don't slow
down execution by throwing and catching an exception.
Change-Id: I8299872cc29c32cb245686ed0bca6b9a5902cdc1
There's no point in keeping broken cookies around, it just means all
future requests will continue to flood the logs.
Change-Id: Ib10c9ed9049b71ed434950fc731ea77960ceca0c
Clearing the cookies in this case is probably a good idea.
This also clears cookies when a non-persisted session's metadata is
dirty, for parallelism with what happens to persisted sessions.
Bug: T127436
Change-Id: I76897eaac063e5e3c3563398d0f4cb36cf93783b
MW_NO_SESSION is supposed to be used in a deterministic way
(either always or never for a given endpoint) so there is
no point to split the cache on session cookies when it is
used (except when it's set to 'warn' in which case it is
not really used).
Bug: T127233
Change-Id: If44e0ec2167359e081e1b4cd4d21e62bd357d23e
For anon requests, the call to SessionManager::isUserSessionPrevented(
$this->user->getName() ) is both expensive (because of the need to
sanitize the IP) and pointless, because the session-prevention feature
is intended for named accounts. So short-circuit the check if the user is not
logged in.
Change-Id: I17386b97e229b492723b46db1e1ae16fd4b0fc5a
When an entry point specifies MW_NO_SESSION, actually enforce that by
having both SessionManager and PHP's session handling (session_start()
and friends) throw exceptions.
If an entry point needs the old behavior of using PHP's default session
handling (as defined in php.ini), it should define
MW_NO_SESSION_HANDLER instead of or in addition to MW_NO_SESSION.
This also makes PHPSessionHandler be installed in CLI mode, where it
wasn't installed before.
Bug: T127233
Change-Id: I2a3db06ee8e44a044096c57a819b5fd5e51c5c5c
Two things were wrong here:
1. SessionManager shouldn't override the configured logger of the
underlying store.
2. CachedBagOStuff shouldn't override the configured logger of the
backend store on construction.
Change-Id: I24ed5a81d5b238a42934a7890dd8d0a9f9bb3b6f
If we failed to fetch the user ID using the default flags but succeeded
with READ_LATEST, we should also be passing READ_LATEST to
$user->loadFromId().
Change-Id: If8fc332810c2703773a153760ad076c398a84e4e
Now that we dropped support for PHP 5.3.3, we can do this.
The behavior of $session['foo'] when that key doesn't already exist is a
little unexpected (it implicitly assigns null), but it's the best we can
do.
Change-Id: Ibef878867d46591a8bf542139a1719dfec3b83ab
This aspect of the pre-SessionManager Setup.php code had been
overlooked.
This also updates an inaccurate doc comment that I happened to notice.
Bug: T125313
Change-Id: Id49836086be837012b02885ce5384ae6a4ebc105
Add the data values and types to the exception raised when mismatched
session data is processed. This is done by passing the old and new
values on via a new MetadataMergeException class. The attached data is
added to the debug logging context info when caught.
Change-Id: If8a7174399289bc284ca1b36052ba515c8857c50
As an attempt to detect SessionManager errors that log people into
the wrong account, log multiple IPs using the same session, or the same
user account.
Bug: T125455
Change-Id: I27468a3f6d582d9b46984227b9307dc71190fd6a
* Use PSR-3 templates and context where applicable
* Add log coverage for exceptional events
Bug: T125452
Change-Id: I8f96fa1c5766c739a21219abcae2dbb76de53e2a
To avoid having to have SessionManager try to reset sessions on every
request, we set the user_token to a special value. When that value is
present, User::getToken() returns a different value every time (so
existing checks will fail) and User::setToken() refuses to alter it.
Bug: T124414
Change-Id: Ie4c84ce993e40a081288cf5a543f8ba99f98806a
Follow up to 7491b52. The 'private, must-revalidate' argument to
session_cache_limiter() does not match any expected values for the
function. This results in the PHP runtime treating it like the
documented empty string argument which completely disables the automatic
addition of cache related headers. Change the implementation to use the
empty string argument explicitly rather than continuing to rely on
the undocumented and potentially confusing existing behavior.
session_cache_limiter( '' ) is called unconditionally in
MediaWiki\Session\PHPSessionHandler::install(). This is safe now that it
is understood that we are disabling the setting of the automatic
headers.
Bug: T124510
Change-Id: I63164f8b7a408e370ff01dead42be27a0135dd35
Ie161e0f was done in a hurry, and so didn't do things in the best ways.
This introduces a new "CachedBagOStuff" that transparently handles all
the logic that had been copy-pasted all over in Ie161e0f.
The differences between CachedBagOStuff and MultiWriteBagOStuff are:
* CachedBagOStuff supports only one "backend".
* There's a flag for writes to only go to the in-memory cache.
* The in-memory cache is always updated.
* Locks go to the backend cache (with MultiWriteBagOStuff, it would wind
up going to the HashBagOStuff used for the in-memory cache).
Change-Id: Iea494729bd2e8c6c5ab8facf4c241232e31e8215
The plan here is to take it out of 1.27.0-wmf.12 and put it back in
1.27.0-wmf.13.
Since BotPasswords depends on SessionManager, that's getting temporarily
removed too.
This reverts the following commits:
* 6acd424e0d SessionManager: Notify AuthPlugin before calling hooks
* 4d1ad32d8a Close a loophole in CookieSessionProvider
* fcdd643a46 SessionManager: Don't save non-persisted sessions to backend storage
* 058aec4c76 MessageCache: Don't get a ParserOptions for $wgUser before the end of Setup.php
* b5c0c03bb7 SessionManager: Save user name to metadata even if the user doesn't exist locally
* 13f2f09a19 SECURITY: Fix User::setToken() call on User::newSystemUser
* 305bc75b27 SessionManager: Don't generate user tokens when checking the tokens
* 7c4bd85d21 RequestContext::exportSession() should only export persisted session IDs
* 296ccfd4a9 SessionManager: Save 'persisted' flag in session metadata
* 94ba53f677 Move CSRF token handling into MediaWiki\Session\Session
* 46a565d6b0 Avoid false "added in both Session and $_SESSION" when value is null
* c00d0b5d94 Log backtrace for "User::loadFromSession called before the end of Setup.php"
* 4eeff5b559 Use $wgSecureCookie to decide whether to actually mark secure cookies as 'secure'
* 7491b52f70 Call session_cache_limiter() before starting a session
* 2c34aeea72 SessionManager: Abstract forceHTTPS cookie setting
* 9aa53627a5 Ignore auth cookies with value 'deleted'
* 43f904b51a SessionManager: Kill getPersistedSessionId()
* 50c5256352 SessionManager: Add SessionBackend::setProviderMetadata()
* f640d40315 SessionManager: Notify AuthPlugin when auto-creating accounts
* 70b05d1ac1 Add checks of $wgEnableBotPasswords in more places
* bfed32eb78 Do not raise a PHP warning when session write fails
* 722a7331ad Only check LoggedOut timestamp on the user loaded from session
* 4f5057b84b SessionManager: Change behavior of getSessionById()
* 66e82e614e Fix typo in [[MediaWiki:Botpasswords-editexisting/en]]
* f9fd9516d9 Add "bot passwords"
* d7716f1df0 Add missing argument for wfDebugLog
* a73c5b7395 Add SessionManager
Change-Id: I2389a8133e25ab929e9f27f41fa9a05df8147a50
This avoids a race in CentralAuth:
* The user doesn't exist locally, so CA wants to create it
* Auto-creation adds the user to the database
* A hook function tries to access the session; now the user does exist
locally but isn't yet attached, so CA rejects the session.
Bug: T125283
Change-Id: I6024885e3cf9c85c527fc160577f66ff97451c98
There's a crazy-small chance that someone could have a logged-out
session (e.g. by logging out or visiting a page that creates a session
despite being logged out), then the session expires, then someone else
logs in and gets the same session ID (which is about a 1 in a
quindecillion chance), then the first person comes in and picks up the
second person's session.
To avoid that, if there's no UserID cookie set (or the cookie value is
0) then indicate that the SessionInfo is for a logged-out user.
No idea if this is actually what happened in T125283, but it's worth
fixing anyway.
Bug: T125283
Change-Id: I44096c69aa7bd285e4e2472959e8d892200c5f2c
This was supposed to reset the user token but did set it to '1'
because User::setToken accepts bool/string but only treats true
as bool.
Bug: T125161
Change-Id: Ia4196eba92cd4d170a3023db0f540a2972ffad4f
This introduces an in-process cache (using a HashBagOStuff) for session
data, and only saves to the external cache when the session is
persisted.
Bug: T125267
Change-Id: Ie161e0f7522cd68515b060ad8cf8c151b7198b0b
Looking at the pre-SessionManager token checking, it's apparently valid
to log in despite user_token being empty. The stored token just gets
compared against the empty string that got returned previously.
This also cleans up some checks that assumed $user->getToken() didn't
automatically create the token if one wasn't already set.
Bug: T125114
Change-Id: Ia3d2382e96e2a0146f33fb7193a2e00ea72e51a0
This allows SessionManager::getSessionById()->isPersisted() to be
reliably set. Otherwise it depends on whether the SessionBackend is
still loaded or not.
Change-Id: I17733559ac5d8fff13881664333f61d36f610b6d
User keeps most of its token-related methods because anon edit tokens
are special. Login and createaccount tokens are completely moved.
Change-Id: I524218fab7e2d78fd24482ad364428e98dc48bdf
The pre-SessionManager code did this, and the change in combination with
the API not honoring forceHTTPS led to T124252.
Bug: T124252
Change-Id: Ic6a79fbb30491040facd7c200b1f47d6b99ce637