MediaWiki  1.32.5
SessionBackendTest.php
Go to the documentation of this file.
1 <?php
2 
3 namespace MediaWiki\Session;
4 
5 use Config;
7 use User;
8 use Wikimedia\TestingAccessWrapper;
9 
16  const SESSIONID = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
17 
19  protected $manager;
20 
22  protected $config;
23 
25  protected $provider;
26 
28  protected $store;
29 
30  protected $onSessionMetadataCalled = false;
31 
38  protected function getBackend( User $user = null, $id = null ) {
39  if ( !$this->config ) {
40  $this->config = new \HashConfig();
41  $this->manager = null;
42  }
43  if ( !$this->store ) {
44  $this->store = new TestBagOStuff();
45  $this->manager = null;
46  }
47 
48  $logger = new \Psr\Log\NullLogger();
49  if ( !$this->manager ) {
50  $this->manager = new SessionManager( [
51  'store' => $this->store,
52  'logger' => $logger,
53  'config' => $this->config,
54  ] );
55  }
56 
57  if ( !$this->provider ) {
58  $this->provider = new \DummySessionProvider();
59  }
60  $this->provider->setLogger( $logger );
61  $this->provider->setConfig( $this->config );
62  $this->provider->setManager( $this->manager );
63 
65  'provider' => $this->provider,
66  'id' => $id ?: self::SESSIONID,
67  'persisted' => true,
68  'userInfo' => UserInfo::newFromUser( $user ?: new User, true ),
69  'idIsSafe' => true,
70  ] );
71  $id = new SessionId( $info->getId() );
72 
73  $backend = new SessionBackend( $id, $info, $this->store, $logger, 10 );
74  $priv = TestingAccessWrapper::newFromObject( $backend );
75  $priv->persist = false;
76  $priv->requests = [ 100 => new \FauxRequest() ];
77  $priv->requests[100]->setSessionId( $id );
78  $priv->usePhpSessionHandling = false;
79 
80  $manager = TestingAccessWrapper::newFromObject( $this->manager );
81  $manager->allSessionBackends = [ $backend->getId() => $backend ] + $manager->allSessionBackends;
82  $manager->allSessionIds = [ $backend->getId() => $id ] + $manager->allSessionIds;
83  $manager->sessionProviders = [ (string)$this->provider => $this->provider ];
84 
85  return $backend;
86  }
87 
88  public function testConstructor() {
89  // Set variables
90  $this->getBackend();
91 
93  'provider' => $this->provider,
94  'id' => self::SESSIONID,
95  'persisted' => true,
96  'userInfo' => UserInfo::newFromName( 'UTSysop', false ),
97  'idIsSafe' => true,
98  ] );
99  $id = new SessionId( $info->getId() );
100  $logger = new \Psr\Log\NullLogger();
101  try {
102  new SessionBackend( $id, $info, $this->store, $logger, 10 );
103  $this->fail( 'Expected exception not thrown' );
104  } catch ( \InvalidArgumentException $ex ) {
105  $this->assertSame(
106  "Refusing to create session for unverified user {$info->getUserInfo()}",
107  $ex->getMessage()
108  );
109  }
110 
111  $info = new SessionInfo( SessionInfo::MIN_PRIORITY, [
112  'id' => self::SESSIONID,
113  'userInfo' => UserInfo::newFromName( 'UTSysop', true ),
114  'idIsSafe' => true,
115  ] );
116  $id = new SessionId( $info->getId() );
117  try {
118  new SessionBackend( $id, $info, $this->store, $logger, 10 );
119  $this->fail( 'Expected exception not thrown' );
120  } catch ( \InvalidArgumentException $ex ) {
121  $this->assertSame( 'Cannot create session without a provider', $ex->getMessage() );
122  }
123 
124  $info = new SessionInfo( SessionInfo::MIN_PRIORITY, [
125  'provider' => $this->provider,
126  'id' => self::SESSIONID,
127  'persisted' => true,
128  'userInfo' => UserInfo::newFromName( 'UTSysop', true ),
129  'idIsSafe' => true,
130  ] );
131  $id = new SessionId( '!' . $info->getId() );
132  try {
133  new SessionBackend( $id, $info, $this->store, $logger, 10 );
134  $this->fail( 'Expected exception not thrown' );
135  } catch ( \InvalidArgumentException $ex ) {
136  $this->assertSame(
137  'SessionId and SessionInfo don\'t match',
138  $ex->getMessage()
139  );
140  }
141 
142  $info = new SessionInfo( SessionInfo::MIN_PRIORITY, [
143  'provider' => $this->provider,
144  'id' => self::SESSIONID,
145  'persisted' => true,
146  'userInfo' => UserInfo::newFromName( 'UTSysop', true ),
147  'idIsSafe' => true,
148  ] );
149  $id = new SessionId( $info->getId() );
150  $backend = new SessionBackend( $id, $info, $this->store, $logger, 10 );
151  $this->assertSame( self::SESSIONID, $backend->getId() );
152  $this->assertSame( $id, $backend->getSessionId() );
153  $this->assertSame( $this->provider, $backend->getProvider() );
154  $this->assertInstanceOf( User::class, $backend->getUser() );
155  $this->assertSame( 'UTSysop', $backend->getUser()->getName() );
156  $this->assertSame( $info->wasPersisted(), $backend->isPersistent() );
157  $this->assertSame( $info->wasRemembered(), $backend->shouldRememberUser() );
158  $this->assertSame( $info->forceHTTPS(), $backend->shouldForceHTTPS() );
159 
160  $expire = time() + 100;
161  $this->store->setSessionMeta( self::SESSIONID, [ 'expires' => $expire ] );
162 
163  $info = new SessionInfo( SessionInfo::MIN_PRIORITY, [
164  'provider' => $this->provider,
165  'id' => self::SESSIONID,
166  'persisted' => true,
167  'forceHTTPS' => true,
168  'metadata' => [ 'foo' ],
169  'idIsSafe' => true,
170  ] );
171  $id = new SessionId( $info->getId() );
172  $backend = new SessionBackend( $id, $info, $this->store, $logger, 10 );
173  $this->assertSame( self::SESSIONID, $backend->getId() );
174  $this->assertSame( $id, $backend->getSessionId() );
175  $this->assertSame( $this->provider, $backend->getProvider() );
176  $this->assertInstanceOf( User::class, $backend->getUser() );
177  $this->assertTrue( $backend->getUser()->isAnon() );
178  $this->assertSame( $info->wasPersisted(), $backend->isPersistent() );
179  $this->assertSame( $info->wasRemembered(), $backend->shouldRememberUser() );
180  $this->assertSame( $info->forceHTTPS(), $backend->shouldForceHTTPS() );
181  $this->assertSame( $expire, TestingAccessWrapper::newFromObject( $backend )->expires );
182  $this->assertSame( [ 'foo' ], $backend->getProviderMetadata() );
183  }
184 
185  public function testSessionStuff() {
186  $backend = $this->getBackend();
187  $priv = TestingAccessWrapper::newFromObject( $backend );
188  $priv->requests = []; // Remove dummy session
189 
190  $manager = TestingAccessWrapper::newFromObject( $this->manager );
191 
192  $request1 = new \FauxRequest();
193  $session1 = $backend->getSession( $request1 );
194  $request2 = new \FauxRequest();
195  $session2 = $backend->getSession( $request2 );
196 
197  $this->assertInstanceOf( Session::class, $session1 );
198  $this->assertInstanceOf( Session::class, $session2 );
199  $this->assertSame( 2, count( $priv->requests ) );
200 
201  $index = TestingAccessWrapper::newFromObject( $session1 )->index;
202 
203  $this->assertSame( $request1, $backend->getRequest( $index ) );
204  $this->assertSame( null, $backend->suggestLoginUsername( $index ) );
205  $request1->setCookie( 'UserName', 'Example' );
206  $this->assertSame( 'Example', $backend->suggestLoginUsername( $index ) );
207 
208  $session1 = null;
209  $this->assertSame( 1, count( $priv->requests ) );
210  $this->assertArrayHasKey( $backend->getId(), $manager->allSessionBackends );
211  $this->assertSame( $backend, $manager->allSessionBackends[$backend->getId()] );
212  try {
213  $backend->getRequest( $index );
214  $this->fail( 'Expected exception not thrown' );
215  } catch ( \InvalidArgumentException $ex ) {
216  $this->assertSame( 'Invalid session index', $ex->getMessage() );
217  }
218  try {
219  $backend->suggestLoginUsername( $index );
220  $this->fail( 'Expected exception not thrown' );
221  } catch ( \InvalidArgumentException $ex ) {
222  $this->assertSame( 'Invalid session index', $ex->getMessage() );
223  }
224 
225  $session2 = null;
226  $this->assertSame( 0, count( $priv->requests ) );
227  $this->assertArrayNotHasKey( $backend->getId(), $manager->allSessionBackends );
228  $this->assertArrayHasKey( $backend->getId(), $manager->allSessionIds );
229  }
230 
231  public function testSetProviderMetadata() {
232  $backend = $this->getBackend();
233  $priv = TestingAccessWrapper::newFromObject( $backend );
234  $priv->providerMetadata = [ 'dummy' ];
235 
236  try {
237  $backend->setProviderMetadata( 'foo' );
238  $this->fail( 'Expected exception not thrown' );
239  } catch ( \InvalidArgumentException $ex ) {
240  $this->assertSame( '$metadata must be an array or null', $ex->getMessage() );
241  }
242 
243  try {
244  $backend->setProviderMetadata( (object)[] );
245  $this->fail( 'Expected exception not thrown' );
246  } catch ( \InvalidArgumentException $ex ) {
247  $this->assertSame( '$metadata must be an array or null', $ex->getMessage() );
248  }
249 
250  $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'sanity check' );
251  $backend->setProviderMetadata( [ 'dummy' ] );
252  $this->assertFalse( $this->store->getSession( self::SESSIONID ) );
253 
254  $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'sanity check' );
255  $backend->setProviderMetadata( [ 'test' ] );
256  $this->assertNotFalse( $this->store->getSession( self::SESSIONID ) );
257  $this->assertSame( [ 'test' ], $backend->getProviderMetadata() );
258  $this->store->deleteSession( self::SESSIONID );
259 
260  $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'sanity check' );
261  $backend->setProviderMetadata( null );
262  $this->assertNotFalse( $this->store->getSession( self::SESSIONID ) );
263  $this->assertSame( null, $backend->getProviderMetadata() );
264  $this->store->deleteSession( self::SESSIONID );
265  }
266 
267  public function testResetId() {
268  $id = session_id();
269 
270  $builder = $this->getMockBuilder( \DummySessionProvider::class )
271  ->setMethods( [ 'persistsSessionId', 'sessionIdWasReset' ] );
272 
273  $this->provider = $builder->getMock();
274  $this->provider->expects( $this->any() )->method( 'persistsSessionId' )
275  ->will( $this->returnValue( false ) );
276  $this->provider->expects( $this->never() )->method( 'sessionIdWasReset' );
277  $backend = $this->getBackend( User::newFromName( 'UTSysop' ) );
278  $manager = TestingAccessWrapper::newFromObject( $this->manager );
279  $sessionId = $backend->getSessionId();
280  $backend->resetId();
281  $this->assertSame( self::SESSIONID, $backend->getId() );
282  $this->assertSame( $backend->getId(), $sessionId->getId() );
283  $this->assertSame( $id, session_id() );
284  $this->assertSame( $backend, $manager->allSessionBackends[self::SESSIONID] );
285 
286  $this->provider = $builder->getMock();
287  $this->provider->expects( $this->any() )->method( 'persistsSessionId' )
288  ->will( $this->returnValue( true ) );
289  $backend = $this->getBackend();
290  $this->provider->expects( $this->once() )->method( 'sessionIdWasReset' )
291  ->with( $this->identicalTo( $backend ), $this->identicalTo( self::SESSIONID ) );
292  $manager = TestingAccessWrapper::newFromObject( $this->manager );
293  $sessionId = $backend->getSessionId();
294  $backend->resetId();
295  $this->assertNotEquals( self::SESSIONID, $backend->getId() );
296  $this->assertSame( $backend->getId(), $sessionId->getId() );
297  $this->assertInternalType( 'array', $this->store->getSession( $backend->getId() ) );
298  $this->assertFalse( $this->store->getSession( self::SESSIONID ) );
299  $this->assertSame( $id, session_id() );
300  $this->assertArrayNotHasKey( self::SESSIONID, $manager->allSessionBackends );
301  $this->assertArrayHasKey( $backend->getId(), $manager->allSessionBackends );
302  $this->assertSame( $backend, $manager->allSessionBackends[$backend->getId()] );
303  }
304 
305  public function testPersist() {
306  $this->provider = $this->getMockBuilder( \DummySessionProvider::class )
307  ->setMethods( [ 'persistSession' ] )->getMock();
308  $this->provider->expects( $this->once() )->method( 'persistSession' );
309  $backend = $this->getBackend();
310  $this->assertFalse( $backend->isPersistent(), 'sanity check' );
311  $backend->save(); // This one shouldn't call $provider->persistSession()
312 
313  $backend->persist();
314  $this->assertTrue( $backend->isPersistent(), 'sanity check' );
315 
316  $this->provider = null;
317  $backend = $this->getBackend();
318  $wrap = TestingAccessWrapper::newFromObject( $backend );
319  $wrap->persist = true;
320  $wrap->expires = 0;
321  $backend->persist();
322  $this->assertNotEquals( 0, $wrap->expires );
323  }
324 
325  public function testUnpersist() {
326  $this->provider = $this->getMockBuilder( \DummySessionProvider::class )
327  ->setMethods( [ 'unpersistSession' ] )->getMock();
328  $this->provider->expects( $this->once() )->method( 'unpersistSession' );
329  $backend = $this->getBackend();
330  $wrap = TestingAccessWrapper::newFromObject( $backend );
331  $wrap->store = new \CachedBagOStuff( $this->store );
332  $wrap->persist = true;
333  $wrap->dataDirty = true;
334 
335  $backend->save(); // This one shouldn't call $provider->persistSession(), but should save
336  $this->assertTrue( $backend->isPersistent(), 'sanity check' );
337  $this->assertNotFalse( $this->store->getSession( self::SESSIONID ), 'sanity check' );
338 
339  $backend->unpersist();
340  $this->assertFalse( $backend->isPersistent() );
341  $this->assertFalse( $this->store->getSession( self::SESSIONID ) );
342  $this->assertNotFalse(
343  $wrap->store->get( $wrap->store->makeKey( 'MWSession', self::SESSIONID ) )
344  );
345  }
346 
347  public function testRememberUser() {
348  $backend = $this->getBackend();
349 
350  $remembered = $backend->shouldRememberUser();
351  $backend->setRememberUser( !$remembered );
352  $this->assertNotEquals( $remembered, $backend->shouldRememberUser() );
353  $backend->setRememberUser( $remembered );
354  $this->assertEquals( $remembered, $backend->shouldRememberUser() );
355  }
356 
357  public function testForceHTTPS() {
358  $backend = $this->getBackend();
359 
360  $force = $backend->shouldForceHTTPS();
361  $backend->setForceHTTPS( !$force );
362  $this->assertNotEquals( $force, $backend->shouldForceHTTPS() );
363  $backend->setForceHTTPS( $force );
364  $this->assertEquals( $force, $backend->shouldForceHTTPS() );
365  }
366 
367  public function testLoggedOutTimestamp() {
368  $backend = $this->getBackend();
369 
370  $backend->setLoggedOutTimestamp( 42 );
371  $this->assertSame( 42, $backend->getLoggedOutTimestamp() );
372  $backend->setLoggedOutTimestamp( '123' );
373  $this->assertSame( 123, $backend->getLoggedOutTimestamp() );
374  }
375 
376  public function testSetUser() {
377  $user = static::getTestSysop()->getUser();
378 
379  $this->provider = $this->getMockBuilder( \DummySessionProvider::class )
380  ->setMethods( [ 'canChangeUser' ] )->getMock();
381  $this->provider->expects( $this->any() )->method( 'canChangeUser' )
382  ->will( $this->returnValue( false ) );
383  $backend = $this->getBackend();
384  $this->assertFalse( $backend->canSetUser() );
385  try {
386  $backend->setUser( $user );
387  $this->fail( 'Expected exception not thrown' );
388  } catch ( \BadMethodCallException $ex ) {
389  $this->assertSame(
390  'Cannot set user on this session; check $session->canSetUser() first',
391  $ex->getMessage()
392  );
393  }
394  $this->assertNotSame( $user, $backend->getUser() );
395 
396  $this->provider = null;
397  $backend = $this->getBackend();
398  $this->assertTrue( $backend->canSetUser() );
399  $this->assertNotSame( $user, $backend->getUser(), 'sanity check' );
400  $backend->setUser( $user );
401  $this->assertSame( $user, $backend->getUser() );
402  }
403 
404  public function testDirty() {
405  $backend = $this->getBackend();
406  $priv = TestingAccessWrapper::newFromObject( $backend );
407  $priv->dataDirty = false;
408  $backend->dirty();
409  $this->assertTrue( $priv->dataDirty );
410  }
411 
412  public function testGetData() {
413  $backend = $this->getBackend();
414  $data = $backend->getData();
415  $this->assertSame( [], $data );
416  $this->assertTrue( TestingAccessWrapper::newFromObject( $backend )->dataDirty );
417  $data['???'] = '!!!';
418  $this->assertSame( [ '???' => '!!!' ], $data );
419 
420  $testData = [ 'foo' => 'foo!', 'bar', [ 'baz', null ] ];
421  $this->store->setSessionData( self::SESSIONID, $testData );
422  $backend = $this->getBackend();
423  $this->assertSame( $testData, $backend->getData() );
424  $this->assertFalse( TestingAccessWrapper::newFromObject( $backend )->dataDirty );
425  }
426 
427  public function testAddData() {
428  $backend = $this->getBackend();
429  $priv = TestingAccessWrapper::newFromObject( $backend );
430 
431  $priv->data = [ 'foo' => 1 ];
432  $priv->dataDirty = false;
433  $backend->addData( [ 'foo' => 1 ] );
434  $this->assertSame( [ 'foo' => 1 ], $priv->data );
435  $this->assertFalse( $priv->dataDirty );
436 
437  $priv->data = [ 'foo' => 1 ];
438  $priv->dataDirty = false;
439  $backend->addData( [ 'foo' => '1' ] );
440  $this->assertSame( [ 'foo' => '1' ], $priv->data );
441  $this->assertTrue( $priv->dataDirty );
442 
443  $priv->data = [ 'foo' => 1 ];
444  $priv->dataDirty = false;
445  $backend->addData( [ 'bar' => 2 ] );
446  $this->assertSame( [ 'foo' => 1, 'bar' => 2 ], $priv->data );
447  $this->assertTrue( $priv->dataDirty );
448  }
449 
450  public function testDelaySave() {
451  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
452  $backend = $this->getBackend();
453  $priv = TestingAccessWrapper::newFromObject( $backend );
454  $priv->persist = true;
455 
456  // Saves happen normally when no delay is in effect
457  $this->onSessionMetadataCalled = false;
458  $priv->metaDirty = true;
459  $backend->save();
460  $this->assertTrue( $this->onSessionMetadataCalled, 'sanity check' );
461 
462  $this->onSessionMetadataCalled = false;
463  $priv->metaDirty = true;
464  $priv->autosave();
465  $this->assertTrue( $this->onSessionMetadataCalled, 'sanity check' );
466 
467  $delay = $backend->delaySave();
468 
469  // Autosave doesn't happen when no delay is in effect
470  $this->onSessionMetadataCalled = false;
471  $priv->metaDirty = true;
472  $priv->autosave();
473  $this->assertFalse( $this->onSessionMetadataCalled );
474 
475  // Save still does happen when no delay is in effect
476  $priv->save();
477  $this->assertTrue( $this->onSessionMetadataCalled );
478 
479  // Save happens when delay is consumed
480  $this->onSessionMetadataCalled = false;
481  $priv->metaDirty = true;
482  \Wikimedia\ScopedCallback::consume( $delay );
483  $this->assertTrue( $this->onSessionMetadataCalled );
484 
485  // Test multiple delays
486  $delay1 = $backend->delaySave();
487  $delay2 = $backend->delaySave();
488  $delay3 = $backend->delaySave();
489  $this->onSessionMetadataCalled = false;
490  $priv->metaDirty = true;
491  $priv->autosave();
492  $this->assertFalse( $this->onSessionMetadataCalled );
493  \Wikimedia\ScopedCallback::consume( $delay3 );
494  $this->assertFalse( $this->onSessionMetadataCalled );
495  \Wikimedia\ScopedCallback::consume( $delay1 );
496  $this->assertFalse( $this->onSessionMetadataCalled );
497  \Wikimedia\ScopedCallback::consume( $delay2 );
498  $this->assertTrue( $this->onSessionMetadataCalled );
499  }
500 
501  public function testSave() {
502  $user = static::getTestSysop()->getUser();
503  $this->store = new TestBagOStuff();
504  $testData = [ 'foo' => 'foo!', 'bar', [ 'baz', null ] ];
505 
506  $neverHook = $this->getMockBuilder( __CLASS__ )
507  ->setMethods( [ 'onSessionMetadata' ] )->getMock();
508  $neverHook->expects( $this->never() )->method( 'onSessionMetadata' );
509 
510  $builder = $this->getMockBuilder( \DummySessionProvider::class )
511  ->setMethods( [ 'persistSession', 'unpersistSession' ] );
512 
513  $neverProvider = $builder->getMock();
514  $neverProvider->expects( $this->never() )->method( 'persistSession' );
515  $neverProvider->expects( $this->never() )->method( 'unpersistSession' );
516 
517  // Not persistent or dirty
518  $this->provider = $neverProvider;
519  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $neverHook ] ] );
520  $this->store->setSessionData( self::SESSIONID, $testData );
521  $backend = $this->getBackend( $user );
522  $this->store->deleteSession( self::SESSIONID );
523  $this->assertFalse( $backend->isPersistent(), 'sanity check' );
524  TestingAccessWrapper::newFromObject( $backend )->metaDirty = false;
525  TestingAccessWrapper::newFromObject( $backend )->dataDirty = false;
526  $backend->save();
527  $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'making sure it didn\'t save' );
528 
529  // (but does unpersist if forced)
530  $this->provider = $builder->getMock();
531  $this->provider->expects( $this->never() )->method( 'persistSession' );
532  $this->provider->expects( $this->atLeastOnce() )->method( 'unpersistSession' );
533  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $neverHook ] ] );
534  $this->store->setSessionData( self::SESSIONID, $testData );
535  $backend = $this->getBackend( $user );
536  $this->store->deleteSession( self::SESSIONID );
537  TestingAccessWrapper::newFromObject( $backend )->persist = false;
538  TestingAccessWrapper::newFromObject( $backend )->forcePersist = true;
539  $this->assertFalse( $backend->isPersistent(), 'sanity check' );
540  TestingAccessWrapper::newFromObject( $backend )->metaDirty = false;
541  TestingAccessWrapper::newFromObject( $backend )->dataDirty = false;
542  $backend->save();
543  $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'making sure it didn\'t save' );
544 
545  // (but not to a WebRequest associated with a different session)
546  $this->provider = $neverProvider;
547  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $neverHook ] ] );
548  $this->store->setSessionData( self::SESSIONID, $testData );
549  $backend = $this->getBackend( $user );
550  TestingAccessWrapper::newFromObject( $backend )->requests[100]
551  ->setSessionId( new SessionId( 'x' ) );
552  $this->store->deleteSession( self::SESSIONID );
553  TestingAccessWrapper::newFromObject( $backend )->persist = false;
554  TestingAccessWrapper::newFromObject( $backend )->forcePersist = true;
555  $this->assertFalse( $backend->isPersistent(), 'sanity check' );
556  TestingAccessWrapper::newFromObject( $backend )->metaDirty = false;
557  TestingAccessWrapper::newFromObject( $backend )->dataDirty = false;
558  $backend->save();
559  $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'making sure it didn\'t save' );
560 
561  // Not persistent, but dirty
562  $this->provider = $neverProvider;
563  $this->onSessionMetadataCalled = false;
564  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
565  $this->store->setSessionData( self::SESSIONID, $testData );
566  $backend = $this->getBackend( $user );
567  $this->store->deleteSession( self::SESSIONID );
568  $this->assertFalse( $backend->isPersistent(), 'sanity check' );
569  TestingAccessWrapper::newFromObject( $backend )->metaDirty = false;
570  TestingAccessWrapper::newFromObject( $backend )->dataDirty = true;
571  $backend->save();
572  $this->assertTrue( $this->onSessionMetadataCalled );
573  $blob = $this->store->getSession( self::SESSIONID );
574  $this->assertInternalType( 'array', $blob );
575  $this->assertArrayHasKey( 'metadata', $blob );
576  $metadata = $blob['metadata'];
577  $this->assertInternalType( 'array', $metadata );
578  $this->assertArrayHasKey( '???', $metadata );
579  $this->assertSame( '!!!', $metadata['???'] );
580  $this->assertFalse( $this->store->getSessionFromBackend( self::SESSIONID ),
581  'making sure it didn\'t save to backend' );
582 
583  // Persistent, not dirty
584  $this->provider = $neverProvider;
585  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $neverHook ] ] );
586  $this->store->setSessionData( self::SESSIONID, $testData );
587  $backend = $this->getBackend( $user );
588  $this->store->deleteSession( self::SESSIONID );
589  TestingAccessWrapper::newFromObject( $backend )->persist = true;
590  $this->assertTrue( $backend->isPersistent(), 'sanity check' );
591  TestingAccessWrapper::newFromObject( $backend )->metaDirty = false;
592  TestingAccessWrapper::newFromObject( $backend )->dataDirty = false;
593  $backend->save();
594  $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'making sure it didn\'t save' );
595 
596  // (but will persist if forced)
597  $this->provider = $builder->getMock();
598  $this->provider->expects( $this->atLeastOnce() )->method( 'persistSession' );
599  $this->provider->expects( $this->never() )->method( 'unpersistSession' );
600  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $neverHook ] ] );
601  $this->store->setSessionData( self::SESSIONID, $testData );
602  $backend = $this->getBackend( $user );
603  $this->store->deleteSession( self::SESSIONID );
604  TestingAccessWrapper::newFromObject( $backend )->persist = true;
605  TestingAccessWrapper::newFromObject( $backend )->forcePersist = true;
606  $this->assertTrue( $backend->isPersistent(), 'sanity check' );
607  TestingAccessWrapper::newFromObject( $backend )->metaDirty = false;
608  TestingAccessWrapper::newFromObject( $backend )->dataDirty = false;
609  $backend->save();
610  $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'making sure it didn\'t save' );
611 
612  // Persistent and dirty
613  $this->provider = $neverProvider;
614  $this->onSessionMetadataCalled = false;
615  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
616  $this->store->setSessionData( self::SESSIONID, $testData );
617  $backend = $this->getBackend( $user );
618  $this->store->deleteSession( self::SESSIONID );
619  TestingAccessWrapper::newFromObject( $backend )->persist = true;
620  $this->assertTrue( $backend->isPersistent(), 'sanity check' );
621  TestingAccessWrapper::newFromObject( $backend )->metaDirty = false;
622  TestingAccessWrapper::newFromObject( $backend )->dataDirty = true;
623  $backend->save();
624  $this->assertTrue( $this->onSessionMetadataCalled );
625  $blob = $this->store->getSession( self::SESSIONID );
626  $this->assertInternalType( 'array', $blob );
627  $this->assertArrayHasKey( 'metadata', $blob );
628  $metadata = $blob['metadata'];
629  $this->assertInternalType( 'array', $metadata );
630  $this->assertArrayHasKey( '???', $metadata );
631  $this->assertSame( '!!!', $metadata['???'] );
632  $this->assertNotSame( false, $this->store->getSessionFromBackend( self::SESSIONID ),
633  'making sure it did save to backend' );
634 
635  // (also persists if forced)
636  $this->provider = $builder->getMock();
637  $this->provider->expects( $this->atLeastOnce() )->method( 'persistSession' );
638  $this->provider->expects( $this->never() )->method( 'unpersistSession' );
639  $this->onSessionMetadataCalled = false;
640  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
641  $this->store->setSessionData( self::SESSIONID, $testData );
642  $backend = $this->getBackend( $user );
643  $this->store->deleteSession( self::SESSIONID );
644  TestingAccessWrapper::newFromObject( $backend )->persist = true;
645  TestingAccessWrapper::newFromObject( $backend )->forcePersist = true;
646  $this->assertTrue( $backend->isPersistent(), 'sanity check' );
647  TestingAccessWrapper::newFromObject( $backend )->metaDirty = false;
648  TestingAccessWrapper::newFromObject( $backend )->dataDirty = true;
649  $backend->save();
650  $this->assertTrue( $this->onSessionMetadataCalled );
651  $blob = $this->store->getSession( self::SESSIONID );
652  $this->assertInternalType( 'array', $blob );
653  $this->assertArrayHasKey( 'metadata', $blob );
654  $metadata = $blob['metadata'];
655  $this->assertInternalType( 'array', $metadata );
656  $this->assertArrayHasKey( '???', $metadata );
657  $this->assertSame( '!!!', $metadata['???'] );
658  $this->assertNotSame( false, $this->store->getSessionFromBackend( self::SESSIONID ),
659  'making sure it did save to backend' );
660 
661  // (also persists if metadata dirty)
662  $this->provider = $builder->getMock();
663  $this->provider->expects( $this->atLeastOnce() )->method( 'persistSession' );
664  $this->provider->expects( $this->never() )->method( 'unpersistSession' );
665  $this->onSessionMetadataCalled = false;
666  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
667  $this->store->setSessionData( self::SESSIONID, $testData );
668  $backend = $this->getBackend( $user );
669  $this->store->deleteSession( self::SESSIONID );
670  TestingAccessWrapper::newFromObject( $backend )->persist = true;
671  $this->assertTrue( $backend->isPersistent(), 'sanity check' );
672  TestingAccessWrapper::newFromObject( $backend )->metaDirty = true;
673  TestingAccessWrapper::newFromObject( $backend )->dataDirty = false;
674  $backend->save();
675  $this->assertTrue( $this->onSessionMetadataCalled );
676  $blob = $this->store->getSession( self::SESSIONID );
677  $this->assertInternalType( 'array', $blob );
678  $this->assertArrayHasKey( 'metadata', $blob );
679  $metadata = $blob['metadata'];
680  $this->assertInternalType( 'array', $metadata );
681  $this->assertArrayHasKey( '???', $metadata );
682  $this->assertSame( '!!!', $metadata['???'] );
683  $this->assertNotSame( false, $this->store->getSessionFromBackend( self::SESSIONID ),
684  'making sure it did save to backend' );
685 
686  // Not marked dirty, but dirty data
687  // (e.g. indirect modification from ArrayAccess::offsetGet)
688  $this->provider = $neverProvider;
689  $this->onSessionMetadataCalled = false;
690  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
691  $this->store->setSessionData( self::SESSIONID, $testData );
692  $backend = $this->getBackend( $user );
693  $this->store->deleteSession( self::SESSIONID );
694  TestingAccessWrapper::newFromObject( $backend )->persist = true;
695  $this->assertTrue( $backend->isPersistent(), 'sanity check' );
696  TestingAccessWrapper::newFromObject( $backend )->metaDirty = false;
697  TestingAccessWrapper::newFromObject( $backend )->dataDirty = false;
698  TestingAccessWrapper::newFromObject( $backend )->dataHash = 'Doesn\'t match';
699  $backend->save();
700  $this->assertTrue( $this->onSessionMetadataCalled );
701  $blob = $this->store->getSession( self::SESSIONID );
702  $this->assertInternalType( 'array', $blob );
703  $this->assertArrayHasKey( 'metadata', $blob );
704  $metadata = $blob['metadata'];
705  $this->assertInternalType( 'array', $metadata );
706  $this->assertArrayHasKey( '???', $metadata );
707  $this->assertSame( '!!!', $metadata['???'] );
708  $this->assertNotSame( false, $this->store->getSessionFromBackend( self::SESSIONID ),
709  'making sure it did save to backend' );
710 
711  // Bad hook
712  $this->provider = null;
713  $mockHook = $this->getMockBuilder( __CLASS__ )
714  ->setMethods( [ 'onSessionMetadata' ] )->getMock();
715  $mockHook->expects( $this->any() )->method( 'onSessionMetadata' )
716  ->will( $this->returnCallback(
717  function ( SessionBackend $backend, array &$metadata, array $requests ) {
718  $metadata['userId']++;
719  }
720  ) );
721  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $mockHook ] ] );
722  $this->store->setSessionData( self::SESSIONID, $testData );
723  $backend = $this->getBackend( $user );
724  $backend->dirty();
725  try {
726  $backend->save();
727  $this->fail( 'Expected exception not thrown' );
728  } catch ( \UnexpectedValueException $ex ) {
729  $this->assertSame(
730  'SessionMetadata hook changed metadata key "userId"',
731  $ex->getMessage()
732  );
733  }
734 
735  // SessionManager::preventSessionsForUser
736  TestingAccessWrapper::newFromObject( $this->manager )->preventUsers = [
737  $user->getName() => true,
738  ];
739  $this->provider = $neverProvider;
740  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $neverHook ] ] );
741  $this->store->setSessionData( self::SESSIONID, $testData );
742  $backend = $this->getBackend( $user );
743  $this->store->deleteSession( self::SESSIONID );
744  TestingAccessWrapper::newFromObject( $backend )->persist = true;
745  $this->assertTrue( $backend->isPersistent(), 'sanity check' );
746  TestingAccessWrapper::newFromObject( $backend )->metaDirty = true;
747  TestingAccessWrapper::newFromObject( $backend )->dataDirty = true;
748  $backend->save();
749  $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'making sure it didn\'t save' );
750  }
751 
752  public function testRenew() {
753  $user = static::getTestSysop()->getUser();
754  $this->store = new TestBagOStuff();
755  $testData = [ 'foo' => 'foo!', 'bar', [ 'baz', null ] ];
756 
757  // Not persistent
758  $this->provider = $this->getMockBuilder( \DummySessionProvider::class )
759  ->setMethods( [ 'persistSession' ] )->getMock();
760  $this->provider->expects( $this->never() )->method( 'persistSession' );
761  $this->onSessionMetadataCalled = false;
762  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
763  $this->store->setSessionData( self::SESSIONID, $testData );
764  $backend = $this->getBackend( $user );
765  $this->store->deleteSession( self::SESSIONID );
766  $wrap = TestingAccessWrapper::newFromObject( $backend );
767  $this->assertFalse( $backend->isPersistent(), 'sanity check' );
768  $wrap->metaDirty = false;
769  $wrap->dataDirty = false;
770  $wrap->forcePersist = false;
771  $wrap->expires = 0;
772  $backend->renew();
773  $this->assertTrue( $this->onSessionMetadataCalled );
774  $blob = $this->store->getSession( self::SESSIONID );
775  $this->assertInternalType( 'array', $blob );
776  $this->assertArrayHasKey( 'metadata', $blob );
777  $metadata = $blob['metadata'];
778  $this->assertInternalType( 'array', $metadata );
779  $this->assertArrayHasKey( '???', $metadata );
780  $this->assertSame( '!!!', $metadata['???'] );
781  $this->assertNotEquals( 0, $wrap->expires );
782 
783  // Persistent
784  $this->provider = $this->getMockBuilder( \DummySessionProvider::class )
785  ->setMethods( [ 'persistSession' ] )->getMock();
786  $this->provider->expects( $this->atLeastOnce() )->method( 'persistSession' );
787  $this->onSessionMetadataCalled = false;
788  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
789  $this->store->setSessionData( self::SESSIONID, $testData );
790  $backend = $this->getBackend( $user );
791  $this->store->deleteSession( self::SESSIONID );
792  $wrap = TestingAccessWrapper::newFromObject( $backend );
793  $wrap->persist = true;
794  $this->assertTrue( $backend->isPersistent(), 'sanity check' );
795  $wrap->metaDirty = false;
796  $wrap->dataDirty = false;
797  $wrap->forcePersist = false;
798  $wrap->expires = 0;
799  $backend->renew();
800  $this->assertTrue( $this->onSessionMetadataCalled );
801  $blob = $this->store->getSession( self::SESSIONID );
802  $this->assertInternalType( 'array', $blob );
803  $this->assertArrayHasKey( 'metadata', $blob );
804  $metadata = $blob['metadata'];
805  $this->assertInternalType( 'array', $metadata );
806  $this->assertArrayHasKey( '???', $metadata );
807  $this->assertSame( '!!!', $metadata['???'] );
808  $this->assertNotEquals( 0, $wrap->expires );
809 
810  // Not persistent, not expiring
811  $this->provider = $this->getMockBuilder( \DummySessionProvider::class )
812  ->setMethods( [ 'persistSession' ] )->getMock();
813  $this->provider->expects( $this->never() )->method( 'persistSession' );
814  $this->onSessionMetadataCalled = false;
815  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
816  $this->store->setSessionData( self::SESSIONID, $testData );
817  $backend = $this->getBackend( $user );
818  $this->store->deleteSession( self::SESSIONID );
819  $wrap = TestingAccessWrapper::newFromObject( $backend );
820  $this->assertFalse( $backend->isPersistent(), 'sanity check' );
821  $wrap->metaDirty = false;
822  $wrap->dataDirty = false;
823  $wrap->forcePersist = false;
824  $expires = time() + $wrap->lifetime + 100;
825  $wrap->expires = $expires;
826  $backend->renew();
827  $this->assertFalse( $this->onSessionMetadataCalled );
828  $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'making sure it didn\'t save' );
829  $this->assertEquals( $expires, $wrap->expires );
830  }
831 
832  public function onSessionMetadata( SessionBackend $backend, array &$metadata, array $requests ) {
833  $this->onSessionMetadataCalled = true;
834  $metadata['???'] = '!!!';
835  }
836 
837  public function testTakeOverGlobalSession() {
840  }
841  if ( !PHPSessionHandler::isEnabled() ) {
842  $rProp = new \ReflectionProperty( PHPSessionHandler::class, 'instance' );
843  $rProp->setAccessible( true );
844  $handler = TestingAccessWrapper::newFromObject( $rProp->getValue() );
845  $resetHandler = new \Wikimedia\ScopedCallback( function () use ( $handler ) {
846  session_write_close();
847  $handler->enable = false;
848  } );
849  $handler->enable = true;
850  }
851 
852  $backend = $this->getBackend( static::getTestSysop()->getUser() );
853  TestingAccessWrapper::newFromObject( $backend )->usePhpSessionHandling = true;
854 
855  $resetSingleton = TestUtils::setSessionManagerSingleton( $this->manager );
856 
857  $manager = TestingAccessWrapper::newFromObject( $this->manager );
858  $request = \RequestContext::getMain()->getRequest();
859  $manager->globalSession = $backend->getSession( $request );
860  $manager->globalSessionRequest = $request;
861 
862  session_id( '' );
863  TestingAccessWrapper::newFromObject( $backend )->checkPHPSession();
864  $this->assertSame( $backend->getId(), session_id() );
865  session_write_close();
866 
867  $backend2 = $this->getBackend(
868  User::newFromName( 'UTSysop' ), 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'
869  );
870  TestingAccessWrapper::newFromObject( $backend2 )->usePhpSessionHandling = true;
871 
872  session_id( '' );
873  TestingAccessWrapper::newFromObject( $backend2 )->checkPHPSession();
874  $this->assertSame( '', session_id() );
875  }
876 
877  public function testResetIdOfGlobalSession() {
880  }
881  if ( !PHPSessionHandler::isEnabled() ) {
882  $rProp = new \ReflectionProperty( PHPSessionHandler::class, 'instance' );
883  $rProp->setAccessible( true );
884  $handler = TestingAccessWrapper::newFromObject( $rProp->getValue() );
885  $resetHandler = new \Wikimedia\ScopedCallback( function () use ( $handler ) {
886  session_write_close();
887  $handler->enable = false;
888  } );
889  $handler->enable = true;
890  }
891 
892  $backend = $this->getBackend( User::newFromName( 'UTSysop' ) );
893  TestingAccessWrapper::newFromObject( $backend )->usePhpSessionHandling = true;
894 
895  $resetSingleton = TestUtils::setSessionManagerSingleton( $this->manager );
896 
897  $manager = TestingAccessWrapper::newFromObject( $this->manager );
898  $request = \RequestContext::getMain()->getRequest();
899  $manager->globalSession = $backend->getSession( $request );
900  $manager->globalSessionRequest = $request;
901 
902  session_id( self::SESSIONID );
903  \Wikimedia\quietCall( 'session_start' );
904  $_SESSION['foo'] = __METHOD__;
905  $backend->resetId();
906  $this->assertNotEquals( self::SESSIONID, $backend->getId() );
907  $this->assertSame( $backend->getId(), session_id() );
908  $this->assertArrayHasKey( 'foo', $_SESSION );
909  $this->assertSame( __METHOD__, $_SESSION['foo'] );
910  session_write_close();
911  }
912 
913  public function testUnpersistOfGlobalSession() {
916  }
917  if ( !PHPSessionHandler::isEnabled() ) {
918  $rProp = new \ReflectionProperty( PHPSessionHandler::class, 'instance' );
919  $rProp->setAccessible( true );
920  $handler = TestingAccessWrapper::newFromObject( $rProp->getValue() );
921  $resetHandler = new \Wikimedia\ScopedCallback( function () use ( $handler ) {
922  session_write_close();
923  $handler->enable = false;
924  } );
925  $handler->enable = true;
926  }
927 
928  $backend = $this->getBackend( User::newFromName( 'UTSysop' ) );
929  $wrap = TestingAccessWrapper::newFromObject( $backend );
930  $wrap->usePhpSessionHandling = true;
931  $wrap->persist = true;
932 
933  $resetSingleton = TestUtils::setSessionManagerSingleton( $this->manager );
934 
935  $manager = TestingAccessWrapper::newFromObject( $this->manager );
936  $request = \RequestContext::getMain()->getRequest();
937  $manager->globalSession = $backend->getSession( $request );
938  $manager->globalSessionRequest = $request;
939 
940  session_id( self::SESSIONID . 'x' );
941  \Wikimedia\quietCall( 'session_start' );
942  $backend->unpersist();
943  $this->assertSame( self::SESSIONID . 'x', session_id() );
944  session_write_close();
945 
946  session_id( self::SESSIONID );
947  $wrap->persist = true;
948  $backend->unpersist();
949  $this->assertSame( '', session_id() );
950  }
951 
952  public function testGetAllowedUserRights() {
953  $this->provider = $this->getMockBuilder( \DummySessionProvider::class )
954  ->setMethods( [ 'getAllowedUserRights' ] )
955  ->getMock();
956  $this->provider->expects( $this->any() )->method( 'getAllowedUserRights' )
957  ->will( $this->returnValue( [ 'foo', 'bar' ] ) );
958 
959  $backend = $this->getBackend();
960  $this->assertSame( [ 'foo', 'bar' ], $backend->getAllowedUserRights() );
961  }
962 
963 }
MediaWiki\Session\SessionBackendTest\onSessionMetadata
onSessionMetadata(SessionBackend $backend, array &$metadata, array $requests)
Definition: SessionBackendTest.php:832
$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:901
MediaWiki\Session\SessionBackendTest\testUnpersist
testUnpersist()
Definition: SessionBackendTest.php:325
MediaWiki\Session\SessionBackendTest\SESSIONID
const SESSIONID
Definition: SessionBackendTest.php:16
MediaWiki\Session\SessionBackendTest\testUnpersistOfGlobalSession
testUnpersistOfGlobalSession()
Definition: SessionBackendTest.php:913
MediaWiki\Session\SessionBackendTest\testDelaySave
testDelaySave()
Definition: SessionBackendTest.php:450
MediaWiki\Session\SessionBackendTest\testResetId
testResetId()
Definition: SessionBackendTest.php:267
captcha-old.count
count
Definition: captcha-old.py:249
MediaWiki\Session\SessionBackendTest\testSessionStuff
testSessionStuff()
Definition: SessionBackendTest.php:185
MediaWiki\Session\SessionBackendTest\testSetProviderMetadata
testSetProviderMetadata()
Definition: SessionBackendTest.php:231
MediaWiki\Session\SessionBackendTest\$manager
SessionManager $manager
Definition: SessionBackendTest.php:19
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:877
User\newFromName
static newFromName( $name, $validate='valid')
Static factory method for creation from username.
Definition: User.php:592
MediaWiki\Session\SessionBackendTest\testGetAllowedUserRights
testGetAllowedUserRights()
Definition: SessionBackendTest.php:952
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:15
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
Config
Interface for configuration instances.
Definition: Config.php:28
MediaWiki\Session\SessionBackendTest\testTakeOverGlobalSession
testTakeOverGlobalSession()
Definition: SessionBackendTest.php:837
MediaWiki\Session\SessionProvider
A SessionProvider provides SessionInfo and support for Session.
Definition: SessionProvider.php:78
$blob
$blob
Definition: testCompression.php:65
MediaWikiTestCase
Definition: MediaWikiTestCase.php:16
MediaWiki\Session\SessionBackendTest\testPersist
testPersist()
Definition: SessionBackendTest.php:305
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:367
MediaWiki\Session\SessionManager\singleton
static singleton()
Get the global SessionManager.
Definition: SessionManager.php:92
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\SessionBackend\dirty
dirty()
Mark data as dirty.
Definition: SessionBackend.php:546
MediaWiki\Session
Definition: BotPasswordSessionProvider.php:24
array
The wiki should then use memcached to cache various data To use multiple just add more items to the array To increase the weight of a make its entry a array("192.168.0.1:11211", 2))
MediaWiki\Session\SessionBackendTest\testRememberUser
testRememberUser()
Definition: SessionBackendTest.php:347
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:376
MediaWiki\Session\SessionBackendTest\testSave
testSave()
Definition: SessionBackendTest.php:501
MediaWiki\Session\SessionBackendTest\testConstructor
testConstructor()
Definition: SessionBackendTest.php:88
$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:2683
MediaWiki\Session\SessionBackendTest\$store
TestBagOStuff $store
Definition: SessionBackendTest.php:28
MediaWiki\Session\SessionBackendTest\testRenew
testRenew()
Definition: SessionBackendTest.php:752
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:412
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:50
MediaWiki\Session\SessionBackendTest\testDirty
testDirty()
Definition: SessionBackendTest.php:404
MediaWiki\Session\SessionBackendTest\$config
Config $config
Definition: SessionBackendTest.php:22
$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:813
RequestContext\getMain
static getMain()
Get the RequestContext object associated with the main request.
Definition: RequestContext.php:434
MediaWiki\Session\SessionBackendTest\testForceHTTPS
testForceHTTPS()
Definition: SessionBackendTest.php:357
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:427
$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
MediaWiki\Session\SessionBackendTest\$provider
SessionProvider $provider
Definition: SessionBackendTest.php:25
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:38
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:47
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\$onSessionMetadataCalled
$onSessionMetadataCalled
Definition: SessionBackendTest.php:30
MediaWiki\Session\SessionBackend
This is the actual workhorse for Session.
Definition: SessionBackend.php:49