MediaWiki  1.29.1
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( $wrap->store->get( wfMemcKey( 'MWSession', self::SESSIONID ) ) );
334  }
335 
336  public function testRememberUser() {
337  $backend = $this->getBackend();
338 
339  $remembered = $backend->shouldRememberUser();
340  $backend->setRememberUser( !$remembered );
341  $this->assertNotEquals( $remembered, $backend->shouldRememberUser() );
342  $backend->setRememberUser( $remembered );
343  $this->assertEquals( $remembered, $backend->shouldRememberUser() );
344  }
345 
346  public function testForceHTTPS() {
347  $backend = $this->getBackend();
348 
349  $force = $backend->shouldForceHTTPS();
350  $backend->setForceHTTPS( !$force );
351  $this->assertNotEquals( $force, $backend->shouldForceHTTPS() );
352  $backend->setForceHTTPS( $force );
353  $this->assertEquals( $force, $backend->shouldForceHTTPS() );
354  }
355 
356  public function testLoggedOutTimestamp() {
357  $backend = $this->getBackend();
358 
359  $backend->setLoggedOutTimestamp( 42 );
360  $this->assertSame( 42, $backend->getLoggedOutTimestamp() );
361  $backend->setLoggedOutTimestamp( '123' );
362  $this->assertSame( 123, $backend->getLoggedOutTimestamp() );
363  }
364 
365  public function testSetUser() {
366  $user = static::getTestSysop()->getUser();
367 
368  $this->provider = $this->getMockBuilder( 'DummySessionProvider' )
369  ->setMethods( [ 'canChangeUser' ] )->getMock();
370  $this->provider->expects( $this->any() )->method( 'canChangeUser' )
371  ->will( $this->returnValue( false ) );
372  $backend = $this->getBackend();
373  $this->assertFalse( $backend->canSetUser() );
374  try {
375  $backend->setUser( $user );
376  $this->fail( 'Expected exception not thrown' );
377  } catch ( \BadMethodCallException $ex ) {
378  $this->assertSame(
379  'Cannot set user on this session; check $session->canSetUser() first',
380  $ex->getMessage()
381  );
382  }
383  $this->assertNotSame( $user, $backend->getUser() );
384 
385  $this->provider = null;
386  $backend = $this->getBackend();
387  $this->assertTrue( $backend->canSetUser() );
388  $this->assertNotSame( $user, $backend->getUser(), 'sanity check' );
389  $backend->setUser( $user );
390  $this->assertSame( $user, $backend->getUser() );
391  }
392 
393  public function testDirty() {
394  $backend = $this->getBackend();
395  $priv = TestingAccessWrapper::newFromObject( $backend );
396  $priv->dataDirty = false;
397  $backend->dirty();
398  $this->assertTrue( $priv->dataDirty );
399  }
400 
401  public function testGetData() {
402  $backend = $this->getBackend();
403  $data = $backend->getData();
404  $this->assertSame( [], $data );
405  $this->assertTrue( TestingAccessWrapper::newFromObject( $backend )->dataDirty );
406  $data['???'] = '!!!';
407  $this->assertSame( [ '???' => '!!!' ], $data );
408 
409  $testData = [ 'foo' => 'foo!', 'bar', [ 'baz', null ] ];
410  $this->store->setSessionData( self::SESSIONID, $testData );
411  $backend = $this->getBackend();
412  $this->assertSame( $testData, $backend->getData() );
413  $this->assertFalse( TestingAccessWrapper::newFromObject( $backend )->dataDirty );
414  }
415 
416  public function testAddData() {
417  $backend = $this->getBackend();
418  $priv = TestingAccessWrapper::newFromObject( $backend );
419 
420  $priv->data = [ 'foo' => 1 ];
421  $priv->dataDirty = false;
422  $backend->addData( [ 'foo' => 1 ] );
423  $this->assertSame( [ 'foo' => 1 ], $priv->data );
424  $this->assertFalse( $priv->dataDirty );
425 
426  $priv->data = [ 'foo' => 1 ];
427  $priv->dataDirty = false;
428  $backend->addData( [ 'foo' => '1' ] );
429  $this->assertSame( [ 'foo' => '1' ], $priv->data );
430  $this->assertTrue( $priv->dataDirty );
431 
432  $priv->data = [ 'foo' => 1 ];
433  $priv->dataDirty = false;
434  $backend->addData( [ 'bar' => 2 ] );
435  $this->assertSame( [ 'foo' => 1, 'bar' => 2 ], $priv->data );
436  $this->assertTrue( $priv->dataDirty );
437  }
438 
439  public function testDelaySave() {
440  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
441  $backend = $this->getBackend();
442  $priv = TestingAccessWrapper::newFromObject( $backend );
443  $priv->persist = true;
444 
445  // Saves happen normally when no delay is in effect
446  $this->onSessionMetadataCalled = false;
447  $priv->metaDirty = true;
448  $backend->save();
449  $this->assertTrue( $this->onSessionMetadataCalled, 'sanity check' );
450 
451  $this->onSessionMetadataCalled = false;
452  $priv->metaDirty = true;
453  $priv->autosave();
454  $this->assertTrue( $this->onSessionMetadataCalled, 'sanity check' );
455 
456  $delay = $backend->delaySave();
457 
458  // Autosave doesn't happen when no delay is in effect
459  $this->onSessionMetadataCalled = false;
460  $priv->metaDirty = true;
461  $priv->autosave();
462  $this->assertFalse( $this->onSessionMetadataCalled );
463 
464  // Save still does happen when no delay is in effect
465  $priv->save();
466  $this->assertTrue( $this->onSessionMetadataCalled );
467 
468  // Save happens when delay is consumed
469  $this->onSessionMetadataCalled = false;
470  $priv->metaDirty = true;
471  \Wikimedia\ScopedCallback::consume( $delay );
472  $this->assertTrue( $this->onSessionMetadataCalled );
473 
474  // Test multiple delays
475  $delay1 = $backend->delaySave();
476  $delay2 = $backend->delaySave();
477  $delay3 = $backend->delaySave();
478  $this->onSessionMetadataCalled = false;
479  $priv->metaDirty = true;
480  $priv->autosave();
481  $this->assertFalse( $this->onSessionMetadataCalled );
482  \Wikimedia\ScopedCallback::consume( $delay3 );
483  $this->assertFalse( $this->onSessionMetadataCalled );
484  \Wikimedia\ScopedCallback::consume( $delay1 );
485  $this->assertFalse( $this->onSessionMetadataCalled );
486  \Wikimedia\ScopedCallback::consume( $delay2 );
487  $this->assertTrue( $this->onSessionMetadataCalled );
488  }
489 
490  public function testSave() {
491  $user = static::getTestSysop()->getUser();
492  $this->store = new TestBagOStuff();
493  $testData = [ 'foo' => 'foo!', 'bar', [ 'baz', null ] ];
494 
495  $neverHook = $this->getMockBuilder( __CLASS__ )
496  ->setMethods( [ 'onSessionMetadata' ] )->getMock();
497  $neverHook->expects( $this->never() )->method( 'onSessionMetadata' );
498 
499  $builder = $this->getMockBuilder( 'DummySessionProvider' )
500  ->setMethods( [ 'persistSession', 'unpersistSession' ] );
501 
502  $neverProvider = $builder->getMock();
503  $neverProvider->expects( $this->never() )->method( 'persistSession' );
504  $neverProvider->expects( $this->never() )->method( 'unpersistSession' );
505 
506  // Not persistent or dirty
507  $this->provider = $neverProvider;
508  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $neverHook ] ] );
509  $this->store->setSessionData( self::SESSIONID, $testData );
510  $backend = $this->getBackend( $user );
511  $this->store->deleteSession( self::SESSIONID );
512  $this->assertFalse( $backend->isPersistent(), 'sanity check' );
513  TestingAccessWrapper::newFromObject( $backend )->metaDirty = false;
514  TestingAccessWrapper::newFromObject( $backend )->dataDirty = false;
515  $backend->save();
516  $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'making sure it didn\'t save' );
517 
518  // (but does unpersist if forced)
519  $this->provider = $builder->getMock();
520  $this->provider->expects( $this->never() )->method( 'persistSession' );
521  $this->provider->expects( $this->atLeastOnce() )->method( 'unpersistSession' );
522  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $neverHook ] ] );
523  $this->store->setSessionData( self::SESSIONID, $testData );
524  $backend = $this->getBackend( $user );
525  $this->store->deleteSession( self::SESSIONID );
526  TestingAccessWrapper::newFromObject( $backend )->persist = false;
527  TestingAccessWrapper::newFromObject( $backend )->forcePersist = true;
528  $this->assertFalse( $backend->isPersistent(), 'sanity check' );
529  TestingAccessWrapper::newFromObject( $backend )->metaDirty = false;
530  TestingAccessWrapper::newFromObject( $backend )->dataDirty = false;
531  $backend->save();
532  $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'making sure it didn\'t save' );
533 
534  // (but not to a WebRequest associated with a different session)
535  $this->provider = $neverProvider;
536  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $neverHook ] ] );
537  $this->store->setSessionData( self::SESSIONID, $testData );
538  $backend = $this->getBackend( $user );
539  TestingAccessWrapper::newFromObject( $backend )->requests[100]
540  ->setSessionId( new SessionId( 'x' ) );
541  $this->store->deleteSession( self::SESSIONID );
542  TestingAccessWrapper::newFromObject( $backend )->persist = false;
543  TestingAccessWrapper::newFromObject( $backend )->forcePersist = true;
544  $this->assertFalse( $backend->isPersistent(), 'sanity check' );
545  TestingAccessWrapper::newFromObject( $backend )->metaDirty = false;
546  TestingAccessWrapper::newFromObject( $backend )->dataDirty = false;
547  $backend->save();
548  $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'making sure it didn\'t save' );
549 
550  // Not persistent, but dirty
551  $this->provider = $neverProvider;
552  $this->onSessionMetadataCalled = false;
553  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
554  $this->store->setSessionData( self::SESSIONID, $testData );
555  $backend = $this->getBackend( $user );
556  $this->store->deleteSession( self::SESSIONID );
557  $this->assertFalse( $backend->isPersistent(), 'sanity check' );
558  TestingAccessWrapper::newFromObject( $backend )->metaDirty = false;
559  TestingAccessWrapper::newFromObject( $backend )->dataDirty = true;
560  $backend->save();
561  $this->assertTrue( $this->onSessionMetadataCalled );
562  $blob = $this->store->getSession( self::SESSIONID );
563  $this->assertInternalType( 'array', $blob );
564  $this->assertArrayHasKey( 'metadata', $blob );
565  $metadata = $blob['metadata'];
566  $this->assertInternalType( 'array', $metadata );
567  $this->assertArrayHasKey( '???', $metadata );
568  $this->assertSame( '!!!', $metadata['???'] );
569  $this->assertFalse( $this->store->getSessionFromBackend( self::SESSIONID ),
570  'making sure it didn\'t save to backend' );
571 
572  // Persistent, not dirty
573  $this->provider = $neverProvider;
574  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $neverHook ] ] );
575  $this->store->setSessionData( self::SESSIONID, $testData );
576  $backend = $this->getBackend( $user );
577  $this->store->deleteSession( self::SESSIONID );
578  TestingAccessWrapper::newFromObject( $backend )->persist = true;
579  $this->assertTrue( $backend->isPersistent(), 'sanity check' );
580  TestingAccessWrapper::newFromObject( $backend )->metaDirty = false;
581  TestingAccessWrapper::newFromObject( $backend )->dataDirty = false;
582  $backend->save();
583  $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'making sure it didn\'t save' );
584 
585  // (but will persist if forced)
586  $this->provider = $builder->getMock();
587  $this->provider->expects( $this->atLeastOnce() )->method( 'persistSession' );
588  $this->provider->expects( $this->never() )->method( 'unpersistSession' );
589  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $neverHook ] ] );
590  $this->store->setSessionData( self::SESSIONID, $testData );
591  $backend = $this->getBackend( $user );
592  $this->store->deleteSession( self::SESSIONID );
593  TestingAccessWrapper::newFromObject( $backend )->persist = true;
594  TestingAccessWrapper::newFromObject( $backend )->forcePersist = true;
595  $this->assertTrue( $backend->isPersistent(), 'sanity check' );
596  TestingAccessWrapper::newFromObject( $backend )->metaDirty = false;
597  TestingAccessWrapper::newFromObject( $backend )->dataDirty = false;
598  $backend->save();
599  $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'making sure it didn\'t save' );
600 
601  // Persistent and dirty
602  $this->provider = $neverProvider;
603  $this->onSessionMetadataCalled = false;
604  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
605  $this->store->setSessionData( self::SESSIONID, $testData );
606  $backend = $this->getBackend( $user );
607  $this->store->deleteSession( self::SESSIONID );
608  TestingAccessWrapper::newFromObject( $backend )->persist = true;
609  $this->assertTrue( $backend->isPersistent(), 'sanity check' );
610  TestingAccessWrapper::newFromObject( $backend )->metaDirty = false;
611  TestingAccessWrapper::newFromObject( $backend )->dataDirty = true;
612  $backend->save();
613  $this->assertTrue( $this->onSessionMetadataCalled );
614  $blob = $this->store->getSession( self::SESSIONID );
615  $this->assertInternalType( 'array', $blob );
616  $this->assertArrayHasKey( 'metadata', $blob );
617  $metadata = $blob['metadata'];
618  $this->assertInternalType( 'array', $metadata );
619  $this->assertArrayHasKey( '???', $metadata );
620  $this->assertSame( '!!!', $metadata['???'] );
621  $this->assertNotSame( false, $this->store->getSessionFromBackend( self::SESSIONID ),
622  'making sure it did save to backend' );
623 
624  // (also persists if forced)
625  $this->provider = $builder->getMock();
626  $this->provider->expects( $this->atLeastOnce() )->method( 'persistSession' );
627  $this->provider->expects( $this->never() )->method( 'unpersistSession' );
628  $this->onSessionMetadataCalled = false;
629  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
630  $this->store->setSessionData( self::SESSIONID, $testData );
631  $backend = $this->getBackend( $user );
632  $this->store->deleteSession( self::SESSIONID );
633  TestingAccessWrapper::newFromObject( $backend )->persist = true;
634  TestingAccessWrapper::newFromObject( $backend )->forcePersist = true;
635  $this->assertTrue( $backend->isPersistent(), 'sanity check' );
636  TestingAccessWrapper::newFromObject( $backend )->metaDirty = false;
637  TestingAccessWrapper::newFromObject( $backend )->dataDirty = true;
638  $backend->save();
639  $this->assertTrue( $this->onSessionMetadataCalled );
640  $blob = $this->store->getSession( self::SESSIONID );
641  $this->assertInternalType( 'array', $blob );
642  $this->assertArrayHasKey( 'metadata', $blob );
643  $metadata = $blob['metadata'];
644  $this->assertInternalType( 'array', $metadata );
645  $this->assertArrayHasKey( '???', $metadata );
646  $this->assertSame( '!!!', $metadata['???'] );
647  $this->assertNotSame( false, $this->store->getSessionFromBackend( self::SESSIONID ),
648  'making sure it did save to backend' );
649 
650  // (also persists if metadata dirty)
651  $this->provider = $builder->getMock();
652  $this->provider->expects( $this->atLeastOnce() )->method( 'persistSession' );
653  $this->provider->expects( $this->never() )->method( 'unpersistSession' );
654  $this->onSessionMetadataCalled = false;
655  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
656  $this->store->setSessionData( self::SESSIONID, $testData );
657  $backend = $this->getBackend( $user );
658  $this->store->deleteSession( self::SESSIONID );
659  TestingAccessWrapper::newFromObject( $backend )->persist = true;
660  $this->assertTrue( $backend->isPersistent(), 'sanity check' );
661  TestingAccessWrapper::newFromObject( $backend )->metaDirty = true;
662  TestingAccessWrapper::newFromObject( $backend )->dataDirty = false;
663  $backend->save();
664  $this->assertTrue( $this->onSessionMetadataCalled );
665  $blob = $this->store->getSession( self::SESSIONID );
666  $this->assertInternalType( 'array', $blob );
667  $this->assertArrayHasKey( 'metadata', $blob );
668  $metadata = $blob['metadata'];
669  $this->assertInternalType( 'array', $metadata );
670  $this->assertArrayHasKey( '???', $metadata );
671  $this->assertSame( '!!!', $metadata['???'] );
672  $this->assertNotSame( false, $this->store->getSessionFromBackend( self::SESSIONID ),
673  'making sure it did save to backend' );
674 
675  // Not marked dirty, but dirty data
676  // (e.g. indirect modification from ArrayAccess::offsetGet)
677  $this->provider = $neverProvider;
678  $this->onSessionMetadataCalled = false;
679  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
680  $this->store->setSessionData( self::SESSIONID, $testData );
681  $backend = $this->getBackend( $user );
682  $this->store->deleteSession( self::SESSIONID );
683  TestingAccessWrapper::newFromObject( $backend )->persist = true;
684  $this->assertTrue( $backend->isPersistent(), 'sanity check' );
685  TestingAccessWrapper::newFromObject( $backend )->metaDirty = false;
686  TestingAccessWrapper::newFromObject( $backend )->dataDirty = false;
687  TestingAccessWrapper::newFromObject( $backend )->dataHash = 'Doesn\'t match';
688  $backend->save();
689  $this->assertTrue( $this->onSessionMetadataCalled );
690  $blob = $this->store->getSession( self::SESSIONID );
691  $this->assertInternalType( 'array', $blob );
692  $this->assertArrayHasKey( 'metadata', $blob );
693  $metadata = $blob['metadata'];
694  $this->assertInternalType( 'array', $metadata );
695  $this->assertArrayHasKey( '???', $metadata );
696  $this->assertSame( '!!!', $metadata['???'] );
697  $this->assertNotSame( false, $this->store->getSessionFromBackend( self::SESSIONID ),
698  'making sure it did save to backend' );
699 
700  // Bad hook
701  $this->provider = null;
702  $mockHook = $this->getMockBuilder( __CLASS__ )
703  ->setMethods( [ 'onSessionMetadata' ] )->getMock();
704  $mockHook->expects( $this->any() )->method( 'onSessionMetadata' )
705  ->will( $this->returnCallback(
706  function ( SessionBackend $backend, array &$metadata, array $requests ) {
707  $metadata['userId']++;
708  }
709  ) );
710  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $mockHook ] ] );
711  $this->store->setSessionData( self::SESSIONID, $testData );
712  $backend = $this->getBackend( $user );
713  $backend->dirty();
714  try {
715  $backend->save();
716  $this->fail( 'Expected exception not thrown' );
717  } catch ( \UnexpectedValueException $ex ) {
718  $this->assertSame(
719  'SessionMetadata hook changed metadata key "userId"',
720  $ex->getMessage()
721  );
722  }
723 
724  // SessionManager::preventSessionsForUser
725  TestingAccessWrapper::newFromObject( $this->manager )->preventUsers = [
726  $user->getName() => true,
727  ];
728  $this->provider = $neverProvider;
729  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $neverHook ] ] );
730  $this->store->setSessionData( self::SESSIONID, $testData );
731  $backend = $this->getBackend( $user );
732  $this->store->deleteSession( self::SESSIONID );
733  TestingAccessWrapper::newFromObject( $backend )->persist = true;
734  $this->assertTrue( $backend->isPersistent(), 'sanity check' );
735  TestingAccessWrapper::newFromObject( $backend )->metaDirty = true;
736  TestingAccessWrapper::newFromObject( $backend )->dataDirty = true;
737  $backend->save();
738  $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'making sure it didn\'t save' );
739  }
740 
741  public function testRenew() {
742  $user = static::getTestSysop()->getUser();
743  $this->store = new TestBagOStuff();
744  $testData = [ 'foo' => 'foo!', 'bar', [ 'baz', null ] ];
745 
746  // Not persistent
747  $this->provider = $this->getMockBuilder( 'DummySessionProvider' )
748  ->setMethods( [ 'persistSession' ] )->getMock();
749  $this->provider->expects( $this->never() )->method( 'persistSession' );
750  $this->onSessionMetadataCalled = false;
751  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
752  $this->store->setSessionData( self::SESSIONID, $testData );
753  $backend = $this->getBackend( $user );
754  $this->store->deleteSession( self::SESSIONID );
755  $wrap = TestingAccessWrapper::newFromObject( $backend );
756  $this->assertFalse( $backend->isPersistent(), 'sanity check' );
757  $wrap->metaDirty = false;
758  $wrap->dataDirty = false;
759  $wrap->forcePersist = false;
760  $wrap->expires = 0;
761  $backend->renew();
762  $this->assertTrue( $this->onSessionMetadataCalled );
763  $blob = $this->store->getSession( self::SESSIONID );
764  $this->assertInternalType( 'array', $blob );
765  $this->assertArrayHasKey( 'metadata', $blob );
766  $metadata = $blob['metadata'];
767  $this->assertInternalType( 'array', $metadata );
768  $this->assertArrayHasKey( '???', $metadata );
769  $this->assertSame( '!!!', $metadata['???'] );
770  $this->assertNotEquals( 0, $wrap->expires );
771 
772  // Persistent
773  $this->provider = $this->getMockBuilder( 'DummySessionProvider' )
774  ->setMethods( [ 'persistSession' ] )->getMock();
775  $this->provider->expects( $this->atLeastOnce() )->method( 'persistSession' );
776  $this->onSessionMetadataCalled = false;
777  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
778  $this->store->setSessionData( self::SESSIONID, $testData );
779  $backend = $this->getBackend( $user );
780  $this->store->deleteSession( self::SESSIONID );
781  $wrap = TestingAccessWrapper::newFromObject( $backend );
782  $wrap->persist = true;
783  $this->assertTrue( $backend->isPersistent(), 'sanity check' );
784  $wrap->metaDirty = false;
785  $wrap->dataDirty = false;
786  $wrap->forcePersist = false;
787  $wrap->expires = 0;
788  $backend->renew();
789  $this->assertTrue( $this->onSessionMetadataCalled );
790  $blob = $this->store->getSession( self::SESSIONID );
791  $this->assertInternalType( 'array', $blob );
792  $this->assertArrayHasKey( 'metadata', $blob );
793  $metadata = $blob['metadata'];
794  $this->assertInternalType( 'array', $metadata );
795  $this->assertArrayHasKey( '???', $metadata );
796  $this->assertSame( '!!!', $metadata['???'] );
797  $this->assertNotEquals( 0, $wrap->expires );
798 
799  // Not persistent, not expiring
800  $this->provider = $this->getMockBuilder( 'DummySessionProvider' )
801  ->setMethods( [ 'persistSession' ] )->getMock();
802  $this->provider->expects( $this->never() )->method( 'persistSession' );
803  $this->onSessionMetadataCalled = false;
804  $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SessionMetadata' => [ $this ] ] );
805  $this->store->setSessionData( self::SESSIONID, $testData );
806  $backend = $this->getBackend( $user );
807  $this->store->deleteSession( self::SESSIONID );
808  $wrap = TestingAccessWrapper::newFromObject( $backend );
809  $this->assertFalse( $backend->isPersistent(), 'sanity check' );
810  $wrap->metaDirty = false;
811  $wrap->dataDirty = false;
812  $wrap->forcePersist = false;
813  $expires = time() + $wrap->lifetime + 100;
814  $wrap->expires = $expires;
815  $backend->renew();
816  $this->assertFalse( $this->onSessionMetadataCalled );
817  $this->assertFalse( $this->store->getSession( self::SESSIONID ), 'making sure it didn\'t save' );
818  $this->assertEquals( $expires, $wrap->expires );
819  }
820 
821  public function onSessionMetadata( SessionBackend $backend, array &$metadata, array $requests ) {
822  $this->onSessionMetadataCalled = true;
823  $metadata['???'] = '!!!';
824  }
825 
826  public function testTakeOverGlobalSession() {
829  }
830  if ( !PHPSessionHandler::isEnabled() ) {
831  $rProp = new \ReflectionProperty( PHPSessionHandler::class, 'instance' );
832  $rProp->setAccessible( true );
833  $handler = TestingAccessWrapper::newFromObject( $rProp->getValue() );
834  $resetHandler = new \Wikimedia\ScopedCallback( function () use ( $handler ) {
835  session_write_close();
836  $handler->enable = false;
837  } );
838  $handler->enable = true;
839  }
840 
841  $backend = $this->getBackend( static::getTestSysop()->getUser() );
842  TestingAccessWrapper::newFromObject( $backend )->usePhpSessionHandling = true;
843 
844  $resetSingleton = TestUtils::setSessionManagerSingleton( $this->manager );
845 
846  $manager = TestingAccessWrapper::newFromObject( $this->manager );
847  $request = \RequestContext::getMain()->getRequest();
848  $manager->globalSession = $backend->getSession( $request );
849  $manager->globalSessionRequest = $request;
850 
851  session_id( '' );
852  TestingAccessWrapper::newFromObject( $backend )->checkPHPSession();
853  $this->assertSame( $backend->getId(), session_id() );
854  session_write_close();
855 
856  $backend2 = $this->getBackend(
857  User::newFromName( 'UTSysop' ), 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'
858  );
859  TestingAccessWrapper::newFromObject( $backend2 )->usePhpSessionHandling = true;
860 
861  session_id( '' );
862  TestingAccessWrapper::newFromObject( $backend2 )->checkPHPSession();
863  $this->assertSame( '', session_id() );
864  }
865 
866  public function testResetIdOfGlobalSession() {
869  }
870  if ( !PHPSessionHandler::isEnabled() ) {
871  $rProp = new \ReflectionProperty( PHPSessionHandler::class, 'instance' );
872  $rProp->setAccessible( true );
873  $handler = TestingAccessWrapper::newFromObject( $rProp->getValue() );
874  $resetHandler = new \Wikimedia\ScopedCallback( function () use ( $handler ) {
875  session_write_close();
876  $handler->enable = false;
877  } );
878  $handler->enable = true;
879  }
880 
881  $backend = $this->getBackend( User::newFromName( 'UTSysop' ) );
882  TestingAccessWrapper::newFromObject( $backend )->usePhpSessionHandling = true;
883 
884  $resetSingleton = TestUtils::setSessionManagerSingleton( $this->manager );
885 
886  $manager = TestingAccessWrapper::newFromObject( $this->manager );
887  $request = \RequestContext::getMain()->getRequest();
888  $manager->globalSession = $backend->getSession( $request );
889  $manager->globalSessionRequest = $request;
890 
891  session_id( self::SESSIONID );
892  \MediaWiki\quietCall( 'session_start' );
893  $_SESSION['foo'] = __METHOD__;
894  $backend->resetId();
895  $this->assertNotEquals( self::SESSIONID, $backend->getId() );
896  $this->assertSame( $backend->getId(), session_id() );
897  $this->assertArrayHasKey( 'foo', $_SESSION );
898  $this->assertSame( __METHOD__, $_SESSION['foo'] );
899  session_write_close();
900  }
901 
902  public function testUnpersistOfGlobalSession() {
905  }
906  if ( !PHPSessionHandler::isEnabled() ) {
907  $rProp = new \ReflectionProperty( PHPSessionHandler::class, 'instance' );
908  $rProp->setAccessible( true );
909  $handler = TestingAccessWrapper::newFromObject( $rProp->getValue() );
910  $resetHandler = new \Wikimedia\ScopedCallback( function () use ( $handler ) {
911  session_write_close();
912  $handler->enable = false;
913  } );
914  $handler->enable = true;
915  }
916 
917  $backend = $this->getBackend( User::newFromName( 'UTSysop' ) );
918  $wrap = TestingAccessWrapper::newFromObject( $backend );
919  $wrap->usePhpSessionHandling = true;
920  $wrap->persist = true;
921 
922  $resetSingleton = TestUtils::setSessionManagerSingleton( $this->manager );
923 
924  $manager = TestingAccessWrapper::newFromObject( $this->manager );
925  $request = \RequestContext::getMain()->getRequest();
926  $manager->globalSession = $backend->getSession( $request );
927  $manager->globalSessionRequest = $request;
928 
929  session_id( self::SESSIONID . 'x' );
930  \MediaWiki\quietCall( 'session_start' );
931  $backend->unpersist();
932  $this->assertSame( self::SESSIONID . 'x', session_id() );
933 
934  session_id( self::SESSIONID );
935  $wrap->persist = true;
936  $backend->unpersist();
937  $this->assertSame( '', session_id() );
938  }
939 
940  public function testGetAllowedUserRights() {
941  $this->provider = $this->getMockBuilder( 'DummySessionProvider' )
942  ->setMethods( [ 'getAllowedUserRights' ] )
943  ->getMock();
944  $this->provider->expects( $this->any() )->method( 'getAllowedUserRights' )
945  ->will( $this->returnValue( [ 'foo', 'bar' ] ) );
946 
947  $backend = $this->getBackend();
948  $this->assertSame( [ 'foo', 'bar' ], $backend->getAllowedUserRights() );
949  }
950 
951 }
MediaWiki\Session\SessionBackendTest\onSessionMetadata
onSessionMetadata(SessionBackend $backend, array &$metadata, array $requests)
Definition: SessionBackendTest.php:821
MediaWiki\Session\PHPSessionHandler\install
static install(SessionManager $manager)
Install a session handler for the current web request.
Definition: PHPSessionHandler.php:108
$request
error also a ContextSource you ll probably need to make sure the header is varied on $request
Definition: hooks.txt:2612
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:766
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:902
MediaWiki\Session\SessionBackendTest\testDelaySave
testDelaySave()
Definition: SessionBackendTest.php:439
MediaWiki\Session\SessionBackendTest\testResetId
testResetId()
Definition: SessionBackendTest.php:258
captcha-old.count
count
Definition: captcha-old.py:225
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
$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:246
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:866
User\newFromName
static newFromName( $name, $validate='valid')
Static factory method for creation from username.
Definition: User.php:556
MediaWiki\Session\SessionBackendTest\testGetAllowedUserRights
testGetAllowedUserRights()
Definition: SessionBackendTest.php:940
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
wfMemcKey
wfMemcKey()
Make a cache key for the local wiki.
Definition: GlobalFunctions.php:2961
MediaWiki\Session\SessionBackendTest\testTakeOverGlobalSession
testTakeOverGlobalSession()
Definition: SessionBackendTest.php:826
$blob
$blob
Definition: testCompression.php:63
MediaWikiTestCase
Definition: MediaWikiTestCase.php:13
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:356
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:336
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:177
MediaWiki\Session\SessionBackendTest\testSetUser
testSetUser()
Definition: SessionBackendTest.php:365
MediaWiki\Session\SessionBackendTest\testSave
testSave()
Definition: SessionBackendTest.php:490
MediaWiki\Session\SessionBackendTest\testConstructor
testConstructor()
Definition: SessionBackendTest.php:79
MediaWiki\Session\SessionBackendTest\testRenew
testRenew()
Definition: SessionBackendTest.php:741
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:401
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:393
$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:783
RequestContext\getMain
static getMain()
Static methods.
Definition: RequestContext.php:468
MediaWiki\Session\SessionBackendTest\testForceHTTPS
testForceHTTPS()
Definition: SessionBackendTest.php:346
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:416
$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:306
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:50
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