Skip to content

Commit

Permalink
Merge branch 'master' into fix-profile-open
Browse files Browse the repository at this point in the history
  • Loading branch information
maxxer authored Aug 1, 2024
2 parents cf6f9db + f3765a0 commit d3d2d5a
Show file tree
Hide file tree
Showing 28 changed files with 336 additions and 144 deletions.
12 changes: 10 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,21 @@

## dev

- Enh: Changed exception thrown in PasswordRecoveryService from `RuntimeException` to `NotFoundException`. (eseperio)
- New #553: created Da\User\AuthClient\Microsoft365 auth client (edegaudenzi)
- Ehh: Added SecurityHelper to the Bootstrap classMap
- Fix #546: The profile/show page must not be visible by default, implement configurable policy (TonisOrmisson)

## 1.6.3 Mar 18th, 2024

- Fix: Update last_login_at and last_login_ip on social networt authenticate (e.luhr)
- Enh: Keycloak auth client (e.luhr)
- Fix: Social Network Auth (eluhr)
- Enh #532: /user/registration/register now shows form validation errors
- Enh: Allow/suggest new v3 releases of 2amigos 2fa dependencies: 2fa-library, qrcode-library (TonisOrmisson)
- Enh: Allow/suggest new v3 releases of 2amigos 2fa dependencies: 2fa-library, qrcode-library (TonisOrmisson)
- Enh: Added option to disable viewing any other user's profile for non-admin users (TonisOrmisson)
- Fix #546: The profile/show page must not be visible by default, implement configurable policy (TonisOrmisson)
- Ehn: updated Estonian (et) translation by (TonisOrmisson)
- Ehn: use recaptcha.net instead of google.com (Eseperio)

## 1.6.2 Jan 4th, 2024

Expand Down
158 changes: 158 additions & 0 deletions src/User/AuthClient/Microsoft365.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
<?php

/*
* This file is part of the 2amigos/yii2-usuario project.
*
* (c) 2amigOS! <http://2amigos.us/>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/

namespace Da\User\AuthClient;

use Da\User\Contracts\AuthClientInterface;
use Da\User\Traits\AuthClientUserIdTrait;
use yii\authclient\OAuth2;

/**
* Microsoft365 allows authentication via Microsoft365 OAuth2 flow.
* Before using Microsoft365 OAuth2 you must register your Microsoft Azure Application
* @see https://portal.azure.com
*
* Note: the registered App must have the following:
* -Authentication: 'Redirect URIs' set 'user/security/auth?authclient=microsoft365' as an absolute URL
* e.g. https://domain.com/index.php/user/security/auth?authclient=microsoft365
* -API Permissions: 'Microsoft Graph' > 'User.Read'
* -Decide whether the App should be
* single-tenant (only allow one Company to use it),
* multi-tenant (also allow other Companies to use it),
* personal account (allow accounts like xbox, skype etc. to use it)
* or both "multi-tenant and personal-account"
* -In the Microsoft world even the Authorization URls are different dendinding if you allow single/multi/personal accounts.
* This client supports them: just set up the 'signInAudience' property (value for this it's in the manifest of your Azure App)
* accordingly to your needs; it defaults to the widest permissions available "AzureADandPersonalMicrosoftAccount"
* (details: https://learn.microsoft.com/en-us/entra/identity-platform/supported-accounts-validation)
*
* Example application configuration:
*
* ```
* 'components' => [
* ...
* 'authClientCollection' => [
* 'class' => 'yii\authclient\Collection',
* 'clients' => [
* 'microsoft365' => [
* 'class' => 'yii\authclient\clients\Microsoft365',
* 'clientId' => 'a5e19acd-dc50-4b0a-864a-d13b9347ddf9',
* 'clientSecret' => 'ljSAd89.lvk34NV-3t4v3_2kl_42Rt4klr234',
* 'signInAudience' => 'AzureADandPersonalMicrosoftAccount',
* ],
* ],
* ]
* ...
* ]
* ```
*/
class Microsoft365 extends OAuth2 implements AuthClientInterface
{
use AuthClientUserIdTrait;

public const ACCOUNT_TYPE_SINGLETENANT = 'AzureADMyOrg'; // Accounts in this organizational directory only (Single tenant)
public const ACCOUNT_TYPE_MULTITENANT = 'AzureADMultipleOrgs'; // Accounts in any organizational directory (Any Microsoft Entra directory - Multitenant)
public const ACCOUNT_TYPE_MULTITENANTANDPERSONAL = 'AzureADandPersonalMicrosoftAccount'; // Accounts in any organizational directory (Any Microsoft Entra directory - Multitenant) and personal Microsoft accounts (such as Skype, Xbox)
public const ACCOUNT_TYPE_PERSONAL = 'PersonalMicrosoftAccount'; // Personal Microsoft accounts only

/**
* @var string Micrososft365 Graph API endpoint.
*/
public $apiBaseUrl = 'https://graph.microsoft.com/v1.0';

/**
* @var string 'signInAudience' in Microsoft Azure App manifest
*/
public $signInAudience;

/**
* {@inheritdoc}
*/
public function init()
{
parent::init();

if (is_null($this->scope)) {
$this->scope = 'User.Read';
}

if (is_null($this->signInAudience)) {
$this->signInAudience = self::ACCOUNT_TYPE_MULTITENANTANDPERSONAL;
}

// In the Microsoft world Authorization URls are different if you use single-tenant or multi-tenant (@see https://learn.microsoft.com/en-us/entra/identity-platform/supported-accounts-validation)
// This OAuth2 client supports also these scenarios: just set up 'signInAudience' accordingly to your needs. It defaults to the widest "AzureADandPersonalMicrosoftAccount"
switch ($this->signInAudience) {
case self::ACCOUNT_TYPE_SINGLETENANT:
$this->authUrl = 'https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize';
$this->tokenUrl = 'https://login.microsoftonline.com/organizations/oauth2/v2.0/token';
break;
case self::ACCOUNT_TYPE_PERSONAL:
$this->authUrl = 'https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize';
$this->tokenUrl = 'https://login.microsoftonline.com/consumers/oauth2/v2.0/token';
break;
case self::ACCOUNT_TYPE_MULTITENANT:
case self::ACCOUNT_TYPE_MULTITENANTANDPERSONAL:
default:
$this->authUrl = 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize';
$this->tokenUrl = 'https://login.microsoftonline.com/common/oauth2/v2.0/token';
}
}

/**
* {@inheritdoc}
*/
protected function initUserAttributes()
{
return $this->api('me', 'GET');
}

/**
* {@inheritdoc}
*/
public function applyAccessTokenToRequest($request, $accessToken)
{
$request->headers->set('Authorization', 'Bearer '.$accessToken->getToken());
}

/**
* {@inheritdoc}
*/
protected function defaultName()
{
return 'microsoft365';
}

/**
* {@inheritdoc}
*/
protected function defaultTitle()
{
return 'Microsoft 365';
}

/**
* {@inheritdoc}
*/
public function getEmail()
{
return $this->getUserAttributes()['mail'];
}

/**
* {@inheritdoc}
*/
public function getUsername()
{
return $this->getUserAttributes()['userPrincipalName'];
}

}
3 changes: 3 additions & 0 deletions src/User/Bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,9 @@ protected function buildClassMap(array $userClassMap)
'Da\User\Service' => [
'MailService',
],
'Da\User\Helper' => [
'SecurityHelper',
]
];

$mapping = array_merge($defaults, $userClassMap);
Expand Down
3 changes: 2 additions & 1 deletion src/User/Service/PasswordRecoveryService.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use Da\User\Traits\ModuleAwareTrait;
use Exception;
use Yii;
use yii\web\NotFoundHttpException;

class PasswordRecoveryService implements ServiceInterface
{
Expand Down Expand Up @@ -50,7 +51,7 @@ public function run()
$user = $this->query->whereEmail($this->email)->one();

if ($user === null) {
throw new \RuntimeException('User not found.');
throw new NotFoundHttpException(Yii::t('usuario', 'User not found'));
}

$token = TokenFactory::makeRecoveryToken($user->id);
Expand Down
2 changes: 1 addition & 1 deletion src/User/Widget/ReCaptchaWidget.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ protected function registerClientScript()
$view = $this->getView();

$view->registerJsFile(
'//www.google.com/recaptcha/api.js?hl=' . $this->getLanguageCode(),
'//www.recaptcha.net/recaptcha/api.js?hl=' . $this->getLanguageCode(),
[
'position' => View::POS_HEAD,
'async' => true,
Expand Down
1 change: 1 addition & 0 deletions src/User/resources/i18n/ca/usuario.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
'Block' => '',
'Block status' => '',
'Blocked at {0, date, MMMM dd, YYYY HH:mm}' => '',
'Can\'t scan? Copy the code instead.' => '',
'Cancel' => '',
'Cannot assign role "{0}" as the AuthManager is not configured on your console application.' => '',
'Change your avatar at Gravatar.com' => '',
Expand Down
1 change: 1 addition & 0 deletions src/User/resources/i18n/da/usuario.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
'Block' => '',
'Block status' => '',
'Blocked at {0, date, MMMM dd, YYYY HH:mm}' => '',
'Can\'t scan? Copy the code instead.' => '',
'Cancel' => '',
'Cannot assign role "{0}" as the AuthManager is not configured on your console application.' => '',
'Change your avatar at Gravatar.com' => '',
Expand Down
1 change: 1 addition & 0 deletions src/User/resources/i18n/de-DU/usuario.php
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@
'According to the European General Data Protection Regulation (GDPR) we need your consent to work with your personal data.' => '',
'Active' => '',
'Application not configured for two factor authentication.' => '',
'Can\'t scan? Copy the code instead.' => '',
'Code for two factor authentication on {0}' => '',
'Current' => '',
'Data privacy' => '',
Expand Down
1 change: 1 addition & 0 deletions src/User/resources/i18n/de/usuario.php
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@
'{0} cannot be blank.' => '{0} darf nicht leer sein.',
'Active' => '',
'Application not configured for two factor authentication.' => '',
'Can\'t scan? Copy the code instead.' => '',
'Code for two factor authentication on {0}' => '',
'Current' => '',
'Error while enabling SMS two factor authentication. Please reload the page.' => '',
Expand Down
31 changes: 16 additions & 15 deletions src/User/resources/i18n/et/usuario.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,17 @@
'A message has been sent to your email address. It contains a confirmation link that you must click to complete registration.' => 'Saatsime sulle kinnituseks e-kirja. Registreerumise kinnitamiseks pead klikkma saadetud kirjas olevale lingile.',
'A new confirmation link has been sent' => 'Uus kinnituslink on saadetud',
'A password will be generated automatically if not provided' => 'Parool genereeritakse automaatselt, kui ei ole seatud',
'According to the European General Data Protection Regulation (GDPR) we need your consent to work with your personal data.' => 'Vastavalt Euroopa Isikuandmete kaitse üldmäärusele (GDPR) vajame sinu isikuandmete töötlemiseks sinu nõusolekut.',
'Account' => 'Konto',
'Account confirmation' => 'Konto kinnitamine',
'Account details' => 'Konto andmed',
'Account details have been updated' => 'Konto andmed on uuendatud',
'Account settings' => 'Konto seaded',
'Active' => 'Aktiivne',
'Already registered? Sign in!' => 'Oled registreerunud? Logi sisse!',
'An email with instructions to create a new password has been sent to {email} if it is associated with an {appName} account. Your existing password has not been changed.' => 'Saatsime aadressile {email} juhendi, kuidas saad oma parooli uuendada, kui see aadress on seotud mõne {appName} kontoga. Me ei muutnud sinu praegust parooli.',
'An error occurred processing your request' => 'Päringu protsessimisel tekkis viga',
'Application not configured for two factor authentication.' => 'Rakendus ei ole seadistatud kaheastmelise autentimise kasutamiseks.',
'Are you sure you want to block this user?' => 'Oled kindel, et tahad selle kasutaja blokeerid?',
'Are you sure you want to confirm this user?' => 'Oled kindel, et tahad selle kasutaja kinnitada?',
'Are you sure you want to delete this user?' => 'Oled kindel, et tahad selle kasutaja kustutada?',
Expand Down Expand Up @@ -79,8 +82,10 @@
'Create new rule' => 'Loo uus reegel',
'Created at' => 'Loodud',
'Credentials will be sent to the user by email' => 'Konto andmed saadetakse kasutajale e-mailiga',
'Current' => 'Praegune',
'Current password' => 'Praegune parool',
'Current password is not valid' => 'Praegune parool ei ole õige',
'Data privacy' => 'Andmete privaatsus',
'Data processing consent' => 'Nõusolek andmete töötlemiseks',
'Delete' => 'Kustuta',
'Delete account' => 'Kustuta konto',
Expand Down Expand Up @@ -117,7 +122,9 @@
'In order to complete your registration, please click the link below' => 'Kliki alloleval lingil, et registreerimine kinnitada',
'In order to complete your request, please click the link below' => 'Kliki alloleval lingil, et oma päring kinnitada',
'In order to finish your registration, we need you to enter following fields' => 'Pead täitma järgnevad väljad, et registreerimine lõpule viia',
'Inactive' => 'Mitteaktiivne',
'Information' => 'Informatsioon',
'Insert' => 'Sisesta',
'Invalid login or password' => 'Vale kasutajanimi või parool',
'Invalid or expired link' => 'Vale või aegunud link',
'Invalid password' => 'Vale parool',
Expand All @@ -126,13 +133,15 @@
'It will be deleted forever' => 'See kustutatakse alatiseks',
'Items' => 'Õigused',
'Joined on {0, date}' => 'Liitunud: {0, date}',
'Last activity' => 'Viimane tegevus',
'Last login IP' => 'Viimane sisselogimise IP',
'Last login time' => 'Viimase sisselogimise aeg',
'Last password change' => 'Viimane parooli muutmine',
'Location' => 'Asukoht',
'Login' => 'Sisene',
'Logout' => 'Logi välja',
'Manage users' => 'Halda kasutajaid',
'Mobile phone number' => 'Mobiiltelefoni number',
'Name' => 'Nimi',
'Networks' => 'Võrgustikud',
'Never' => 'Mitte kunagi',
Expand Down Expand Up @@ -186,6 +195,8 @@
'Sign in' => 'Logi sisse',
'Sign up' => 'Liitu',
'Something went wrong' => 'Midagi läks valesti',
'Status' => 'Staatus',
'Submit' => 'Saada',
'Switch identities is disabled.' => 'Identiteedi vahetamine on keelatud',
'Thank you for signing up on {0}' => 'Aitäh, et liitusid lehega {0}',
'Thank you, registration is now complete.' => 'Aitäh, oled nüüd registreeritud',
Expand Down Expand Up @@ -220,6 +231,7 @@
'Unable to update block status.' => 'Blokkimise staatuse muutmine ebaõnnestus.',
'Unblock' => 'Eemalda blokk',
'Unconfirmed' => 'Kinnitamata',
'Unfortunately, you can not work with this site without giving us consent to process your data.' => 'Kahjuks ei ole selle lehe kasutamine võimalik ilma, et annaksid meile nõusoleku sinu andmeid töödelda.',
'Update' => 'Muuda',
'Update assignments' => 'Muuda omistamisi',
'Update permission' => 'Muud õigus',
Expand All @@ -230,6 +242,7 @@
'User account could not be created.' => 'Kasutajakonto loomine ebaõnnestus.',
'User block status has been updated.' => 'Kasutaja blokeering on muudetud.',
'User could not be registered.' => 'Kasutaja registreerimine ebaõnnestus.',
'User does not have sufficient permissions.' => 'Kasutajal ei ole piisavalt õigusi.',
'User has been confirmed' => 'Kasutaja on kinnitatud',
'User has been created' => 'Kasutaja on loodud',
'User has been deleted' => 'Kasutaja on kustutatud',
Expand All @@ -251,6 +264,7 @@
'You can connect multiple accounts to be able to log in using them' => 'Võid ühendada mitu sotsiaalmeedia kontot, mida saad kasutada kontole sisse logimiseks',
'You cannot remove your own account' => 'Sa ei saa kustutada iseenda kontot',
'You need to confirm your email address' => 'Sa pead oma e-posti aadressi kinnitama',
'You received this email because someone, possibly you or someone on your behalf, have created an account at {app_name}' => 'Said selle kirja, sest keegi, tõenäoliselt sa ise või keegi sinu nimel, on loonud konto rakenduses {app_name}',
'Your account details have been updated' => 'Sinu konto andmed on uuendatud',
'Your account has been blocked' => 'Sinu konto on blokeeritud',
'Your account has been blocked.' => 'Sinu konto on blokeeritud.',
Expand All @@ -261,38 +275,29 @@
'Your account on {0} has been created' => 'Sinu {0} konto on loodud',
'Your confirmation token is invalid or expired' => 'Kinnituse kood on vale või aegunud',
'Your consent is required to register' => 'Registreerumiseks on vaja sinu nõusolekut',
'Your consent is required to work with this site' => 'Selle lehe kasutamiseks on vaja sinu nõusolekut',
'Your email address has been changed' => 'Sinu e-mail on muudetud',
'Your password has expired, you must change it now' => 'Sinu parool on aegunud, pead seda uuendama.',
'Your personal information has been removed' => 'Sinu isiklikud andmed on kustutatud',
'Your profile has been updated' => 'Sinu profiil on uuendatud',
'privacy policy' => 'privaatsuspoliitika',
'{0} cannot be blank.' => '{0} ei või olla tühi.',
'According to the European General Data Protection Regulation (GDPR) we need your consent to work with your personal data.' => '',
'Active' => '',
'Application not configured for two factor authentication.' => '',
'Authentication rule class {0} can not be instantiated' => '',
'Can\'t scan? Copy the code instead.' => '',
'Code for two factor authentication on {0}' => '',
'Current' => '',
'Data privacy' => '',
'Error while enabling SMS two factor authentication. Please reload the page.' => '',
'Google Authenticator' => '',
'IP' => '',
'If you haven\'t received a password, you can reset it at' => '',
'Inactive' => '',
'Insert' => '',
'Insert the code you received by SMS.' => '',
'Insert the code you received by email.' => '',
'Insert the mobile phone number where you want to receive text message in international format' => '',
'Last activity' => '',
'Mobile phone number' => '',
'Mobile phone number successfully enabled.' => '',
'Please, enter the right code. The code is valid for {0} seconds. If you want to get a new code, please click on \'Cancel\' and repeat the login request.' => '',
'Please, enter the right code. The code is valid for {0} seconds. If you want to get a new code, please close this window and repeat the enabling request.' => '',
'Rule class must extend "yii\\rbac\\Rule".' => '',
'Session ID' => '',
'Session history' => '',
'Status' => '',
'Submit' => '',
'Terminate all sessions' => '',
'Text message' => '',
'The email address set is: "{0}".' => '',
Expand All @@ -303,16 +308,12 @@
'This is the code to insert to enable two factor authentication' => '',
'Two factor authentication code by SMS' => '',
'Two factor authentication code by email' => '',
'Unfortunately, you can not work with this site without giving us consent to process your data.' => '',
'User ID' => '',
'User agent' => '',
'User does not have sufficient permissions.' => '',
'VKontakte' => '',
'Yandex' => '',
'You cannot block your own account.' => '',
'You cannot remove your own account.' => '',
'You received this email because someone, possibly you or someone on your behalf, have created an account at {app_name}' => '',
'Your consent is required to work with this site' => '',
'Your role requires 2FA, you won\'t be able to use the application until you enable it' => '',
'Your two factor authentication method is based on "{0}".' => '',
'{0, date, MMM dd, YYYY HH:mm}' => '',
Expand Down
Loading

0 comments on commit d3d2d5a

Please sign in to comment.