Skip to content

Commit

Permalink
SSO: Allow to update access urls for user in generic oauth2 - refs BT…
Browse files Browse the repository at this point in the history
…#21881
  • Loading branch information
AngelFQC committed Aug 27, 2024
1 parent d72da91 commit 81507f8
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 1 deletion.
6 changes: 5 additions & 1 deletion config/authentication.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ parameters:
urlAccessToken: ''
urlResourceOwnerDetails: ''
responseResourceOwnerId: 'sub'
accessTokenMethod: 'POST'
# accessTokenMethod: 'POST'
# responseError: 'error'
# responseCode: ''
# scopeSeparator: ' '
scopes:
- openid
allow_create_new_users: true
Expand All @@ -27,6 +30,7 @@ parameters:
resource_owner_hr_status_field: null
resource_owner_status_status_field: null
resource_owner_anon_status_field: null
resource_owner_urls_field: null

facebook:
enabled: false
Expand Down
19 changes: 19 additions & 0 deletions src/CoreBundle/Repository/Node/AccessUrlRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
namespace Chamilo\CoreBundle\Repository\Node;

use Chamilo\CoreBundle\Entity\AccessUrl;
use Chamilo\CoreBundle\Entity\User;
use Chamilo\CoreBundle\Repository\ResourceRepository;
use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\NoResultException;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Persistence\ManagerRegistry;

class AccessUrlRepository extends ResourceRepository
Expand All @@ -36,4 +38,21 @@ public function getFirstId(): int
return 0;
}
}

/**
* @return array<int, AccessUrl>
*/
public function findByUser(User $user): array
{
/** @var QueryBuilder $qb */
$qb = $this->createQueryBuilder('url');

return $qb
->join('url.users', 'users')
->where($qb->expr()->eq('users.user', ':user'))
->setParameter('user', $user->getId())
->getQuery()
->getResult()
;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@

namespace Chamilo\CoreBundle\Security\Authenticator\OAuth2;

use Chamilo\CoreBundle\Entity\AccessUrl;
use Chamilo\CoreBundle\Entity\AccessUrlRelUser;
use Chamilo\CoreBundle\Entity\User;
use Chamilo\CoreBundle\Repository\ExtraFieldRepository;
use Chamilo\CoreBundle\Repository\ExtraFieldValuesRepository;
use Chamilo\CoreBundle\Repository\Node\AccessUrlRepository;
use Chamilo\CoreBundle\Repository\Node\UserRepository;
use Chamilo\CoreBundle\ServiceHelper\AccessUrlHelper;
use Chamilo\CoreBundle\ServiceHelper\AuthenticationConfigHelper;
use Doctrine\ORM\EntityManagerInterface;
use ExtraField;
use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
use League\OAuth2\Client\Provider\GenericResourceOwner;
Expand All @@ -38,6 +42,8 @@ public function __construct(
AccessUrlHelper $urlHelper,
protected readonly ExtraFieldRepository $extraFieldRepository,
protected readonly ExtraFieldValuesRepository $extraFieldValuesRepository,
protected readonly AccessUrlRepository $accessUrlRepository,
protected readonly EntityManagerInterface $entityManager,
) {
parent::__construct(
$clientRegistry,
Expand Down Expand Up @@ -108,6 +114,8 @@ protected function userLoader(AccessToken $accessToken): User
$user,
$resourceOwnerId
);

$this->updateUrls($user, $resourceOwnerData, $providerParams);
} else {
/** @var User $user */
$user = $this->userRepository->find(
Expand All @@ -116,6 +124,8 @@ protected function userLoader(AccessToken $accessToken): User

if ($providerParams['allow_update_user_info']) {
$this->saveUserInfo($user, $resourceOwnerData, $providerParams);

$this->updateUrls($user, $resourceOwnerData, $providerParams);
}
}

Expand Down Expand Up @@ -203,4 +213,61 @@ private function getUserStatus(array $resourceOwnerData, int $defaultStatus, arr

return $map[$status] ?? $status;
}

private function updateUrls(User $user, array $resourceOwnerData, array $providerParams): void
{
if (!($urlsField = $providerParams['resource_owner_urls_field'])) {
return;
}

$availableUrls = [];

$urls = $this->accessUrlRepository->findAll();

/** @var AccessUrl $existingUrl */
foreach ($urls as $existingUrl) {
$availableUrls[(string) $existingUrl->getId()] = $existingUrl->getId();
$availableUrls[$existingUrl->getUrl()] = $existingUrl->getId();
}

$allowedUrlIds = [];

foreach ($this->getValueByKey($resourceOwnerData, $urlsField) as $value) {
if (array_key_exists($value, $availableUrls)) {
$allowedUrlIds[] = $availableUrls[$value];
} else {
$newValue = ($value[-1] === '/') ? substr($value, 0, -1) : $value.'/';

if (array_key_exists($newValue, $availableUrls)) {
$allowedUrlIds[] = $availableUrls[$newValue];
}
}
}

$grantedUrlIds = [];

foreach ($this->accessUrlRepository->findByUser($user) as $grantedUrl) {
$grantedUrlIds[] = $grantedUrl->getId();
}

$urlRelUserRepo = $this->entityManager->getRepository(AccessUrlRelUser::class);

foreach (array_diff($grantedUrlIds, $allowedUrlIds) as $extraUrlId) {
$urlRelUser = $urlRelUserRepo->findOneBy(['user' => $user, 'url' => $extraUrlId]);

if ($urlRelUser) {
$this->entityManager->remove($urlRelUser);
}
}

$this->entityManager->flush();

foreach (array_diff($allowedUrlIds, $grantedUrlIds) as $missingUrlId) {
/** @var AccessUrl $missingUrl */
$missingUrl = $this->accessUrlRepository->find($missingUrlId);
$missingUrl->addUser($user);
}

$this->entityManager->flush();
}
}

0 comments on commit 81507f8

Please sign in to comment.