pixelfed/tests/Feature/RemoteOidcTest.php

118 wiersze
4.4 KiB
PHP
Czysty Zwykły widok Historia

Staging (#5978) * Added current title as value for input so that the current value remains stored by default * Added parameter 'show_legal_notice_link' => (bool) config_cache('instance.has_legal_notice'), * Added conditional display of a link to legal notice if the page is active * Added key 'legalNotice' * feat translate story * translate auth - register - login * add remove follow * Update ApiV1Controller.php Co-Authored-By: Mathieu <385764+Casmo@users.noreply.github.com> * New translations web.php (Chinese Simplified) [ci skip] * Added current title as value for input so that the current value remains stored by default * Added parameter 'show_legal_notice_link' => (bool) config_cache('instance.has_legal_notice'), * Added conditional display of a link to legal notice if the page is active * Added key 'legalNotice' * add missing key * add missing keys * New translations web.php (Portuguese, Brazilian) [ci skip] * New translations web.php (Turkish) [ci skip] * New translations web.php (Italian) [ci skip] * translate custom filter * New translations web.php (Italian) [ci skip] * use configured alt text length limit when uploading multiple photos * in notifications sidebar, show popover on shared posts too, not just liked posts * use case insensitive search when tagging accounts * New translations web.php (Portuguese, Brazilian) [ci skip] * Generic OIDC Support * Everything should be configurable by env variables * Basic request tests * Fixes for items highlighted by review.ai * Consider using `hash_equals()` instead of `==` when comparing the state values to prevent timing attacks: `abort_unless(hash_equals($request->input('state'), $request->session()->pull('oauth2state')), 400, 'invalid state');` * For better data integrity, consider adding a foreign key constraint to the user_id column: `$table- >foreign('user_id')->references('id')->on('users')->onDelete('cascade');` * Does the OIDC provider guarantee that the username field exists in the userInfo data? Consider adding a null check or fallback: `$userInfoData[config('remote-auth.oidc.field_username')] ?? null` * field isnt accessTokenResourceOwnerId but responseResourceOwnerId * New translations web.php (Dutch) [ci skip] * Fix components * Update LandingService and Config util to properly support the legal_notice setting * Update footer to use legalNotice i18n * Update i18n * Update sidebar with gap padding for footer links * Update compiled assets * Update i18n json * Update OIDC config with comments, and disable tests as we dont have db tests configured * Update remove_from_followers api endpoint * Update i18n * Update compiled assets * Update changelog * New supported formats, Preserve ICC Color Profiles, libvips support Update image pipeline to handle avif, heic and webp and preserve ICC color profiles and added libvips support. * Fix tests * Update CHANGELOG.md --------- Co-authored-by: Samy Elshamy <elshamy@coderbutze.de> Co-authored-by: Felipe Mateus <eu@felipemateus.com> Co-authored-by: Mathieu <385764+Casmo@users.noreply.github.com> Co-authored-by: Mackenzie Morgan <macoafi@gmail.com> Co-authored-by: Gavin Mogan <git@gavinmogan.com>
2025-05-13 08:25:23 +00:00
<?php
namespace Tests\Feature;
use App\Models\UserOidcMapping;
use App\Services\UserOidcService;
use App\User;
use Auth;
use Faker\Factory as Faker;
use League\OAuth2\Client\Provider\GenericResourceOwner;
use League\OAuth2\Client\Token\AccessToken;
use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;
use Mockery\MockInterface;
use Tests\TestCase;
class RemoteOidcTest extends TestCase
{
use MockeryPHPUnitIntegration;
public function view_oidc_start()
{
config([
'remote-auth.oidc.enabled'=> true,
'remote-auth.oidc.clientId' => 'fake',
'remote-auth.oidc.clientSecret' => 'fakeSecret',
'remote-auth.oidc.authorizeURL' => 'http://fakeserver.oidc/authorizeURL',
'remote-auth.oidc.tokenURL' => 'http://fakeserver.oidc/tokenURL',
'remote-auth.oidc.profileURL' => 'http://fakeserver.oidc/profile',
]);
$response = $this->withoutExceptionHandling()->get('auth/oidc/start');
$state = session()->get('oauth2state');
$callbackUrl = urlencode(url('auth/oidc/callback'));
$response->assertRedirect("http://fakeserver.oidc/authorizeURL?scope=openid%20profile%20email&state={$state}&response_type=code&approval_prompt=auto&redirect_uri={$callbackUrl}&client_id=fake");
}
public function view_oidc_callback_new_user()
{
$originalUserCount = User::count();
$this->assertDatabaseCount('users', $originalUserCount);
config(['remote-auth.oidc.enabled' => true]);
$oauthData = array(
"sub" => str_random(10),
"preferred_username" => fake()->unique()->userName,
"email" => fake()->unique()->freeEmail,
);
$this->partialMock(UserOidcService::class, function (MockInterface $mock) use ($oauthData) {
$mock->shouldReceive('getAccessToken')->once()->andReturn(new AccessToken(["access_token" => "token" ]));
$mock->shouldReceive('getResourceOwner')->once()->andReturn(new GenericResourceOwner($oauthData, 'sub'));
return $mock;
});
$response = $this->withoutExceptionHandling()->withSession([
'oauth2state' => 'abc123',
])->get('auth/oidc/callback?state=abc123&code=1');
$response->assertRedirect('/');
$mappedUser = UserOidcMapping::where('oidc_id', $oauthData['sub'])->first();
$this->assertNotNull($mappedUser, "mapping is found");
$user = $mappedUser->user;
$this->assertEquals($user->username, $oauthData['preferred_username']);
$this->assertEquals($user->email, $oauthData['email']);
$this->assertEquals(Auth::guard()->user()->id, $user->id);
$this->assertDatabaseCount('users', $originalUserCount+1);
}
public function view_oidc_callback_existing_user()
{
$user = User::create([
'name' => fake()->name,
'username' => fake()->unique()->username,
'email' => fake()->unique()->freeEmail,
]);
$originalUserCount = User::count();
$this->assertDatabaseCount('users', $originalUserCount);
config(['remote-auth.oidc.enabled' => true]);
$oauthData = array(
"sub" => str_random(10),
"preferred_username" => $user->username,
"email" => $user->email,
);
UserOidcMapping::create([
'oidc_id' => $oauthData['sub'],
'user_id' => $user->id,
]);
$this->partialMock(UserOidcService::class, function (MockInterface $mock) use ($oauthData) {
$mock->shouldReceive('getAccessToken')->once()->andReturn(new AccessToken(["access_token" => "token" ]));
$mock->shouldReceive('getResourceOwner')->once()->andReturn(new GenericResourceOwner($oauthData, 'sub'));
return $mock;
});
$response = $this->withoutExceptionHandling()->withSession([
'oauth2state' => 'abc123',
])->get('auth/oidc/callback?state=abc123&code=1');
$response->assertRedirect('/');
$mappedUser = UserOidcMapping::where('oidc_id', $oauthData['sub'])->first();
$this->assertNotNull($mappedUser, "mapping is found");
$user = $mappedUser->user;
$this->assertEquals($user->username, $oauthData['preferred_username']);
$this->assertEquals($user->email, $oauthData['email']);
$this->assertEquals(Auth::guard()->user()->id, $user->id);
$this->assertDatabaseCount('users', $originalUserCount);
}
}