8 use Wikimedia\TestingAccessWrapper;
18 TestingAccessWrapper::newFromObject( $backend )->requests = [ -1 =>
'dummy' ];
19 TestingAccessWrapper::newFromObject( $backend )->id =
new SessionId(
'abc' );
22 $priv = TestingAccessWrapper::newFromObject( $session );
23 $this->assertSame( $backend, $priv->backend );
24 $this->assertSame( 42, $priv->index );
27 $priv2 = TestingAccessWrapper::newFromObject( $session->sessionWithRequest(
$request ) );
28 $this->assertSame( $backend, $priv2->backend );
29 $this->assertNotSame( $priv->index, $priv2->index );
30 $this->assertSame(
$request, $priv2->getRequest() );
42 ->setMethods( [ $m,
'deregisterSession' ] )
44 $mock->expects( $this->once() )->method(
'deregisterSession' )
45 ->with( $this->identicalTo( 42 ) );
47 $tmp = $mock->expects( $this->once() )->method( $m );
50 $expectArgs[] = $this->identicalTo( 42 );
53 $expectArgs[] = $this->identicalTo( $arg );
55 $tmp = call_user_func_array( [ $tmp,
'with' ], $expectArgs );
57 $retval = new \stdClass;
58 $tmp->will( $this->returnValue( $retval ) );
63 $this->assertSame( $retval, call_user_func_array( [ $session, $m ],
$args ) );
65 $this->assertNull( call_user_func_array( [ $session, $m ],
$args ) );
74 [
'getId', [],
false,
true ],
75 [
'getSessionId', [],
false,
true ],
76 [
'resetId', [],
false,
true ],
77 [
'getProvider', [],
false,
true ],
78 [
'isPersistent', [],
false,
true ],
79 [
'persist', [],
false,
false ],
80 [
'unpersist', [],
false,
false ],
81 [
'shouldRememberUser', [],
false,
true ],
82 [
'setRememberUser', [
true ],
false,
false ],
83 [
'getRequest', [],
true,
true ],
84 [
'getUser', [],
false,
true ],
85 [
'getAllowedUserRights', [],
false,
true ],
86 [
'canSetUser', [],
false,
true ],
87 [
'setUser', [ new \stdClass ],
false,
false ],
88 [
'suggestLoginUsername', [],
true,
true ],
89 [
'shouldForceHTTPS', [],
false,
true ],
90 [
'setForceHTTPS', [
true ],
false,
false ],
91 [
'getLoggedOutTimestamp', [],
false,
true ],
92 [
'setLoggedOutTimestamp', [ 123 ],
false,
false ],
93 [
'getProviderMetadata', [],
false,
true ],
94 [
'save', [],
false,
false ],
95 [
'delaySave', [],
false,
true ],
96 [
'renew', [],
false,
false ],
102 $backend = TestingAccessWrapper::newFromObject( $session )->backend;
104 $this->assertEquals( 1, $session->get(
'foo' ) );
105 $this->assertEquals(
'zero', $session->get( 0 ) );
106 $this->assertFalse( $backend->dirty );
108 $this->assertEquals(
null, $session->get(
'null' ) );
109 $this->assertEquals(
'default', $session->get(
'null',
'default' ) );
110 $this->assertFalse( $backend->dirty );
112 $session->set(
'foo', 55 );
113 $this->assertEquals( 55, $backend->data[
'foo'] );
114 $this->assertTrue( $backend->dirty );
115 $backend->dirty =
false;
117 $session->set( 1,
'one' );
118 $this->assertEquals(
'one', $backend->data[1] );
119 $this->assertTrue( $backend->dirty );
120 $backend->dirty =
false;
122 $session->set( 1,
'one' );
123 $this->assertFalse( $backend->dirty );
125 $this->assertTrue( $session->exists(
'foo' ) );
126 $this->assertTrue( $session->exists( 1 ) );
127 $this->assertFalse( $session->exists(
'null' ) );
128 $this->assertFalse( $session->exists( 100 ) );
129 $this->assertFalse( $backend->dirty );
131 $session->remove(
'foo' );
132 $this->assertArrayNotHasKey(
'foo', $backend->data );
133 $this->assertTrue( $backend->dirty );
134 $backend->dirty =
false;
135 $session->remove( 1 );
136 $this->assertArrayNotHasKey( 1, $backend->data );
137 $this->assertTrue( $backend->dirty );
138 $backend->dirty =
false;
140 $session->remove( 101 );
141 $this->assertFalse( $backend->dirty );
143 $backend->data = [
'a',
'b',
'?' =>
'c' ];
144 $this->assertSame( 3, $session->count() );
145 $this->assertSame( 3,
count( $session ) );
146 $this->assertFalse( $backend->dirty );
149 foreach ( $session
as $key =>
$value ) {
152 $this->assertEquals( $backend->data,
$data );
153 $this->assertFalse( $backend->dirty );
155 $this->assertEquals( $backend->data, iterator_to_array( $session ) );
156 $this->assertFalse( $backend->dirty );
160 $logger = new \TestLogger;
162 $backend = TestingAccessWrapper::newFromObject( $session )->backend;
164 $this->assertEquals( 1, $session[
'foo'] );
165 $this->assertEquals(
'zero', $session[0] );
166 $this->assertFalse( $backend->dirty );
168 $logger->setCollect(
true );
169 $this->assertEquals(
null, $session[
'null'] );
170 $logger->setCollect(
false );
171 $this->assertFalse( $backend->dirty );
173 [ LogLevel::DEBUG,
'Undefined index (auto-adds to session with a null value): null' ]
174 ], $logger->getBuffer() );
175 $logger->clearBuffer();
177 $session[
'foo'] = 55;
178 $this->assertEquals( 55, $backend->data[
'foo'] );
179 $this->assertTrue( $backend->dirty );
180 $backend->dirty =
false;
183 $this->assertEquals(
'one', $backend->data[1] );
184 $this->assertTrue( $backend->dirty );
185 $backend->dirty =
false;
188 $this->assertFalse( $backend->dirty );
190 $session[
'bar'] = [
'baz' => [] ];
191 $session[
'bar'][
'baz'][
'quux'] = 2;
192 $this->assertEquals( [
'baz' => [
'quux' => 2 ] ], $backend->data[
'bar'] );
194 $logger->setCollect(
true );
195 $session[
'bar2'][
'baz'][
'quux'] = 3;
196 $logger->setCollect(
false );
197 $this->assertEquals( [
'baz' => [
'quux' => 3 ] ], $backend->data[
'bar2'] );
199 [ LogLevel::DEBUG,
'Undefined index (auto-adds to session with a null value): bar2' ]
200 ], $logger->getBuffer() );
201 $logger->clearBuffer();
203 $backend->dirty =
false;
204 $this->assertTrue( isset( $session[
'foo'] ) );
205 $this->assertTrue( isset( $session[1] ) );
206 $this->assertFalse( isset( $session[
'null'] ) );
207 $this->assertFalse( isset( $session[
'missing'] ) );
208 $this->assertFalse( isset( $session[100] ) );
209 $this->assertFalse( $backend->dirty );
211 unset( $session[
'foo'] );
212 $this->assertArrayNotHasKey(
'foo', $backend->data );
213 $this->assertTrue( $backend->dirty );
214 $backend->dirty =
false;
215 unset( $session[1] );
216 $this->assertArrayNotHasKey( 1, $backend->data );
217 $this->assertTrue( $backend->dirty );
218 $backend->dirty =
false;
220 unset( $session[101] );
221 $this->assertFalse( $backend->dirty );
226 $priv = TestingAccessWrapper::newFromObject( $session );
229 ->setMethods( [
'canSetUser',
'setUser',
'save' ] )
231 $backend->expects( $this->once() )->method(
'canSetUser' )
232 ->will( $this->returnValue(
true ) );
233 $backend->expects( $this->once() )->method(
'setUser' )
234 ->with( $this->callback(
function (
$user ) {
237 $backend->expects( $this->once() )->method(
'save' );
238 $priv->backend = $backend;
240 $this->assertSame( [], $backend->data );
241 $this->assertTrue( $backend->dirty );
244 ->setMethods( [
'canSetUser',
'setUser',
'save' ] )
247 $backend->expects( $this->once() )->method(
'canSetUser' )
248 ->will( $this->returnValue(
true ) );
249 $backend->expects( $this->once() )->method(
'setUser' )
250 ->with( $this->callback(
function (
$user ) {
253 $backend->expects( $this->once() )->method(
'save' );
254 $priv->backend = $backend;
256 $this->assertFalse( $backend->dirty );
259 ->setMethods( [
'canSetUser',
'setUser',
'save' ] )
261 $backend->expects( $this->once() )->method(
'canSetUser' )
262 ->will( $this->returnValue(
false ) );
263 $backend->expects( $this->never() )->method(
'setUser' );
264 $backend->expects( $this->once() )->method(
'save' );
265 $priv->backend = $backend;
267 $this->assertSame( [], $backend->data );
268 $this->assertTrue( $backend->dirty );
273 $priv = TestingAccessWrapper::newFromObject( $session );
274 $backend = $priv->backend;
276 $token = TestingAccessWrapper::newFromObject( $session->getToken() );
277 $this->assertArrayHasKey(
'wsTokenSecrets', $backend->data );
278 $this->assertArrayHasKey(
'default', $backend->data[
'wsTokenSecrets'] );
279 $secret = $backend->data[
'wsTokenSecrets'][
'default'];
280 $this->assertSame( $secret, $token->secret );
281 $this->assertSame(
'', $token->salt );
282 $this->assertTrue( $token->wasNew() );
284 $token = TestingAccessWrapper::newFromObject( $session->getToken(
'foo' ) );
285 $this->assertSame( $secret, $token->secret );
286 $this->assertSame(
'foo', $token->salt );
287 $this->assertFalse( $token->wasNew() );
289 $backend->data[
'wsTokenSecrets'][
'secret'] =
'sekret';
290 $token = TestingAccessWrapper::newFromObject(
291 $session->getToken( [
'bar',
'baz' ],
'secret' )
293 $this->assertSame(
'sekret', $token->secret );
294 $this->assertSame(
'bar|baz', $token->salt );
295 $this->assertFalse( $token->wasNew() );
297 $session->resetToken(
'secret' );
298 $this->assertArrayHasKey(
'wsTokenSecrets', $backend->data );
299 $this->assertArrayHasKey(
'default', $backend->data[
'wsTokenSecrets'] );
300 $this->assertArrayNotHasKey(
'secret', $backend->data[
'wsTokenSecrets'] );
302 $session->resetAllTokens();
303 $this->assertArrayNotHasKey(
'wsTokenSecrets', $backend->data );
314 $session->setSecret(
'secret',
$data );
315 $this->assertNotEquals(
$data, $session->get(
'secret' ) );
316 $this->assertEquals(
$data, $session->getSecret(
'secret',
'defaulted' ) );
323 [ [
'foo',
'bar' =>
'baz',
'subarray' => [ 1, 2, 3 ] ] ],
324 [ (
object)[
'foo',
'bar' =>
'baz',
'subarray' => [ 1, 2, 3 ] ] ],
332 $logger = new \TestLogger;
336 $this->assertEquals(
'defaulted', $session->getSecret(
'test',
'defaulted' ) );
339 $session->set(
'test',
'foobar' );
340 $logger->setCollect(
true );
341 $this->assertEquals(
'defaulted', $session->getSecret(
'test',
'defaulted' ) );
342 $logger->setCollect(
false );
344 [ LogLevel::WARNING,
'Invalid sealed-secret format' ]
345 ], $logger->getBuffer() );
346 $logger->clearBuffer();
349 $session->setSecret(
'test',
'foobar' );
350 $encrypted = $session->get(
'test' );
351 $session->set(
'test', $encrypted .
'x' );
352 $logger->setCollect(
true );
353 $this->assertEquals(
'defaulted', $session->getSecret(
'test',
'defaulted' ) );
354 $logger->setCollect(
false );
356 [ LogLevel::WARNING,
'Sealed secret has been tampered with, aborting.' ]
357 ], $logger->getBuffer() );
358 $logger->clearBuffer();
361 $iv = random_bytes( 16 );
362 list( $encKey, $hmacKey ) = TestingAccessWrapper::newFromObject( $session )->getSecretKeys();
363 $ciphertext = openssl_encrypt(
'foobar',
'aes-256-ctr', $encKey, OPENSSL_RAW_DATA, $iv );
364 $sealed = base64_encode( $iv ) .
'.' . base64_encode( $ciphertext );
365 $hmac = hash_hmac(
'sha256', $sealed, $hmacKey,
true );
366 $encrypted = base64_encode( $hmac ) .
'.' . $sealed;
367 $session->set(
'test', $encrypted );
368 \Wikimedia\suppressWarnings();
369 $this->assertEquals(
'defaulted', $session->getSecret(
'test',
'defaulted' ) );
370 \Wikimedia\restoreWarnings();