Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -394,10 +394,9 @@ protected function checkDataPermissions(PresentationSpeaker $speaker, array $val
}
*/

if(!$speaker->isPublicProfileShowTelephoneNumber())
{
if(isset($values['phone_number'])) $values['phone_number'] = '';
}
// phone_number is never public regardless of the target speaker's own account
// visibility toggle - see policy/profile-data-handling.md Rule 4.
if(isset($values['phone_number'])) $values['phone_number'] = '';

return $values;
}
Expand Down
52 changes: 52 additions & 0 deletions tests/PresentationSpeakerSerializerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php namespace Tests;
/*
* Copyright 2026 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/

use models\oauth2\IResourceServerContext;
use models\summit\PresentationSpeaker;
use ModelSerializers\PresentationSpeakerSerializer;
use Mockery;

/**
* Class PresentationSpeakerSerializerTest
* @package Tests
*/
final class PresentationSpeakerSerializerTest extends TestCase
{
public function tearDown(): void
{
Mockery::close();
parent::tearDown();
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

public function testPhoneNumberIsMaskedInPublicContextEvenWhenSpeakerToggleIsOn()
{
$speaker = Mockery::mock(PresentationSpeaker::class)->makePartial();
$speaker->shouldReceive('hasMember')->andReturn(false);
$speaker->shouldReceive('getPhoneNumber')->andReturn('+1-555-0100');
// target speaker's own account-level toggle is ON - the exact case that used to leak
// the raw phone_number regardless of the requesting caller's identity.
$speaker->shouldReceive('isPublicProfileShowTelephoneNumber')->andReturn(true);
$speaker->shouldReceive('isPublicProfileShowBio')->andReturn(true);
$speaker->shouldReceive('isPublicProfileShowEmail')->andReturn(true);
$speaker->shouldReceive('isPublicProfileShowSocialMediaInfo')->andReturn(true);
$speaker->shouldReceive('isPublicProfileShowPhoto')->andReturn(true);

$resource_server_context = Mockery::mock(IResourceServerContext::class);
$serializer = new PresentationSpeakerSerializer($speaker, $resource_server_context);

$values = $serializer->serialize(null, ['phone_number'], ['none']);

$this->assertSame('', $values['phone_number']);
}
}
Loading