3 namespace MediaWiki\Session
;
8 use Wikimedia\TestingAccessWrapper
;
12 * @covers MediaWiki\Session\Session
14 class SessionTest
extends MediaWikiTestCase
{
16 public function testClear() {
17 $session = TestUtils
::getDummySession();
18 $priv = TestingAccessWrapper
::newFromObject( $session );
20 $backend = $this->getMockBuilder( DummySessionBackend
::class )
21 ->setMethods( [ 'canSetUser', 'setUser', 'save' ] )
23 $backend->expects( $this->once() )->method( 'canSetUser' )
24 ->will( $this->returnValue( true ) );
25 $backend->expects( $this->once() )->method( 'setUser' )
26 ->with( $this->callback( function ( $user ) {
27 return $user instanceof User
&& $user->isAnon();
29 $backend->expects( $this->once() )->method( 'save' );
30 $priv->backend
= $backend;
32 $this->assertSame( [], $backend->data
);
33 $this->assertTrue( $backend->dirty
);
35 $backend = $this->getMockBuilder( DummySessionBackend
::class )
36 ->setMethods( [ 'canSetUser', 'setUser', 'save' ] )
39 $backend->expects( $this->once() )->method( 'canSetUser' )
40 ->will( $this->returnValue( true ) );
41 $backend->expects( $this->once() )->method( 'setUser' )
42 ->with( $this->callback( function ( $user ) {
43 return $user instanceof User
&& $user->isAnon();
45 $backend->expects( $this->once() )->method( 'save' );
46 $priv->backend
= $backend;
48 $this->assertFalse( $backend->dirty
);
50 $backend = $this->getMockBuilder( DummySessionBackend
::class )
51 ->setMethods( [ 'canSetUser', 'setUser', 'save' ] )
53 $backend->expects( $this->once() )->method( 'canSetUser' )
54 ->will( $this->returnValue( false ) );
55 $backend->expects( $this->never() )->method( 'setUser' );
56 $backend->expects( $this->once() )->method( 'save' );
57 $priv->backend
= $backend;
59 $this->assertSame( [], $backend->data
);
60 $this->assertTrue( $backend->dirty
);
63 public function testSecrets() {
64 $logger = new \TestLogger
;
65 $session = TestUtils
::getDummySession( null, -1, $logger );
68 $this->assertEquals( 'defaulted', $session->getSecret( 'test', 'defaulted' ) );
71 $session->set( 'test', 'foobar' );
72 $logger->setCollect( true );
73 $this->assertEquals( 'defaulted', $session->getSecret( 'test', 'defaulted' ) );
74 $logger->setCollect( false );
76 [ LogLevel
::WARNING
, 'Invalid sealed-secret format' ]
77 ], $logger->getBuffer() );
78 $logger->clearBuffer();
81 $session->setSecret( 'test', 'foobar' );
82 $encrypted = $session->get( 'test' );
83 $session->set( 'test', $encrypted . 'x' );
84 $logger->setCollect( true );
85 $this->assertEquals( 'defaulted', $session->getSecret( 'test', 'defaulted' ) );
86 $logger->setCollect( false );
88 [ LogLevel
::WARNING
, 'Sealed secret has been tampered with, aborting.' ]
89 ], $logger->getBuffer() );
90 $logger->clearBuffer();
92 // Unserializable data
93 $iv = random_bytes( 16 );
94 list( $encKey, $hmacKey ) = TestingAccessWrapper
::newFromObject( $session )->getSecretKeys();
95 $ciphertext = openssl_encrypt( 'foobar', 'aes-256-ctr', $encKey, OPENSSL_RAW_DATA
, $iv );
96 $sealed = base64_encode( $iv ) . '.' . base64_encode( $ciphertext );
97 $hmac = hash_hmac( 'sha256', $sealed, $hmacKey, true );
98 $encrypted = base64_encode( $hmac ) . '.' . $sealed;
99 $session->set( 'test', $encrypted );
100 \Wikimedia\
suppressWarnings();
101 $this->assertEquals( 'defaulted', $session->getSecret( 'test', 'defaulted' ) );
102 \Wikimedia\restoreWarnings
();
106 * @dataProvider provideSecretsRoundTripping
109 public function testSecretsRoundTripping( $data ) {
110 $session = TestUtils
::getDummySession();
113 $session->setSecret( 'secret', $data );
114 $this->assertNotEquals( $data, $session->get( 'secret' ) );
115 $this->assertEquals( $data, $session->getSecret( 'secret', 'defaulted' ) );
118 public static function provideSecretsRoundTripping() {
122 [ [ 'foo', 'bar' => 'baz', 'subarray' => [ 1, 2, 3 ] ] ],
123 [ (object)[ 'foo', 'bar' => 'baz', 'subarray' => [ 1, 2, 3 ] ] ],