psr12 fixes for new PHP_CodeSniffer (#4795)
[openemr.git] / src / Common / Auth / OpenIDConnect / Entities / UserEntity.php
blob5ad2f746eaa5ded29c5f03802cfab22e6af96b16
1 <?php
3 /**
4 * Authorization Server Member
6 * @package OpenEMR
7 * @link http://www.open-emr.org
8 * @author Jerry Padgett <sjpadgett@gmail.com>
9 * @copyright Copyright (c) 2020 Jerry Padgett <sjpadgett@gmail.com>
10 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
13 namespace OpenEMR\Common\Auth\OpenIDConnect\Entities;
15 use League\OAuth2\Server\Entities\UserEntityInterface;
16 use League\OAuth2\Server\Exception\OAuthServerException;
17 use OpenEMR\Common\Auth\AuthUtils;
18 use OpenEMR\Common\Auth\MfaUtils;
19 use OpenEMR\Common\Auth\UuidUserAccount;
20 use OpenEMR\Common\Logging\SystemLogger;
21 use OpenEMR\Common\Uuid\UuidRegistry;
22 use OpenEMR\Services\PractitionerService;
23 use OpenIDConnectServer\Entities\ClaimSetInterface;
25 class UserEntity implements ClaimSetInterface, UserEntityInterface
27 public $userRole;
28 public $identifier;
30 public function getClaims()
32 $claimsType = (!empty($_REQUEST['grant_type']) && ($_REQUEST['grant_type'] === 'client_credentials')) ? 'client' : 'oidc';
33 if ($claimsType === 'oidc') {
34 $uuidToUser = new UuidUserAccount($this->identifier);
35 $fhirUser = '';
36 $userRole = $uuidToUser->getUserRole();
37 $fhirUserResource = "Person";
38 if ($userRole == UuidUserAccount::USER_ROLE_USERS) {
39 // need to find out if its a practitioner or not
40 $practitionerService = new PractitionerService();
41 // ONC validation does not accept Person as a valid test case so we have to differentiate practitioners
42 // from the more generic Person resource.
43 if ($practitionerService->isValidPractitionerUuid($this->identifier)) {
44 $fhirUserResource = "Practitioner";
46 } else if ($userRole == UuidUserAccount::USER_ROLE_PATIENT) {
47 $fhirUserResource = "Patient";
48 } else {
49 (new SystemLogger())->error("user role not supported for fhirUser claim ", ['role' => $userRole]);
51 $fhirUser = $GLOBALS['site_addr_oath'] . $GLOBALS['web_root'] . '/apis/' . $_SESSION['site_id'] . "/fhir/" . $fhirUserResource . "/" . $this->identifier;
53 (new SystemLogger())->debug("UserEntity->getClaims() fhirUser claim is ", ['role' => $userRole, 'fhirUser' => $fhirUser]);
55 $user = $uuidToUser->getUserAccount();
56 if (empty($user)) {
57 $user = false;
59 $claims = [
60 'name' => $user['fullname'],
61 'family_name' => $user['lastname'],
62 'given_name' => $user['firstname'],
63 'middle_name' => $user['middlename'],
64 'nickname' => '',
65 'preferred_username' => $user['username'] ?? '',
66 'profile' => '',
67 'picture' => '',
68 'website' => '',
69 'gender' => '',
70 'birthdate' => '',
71 'zoneinfo' => '',
72 'locale' => 'US',
73 'updated_at' => '',
74 'email' => $user['email'],
75 'email_verified' => true,
76 'phone_number' => $user['phone'],
77 'phone_number_verified' => true,
78 'address' => $user['street'] . ' ' . $user['city'] . ' ' . $user['state'],
79 'zip' => $user['zip'],
80 'fhirUser' => $fhirUser,
81 'api:fhir' => true,
82 'api:oemr' => true,
83 'api:port' => true,
86 if ($claimsType === 'client') {
87 $claims = [
88 'fhirUser' => $fhirUser,
89 'api:fhir' => true,
90 'api:oemr' => true,
91 'api:port' => true,
94 if (!empty($_SESSION['nonce'])) {
95 $claims['nonce'] = $_SESSION['nonce'];
97 if ($_SESSION['site_id']) {
98 $claims['site'] = $_SESSION['site_id'];
101 return $claims;
104 public function getIdentifier()
106 return $this->identifier;
109 public function setIdentifier($id): void
111 $this->identifier = $id;
114 protected function getAccountByPassword($userrole, $username, $password, $email = ''): bool
116 if (($userrole == UuidUserAccount::USER_ROLE_USERS) && (($GLOBALS['oauth_password_grant'] == 1) || ($GLOBALS['oauth_password_grant'] == 3))) {
117 $auth = new AuthUtils('api');
118 if ($auth->confirmPassword($username, $password)) {
119 $id = $auth->getUserId();
120 UuidRegistry::createMissingUuidsForTables(['users']);
121 $uuid = sqlQueryNoLog("SELECT `uuid` FROM `users` WHERE `id` = ?", [$id])['uuid'];
122 if (empty($uuid)) {
123 error_log("OpenEMR Error: unable to map uuid for user when creating oauth password grant token");
124 return false;
126 $this->setIdentifier(UuidRegistry::uuidToString($uuid));
128 // If an mfa_token was provided, then will force TOTP MFA (U2F impossible to support via password grant)
129 // (note that this is only forced if mfa_token is provided)
130 $mfa = new MfaUtils($id);
131 $mfaToken = $mfa->tokenFromRequest(MfaUtils::TOTP);
132 if (!is_null($mfaToken)) {
133 if (!$mfa->isMfaRequired() || !in_array(MfaUtils::TOTP, $mfa->getType())) {
134 // A mfa_token was provided, however the user is not configured for totp
135 throw new OAuthServerException(
136 'MFA not supported.',
138 'mfa_not_supported',
141 } else {
142 //Check the validity of the totp token, if applicable
143 if (!empty($mfaToken) && $mfa->check($mfaToken, MfaUtils::TOTP)) {
144 return true;
145 } else {
146 throw new OAuthServerException(
147 $mfa->errorMessage(),
149 'mfa_token_invalid',
156 return true;
158 } elseif (($userrole == UuidUserAccount::USER_ROLE_PATIENT) && (($GLOBALS['oauth_password_grant'] == 2) || ($GLOBALS['oauth_password_grant'] == 3))) {
159 $auth = new AuthUtils('portal-api');
160 if ($auth->confirmPassword($username, $password, $email)) {
161 $id = $auth->getPatientId();
162 UuidRegistry::createMissingUuidsForTables(['patient_data']);
163 $uuid = sqlQueryNoLog("SELECT `uuid` FROM `patient_data` WHERE `pid` = ?", [$id])['uuid'];
164 if (empty($uuid)) {
165 error_log("OpenEMR Error: unable to map uuid for patient when creating oauth password grant token");
166 return false;
168 $this->setIdentifier(UuidRegistry::uuidToString($uuid));
169 return true;
173 return false;