diff --git a/app-modules/authorization/database/migrations/2024_12_30_142708_add_matching_property_to_azure_sso_settings.php b/app-modules/authorization/database/migrations/2024_12_30_142708_add_matching_property_to_azure_sso_settings.php new file mode 100644 index 0000000000..27fb066307 --- /dev/null +++ b/app-modules/authorization/database/migrations/2024_12_30_142708_add_matching_property_to_azure_sso_settings.php @@ -0,0 +1,47 @@ + + + Copyright © 2016-2024, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +use Spatie\LaravelSettings\Migrations\SettingsBlueprint; +use Spatie\LaravelSettings\Migrations\SettingsMigration; + +return new class () extends SettingsMigration { + public function up(): void + { + $this->migrator->inGroup('azure_sso', function (SettingsBlueprint $blueprint): void { + $blueprint->add('matching_property', 'user_principal_name'); + }); + } +}; diff --git a/app-modules/authorization/database/migrations/2024_12_30_144224_data_activate_azure_matching_property_feature.php b/app-modules/authorization/database/migrations/2024_12_30_144224_data_activate_azure_matching_property_feature.php new file mode 100644 index 0000000000..0d33f81c4c --- /dev/null +++ b/app-modules/authorization/database/migrations/2024_12_30_144224_data_activate_azure_matching_property_feature.php @@ -0,0 +1,50 @@ + + + Copyright © 2016-2024, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +use App\Features\AzureMatchingPropertyFeature; +use Illuminate\Database\Migrations\Migration; + +return new class () extends Migration { + public function up(): void + { + AzureMatchingPropertyFeature::activate(); + } + + public function down(): void + { + AzureMatchingPropertyFeature::deactivate(); + } +}; diff --git a/app-modules/authorization/src/Enums/AzureMatchingProperty.php b/app-modules/authorization/src/Enums/AzureMatchingProperty.php new file mode 100644 index 0000000000..611da5523c --- /dev/null +++ b/app-modules/authorization/src/Enums/AzureMatchingProperty.php @@ -0,0 +1,51 @@ + + + Copyright © 2016-2024, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\Authorization\Enums; + +use Filament\Support\Contracts\HasLabel; + +enum AzureMatchingProperty: string implements HasLabel +{ + case UserPrincipalName = 'user_principal_name'; + + case Mail = 'mail'; + + public function getLabel(): ?string + { + return $this->name; + } +} diff --git a/app-modules/authorization/src/Enums/SocialiteProvider.php b/app-modules/authorization/src/Enums/SocialiteProvider.php index 11b1df078b..2d15af92e9 100644 --- a/app-modules/authorization/src/Enums/SocialiteProvider.php +++ b/app-modules/authorization/src/Enums/SocialiteProvider.php @@ -36,13 +36,16 @@ namespace AdvisingApp\Authorization\Enums; +use AdvisingApp\Authorization\Exceptions\InvalidAzureMatchingProperty; use AdvisingApp\Authorization\Settings\AzureSsoSettings; use AdvisingApp\Authorization\Settings\GoogleSsoSettings; use AdvisingApp\MeetingCenter\Settings\AzureCalendarSettings; +use App\Features\AzureMatchingPropertyFeature; use Exception; use Laravel\Socialite\Contracts\Provider; use Laravel\Socialite\Facades\Socialite; use Mockery\MockInterface; +use SocialiteProviders\Azure\User; use SocialiteProviders\Manager\Config; enum SocialiteProvider: string @@ -93,4 +96,25 @@ public function config(): Config default => throw new Exception('Invalid socialite provider'), }; } + + public function getEmailFromUser(mixed $user): string + { + return match ($this->value) { + 'azure', 'azure_calendar' => (function () use ($user) { + if (! AzureMatchingPropertyFeature::active()) { + return $user->getEmail(); + } + + /** @var User $user */ + + return match (app(AzureSsoSettings::class)->matching_property) { + AzureMatchingProperty::UserPrincipalName => $user->getPrincipalName(), + AzureMatchingProperty::Mail => $user->getMail(), + default => throw new InvalidAzureMatchingProperty(app(AzureSsoSettings::class)->matching_property), + }; + })(), + 'google' => $user->getEmail(), + default => throw new Exception('Invalid socialite provider'), + }; + } } diff --git a/app-modules/authorization/src/Exceptions/InvalidAzureMatchingProperty.php b/app-modules/authorization/src/Exceptions/InvalidAzureMatchingProperty.php new file mode 100644 index 0000000000..7e2cd0750e --- /dev/null +++ b/app-modules/authorization/src/Exceptions/InvalidAzureMatchingProperty.php @@ -0,0 +1,47 @@ + + + Copyright © 2016-2024, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace AdvisingApp\Authorization\Exceptions; + +use Exception; + +class InvalidAzureMatchingProperty extends Exception +{ + public function __construct(mixed $valueUsed) + { + parent::__construct('Invalid Azure matching property. Value used: ' . strval($valueUsed)); + } +} diff --git a/app-modules/authorization/src/Filament/Pages/ManageAzureSsoSettings.php b/app-modules/authorization/src/Filament/Pages/ManageAzureSsoSettings.php index 4a97d4c322..29efe6d580 100644 --- a/app-modules/authorization/src/Filament/Pages/ManageAzureSsoSettings.php +++ b/app-modules/authorization/src/Filament/Pages/ManageAzureSsoSettings.php @@ -36,10 +36,13 @@ namespace AdvisingApp\Authorization\Filament\Pages; +use AdvisingApp\Authorization\Enums\AzureMatchingProperty; use AdvisingApp\Authorization\Settings\AzureSsoSettings; +use App\Features\AzureMatchingPropertyFeature; use App\Filament\Clusters\ProductIntegrations; use App\Models\User; use Filament\Forms\Components\Section; +use Filament\Forms\Components\Select; use Filament\Forms\Components\TextInput; use Filament\Forms\Components\Toggle; use Filament\Forms\Form; @@ -95,6 +98,12 @@ public function form(Form $form): Form ->required(fn (Get $get) => $get('is_enabled')) ->password() ->revealable(), + Select::make('matching_property') + ->label('Matching Property') + ->options(AzureMatchingProperty::class) + ->enum(AzureMatchingProperty::class) + ->required(fn (Get $get) => $get('is_enabled')) + ->visible(AzureMatchingPropertyFeature::active()), ])->visible(fn (Get $get) => $get('is_enabled')), ]); } diff --git a/app-modules/authorization/src/Http/Controllers/SocialiteController.php b/app-modules/authorization/src/Http/Controllers/SocialiteController.php index 2299b4fa24..11858a5712 100644 --- a/app-modules/authorization/src/Http/Controllers/SocialiteController.php +++ b/app-modules/authorization/src/Http/Controllers/SocialiteController.php @@ -80,7 +80,7 @@ public function callback(SocialiteProvider $provider) /** @var User $user */ $user = User::query() - ->where(new Expression('lower(email)'), strtolower($socialiteUser->getEmail())) + ->where(new Expression('lower(email)'), strtolower($provider->getEmailFromUser($socialiteUser))) ->first(); if (! $user?->is_external) { diff --git a/app-modules/authorization/src/Settings/AzureSsoSettings.php b/app-modules/authorization/src/Settings/AzureSsoSettings.php index a384645b8a..a281eed298 100644 --- a/app-modules/authorization/src/Settings/AzureSsoSettings.php +++ b/app-modules/authorization/src/Settings/AzureSsoSettings.php @@ -36,6 +36,7 @@ namespace AdvisingApp\Authorization\Settings; +use AdvisingApp\Authorization\Enums\AzureMatchingProperty; use Spatie\LaravelSettings\Settings; class AzureSsoSettings extends Settings @@ -48,6 +49,8 @@ class AzureSsoSettings extends Settings public ?string $tenant_id = null; + public AzureMatchingProperty $matching_property = AzureMatchingProperty::UserPrincipalName; + public static function group(): string { return 'azure_sso'; diff --git a/app/Features/AzureMatchingPropertyFeature.php b/app/Features/AzureMatchingPropertyFeature.php new file mode 100644 index 0000000000..d893687e7e --- /dev/null +++ b/app/Features/AzureMatchingPropertyFeature.php @@ -0,0 +1,47 @@ + + + Copyright © 2016-2024, Canyon GBS LLC. All rights reserved. + + Advising App™ is licensed under the Elastic License 2.0. For more details, + see https://github.com/canyongbs/advisingapp/blob/main/LICENSE. + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Advising App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + https://www.canyongbs.com or contact us via email at legal@canyongbs.com. + + +*/ + +namespace App\Features; + +use App\Support\AbstractFeatureFlag; + +class AzureMatchingPropertyFeature extends AbstractFeatureFlag +{ + public function resolve(mixed $scope): mixed + { + return false; + } +}