MediaWiki  1.30.0
SessionBackendTest.php
Go to the documentation of this file.
1 <?php
2 
3 namespace MediaWiki\Session;
4 
6 use User;
7 use Wikimedia\TestingAccessWrapper;
8 
15  const SESSIONID = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
16 
17  protected $manager;
18  protected $config;
19  protected $provider;
20  protected $store;
21 
22  protected $onSessionMetadataCalled = false;
23 
29  protected function getBackend( User $user = null, $id = null ) {
30  if ( !$this->config ) {
31  $this->config = new \HashConfig();
32  $this->manager = null;
33  }
34  if ( !$this->store ) {
35  $this->store = new TestBagOStuff();
36  $this->manager = null;
37  }
38 
39  $logger = new \Psr\Log\NullLogger();
40  if ( !$this->manager ) {
41  $this->manager = new SessionManager( [
42  'store' => $this->store,
43  'logger' => $logger,
44  'config' => $this->config,
45  ] );
46  }
47 
48  if ( !$this->provider ) {
49  $this->provider = new \DummySessionProvider();
50  }
51  $this->provider->setLogger( $logger );
52  $this->provider->setConfig( $this->config );
53  $this->provider->setManager( $this->manager );
54 
56  'provider' => $this->provider,
57  'id' => $id ?: self::SESSIONID,
58  'persisted' => true,
59  'userInfo' => UserInfo::newFromUser( $user ?: new User, true ),
60  'idIsSafe' => true,
61  ] );
62  $id = new SessionId( $info->getId() );
63 
64  $backend = new SessionBackend( $id, $info, $this->store, $logger, 10 );
65  $priv = TestingAccessWrapper::newFromObject( $backend );
66  $priv->persist = false;
67  $priv->requests = [ 100 => new \FauxRequest() ];
68  $priv->requests[100]->setSessionId( $id );
69  $priv->usePhpSessionHandling = false;
70 
71  $manager = TestingAccessWrapper::newFromObject( $this->manager );
72  $manager->allSessionBackends = [ $backend->getId() => $backend ] + $manager->allSessionBackends;
73  $manager->allSessionIds = [ $backend->getId() => $id ] + $manager->allSessionIds;
74  $manager->sessionProviders = [ (string)$this->provider => $this->provider ];
75 
76  return $backend;
77  }
78 
79  public function testConstructor() {
80  // Set variables
81  $this->getBackend();
82 
84  'provider' => $this->provider,
85  'id' => self::SESSIONID,
86  'persisted' => true,
87  'userInfo' => UserInfo::newFromName( 'UTSysop', false ),
88  'idIsSafe' => true,
89  ] );
90  $id = new SessionId( $info->getId() );
91  $logger = new \Psr\Log\NullLogger();
92  try {
93  new SessionBackend( $id, $info, $this->store, $logger, 10 );
94  $this->fail( 'Expected exception not thrown' );
95  } catch ( \InvalidArgumentException $ex ) {
96  $this->assertSame(
97  "Refusing to create session for unverified user {$info->getUserInfo()}",
98  $ex->getMessage()
99  );
100  }
101 
102  $info = new SessionInfo( SessionInfo::MIN_PRIORITY, [
103  'id' => self::SESSIONID,
104  'userInfo' => UserInfo::newFromName( 'UTSysop', true ),
105  'idIsSafe' => true,
106  ] );
107  $id = new SessionId( $info->getId() );
108  try {
109  new SessionBackend( $id, $info, $this->store, $logger, 10 );
110  $this->fail( 'Expected exception not thrown' );
111  } catch ( \InvalidArgumentException $ex ) {
112  $this->assertSame( 'Cannot create session without a provider', $ex->getMessage() );
113  }
114 
115  $info = new SessionInfo( SessionInfo::MIN_PRIORITY, [
116  'provider' => $this->provider,
117  'id' => self::SESSIONID,
118  'persisted' => true,
119  'userInfo' => UserInfo::newFromName( 'UTSysop', true ),
120  'idIsSafe' => true,
121  ] );
122  $id = new SessionId( '!' . $info->getId() );
123  try {
124  new SessionBackend( $id, $info, $this->store, $logger, 10 );
125  $this->fail( 'Expected exception not thrown' );
126  } catch ( \InvalidArgumentException $ex ) {
127  $this->assertSame(
128  'SessionId and SessionInfo don\'t match',
129  $ex->getMessage()
130  );
131  }
132 
133  $info = new SessionInfo( SessionInfo::MIN_PRIORITY, [
134  'provider' => $this->provider,
135  'id' => self::SESSIONID,
136  'persisted' => true,
137  'userInfo' => UserInfo::newFromName( 'UTSysop', true ),
138  'idIsSafe' => true,
139  ] );
140  $id = new SessionId( $info->getId() );
141  $backend = new SessionBackend( $id, $info, $this->store, $logger, 10 );
142  $this->assertSame( self::SESSIONID, $backend->getId() );
143  $this->assertSame( $id, $backend->getSessionId() );
144  $this->assertSame( $this->provider, $backend->getProvider() );
145  $this->assertInstanceOf( 'User', $backend->getUser() );
146  $this->assertSame( 'UTSysop', $backend->getUser()->getName() );
147  $this->assertSame( $info->wasPersisted(), $backend->isPersistent() );
148  $this->assertSame( $info->wasRemembered(), $backend->shouldRememberUser() );
149  $this->assertSame( $info->forceHTTPS(), $backend->shouldForceHTTPS() );
150 
151  $expire = time() + 100;
152  $this->store->setSessionMeta( self::SESSIONID, [ 'expires' => $expire ], 2 );
153 
154  $info = new SessionInfo( SessionInfo::MIN_PRIORITY, [
155  'provider' => $this->provider,
156  'id' => self::SESSIONID,
157  'persisted' => true,
158  'forceHTTPS' => true,
159  'metadata' => [ 'foo' ],
160  'idIsSafe' => true,
161  ] );
162  $id = new SessionId( $info->getId() );
163  $backend = new SessionBackend( $id, $info, $this->store, $logger, 10 );
164  $this->assertSame( self::SESSIONID, $backend->getId() );
165  $this->assertSame( $id, $backend->getSessionId() );
166  $this->assertSame( $this->provider, $backend->getProvider() );
167  $this->assertInstanceOf( 'User', $backend->getUser() );
168  $this->assertTrue( $backend->getUser()->isAnon() );
169  $this->assertSame( $info->wasPersisted(), $backend->isPersistent() );
170  $this->assertSame( $info->wasRemembered(), $backend->shouldRememberUser() );
171  $this->assertSame( $info->forceHTTPS(), $backend->shouldForceHTTPS() );
172  $this->assertSame( $expire, TestingAccessWrapper::newFromObject( $backend )->expires );
173  $this->assertSame( [ 'foo' ], $backend->getProviderMetadata() );
174  }
175 
176  public function testSessionStuff() {
177  $backend = $this->getBackend();
178  $priv = TestingAccessWrapper::newFromObject( $backend );
179  $priv->requests = []; // Remove dummy session
180 
181  $manager = TestingAccessWrapper::newFromObject( $this->manager );
182 
183  $request1 = new \FauxRequest();
184  $session1 = $backend->getSession( $request1 );
185  $request2 = new \FauxRequest();
186  $session2 = $backend->getSession( $request2 );
187 
188  $this->assertInstanceOf( Session::class, $session1 );
189  $this->assertInstanceOf( Session::class, $session2 );
190  $this->assertSame( 2, count( $priv->requests ) );
191 
192  $index = TestingAccessWrapper::newFromObject( $session1 )->index;
193 
194  $this->assertSame( $request1, $backend->getRequest( $index ) );
195  $this->assertSame( null, $backend->suggestLoginUsername( $index ) );
196  $request1->setCookie( 'UserName', 'Example' );
197  $this->assertSame( 'Example', $backend->suggestLoginUsername( $index ) );
198 
199  $session1 = null;
200  $this->assertSame( 1, count( $priv->requests ) );
201  $this->assertArrayHasKey( $backend->getId(), $manager->allSessionBackends );
202  $this->assertSame( $backend, $manager->allSessionBackends[$backend->getId()] );
203  try {
204  $backend->getRequest( $index );
205  $this->fail( 'Expected exception not thrown' );
206  } catch ( \InvalidArgumentException $ex ) {
207  $this->assertSame( 'Invalid session index', $ex->getMessage() );
208  }
209  try {
210  $backend->suggestLoginUsername( $index );
211  $this->fail( 'Expected exception not thrown' );
212  } catch ( \InvalidArgumentException $ex ) {
213  $this->assertSame( 'Invalid session index', $ex->getMessage() );
214  }
215 
216  $session2 = null;
217  $this->assertSame( 0, count( $priv->requests ) );
218  $this->assertArrayNotHasKey( $backend->getId(), $manager->allSessionBackends );
219  $this->assertArrayHasKey( $backend->getId(), $manager->allSessionIds );
220  }
221 
222  public function testSetProviderMetadata() {
223  $backend = $this->getBackend();
224  $priv = TestingAccessWrapper::newFromObject( $backend );
225  $priv->providerMetadata = [ 'dummy' ];
226 
227  try {
228  $backend->setProviderMetadata( 'foo' );
229  $this->fail( 'Expected exception not thrown' );
230  } catch ( \InvalidArgumentException $ex ) {
231  $this->assertSame( '$metadata must be an array or null', $ex->getMessage() );
232  }
233 
234  try {
235  $backend->setProviderMetadata( (object)[] );
236  $this->fail( 'Expected exception not thrown' );
237  } catch ( \InvalidArgumentException $ex ) {
238  $this->assertSame( '$metadata must be an array or null', $ex->getMessage() );
239  }
240 
241  $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'sanity check' );
242  $backend->setProviderMetadata( [ 'dummy' ] );
243  $this->assertFalse( $this->store->getSession( self::SESSIONID ) );
244 
245  $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'sanity check' );
246  $backend->setProviderMetadata( [ 'test' ] );
247  $this->assertNotFalse( $this->store->getSession( self::SESSIONID ) );
248  $this->assertSame( [ 'test' ], $backend->getProviderMetadata() );
249  $this->store->deleteSession( self::SESSIONID );
250 
251  $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'sanity check' );
252  $backend->setProviderMetadata( null );
253  $this->assertNotFalse( $this->store->getSession( self::SESSIONID ) );
254  $this->assertSame( null, $backend->getProviderMetadata() );
255  $this->store->deleteSession( self::SESSIONID );
256  }
257 
258  public function testResetId() {
259  $id = session_id();
260 
261  $builder = $this->getMockBuilder( 'DummySessionProvider' )
262  ->setMethods( [ 'persistsSessionId', 'sessionIdWasReset' ] );
263 
264  $this->provider = $builder->getMock();
265  $this->provider->expects( $this->any() )->method( 'persistsSessionId' )
266  ->will( $this->returnValue( false ) );
267  $this->provider->expects( $this->never() )->method( 'sessionIdWasReset' );
268  $backend = $this->getBackend( User::newFromName( 'UTSysop' ) );
269  $manager = TestingAccessWrapper::newFromObject( $this->manager );
270  $sessionId = $backend->getSessionId();
271  $backend->resetId();
272  $this->assertSame( self::SESSIONID, $backend->getId() );
273  $this->assertSame( $backend->getId(), $sessionId->getId() );
274  $this->assertSame( $id, session_id() );
275  $this->assertSame( $backend, $manager->allSessionBackends[self::SESSIONID] );
276 
277  $this->provider = $builder->getMock();
278  $this->provider->expects( $this->any() )->method( 'persistsSessionId' )
279  ->will( $this->returnValue( true ) );
280  $backend = $this->getBackend();
281  $this->provider->expects( $this->once() )->method( 'sessionIdWasReset' )
282  ->with( $this->identicalTo( $backend ), $this->identicalTo( self::SESSIONID ) );
283  $manager = TestingAccessWrapper::newFromObject( $this->manager );
284  $sessionId = $backend->getSessionId();
285  $backend->resetId();
286  $this->assertNotEquals( self::SESSIONID, $backend->getId() );
287  $this->assertSame( $backend->getId(), $sessionId->getId() );
288  $this->assertInternalType( 'array', $this->store->getSession( $backend->getId() ) );
289  $this->assertFalse( $this->store->getSession( self::SESSIONID ) );
290  $this->assertSame( $id, session_id() );
291  $this->assertArrayNotHasKey( self::SESSIONID, $manager->allSessionBackends );
292  $this->assertArrayHasKey( $backend->getId(), $manager->allSessionBackends );
293  $this->assertSame( $backend, $manager->allSessionBackends[$backend->getId()] );
294  }
295 
296  public function testPersist() {
297  $this->provider = $this->getMockBuilder( 'DummySessionProvider' )
298  ->setMethods( [ 'persistSession' ] )->getMock();
299  $this->provider->expects( $this->once() )->method( 'persistSession' );
300  $backend = $this->getBackend();
301  $this->assertFalse( $backend->isPersistent(), 'sanity check' );
302  $backend->save(); // This one shouldn't call $provider->persistSession()
303 
304  $backend->persist();
305  $this->assertTrue( $backend->isPersistent(), 'sanity check' );
306 
307  $this->provider = null;
308  $backend = $this->getBackend();
309  $wrap = TestingAccessWrapper::newFromObject( $backend );
310  $wrap->persist = true;
311  $wrap->expires = 0;
312  $backend->persist();
313  $this->assertNotEquals( 0, $wrap->expires );
314  }
315 
316  public function testUnpersist() {
317  $this->provider = $this->getMockBuilder( 'DummySessionProvider' )
318  ->setMethods( [ 'unpersistSession' ] )->getMock();
319  $this->provider->expects( $this->once() )->method( 'unpersistSession' );
320  $backend = $this->getBackend();
321  $wrap = TestingAccessWrapper::newFromObject( $backend );
322  $wrap->store = new \CachedBagOStuff( $this->store );
323  $wrap->persist = true;
324  $wrap->dataDirty = true;
325 
326  $backend->save(); // This one shouldn't call $provider->persistSession(), but should save
327  $this->assertTrue( $backend->isPersistent(), 'sanity check' );
328  $this->assertNotFalse( $this->store->getSession( self::SESSIONID ), 'sanity check' );
329 
330  $backend->unpersist();
331  $this->assertFalse( $backend->isPersistent() );
332  $this->assertFalse( $this->store->getSession( self::SESSIONID ) );
333  $this->assertNotFalse(
334  $wrap->store->get( $wrap->store->makeKey( 'MWSession', self::SESSIONID ) )
335  );
336  }
337 
338  public function testRememberUser() {
339  $backend = $this->getBackend();
340 
341  $remembered = $backend->shouldRememberUser();
342  $backend->setRememberUser( !$remembered );
343  $this->assertNotEquals( $remembered, $backend->shouldRememberUser() );
344  $backend->setRememberUser( $remembered );
345  $this->assertEquals( $remembered, $backend->shouldRememberUser() );
346  }
347 
348  public function testForceHTTPS() {
349  $backend = $this->getBackend();
350 
351  $force = $backend->shouldForceHTTPS();
352  $backend->setForceHTTPS( !$force );
353  $this->assertNotEquals( $force, $backend->shouldForceHTTPS() );
354  $backend->setForceHTTPS( $force );
355  $this->assertEquals( $force, $backend->shouldForceHTTPS() );
356  }
357 
358  public function testLoggedOutTimestamp() {
359  $backend = $this->getBackend();
360 
361  $backend->setLoggedOutTimestamp( 42 );
362  $this->assertSame( 42, $backend->getLoggedOutTimestamp() );
363  $backend->setLoggedOutTimestamp( '123' );
364  $this->assertSame( 123, $backend->getLoggedOutTimestamp() );
365  }
366 
367  public function testSetUser() {
368  $user = static::getTestSysop()->getUser();
369 
370  $this->provider = $this->getMockBuilder( 'DummySessionProvider' )
371  ->setMethods( [ 'canChangeUser' ] )->getMock();
372  $this->provider->expects( $this->any() )->method( 'canChangeUser' )
373  ->will( $this->returnValue( false ) );
374  $backend = $this->getBackend();
375  $this->assertFalse( $backend->canSetUser() );
376  try {
377  $backend->setUser( $user );
378  $this->fail( 'Expected exception not thrown' );
379  } catch ( \BadMethodCallException $ex ) {
380  $this->assertSame(
381  'Cannot set user on this session; check $session->canSetUser() first',
382  $ex->getMessage()
383  );
384  }
385  $this->assertNotSame( $user, $backend->getUser() );
386 
387  $this->provider = null;
388  $backend = $this->getBackend();
389  $this->assertTrue( $backend->canSetUser() );
390  $this->assertNotSame( $user, $backend->getUser(), 'sanity check' );
391  $backend->setUser( $user );
392  $this->assertSame( $user, $backend->getUser() );
393  }
394 
395  public function testDirty() {
396  $backend = $this->getBackend();
397  $priv = TestingAccessWrapper::newFromObject( $backend );
398  $priv->dataDirty = false;
399  $backend->dirty();
400  $this->assertTrue( $priv->dataDirty );
401  }
402 
403  public function testGetData() {
404  $backend = $this->getBackend();
405  $data = $backend->getData();
406  $this->assertSame( [], $data );
407  $this->assertTrue( TestingAccessWrapper::newFromObject( $backend )->dataDirty );
408  $data['???'] = '!!!';
409  $this->assertSame( [ '???' => '!!!' ], $data );
410 
411  $testData = [ 'foo' => 'foo!', 'bar', [ 'baz', null ] ];
412  $this->store->setSessionData( self::SESSIONID, $testData );
413  $backend = $this->getBackend();
414  $this->assertSame( $testData, $backend->getData() );
415  $this->assertFalse( TestingAccessWrapper::newFromObject( $backend )->dataDirty );
416  }
417 
418  public function testAddData() {
419  $backend = $this->getBackend();
420  $priv = TestingAccessWrapper::newFromObject( $backend );
421 
422  $priv->data = [ 'foo' => 1 ];
423  $priv->dataDirty = false;
424  $backend->addData( [ 'foo' => 1 ] );
425  $this->assertSame( [ 'foo' => 1 ], $priv->data );
426  $this->assertFalse( $priv->dataDirty );
427 
428  $priv->data = [ 'foo' => 1 ];
429  $priv->dataDirty = false;
430  $backend->addData( [ 'foo' => '1' ] );
431  $this->assertSame( [ 'foo' => '1' ], $priv->data );
432  $this->assertTrue( $priv->dataDirty );
433 
434  $priv->data = [ 'foo' => 1 ];
435  $priv->dataDirty = false;
436  $backend->addData( [ 'bar' => 2 ] );
437  $this->assertSame( [ 'foo' => 1, 'bar' => 2 ], $priv->data );
438  $this->assertTrue( $priv->dataDirty );
439  }
440 
441  public function testDelaySave() {
442  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
443  $backend = $this->getBackend();
444  $priv = TestingAccessWrapper::newFromObject( $backend );
445  $priv->persist = true;
446 
447  // Saves happen normally when no delay is in effect
448  $this->onSessionMetadataCalled = false;
449  $priv->metaDirty = true;
450  $backend->save();
451  $this->assertTrue( $this->onSessionMetadataCalled, 'sanity check' );
452 
453  $this->onSessionMetadataCalled = false;
454  $priv->metaDirty = true;
455  $priv->autosave();
456  $this->assertTrue( $this->onSessionMetadataCalled, 'sanity check' );
457 
458  $delay = $backend->delaySave();
459 
460  // Autosave doesn't happen when no delay is in effect
461  $this->onSessionMetadataCalled = false;
462  $priv->metaDirty = true;
463  $priv->autosave();
464  $this->assertFalse( $this->onSessionMetadataCalled );
465 
466  // Save still does happen when no delay is in effect
467  $priv->save();
468  $this->assertTrue( $this->onSessionMetadataCalled );
469 
470  // Save happens when delay is consumed
471  $this->onSessionMetadataCalled = false;
472  $priv->metaDirty = true;
473  \Wikimedia\ScopedCallback::consume( $delay );
474  $this->assertTrue( $this->onSessionMetadataCalled );
475 
476  // Test multiple delays
477  $delay1 = $backend->delaySave();
478  $delay2 = $backend->delaySave();
479  $delay3 = $backend->delaySave();
480  $this->onSessionMetadataCalled = false;
481  $priv->metaDirty = true;
482  $priv->autosave();
483  $this->assertFalse( $this->onSessionMetadataCalled );
484  \Wikimedia\ScopedCallback::consume( $delay3 );
485  $this->assertFalse( $this->onSessionMetadataCalled );
486  \Wikimedia\ScopedCallback::consume( $delay1 );
487  $this->assertFalse( $this->onSessionMetadataCalled );
488  \Wikimedia\ScopedCallback::consume( $delay2 );
489  $this->assertTrue( $this->onSessionMetadataCalled );
490  }
491 
492  public function testSave() {
493  $user = static::getTestSysop()->getUser();
494  $this->store = new TestBagOStuff();
495  $testData = [ 'foo' => 'foo!', 'bar', [ 'baz', null ] ];
496 
497  $neverHook = $this->getMockBuilder( __CLASS__ )
498  ->setMethods( [ 'onSessionMetadata' ] )->getMock();
499  $neverHook->expects( $this->never() )->method( 'onSessionMetadata' );
500 
501  $builder = $this->getMockBuilder( 'DummySessionProvider' )
502  ->setMethods( [ 'persistSession', 'unpersistSession' ] );
503 
504  $neverProvider = $builder->getMock();
505  $neverProvider->expects( $this->never() )->method( 'persistSession' );
506  $neverProvider->expects( $this->never() )->method( 'unpersistSession' );
507 
508  // Not persistent or dirty
509  $this->provider = $neverProvider;
510  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $neverHook ] ] );
511  $this->store->setSessionData( self::SESSIONID, $testData );
512  $backend = $this->getBackend( $user );
513  $this->store->deleteSession( self::SESSIONID );
514  $this->assertFalse( $backend->isPersistent(), 'sanity check' );
515  TestingAccessWrapper::newFromObject( $backend )->metaDirty = false;
516  TestingAccessWrapper::newFromObject( $backend )->dataDirty = false;
517  $backend->save();
518  $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'making sure it didn\'t save' );
519 
520  // (but does unpersist if forced)
521  $this->provider = $builder->getMock();
522  $this->provider->expects( $this->never() )->method( 'persistSession' );
523  $this->provider->expects( $this->atLeastOnce() )->method( 'unpersistSession' );
524  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $neverHook ] ] );
525  $this->store->setSessionData( self::SESSIONID, $testData );
526  $backend = $this->getBackend( $user );
527  $this->store->deleteSession( self::SESSIONID );
528  TestingAccessWrapper::newFromObject( $backend )->persist = false;
529  TestingAccessWrapper::newFromObject( $backend )->forcePersist = true;
530  $this->assertFalse( $backend->isPersistent(), 'sanity check' );
531  TestingAccessWrapper::newFromObject( $backend )->metaDirty = false;
532  TestingAccessWrapper::newFromObject( $backend )->dataDirty = false;
533  $backend->save();
534  $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'making sure it didn\'t save' );
535 
536  // (but not to a WebRequest associated with a different session)
537  $this->provider = $neverProvider;
538  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $neverHook ] ] );
539  $this->store->setSessionData( self::SESSIONID, $testData );
540  $backend = $this->getBackend( $user );
541  TestingAccessWrapper::newFromObject( $backend )->requests[100]
542  ->setSessionId( new SessionId( 'x' ) );
543  $this->store->deleteSession( self::SESSIONID );
544  TestingAccessWrapper::newFromObject( $backend )->persist = false;
545  TestingAccessWrapper::newFromObject( $backend )->forcePersist = true;
546  $this->assertFalse( $backend->isPersistent(), 'sanity check' );
547  TestingAccessWrapper::newFromObject( $backend )->metaDirty = false;
548  TestingAccessWrapper::newFromObject( $backend )->dataDirty = false;
549  $backend->save();
550  $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'making sure it didn\'t save' );
551 
552  // Not persistent, but dirty
553  $this->provider = $neverProvider;
554  $this->onSessionMetadataCalled = false;
555  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
556  $this->store->setSessionData( self::SESSIONID, $testData );
557  $backend = $this->getBackend( $user );
558  $this->store->deleteSession( self::SESSIONID );
559  $this->assertFalse( $backend->isPersistent(), 'sanity check' );
560  TestingAccessWrapper::newFromObject( $backend )->metaDirty = false;
561  TestingAccessWrapper::newFromObject( $backend )->dataDirty = true;
562  $backend->save();
563  $this->assertTrue( $this->onSessionMetadataCalled );
564  $blob = $this->store->getSession( self::SESSIONID );
565  $this->assertInternalType( 'array', $blob );
566  $this->assertArrayHasKey( 'metadata', $blob );
567  $metadata = $blob['metadata'];
568  $this->assertInternalType( 'array', $metadata );
569  $this->assertArrayHasKey( '???', $metadata );
570  $this->assertSame( '!!!', $metadata['???'] );
571  $this->assertFalse( $this->store->getSessionFromBackend( self::SESSIONID ),
572  'making sure it didn\'t save to backend' );
573 
574  // Persistent, not dirty
575  $this->provider = $neverProvider;
576  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $neverHook ] ] );
577  $this->store->setSessionData( self::SESSIONID, $testData );
578  $backend = $this->getBackend( $user );
579  $this->store->deleteSession( self::SESSIONID );
580  TestingAccessWrapper::newFromObject( $backend )->persist = true;
581  $this->assertTrue( $backend->isPersistent(), 'sanity check' );
582  TestingAccessWrapper::newFromObject( $backend )->metaDirty = false;
583  TestingAccessWrapper::newFromObject( $backend )->dataDirty = false;
584  $backend->save();
585  $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'making sure it didn\'t save' );
586 
587  // (but will persist if forced)
588  $this->provider = $builder->getMock();
589  $this->provider->expects( $this->atLeastOnce() )->method( 'persistSession' );
590  $this->provider->expects( $this->never() )->method( 'unpersistSession' );
591  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $neverHook ] ] );
592  $this->store->setSessionData( self::SESSIONID, $testData );
593  $backend = $this->getBackend( $user );
594  $this->store->deleteSession( self::SESSIONID );
595  TestingAccessWrapper::newFromObject( $backend )->persist = true;
596  TestingAccessWrapper::newFromObject( $backend )->forcePersist = true;
597  $this->assertTrue( $backend->isPersistent(), 'sanity check' );
598  TestingAccessWrapper::newFromObject( $backend )->metaDirty = false;
599  TestingAccessWrapper::newFromObject( $backend )->dataDirty = false;
600  $backend->save();
601  $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'making sure it didn\'t save' );
602 
603  // Persistent and dirty
604  $this->provider = $neverProvider;
605  $this->onSessionMetadataCalled = false;
606  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
607  $this->store->setSessionData( self::SESSIONID, $testData );
608  $backend = $this->getBackend( $user );
609  $this->store->deleteSession( self::SESSIONID );
610  TestingAccessWrapper::newFromObject( $backend )->persist = true;
611  $this->assertTrue( $backend->isPersistent(), 'sanity check' );
612  TestingAccessWrapper::newFromObject( $backend )->metaDirty = false;
613  TestingAccessWrapper::newFromObject( $backend )->dataDirty = true;
614  $backend->save();
615  $this->assertTrue( $this->onSessionMetadataCalled );
616  $blob = $this->store->getSession( self::SESSIONID );
617  $this->assertInternalType( 'array', $blob );
618  $this->assertArrayHasKey( 'metadata', $blob );
619  $metadata = $blob['metadata'];
620  $this->assertInternalType( 'array', $metadata );
621  $this->assertArrayHasKey( '???', $metadata );
622  $this->assertSame( '!!!', $metadata['???'] );
623  $this->assertNotSame( false, $this->store->getSessionFromBackend( self::SESSIONID ),
624  'making sure it did save to backend' );
625 
626  // (also persists if forced)
627  $this->provider = $builder->getMock();
628  $this->provider->expects( $this->atLeastOnce() )->method( 'persistSession' );
629  $this->provider->expects( $this->never() )->method( 'unpersistSession' );
630  $this->onSessionMetadataCalled = false;
631  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
632  $this->store->setSessionData( self::SESSIONID, $testData );
633  $backend = $this->getBackend( $user );
634  $this->store->deleteSession( self::SESSIONID );
635  TestingAccessWrapper::newFromObject( $backend )->persist = true;
636  TestingAccessWrapper::newFromObject( $backend )->forcePersist = true;
637  $this->assertTrue( $backend->isPersistent(), 'sanity check' );
638  TestingAccessWrapper::newFromObject( $backend )->metaDirty = false;
639  TestingAccessWrapper::newFromObject( $backend )->dataDirty = true;
640  $backend->save();
641  $this->assertTrue( $this->onSessionMetadataCalled );
642  $blob = $this->store->getSession( self::SESSIONID );
643  $this->assertInternalType( 'array', $blob );
644  $this->assertArrayHasKey( 'metadata', $blob );
645  $metadata = $blob['metadata'];
646  $this->assertInternalType( 'array', $metadata );
647  $this->assertArrayHasKey( '???', $metadata );
648  $this->assertSame( '!!!', $metadata['???'] );
649  $this->assertNotSame( false, $this->store->getSessionFromBackend( self::SESSIONID ),
650  'making sure it did save to backend' );
651 
652  // (also persists if metadata dirty)
653  $this->provider = $builder->getMock();
654  $this->provider->expects( $this->atLeastOnce() )->method( 'persistSession' );
655  $this->provider->expects( $this->never() )->method( 'unpersistSession' );
656  $this->onSessionMetadataCalled = false;
657  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
658  $this->store->setSessionData( self::SESSIONID, $testData );
659  $backend = $this->getBackend( $user );
660  $this->store->deleteSession( self::SESSIONID );
661  TestingAccessWrapper::newFromObject( $backend )->persist = true;
662  $this->assertTrue( $backend->isPersistent(), 'sanity check' );
663  TestingAccessWrapper::newFromObject( $backend )->metaDirty = true;
664  TestingAccessWrapper::newFromObject( $backend )->dataDirty = false;
665  $backend->save();
666  $this->assertTrue( $this->onSessionMetadataCalled );
667  $blob = $this->store->getSession( self::SESSIONID );
668  $this->assertInternalType( 'array', $blob );
669  $this->assertArrayHasKey( 'metadata', $blob );
670  $metadata = $blob['metadata'];
671  $this->assertInternalType( 'array', $metadata );
672  $this->assertArrayHasKey( '???', $metadata );
673  $this->assertSame( '!!!', $metadata['???'] );
674  $this->assertNotSame( false, $this->store->getSessionFromBackend( self::SESSIONID ),
675  'making sure it did save to backend' );
676 
677  // Not marked dirty, but dirty data
678  // (e.g. indirect modification from ArrayAccess::offsetGet)
679  $this->provider = $neverProvider;
680  $this->onSessionMetadataCalled = false;
681  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
682  $this->store->setSessionData( self::SESSIONID, $testData );
683  $backend = $this->getBackend( $user );
684  $this->store->deleteSession( self::SESSIONID );
685  TestingAccessWrapper::newFromObject( $backend )->persist = true;
686  $this->assertTrue( $backend->isPersistent(), 'sanity check' );
687  TestingAccessWrapper::newFromObject( $backend )->metaDirty = false;
688  TestingAccessWrapper::newFromObject( $backend )->dataDirty = false;
689  TestingAccessWrapper::newFromObject( $backend )->dataHash = 'Doesn\'t match';
690  $backend->save();
691  $this->assertTrue( $this->onSessionMetadataCalled );
692  $blob = $this->store->getSession( self::SESSIONID );
693  $this->assertInternalType( 'array', $blob );
694  $this->assertArrayHasKey( 'metadata', $blob );
695  $metadata = $blob['metadata'];
696  $this->assertInternalType( 'array', $metadata );
697  $this->assertArrayHasKey( '???', $metadata );
698  $this->assertSame( '!!!', $metadata['???'] );
699  $this->assertNotSame( false, $this->store->getSessionFromBackend( self::SESSIONID ),
700  'making sure it did save to backend' );
701 
702  // Bad hook
703  $this->provider = null;
704  $mockHook = $this->getMockBuilder( __CLASS__ )
705  ->setMethods( [ 'onSessionMetadata' ] )->getMock();
706  $mockHook->expects( $this->any() )->method( 'onSessionMetadata' )
707  ->will( $this->returnCallback(
708  function ( SessionBackend $backend, array &$metadata, array $requests ) {
709  $metadata['userId']++;
710  }
711  ) );
712  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $mockHook ] ] );
713  $this->store->setSessionData( self::SESSIONID, $testData );
714  $backend = $this->getBackend( $user );
715  $backend->dirty();
716  try {
717  $backend->save();
718  $this->fail( 'Expected exception not thrown' );
719  } catch ( \UnexpectedValueException $ex ) {
720  $this->assertSame(
721  'SessionMetadata hook changed metadata key "userId"',
722  $ex->getMessage()
723  );
724  }
725 
726  // SessionManager::preventSessionsForUser
727  TestingAccessWrapper::newFromObject( $this->manager )->preventUsers = [
728  $user->getName() => true,
729  ];
730  $this->provider = $neverProvider;
731  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $neverHook ] ] );
732  $this->store->setSessionData( self::SESSIONID, $testData );
733  $backend = $this->getBackend( $user );
734  $this->store->deleteSession( self::SESSIONID );
735  TestingAccessWrapper::newFromObject( $backend )->persist = true;
736  $this->assertTrue( $backend->isPersistent(), 'sanity check' );
737  TestingAccessWrapper::newFromObject( $backend )->metaDirty = true;
738  TestingAccessWrapper::newFromObject( $backend )->dataDirty = true;
739  $backend->save();
740  $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'making sure it didn\'t save' );
741  }
742 
743  public function testRenew() {
744  $user = static::getTestSysop()->getUser();
745  $this->store = new TestBagOStuff();
746  $testData = [ 'foo' => 'foo!', 'bar', [ 'baz', null ] ];
747 
748  // Not persistent
749  $this->provider = $this->getMockBuilder( 'DummySessionProvider' )
750  ->setMethods( [ 'persistSession' ] )->getMock();
751  $this->provider->expects( $this->never() )->method( 'persistSession' );
752  $this->onSessionMetadataCalled = false;
753  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
754  $this->store->setSessionData( self::SESSIONID, $testData );
755  $backend = $this->getBackend( $user );
756  $this->store->deleteSession( self::SESSIONID );
757  $wrap = TestingAccessWrapper::newFromObject( $backend );
758  $this->assertFalse( $backend->isPersistent(), 'sanity check' );
759  $wrap->metaDirty = false;
760  $wrap->dataDirty = false;
761  $wrap->forcePersist = false;
762  $wrap->expires = 0;
763  $backend->renew();
764  $this->assertTrue( $this->onSessionMetadataCalled );
765  $blob = $this->store->getSession( self::SESSIONID );
766  $this->assertInternalType( 'array', $blob );
767  $this->assertArrayHasKey( 'metadata', $blob );
768  $metadata = $blob['metadata'];
769  $this->assertInternalType( 'array', $metadata );
770  $this->assertArrayHasKey( '???', $metadata );
771  $this->assertSame( '!!!', $metadata['???'] );
772  $this->assertNotEquals( 0, $wrap->expires );
773 
774  // Persistent
775  $this->provider = $this->getMockBuilder( 'DummySessionProvider' )
776  ->setMethods( [ 'persistSession' ] )->getMock();
777  $this->provider->expects( $this->atLeastOnce() )->method( 'persistSession' );
778  $this->onSessionMetadataCalled = false;
779  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
780  $this->store->setSessionData( self::SESSIONID, $testData );
781  $backend = $this->getBackend( $user );
782  $this->store->deleteSession( self::SESSIONID );
783  $wrap = TestingAccessWrapper::newFromObject( $backend );
784  $wrap->persist = true;
785  $this->assertTrue( $backend->isPersistent(), 'sanity check' );
786  $wrap->metaDirty = false;
787  $wrap->dataDirty = false;
788  $wrap->forcePersist = false;
789  $wrap->expires = 0;
790  $backend->renew();
791  $this->assertTrue( $this->onSessionMetadataCalled );
792  $blob = $this->store->getSession( self::SESSIONID );
793  $this->assertInternalType( 'array', $blob );
794  $this->assertArrayHasKey( 'metadata', $blob );
795  $metadata = $blob['metadata'];
796  $this->assertInternalType( 'array', $metadata );
797  $this->assertArrayHasKey( '???', $metadata );
798  $this->assertSame( '!!!', $metadata['???'] );
799  $this->assertNotEquals( 0, $wrap->expires );
800 
801  // Not persistent, not expiring
802  $this->provider = $this->getMockBuilder( 'DummySessionProvider' )
803  ->setMethods( [ 'persistSession' ] )->getMock();
804  $this->provider->expects( $this->never() )->method( 'persistSession' );
805  $this->onSessionMetadataCalled = false;
806  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
807  $this->store->setSessionData( self::SESSIONID, $testData );
808  $backend = $this->getBackend( $user );
809  $this->store->deleteSession( self::SESSIONID );
810  $wrap = TestingAccessWrapper::newFromObject( $backend );
811  $this->assertFalse( $backend->isPersistent(), 'sanity check' );
812  $wrap->metaDirty = false;
813  $wrap->dataDirty = false;
814  $wrap->forcePersist = false;
815  $expires = time() + $wrap->lifetime + 100;
816  $wrap->expires = $expires;
817  $backend->renew();
818  $this->assertFalse( $this->onSessionMetadataCalled );
819  $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'making sure it didn\'t save' );
820  $this->assertEquals( $expires, $wrap->expires );
821  }
822 
823  public function onSessionMetadata( SessionBackend $backend, array &$metadata, array $requests ) {
824  $this->onSessionMetadataCalled = true;
825  $metadata['???'] = '!!!';
826  }
827 
828  public function testTakeOverGlobalSession() {
831  }
832  if ( !PHPSessionHandler::isEnabled() ) {
833  $rProp = new \ReflectionProperty( PHPSessionHandler::class, 'instance' );
834  $rProp->setAccessible( true );
835  $handler = TestingAccessWrapper::newFromObject( $rProp->getValue() );
836  $resetHandler = new \Wikimedia\ScopedCallback( function () use ( $handler ) {
837  session_write_close();
838  $handler->enable = false;
839  } );
840  $handler->enable = true;
841  }
842 
843  $backend = $this->getBackend( static::getTestSysop()->getUser() );
844  TestingAccessWrapper::newFromObject( $backend )->usePhpSessionHandling = true;
845 
846  $resetSingleton = TestUtils::setSessionManagerSingleton( $this->manager );
847 
848  $manager = TestingAccessWrapper::newFromObject( $this->manager );
849  $request = \RequestContext::getMain()->getRequest();
850  $manager->globalSession = $backend->getSession( $request );
851  $manager->globalSessionRequest = $request;
852 
853  session_id( '' );
854  TestingAccessWrapper::newFromObject( $backend )->checkPHPSession();
855  $this->assertSame( $backend->getId(), session_id() );
856  session_write_close();
857 
858  $backend2 = $this->getBackend(
859  User::newFromName( 'UTSysop' ), 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'
860  );
861  TestingAccessWrapper::newFromObject( $backend2 )->usePhpSessionHandling = true;
862 
863  session_id( '' );
864  TestingAccessWrapper::newFromObject( $backend2 )->checkPHPSession();
865  $this->assertSame( '', session_id() );
866  }
867 
868  public function testResetIdOfGlobalSession() {
871  }
872  if ( !PHPSessionHandler::isEnabled() ) {
873  $rProp = new \ReflectionProperty( PHPSessionHandler::class, 'instance' );
874  $rProp->setAccessible( true );
875  $handler = TestingAccessWrapper::newFromObject( $rProp->getValue() );
876  $resetHandler = new \Wikimedia\ScopedCallback( function () use ( $handler ) {
877  session_write_close();
878  $handler->enable = false;
879  } );
880  $handler->enable = true;
881  }
882 
883  $backend = $this->getBackend( User::newFromName( 'UTSysop' ) );
884  TestingAccessWrapper::newFromObject( $backend )->usePhpSessionHandling = true;
885 
886  $resetSingleton = TestUtils::setSessionManagerSingleton( $this->manager );
887 
888  $manager = TestingAccessWrapper::newFromObject( $this->manager );
889  $request = \RequestContext::getMain()->getRequest();
890  $manager->globalSession = $backend->getSession( $request );
891  $manager->globalSessionRequest = $request;
892 
893  session_id( self::SESSIONID );
894  \MediaWiki\quietCall( 'session_start' );
895  $_SESSION['foo'] = __METHOD__;
896  $backend->resetId();
897  $this->assertNotEquals( self::SESSIONID, $backend->getId() );
898  $this->assertSame( $backend->getId(), session_id() );
899  $this->assertArrayHasKey( 'foo', $_SESSION );
900  $this->assertSame( __METHOD__, $_SESSION['foo'] );
901  session_write_close();
902  }
903 
904  public function testUnpersistOfGlobalSession() {
907  }
908  if ( !PHPSessionHandler::isEnabled() ) {
909  $rProp = new \ReflectionProperty( PHPSessionHandler::class, 'instance' );
910  $rProp->setAccessible( true );
911  $handler = TestingAccessWrapper::newFromObject( $rProp->getValue() );
912  $resetHandler = new \Wikimedia\ScopedCallback( function () use ( $handler ) {
913  session_write_close();
914  $handler->enable = false;
915  } );
916  $handler->enable = true;
917  }
918 
919  $backend = $this->getBackend( User::newFromName( 'UTSysop' ) );
920  $wrap = TestingAccessWrapper::newFromObject( $backend );
921  $wrap->usePhpSessionHandling = true;
922  $wrap->persist = true;
923 
924  $resetSingleton = TestUtils::setSessionManagerSingleton( $this->manager );
925 
926  $manager = TestingAccessWrapper::newFromObject( $this->manager );
927  $request = \RequestContext::getMain()->getRequest();
928  $manager->globalSession = $backend->getSession( $request );
929  $manager->globalSessionRequest = $request;
930 
931  session_id( self::SESSIONID . 'x' );
932  \MediaWiki\quietCall( 'session_start' );
933  $backend->unpersist();
934  $this->assertSame( self::SESSIONID . 'x', session_id() );
935 
936  session_id( self::SESSIONID );
937  $wrap->persist = true;
938  $backend->unpersist();
939  $this->assertSame( '', session_id() );
940  }
941 
942  public function testGetAllowedUserRights() {
943  $this->provider = $this->getMockBuilder( 'DummySessionProvider' )
944  ->setMethods( [ 'getAllowedUserRights' ] )
945  ->getMock();
946  $this->provider->expects( $this->any() )->method( 'getAllowedUserRights' )
947  ->will( $this->returnValue( [ 'foo', 'bar' ] ) );
948 
949  $backend = $this->getBackend();
950  $this->assertSame( [ 'foo', 'bar' ], $backend->getAllowedUserRights() );
951  }
952 
953 }
MediaWiki\Session\SessionBackendTest\onSessionMetadata
onSessionMetadata(SessionBackend $backend, array &$metadata, array $requests)
Definition: SessionBackendTest.php:823
$user
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a account $user
Definition: hooks.txt:244
MediaWiki\Session\PHPSessionHandler\install
static install(SessionManager $manager)
Install a session handler for the current web request.
Definition: PHPSessionHandler.php:108
MediaWiki\Session\SessionId\getId
getId()
Get the ID.
Definition: SessionId.php:53
MediaWikiTestCase\mergeMwGlobalArrayValue
mergeMwGlobalArrayValue( $name, $values)
Merges the given values into a MW global array variable.
Definition: MediaWikiTestCase.php:807
MediaWiki\Session\SessionBackendTest\testUnpersist
testUnpersist()
Definition: SessionBackendTest.php:316
MediaWiki\Session\SessionBackendTest\SESSIONID
const SESSIONID
Definition: SessionBackendTest.php:15
MediaWiki\Session\SessionBackendTest\testUnpersistOfGlobalSession
testUnpersistOfGlobalSession()
Definition: SessionBackendTest.php:904
MediaWiki\Session\SessionBackendTest\testDelaySave
testDelaySave()
Definition: SessionBackendTest.php:441
MediaWiki\Session\SessionBackendTest\testResetId
testResetId()
Definition: SessionBackendTest.php:258
captcha-old.count
count
Definition: captcha-old.py:249
MediaWiki\Session\SessionBackendTest\testSessionStuff
testSessionStuff()
Definition: SessionBackendTest.php:176
MediaWiki\Session\SessionBackendTest\testSetProviderMetadata
testSetProviderMetadata()
Definition: SessionBackendTest.php:222
use
as see the revision history and available at free of to any person obtaining a copy of this software and associated documentation to deal in the Software without including without limitation the rights to use
Definition: MIT-LICENSE.txt:10
MediaWiki\Session\SessionBackendTest\$store
$store
Definition: SessionBackendTest.php:20
MediaWiki\Session\PHPSessionHandler\isEnabled
static isEnabled()
Test whether the handler is installed and enabled.
Definition: PHPSessionHandler.php:100
MediaWiki\Session\TestUtils\setSessionManagerSingleton
static setSessionManagerSingleton(SessionManager $manager=null)
Override the singleton for unit testing.
Definition: TestUtils.php:18
MediaWiki\Session\SessionBackendTest\testResetIdOfGlobalSession
testResetIdOfGlobalSession()
Definition: SessionBackendTest.php:868
User\newFromName
static newFromName( $name, $validate='valid')
Static factory method for creation from username.
Definition: User.php:550
MediaWiki\Session\SessionBackendTest\testGetAllowedUserRights
testGetAllowedUserRights()
Definition: SessionBackendTest.php:942
MediaWiki\Session\SessionBackendTest\$manager
$manager
Definition: SessionBackendTest.php:17
User
User
Definition: All_system_messages.txt:425
MediaWiki\Session\UserInfo\newFromUser
static newFromUser(User $user, $verified=false)
Create an instance from an existing User object.
Definition: UserInfo.php:116
MediaWiki\Session\SessionBackendTest
Session Database MediaWiki\Session\SessionBackend.
Definition: SessionBackendTest.php:14
php
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:35
MediaWiki\Session\SessionBackendTest\testTakeOverGlobalSession
testTakeOverGlobalSession()
Definition: SessionBackendTest.php:828
$blob
$blob
Definition: testCompression.php:63
MediaWikiTestCase
Definition: MediaWikiTestCase.php:15
MediaWiki\Session\SessionBackendTest\testPersist
testPersist()
Definition: SessionBackendTest.php:296
store
MediaWiki s SiteStore can be cached and stored in a flat in a json format If the SiteStore is frequently the file cache may provide a performance benefit over a database store
Definition: sitescache.txt:1
MediaWiki\Session\SessionBackendTest\testLoggedOutTimestamp
testLoggedOutTimestamp()
Definition: SessionBackendTest.php:358
MediaWiki\Session\SessionManager\singleton
static singleton()
Get the global SessionManager.
Definition: SessionManager.php:91
MediaWiki\Session\SessionBackendTest\$config
$config
Definition: SessionBackendTest.php:18
MediaWiki\Session\SessionBackend\dirty
dirty()
Mark data as dirty.
Definition: SessionBackend.php:546
MediaWiki\Session
Definition: BotPasswordSessionProvider.php:24
MediaWiki\Session\SessionBackendTest\testRememberUser
testRememberUser()
Definition: SessionBackendTest.php:338
string
This code would result in ircNotify being run twice when an article is and once for brion Hooks can return three possible true was required This is the default since MediaWiki *some string
Definition: hooks.txt:175
MediaWiki\Session\SessionBackendTest\testSetUser
testSetUser()
Definition: SessionBackendTest.php:367
MediaWiki\Session\SessionBackendTest\testSave
testSave()
Definition: SessionBackendTest.php:492
MediaWiki\Session\SessionBackendTest\testConstructor
testConstructor()
Definition: SessionBackendTest.php:79
$request
do that in ParserLimitReportFormat instead use this to modify the parameters of the image all existing parser cache entries will be invalid To avoid you ll need to handle that somehow(e.g. with the RejectParserCacheValue hook) because MediaWiki won 't do it for you. & $defaults also a ContextSource after deleting those rows but within the same transaction you ll probably need to make sure the header is varied on $request
Definition: hooks.txt:2581
MediaWiki\Session\SessionBackendTest\testRenew
testRenew()
Definition: SessionBackendTest.php:743
any
they could even be mouse clicks or menu items whatever suits your program You should also get your if any
Definition: COPYING.txt:326
MediaWiki\Session\SessionBackendTest\testGetData
testGetData()
Definition: SessionBackendTest.php:403
MediaWiki\Session\TestBagOStuff
BagOStuff with utility functions for MediaWiki\\Session\\* testing.
Definition: TestBagOStuff.php:8
MediaWiki\Session\UserInfo\newFromName
static newFromName( $name, $verified=false)
Create an instance for a logged-in user by name.
Definition: UserInfo.php:102
MediaWiki\Session\SessionManager
This serves as the entry point to the MediaWiki session handling system.
Definition: SessionManager.php:49
MediaWiki\Session\SessionBackendTest\testDirty
testDirty()
Definition: SessionBackendTest.php:395
$handler
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that probably a stub it is not rendered in wiki pages or galleries in category pages allow injecting custom HTML after the section Any uses of the hook need to handle escaping see BaseTemplate::getToolbox and BaseTemplate::makeListItem for details on the format of individual items inside of this array or by returning and letting standard HTTP rendering take place modifiable or by returning false and taking over the output modifiable modifiable after all normalizations have been except for the $wgMaxImageArea check set to true or false to override the $wgMaxImageArea check result gives extension the possibility to transform it themselves $handler
Definition: hooks.txt:781
RequestContext\getMain
static getMain()
Static methods.
Definition: RequestContext.php:470
MediaWiki\Session\SessionBackendTest\testForceHTTPS
testForceHTTPS()
Definition: SessionBackendTest.php:348
MediaWiki\Session\SessionInfo
Value object returned by SessionProvider.
Definition: SessionInfo.php:34
MediaWiki\Session\SessionBackend\isPersistent
isPersistent()
Indicate whether this session is persisted across requests.
Definition: SessionBackend.php:271
MediaWiki\Session\SessionId
Value object holding the session ID in a manner that can be globally updated.
Definition: SessionId.php:38
MediaWiki\Session\SessionBackendTest\testAddData
testAddData()
Definition: SessionBackendTest.php:418
$requests
Allows to change the fields on the form that will be generated are created Can be used to omit specific feeds from being outputted You must not use this hook to add use OutputPage::addFeedLink() instead. & $feedLinks hooks can tweak the array to change how login etc forms should look $requests
Definition: hooks.txt:304
class
you have access to all of the normal MediaWiki so you can get a DB use the etc For full docs on the Maintenance class
Definition: maintenance.txt:52
MediaWiki\Session\PHPSessionHandler\isInstalled
static isInstalled()
Test whether the handler is installed.
Definition: PHPSessionHandler.php:92
MediaWiki\Session\SessionBackendTest\getBackend
getBackend(User $user=null, $id=null)
Returns a non-persistent backend that thinks it has at least one session active.
Definition: SessionBackendTest.php:29
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:51
MediaWiki\Session\SessionInfo\MIN_PRIORITY
const MIN_PRIORITY
Minimum allowed priority.
Definition: SessionInfo.php:36
MediaWiki\Session\SessionBackend\save
save( $closing=false)
Save the session.
Definition: SessionBackend.php:620
MediaWiki\Session\SessionBackendTest\$provider
$provider
Definition: SessionBackendTest.php:19
array
the array() calling protocol came about after MediaWiki 1.4rc1.
MediaWiki\Session\SessionBackendTest\$onSessionMetadataCalled
$onSessionMetadataCalled
Definition: SessionBackendTest.php:22
MediaWiki\Session\SessionBackend
This is the actual workhorse for Session.
Definition: SessionBackend.php:49