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

Support external users #162

Merged
merged 59 commits into from
Nov 9, 2023

Conversation

tuj
Copy link
Contributor

@tuj tuj commented Sep 1, 2023

Link to ticket

https://jira.itkdev.dk/browse/DISPLAY-993

Description

  • Adds "external" openid-connect provider.
  • Renamed "oidc" openid-connect provider to "ad".
  • Modifies User to support external user type.
  • Adds command to set user type.
  • Expands api with external user endpoints.
  • Upgrades openid-connect bundle to 3.1 to support multiple providers.
  • Changes php requirement in composer.json to >= 8.1.
  • Changed user identifier to providerId.

NB! Uses the changes from #163 since support for multiple providers is necessary.

Screenshots

Screenshot 2023-10-04 at 12 17 01

Checklist

  • My code is covered by test cases.
  • My code passes our test (all our tests).
  • My code passes our static analysis suite.
  • My code passes our continuous integration process.

tuj and others added 30 commits September 1, 2023 11:57
@tuj tuj changed the base branch from feature/external-login to develop September 29, 2023 13:39
@tuj tuj changed the base branch from develop to feature/external-login September 29, 2023 13:44
README.md Show resolved Hide resolved
App\Entity\Tenant\UserActivationCode:
itemOperations:
get:
security: 'is_granted("ROLE_ADMIN") or is_granted("ROLE_EXTERNAL_USER_ADMIN")'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be better to only have is_granted("ROLE_EXTERNAL_USER_ADMIN") here and the use the role hierarchy to let ROLE_ADMIN have the ROLE_EXTERNAL_USER_ADMIN. I think that would make it easier to change this later if we decide that **_USER_ADMIN should be a dedicated role.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

get:
security: 'is_granted("ROLE_ADMIN") or is_granted("ROLE_EXTERNAL_USER_ADMIN")'
delete:
security: 'is_granted("ROLE_ADMIN") or is_granted("ROLE_EXTERNAL_USER_ADMIN")'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using role hierarchy as above

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

delete:
security: 'is_granted("ROLE_ADMIN") or is_granted("ROLE_EXTERNAL_USER_ADMIN")'
refresh_code:
security: 'is_granted("ROLE_ADMIN") or is_granted("ROLE_EXTERNAL_USER_ADMIN")'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using role hierarchy as above

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

refresh_code:
security: 'is_granted("ROLE_ADMIN") or is_granted("ROLE_EXTERNAL_USER_ADMIN")'
method: 'POST'
path: '/user-activation-codes/{id}/refresh-code'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have other auth related endpoint under /v1/authentication should this be there as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I will leave it as a separate endpoint since it relates to an entity

$user = $passport->getUser();

if (!$user instanceof User) {
throw new AuthenticationException('UserInterface not of User type');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no idea what that exception message means

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

{
$slugged = $this->slugifyDisplayName($displayName);

return "$slugged@ext";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer $slugged.'@ext' or a sprintf() for readbility

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

$type = UserTypeEnum::OIDC_EXTERNAL;
$name = ExternalUserService::EXTERNAL_USER_DEFAULT_NAME;
$providerId = $this->externalUserService->generatePersonalIdentifierHash($signInName);
$email = null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what the best solution is if the email is not nullable. Either do $signInName.'@ext' as a temporary value or make email nullable, but unique. (MySQL allows multiple NULLs in a column with a unique constraint.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will create a temporary email from providerId when the user has not activated. The mail will be updated after activation.

public function refreshCode(UserActivationCode $code): UserActivationCode
{
$code->setCode($this->generateExternalUserCode());
$code->setCodeExpire((new \DateTime())->add(new \DateInterval('P2D')));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not have this hardcoded two different places (Also found in ExternalUserActivationCodeInputDataTransformer). Promote it to a public class constant here, and then reference it.

(Or better, make it and .env value)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

private function generateRandomCode(): string
{
$length = 12;
$chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Promote to class constant

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@tuj tuj requested a review from turegjorup October 4, 2023 11:48
@tuj tuj merged commit 2f5a3a0 into feature/external-login Nov 9, 2023
10 checks passed
@tuj tuj deleted the feature/external-login-entity-and-api branch November 9, 2023 10:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants