Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleanup for User login, Applications+domains & session stuff for better logging #1581

Merged
merged 6 commits into from
Nov 10, 2023
5 changes: 2 additions & 3 deletions api/src/Controller/LoginController.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,8 @@ public function MeAction(Request $request, CommonGroundService $commonGroundServ
'last_name' => $this->getUser()->getLastName(),
'name' => $this->getUser()->getName(),
'email' => $this->getUser()->getEmail(),
// TODO: if we have no person connected to this user create one? with $this->createPersonForUser()
'person' => $userService->getPersonForUser($this->getUser()),
'organization' => $userService->getOrganizationForUser($this->getUser()),
'person' => $userService->getPersonForUser($this->getUser()), // Get person ObjectEntity (->Entity with function = person) by id
'organization' => $userService->getOrganizationForUser($this->getUser()), // Get organization ObjectEntity (->Entity with function = organization) by id
];
$result = json_encode($result);
} else {
Expand Down
75 changes: 50 additions & 25 deletions api/src/Controller/UserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public function resetTokenAction(SerializerInterface $serializer, \CommonGateway
$accessToken = $this->authenticationService->refreshAccessToken($session->get('refresh_token'), $session->get('authenticator'));
$user = $this->getUser();
if ($user instanceof AuthenticationUser === false) {
return new Response('User not found', 401);
return new Response(json_encode(["Message" => 'User not found.']), 401, ['Content-type' => 'application/json']);
}

$serializeUser = new User();
Expand Down Expand Up @@ -95,30 +95,28 @@ public function resetTokenAction(SerializerInterface $serializer, \CommonGateway
$status = 200;
$user = $this->getUser();
if ($user instanceof AuthenticationUser === false) {
return new Response('User not found', 401);
return new Response(json_encode(["Message" => 'User not found.']), 401, ['Content-type' => 'application/json']);
}

$user = $this->entityManager->getRepository('App:User')->find($user->getUserIdentifier());

if ($user->getOrganization() !== null) {
$organizations[] = $user->getOrganization();
}
foreach ($user->getApplications() as $application) {
if ($application->getOrganization() !== null) {
$organizations[] = $application->getOrganization();
}
}
// Set organization id and user id in session
$this->session->set('user', $user->getId()->toString());
$this->session->set('organization', $user->getOrganization() !== null ? $user->getOrganization()->getId()->toString() : null);

// If user has no organization, we default activeOrganization to an organization of a userGroup this user has and else the application organization;
$this->session->set('activeOrganization', $user->getOrganization()->getId()->toString());
$response = $this->validateUserApp($user);
if ($response !== null)
return $response;

// TODO: maybe do not just get the first Application here, but get application using ApplicationService->getApplication() and ...
// todo... if this returns an application check if the user is part of this application or one of the organizations of this application?
$user->setJwtToken($authenticationService->createJwtToken($user->getApplications()[0]->getPrivateKey(), $authenticationService->serializeUser($user, $this->session)));

return new Response($serializer->serialize($user, 'json'), $status, ['Content-type' => 'application/json']);
}

/**
* Create an authentication user from a entity user.
* Create an authentication user from an entity user.
*
* @param User $user The user to log in.
*
Expand Down Expand Up @@ -166,10 +164,11 @@ public function createAuthenticationUser(User $user): AuthenticationUser
}

/**
* Add the logged in user to session.
* Add the logged-in user to session.
*
* @param User $user The user to log in.
* @param User $user The user to log in.
* @param EventDispatcherInterface $eventDispatcher The event dispatcher.
* @param Request $request
*
* @return void
*/
Expand Down Expand Up @@ -203,18 +202,16 @@ public function apiLoginAction(Request $request, UserPasswordHasherInterface $ha
return new Response(json_encode($response), 401, ['Content-type' => 'application/json']);
}

if ($user->getOrganization() !== null) {
$organizations[] = $user->getOrganization();
}
foreach ($user->getApplications() as $application) {
if ($application->getOrganization() !== null) {
$organizations[] = $application->getOrganization();
}
}
// Set organization id and user id in session
$this->session->set('user', $user->getId()->toString());
$this->session->set('organization', $user->getOrganization() !== null ? $user->getOrganization()->getId()->toString() : null);

// If user has no organization, we default activeOrganization to an organization of a userGroup this user has and else the application organization;
$this->session->set('activeOrganization', $user->getOrganization()->getId()->toString());
$response = $this->validateUserApp($user);
if ($response !== null)
return $response;

// TODO: maybe do not just get the first Application here, but get application using ApplicationService->getApplication() and ...
// todo... if this returns an application check if the user is part of this application or one of the organizations of this application?
$token = $authenticationService->createJwtToken($user->getApplications()[0]->getPrivateKey(), $authenticationService->serializeUser($user, $this->session));

$user->setJwtToken($token);
Expand All @@ -238,6 +235,34 @@ public function apiLoginAction(Request $request, UserPasswordHasherInterface $ha
return new Response(json_encode($userArray), $status, ['Content-type' => 'application/json']);
}

/**
* Checks if $user has an application and if that application has a PrivateKey set. If not return error Response.
*
* @param User $user A user to check.
*
* @return Response|null Error Response or null.
*/
private function validateUserApp(User $user): ?Response
{
if (empty($user->getApplications()) === true) {
return new Response(
json_encode(["Message" => 'This user is not yet connected to any application.']),
409,
['Content-type' => 'application/json']
);
}

if (empty($user->getApplications()[0]->getPrivateKey()) === true) {
return new Response(
json_encode(["Message" => "Can't create a token because application ({$user->getApplications()[0]->getId()->toString()}) doesn't have a PrivateKey."]),
409,
['Content-type' => 'application/json']
);
}

return null;
}

/**
* Removes some sensitive data from the login response.
*
Expand Down
3 changes: 2 additions & 1 deletion api/src/Logger/SessionDataProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class SessionDataProcessor
* @param SessionInterface $session
* @param RequestStack $requestStack
* @param EventDispatcherInterface $eventDispatcher
* @param EntityManagerInterface $entityManager
*/
public function __construct(
SessionInterface $session,
Expand All @@ -48,7 +49,7 @@ public function __construct(
*
* @return array The updated context.
*/
public function updateContext($context): array
public function updateContext(array $context): array
{
$context['session'] = $this->session->getId();
$context['process'] = $this->session->has('process') ? $this->session->get('process') : '';
Expand Down
17 changes: 7 additions & 10 deletions api/src/Repository/ApplicationRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,21 @@ public function __construct(ManagerRegistry $registry)
}

/**
* @param string $domain
* Find all applications that have the given $domain in there list of domains.
*
* @throws NonUniqueResultException
* @param string $domain A domain to search with.
*
* @return Application|null
* @return array|null
*/
public function findByDomain(string $domain): ?Application
public function findByDomain(string $domain): ?array
{
// TODO: something like this
$query = $this->createQueryBuilder('a')
->andWhere(':domain IN (a.domains)')
->setParameters(['domain' => $domain]);

// var_dump($query->getDQL());
->andWhere('a.domains LIKE :domain')
->setParameters(['domain' => "%$domain%"]);

return $query
->getQuery()
->getOneOrNullResult();
->getResult();
}

// /**
Expand Down
Loading
Loading