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

2fa: Initial setup #386

Draft
wants to merge 24 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
05d898a
2fa: Initial setup
dpslwk May 20, 2019
d28fca0
Merge branch 'master' into #355-2fa
dpslwk May 21, 2019
dd7030d
Vagrant: this should help to keep the time in sync now we are using 2fa
dpslwk May 21, 2019
4b046a5
Role: fix missing ArrayColletion init
dpslwk May 21, 2019
3367500
Database: add new artisan `hms:reseed` command
dpslwk May 21, 2019
731cc8a
Vagrant: require new box with added php-imagick to generate qrCodes
dpslwk May 21, 2019
ee591e1
Frontend: Vue #app needs to end before the footer layout
dpslwk May 21, 2019
37bb525
2fa: protect all user routes
dpslwk May 21, 2019
eb0b76b
Merge branch 'master' into #355-2fa
dpslwk May 22, 2019
4f104f6
2fa: Recovery WIP
dpslwk May 22, 2019
f72c759
Merge branch 'master' into #355-2fa
dpslwk May 25, 2019
409c474
Nexmo: pull in sms dependancy
dpslwk May 21, 2019
96f3326
Pins: fix index
dpslwk May 25, 2019
f4e6927
Profile: add verified phone number field
dpslwk May 25, 2019
4d8b0df
User: add recovery codes field
dpslwk May 25, 2019
27e1563
composer: use my orm branch to work around late loading of AclService…
dpslwk May 26, 2019
41cdfb3
UserManager: we only update email if its actually changed
dpslwk May 26, 2019
ccc43c3
Profile: add phone number verification
dpslwk May 26, 2019
d3f66ae
Merge branch 'master' into #355-2fa
dpslwk Jul 7, 2019
d1cf316
Revert Pins: fix index
dpslwk Jul 7, 2019
429612e
Composer updates
dpslwk Jul 7, 2019
f7265cf
Merge branch 'release' into #355-2fa
dpslwk Jul 8, 2019
fee7dd6
Profile: correct contact_number_verified default
dpslwk Jul 8, 2019
3b74631
Merge branch 'master' into #355-2fa
dpslwk Aug 11, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Vagrantfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
vb.customize ['modifyvm', :id, '--memory', '4096']
vb.customize ['modifyvm', :id, '--natdnsproxy1', 'on']
vb.customize ['modifyvm', :id, '--natdnshostresolver1', 'on']
vb.customize ['guestproperty', 'set', :id,
'/VirtualBox/GuestAdd/VBoxService/--timesync-set-threshold', 10000 ]
end

config.vm.provision :shell, path: "dev/vagrant-config/scripts/nginx.sh"
Expand Down
39 changes: 39 additions & 0 deletions app/HMS/Auth/Google2FAAuthenticator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace HMS\Auth;

use PragmaRX\Google2FALaravel\Support\Authenticator;

class Google2FAAuthenticator extends Authenticator
{
/**
* Check if it is already logged in or passable without checking for an OTP.
*
* @return bool
*/
protected function canPassWithoutCheckingOTP()
{
return ! $this->getUser()->isGoogle2faEnable() ||
! $this->isEnabled() ||
$this->noUserIsAuthenticated() ||
$this->twoFactorAuthStillValid();
}

/**
* Get the user Google2FA secret.
*
* @throws InvalidSecretKey
*
* @return mixed
*/
protected function getGoogle2FASecretKey()
{
$secret = $this->getUser()->getGoogle2faSecret();

if (is_null($secret) || empty($secret)) {
throw new InvalidSecretKey('Secret key cannot be empty.');
}

return $secret;
}
}
29 changes: 29 additions & 0 deletions app/HMS/Entities/Profile.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ class Profile
*/
protected $balance;

/**
* Has the contactNumber been verified.
*
* @var bool
*/
protected $contactNumberVerified;

/**
* Profile constructor.
*
Expand All @@ -86,6 +93,7 @@ public function __construct(User $user)
// setup defaults.
$this->creditLimit = 0;
$this->balance = 0;
$this->contactNumberVerified = false;
}

/**
Expand Down Expand Up @@ -304,6 +312,7 @@ public function getContactNumber(): ?string
public function setContactNumber(?string $contactNumber): self
{
$this->contactNumber = $contactNumber;
$this->contactNumberVerified = false;

return $this;
}
Expand Down Expand Up @@ -363,4 +372,24 @@ public function updateBalanceByAmount(int $amount): self

return $this;
}

/**
* @return bool
*/
public function isContactNumberVerified(): bool
{
return $this->contactNumberVerified;
}

/**
* @param bool $contactNumberVerified
*
* @return self
*/
public function setContactNumberVerified(bool $contactNumberVerified): self
{
$this->contactNumberVerified = $contactNumberVerified;

return $this;
}
}
1 change: 1 addition & 0 deletions app/HMS/Entities/Role.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ public function __construct($name, $displayName, $description)
$this->displayName = $displayName;
$this->description = $description;
$this->permissions = new ArrayCollection();
$this->users = new ArrayCollection();
$this->retained = false;
}

Expand Down
90 changes: 90 additions & 0 deletions app/HMS/Entities/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,23 @@ class User implements
*/
protected $rfidTags;

/**
* @var bool
*/
protected $google2faEnable;

/**
* @var string|null
*/
protected $google2faSecret;

/**
* Encrypted recovery codes.
*
* @var string
*/
protected $google2faRecoveryCodes;

/**
* User constructor.
*
Expand All @@ -123,6 +140,7 @@ public function __construct(
$this->roles = new ArrayCollection();
$this->emails = new ArrayCollection();
$this->rfidTags = new ArrayCollection();
$this->google2faEnable = false;
}

/**
Expand Down Expand Up @@ -393,4 +411,76 @@ public function setRfidTags($rfidTags)

return $this;
}

/**
* @return bool
*/
public function isGoogle2faEnable()
{
return $this->google2faEnable;
}

/**
* @param bool $google2faEnable
*
* @return self
*/
public function setGoogle2faEnable(bool $google2faEnable)
{
$this->google2faEnable = $google2faEnable;

return $this;
}

/**
* @return string|null
*/
public function getGoogle2faSecret()
{
return $this->google2faSecret;
}

/**
* @param string|null $google2faSecret
*
* @return self
*/
public function setGoogle2faSecret($google2faSecret)
{
$this->google2faSecret = $google2faSecret;

return $this;
}

/**
* @return string
*/
public function getGoogle2faRecoveryCodes()
{
return $this->google2faRecoveryCodes;
}

/**
* @param string $google2faRecoveryCodes
*
* @return self
*/
public function setGoogle2faRecoveryCodes($google2faRecoveryCodes)
{
$this->google2faRecoveryCodes = $google2faRecoveryCodes;

return $this;
}

/**
* Route notifications for the Nexmo channel.
*
* @param \Illuminate\Notifications\Notification $notification
*
* @return string
*/
public function routeNotificationForNexmo($notification)
{
return $this->profile->getContactNumber();
}
}
5 changes: 5 additions & 0 deletions app/HMS/Mappings/HMS.Entities.Profile.dcm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ HMS\Entities\Profile:
column: contact_number
length: 50
nullable: true
contactNumberVerified:
type: boolean
nullable: false
options:
default: false
dateOfBirth:
type: date
column: date_of_birth
Expand Down
10 changes: 10 additions & 0 deletions app/HMS/Mappings/HMS.Entities.User.dcm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ HMS\Entities\User:
column: email_verified_at
type: datetime
nullable: true
google2faEnable:
type: boolean
options:
default: 0
google2faSecret:
type: string
nullable: true
google2faRecoveryCodes:
type: string
nullable: true
deletedAt:
type: datetime
nullable: true
Expand Down
8 changes: 6 additions & 2 deletions app/HMS/User/ProfileManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
use Carbon\Carbon;
use HMS\Entities\User;
use HMS\Entities\Profile;
use libphonenumber\RegionCode;
use HMS\Repositories\MetaRepository;
use HMS\Repositories\UserRepository;
use HMS\Repositories\ProfileRepository;
use Propaganistas\LaravelPhone\PhoneNumber;

class ProfileManager
{
Expand Down Expand Up @@ -84,7 +86,8 @@ public function create(
$profile->setAddressCity($addressCity);
$profile->setAddressCounty($addressCounty);
$profile->setAddressPostcode($addressPostcode);
$profile->setContactNumber($contactNumber);
$e164 = PhoneNumber::make($contactNumber, RegionCode::GB)->formatE164();
$profile->setContactNumber($e164);

if (! empty($dateOfBirth)) {
$profile->setDateOfBirth(new Carbon($dateOfBirth));
Expand Down Expand Up @@ -141,7 +144,8 @@ public function updateUserProfileFromRequest(User $user, array $request)
}

if (isset($request['contactNumber'])) {
$profile->setContactNumber($request['contactNumber']);
$e164 = PhoneNumber::make($request['contactNumber'], RegionCode::GB)->formatE164();
$profile->setContactNumber($e164);
}

// Nullable field
Expand Down
1 change: 1 addition & 0 deletions app/Http/Controllers/Api/SearchController.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ public function users(string $searchQuery = null, Request $request)
'email' => $user->getEmail(),
'accountId' => $user->getAccount() ? $user->getAccount()->getId() : null,
'paymentRef' => $user->getAccount() ? $user->getAccount()->getPaymentRef() : '',
'google2fa' => $user->isGoogle2faEnable(),
];

if (\Gate::allows('profile.view.all')) {
Expand Down
2 changes: 1 addition & 1 deletion app/Http/Controllers/Auth/RegisterController.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ protected function validator(array $data)
'addressCity' => 'required|max:100',
'addressCounty' => 'required|max:100',
'addressPostcode' => 'required|max:10',
'contactNumber' => 'required|max:50',
'contactNumber' => 'required|max:50|phone:GB',
'dateOfBirth' => 'nullable|date_format:Y-m-d',
]);
}
Expand Down
Loading