Skip to content

Commit

Permalink
Fixed Azure authenticator + External auth list
Browse files Browse the repository at this point in the history
- fixed Azure authenticator
- fixed Doctrine mapping
- added the list of external authentication on the user edit page
  • Loading branch information
tg666 committed Jan 26, 2024
1 parent b5822a1 commit b3cf600
Show file tree
Hide file tree
Showing 18 changed files with 217 additions and 5 deletions.
3 changes: 3 additions & 0 deletions config/model/user/infrastructure.neon
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ services:
-
autowired: no
factory: App\Infrastructure\User\Doctrine\ReadModel\FindNotificationReceiversByTypeAndProjectIdsQueryHandler
-
autowired: no
factory: App\Infrastructure\User\Doctrine\ReadModel\FindExternalAuthenticationsQueryHandler

# infra: doctrine mapping
nettrine.orm.xml:
Expand Down
1 change: 1 addition & 0 deletions config/services.neon
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ services:
- App\Web\AdminModule\UserModule\Control\UserForm\UserFormControlFactoryInterface
- App\Web\AdminModule\ProfileModule\Control\PasswordChange\PasswordChangeControlFactoryInterface
- App\Web\AdminModule\UserModule\Control\NotificationPreferences\NotificationPreferencesControlFactoryInterface
- App\Web\AdminModule\UserModule\Control\ExternalAuthList\ExternalAuthListControlFactoryInterface

# Web\AdminModule\CookieModule
- App\Web\AdminModule\CookieModule\Control\CategoryList\CategoryListControlFactoryInterface
Expand Down
15 changes: 12 additions & 3 deletions src/Bridge/SixtyEightPublishers/OAuth/Azure/AzureAuthenticator.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace App\Bridge\SixtyEightPublishers\OAuth\Azure;

use App\Application\Localization\ApplicationDateTimeZone;
use App\Application\Localization\Profiles;
use App\Domain\User\Command\StoreExternalAuthenticationCommand;
use App\Domain\User\RolesEnum;
use App\ReadModel\User\UserView;
Expand All @@ -30,6 +32,7 @@ public function __construct(
private readonly CommandBusInterface $commandBus,
private readonly QueryBusInterface $queryBus,
private readonly LoggerInterface $logger,
private readonly Profiles $profiles,
) {}

public function authenticate(string $flowName, AuthorizationResult $authorizationResult): IIdentity
Expand Down Expand Up @@ -90,7 +93,7 @@ public function authenticate(string $flowName, AuthorizationResult $authorizatio
);

$identity = IdentityDecorator::newInstance()->wakeupIdentity(
identity: Identity::createSleeping($userId),
identity: Identity::createSleeping(UserId::fromString($userId)),
queryBus: $this->queryBus,
);

Expand All @@ -114,15 +117,21 @@ private function createUser(ResourceOwnerInterface $resourceOwner, string $flowN
$userData = $resourceOwner->toArray();

try {
$this->commandBus->dispatch(CreateUserCommand::create(
$command = CreateUserCommand::create(
username: $username,
password: null,
emailAddress: $username,
firstname: $userData['given_name'] ?? '',
surname: $userData['family_name'] ?? '',
roles: $roles,
userId: $userId,
));
);

$command = $command
->withParam('profile', $this->profiles->active()->locale())
->withParam('timezone', ApplicationDateTimeZone::get()->getName());

$this->commandBus->dispatch($command);
} catch (Throwable $e) {
$this->logger->error(sprintf(
'Unable to create the user with oid %s via %s. %s',
Expand Down
4 changes: 4 additions & 0 deletions src/Domain/User/ValueObject/AuthProviderCode.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@

final class AuthProviderCode extends AbstractStringValueObject
{
public function __toString(): string
{
return $this->value();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
</cascade>
</one-to-many>

<one-to-many field="externalAuths" target-entity="App\Domain\User\ExternalAuth" mapped-by="user" orphan-removal="true">
<one-to-many field="externalAuths" target-entity="App\Domain\User\ExternalAuth" mapped-by="user" orphan-removal="true" fetch="LAZY" index-by="providerCode">
<cascade>
<cascade-persist />
<cascade-remove />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

namespace App\Infrastructure\User\Doctrine\ReadModel;

use App\ReadModel\User\ExternalAuthView;
use App\ReadModel\User\FindExternalAuthenticationsQuery;
use DateTimeImmutable;
use DateTimeZone;
use Doctrine\DBAL\Connection;
use Exception;
use SixtyEightPublishers\ArchitectureBundle\ReadModel\Query\QueryHandlerInterface;

final class FindExternalAuthenticationsQueryHandler implements QueryHandlerInterface
{
public function __construct(
private readonly Connection $connection,
) {}

/**
* @return array<int, ExternalAuthView>
* @throws Exception
*/
public function __invoke(FindExternalAuthenticationsQuery $query): array
{
$rows = $this->connection->createQueryBuilder()
->select('uea.user_id, uea.provider_code, uea.created_at, uea.resource_owner_id')
->from('user_external_auth', 'uea')
->join('uea', '"user"', 'u', 'u.id = uea.user_id AND u.deleted_at IS NULL')
->where('uea.user_id = :userId')
->orderBy('uea.created_at', 'DESC')
->setParameters([
'userId' => $query->userId(),
])
->fetchAllAssociative();

$result = [];

foreach ($rows as $row) {
$result[] = new ExternalAuthView(
userId: $row['user_id'],
providerCode: $row['provider_code'],
createdAt: new DateTimeImmutable($row['created_at'], new DateTimeZone('UTC')),
resourceOwnerId: $row['resource_owner_id'],
);
}

return $result;
}
}
17 changes: 17 additions & 0 deletions src/ReadModel/User/ExternalAuthView.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

namespace App\ReadModel\User;

use DateTimeImmutable;

final class ExternalAuthView
{
public function __construct(
public readonly string $userId,
public readonly string $providerCode,
public readonly ?DateTimeImmutable $createdAt,
public readonly string $resourceOwnerId,
) {}
}
22 changes: 22 additions & 0 deletions src/ReadModel/User/FindExternalAuthenticationsQuery.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace App\ReadModel\User;

use SixtyEightPublishers\ArchitectureBundle\ReadModel\Query\AbstractQuery;

final class FindExternalAuthenticationsQuery extends AbstractQuery
{
public static function create(string $userId): self
{
return self::fromParameters([
'user_id' => $userId,
]);
}

public function userId(): string
{
return $this->getParam('user_id');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace App\Web\AdminModule\UserModule\Control\ExternalAuthList;

use App\ReadModel\User\FindExternalAuthenticationsQuery;
use App\Web\Ui\Control;
use SixtyEightPublishers\ArchitectureBundle\Bus\QueryBusInterface;

final class ExternalAuthListControl extends Control
{
public function __construct(
private readonly string $userId,
private readonly QueryBusInterface $queryBus,
) {}

protected function beforeRender(): void
{
parent::beforeRender();

$template = $this->getTemplate();
assert($template instanceof ExternalAuthListTemplate);

$template->externalAuths = $this->queryBus->dispatch(FindExternalAuthenticationsQuery::create(
userId: $this->userId,
));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace App\Web\AdminModule\UserModule\Control\ExternalAuthList;

interface ExternalAuthListControlFactoryInterface
{
public function create(string $userId): ExternalAuthListControl;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace App\Web\AdminModule\UserModule\Control\ExternalAuthList;

use App\ReadModel\User\ExternalAuthView;
use Nette\Bridges\ApplicationLatte\Template;

final class ExternalAuthListTemplate extends Template
{
/** @var array<int, ExternalAuthView> */
public array $externalAuths;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{templateType App\Web\AdminModule\UserModule\Control\ExternalAuthList\ExternalAuthListTemplate}

<div class="px-4 sm:px-6 lg:px-8 py-4">
<div class="-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
<div class="inline-block min-w-full py-2 align-middle sm:px-6 lg:px-8">
<table class="min-w-full divide-y divide-gray-300">
<thead>
<tr>
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-0">{_auth_type}</th>
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">{_resource_owner_id}</th>
</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
<tr n:foreach="$externalAuths as $externalAuth">
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm text-gray-500 sm:pl-0">{$externalAuth->providerCode}</td>
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">{$externalAuth->resourceOwnerId}</td>
</tr>
<tr n:if="0 >= count($externalAuths)">
<td colspan="2" class="whitespace-nowrap py-4 pl-4 pr-3 text-sm text-gray-500 sm:pl-0">{_no_rows}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
10 changes: 10 additions & 0 deletions src/Web/AdminModule/UserModule/Presenter/EditUserPresenter.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
use App\Application\Acl\UserResource;
use App\ReadModel\User\UserView;
use App\Web\AdminModule\Presenter\AdminPresenter;
use App\Web\AdminModule\UserModule\Control\ExternalAuthList\ExternalAuthListControl;
use App\Web\AdminModule\UserModule\Control\ExternalAuthList\ExternalAuthListControlFactoryInterface;
use App\Web\AdminModule\UserModule\Control\NotificationPreferences\Event\NotificationPreferencesProcessingFailedEvent;
use App\Web\AdminModule\UserModule\Control\NotificationPreferences\Event\NotificationPreferencesUpdatedEvent;
use App\Web\AdminModule\UserModule\Control\NotificationPreferences\NotificationPreferencesControl;
Expand All @@ -31,6 +33,7 @@ final class EditUserPresenter extends AdminPresenter
public function __construct(
private readonly UserFormControlFactoryInterface $userFormControlFactory,
private readonly NotificationPreferencesControlFactoryInterface $notificationPreferencesControlFactory,
private readonly ExternalAuthListControlFactoryInterface $externalAuthListControlFactory,
private readonly QueryBusInterface $queryBus,
) {
parent::__construct();
Expand Down Expand Up @@ -91,4 +94,11 @@ protected function createComponentNotificationPreferences(): NotificationPrefere

return $control;
}

protected function createComponentExternalAuthList(): ExternalAuthListControl
{
return $this->externalAuthListControlFactory->create(
userId: $this->userView->id->toString(),
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,18 @@
{control userForm}
</div>

<div class="bg-white shadow sm:rounded-lg">
<div class="bg-white shadow sm:rounded-lg mb-12">
<div class="px-4 py-5 sm:px-6 border-b border-gray-200">
<h3 class="text-lg leading-6 font-medium text-gray-900">{_notification_preferences}</h3>
</div>

{control notificationPreferences}
</div>

<div class="bg-white shadow sm:rounded-lg">
<div class="px-4 py-5 sm:px-6 border-b border-gray-200">
<h3 class="text-lg leading-6 font-medium text-gray-900">{_external_auth_list}</h3>
</div>

{control externalAuthList}
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
auth_type: Typ autentizace
resource_owner_id: ID uživatele
no_rows: Uživatel nepoužívá žádnou externí autentizaci.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
auth_type: Authentication type
resource_owner_id: User ID
no_rows: The user does not use any external authentication.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
page_title: Upravit uživatele
heading_basic: Základní informace
notification_preferences: Nastavení notifikací
external_auth_list: Externí autentizace
back_to_list: Zpět na výpis uživatelů

message:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
page_title: Edit user
heading_basic: Basic information
notification_preferences: Notification settings
external_auth_list: External authentication
back_to_list: Back to the user list

message:
Expand Down

0 comments on commit b3cf600

Please sign in to comment.