Passed
Push — master ( cdfeb3...b96e37 )
by meta
06:35 queued 04:19
created

AzureOauthProvider::mapUserToObject()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 24
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 17
nc 2
nop 1
dl 0
loc 24
rs 8.9713
c 0
b 0
f 0
1
<?php
2
3
namespace Metrogistics\AzureSocialite;
4
5
use Illuminate\Support\Arr;
6
use Laravel\Socialite\Two\User;
7
use Laravel\Socialite\Two\AbstractProvider;
8
use Laravel\Socialite\Two\ProviderInterface;
9
10
class AzureOauthProvider extends AbstractProvider implements ProviderInterface
11
{
12
    const IDENTIFIER = 'AZURE_OAUTH';
13
    protected $scopes = ['User.Read'];
14
    protected $scopeSeparator = ' ';
15
16
    protected function getAuthUrl($state)
17
    {
18
        return $this->buildAuthUrlFromBase('https://login.microsoftonline.com/common/oauth2/authorize', $state);
19
    }
20
21
    protected function getTokenUrl()
22
    {
23
        return 'https://login.microsoftonline.com/common/oauth2/token';
24
    }
25
26
    protected function getTokenFields($code)
27
    {
28
        return array_merge(parent::getTokenFields($code), [
29
            'grant_type' => 'authorization_code',
30
            'resource'   => 'https://graph.microsoft.com',
31
        ]);
32
    }
33
34
    protected function getUserByToken($token)
35
    {
36
        $response = $this->getHttpClient()->get('https://graph.microsoft.com/v1.0/me/', [
37
            'headers' => [
38
                'Authorization' => 'Bearer '.$token,
39
            ],
40
        ]);
41
42
        return json_decode($response->getBody(), true);
43
    }
44
45
    protected function getUserGroupsByToken($token)
46
    {
47
        $response = $this->getHttpClient()->get('https://graph.microsoft.com/v1.0/me/memberOf/', [
48
            'headers' => [
49
                'Authorization' => 'Bearer '.$token,
50
            ],
51
        ]);
52
53
        return json_decode($response->getBody(), true);
54
    }
55
56
    protected function groups($token)
57
    {
58
        $groups = [];
59
        try {
60
            // try updating users bouncer permissions
61
            $azureadgroups = $this->getUserGroupsByToken($token);
62
            // only proceed if we got a good response with group info
63
            if (isset($azureadgroups['value']) && count($azureadgroups['value'])) {
64
                foreach ($azureadgroups['value'] as $group) {
65
                    $groups[] = $group['displayName'];
66
                }
67
            }
68
        } catch (\GuzzleHttp\Exception\ClientException  $e) {
69
            // This is usually due to insufficient permissions on the azure ad app
70
            throw new \Exception('This AzureAD application does not seem to have permission to view user groups. Did you configure that permission in AzureAD correctly? '.$e->getMessage());
71
        } catch (\Exception $e) {
72
            // I have no idea what would cause other exceptions yet
73
            throw $e;
74
        }
75
76
        return $groups;
77
    }
78
79
    public function user()
80
    {
81
        if ($this->hasInvalidState()) {
82
            throw new InvalidStateException();
0 ignored issues
show
Bug introduced by
The type Metrogistics\AzureSocialite\InvalidStateException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
83
        }
84
85
        $response = $this->getAccessTokenResponse($this->getCode());
86
87
        $token = Arr::get($response, 'access_token');
88
        $user = $this->mapUserToObject($this->getUserByToken($token));
89
        $user->groups = $this->groups($token);
0 ignored issues
show
Bug introduced by
The property groups does not seem to exist on Laravel\Socialite\Two\User.
Loading history...
90
        $user->idToken = Arr::get($response, 'id_token');
0 ignored issues
show
Bug introduced by
The property idToken does not seem to exist on Laravel\Socialite\Two\User.
Loading history...
91
        $user->expiresAt = time() + Arr::get($response, 'expires_in');
0 ignored issues
show
Bug introduced by
The property expiresAt does not exist on Laravel\Socialite\Two\User. Did you mean expiresIn?
Loading history...
92
93
        return $user->setToken($token)
94
                    ->setRefreshToken(Arr::get($response, 'refresh_token'));
95
    }
96
97
    protected function mapUserToObject(array $user)
98
    {
99
        //dd($user);
100
        // WELL this is extremely stupid. if email address isnt set, use their UPN...
101
        if (! $user['mail']) {
102
            $user['mail'] = $user['userPrincipalName'];
103
        }
104
105
        return (new User())->setRaw($user)->map([
106
            'id'                => $user['id'],
107
            'name'              => $user['displayName'],
108
            'email'             => $user['mail'],
109
            'password'          => '',
110
111
            'businessPhones'    => $user['businessPhones'],
112
            'displayName'       => $user['displayName'],
113
            'givenName'         => $user['givenName'],
114
            'jobTitle'          => $user['jobTitle'],
115
            'mail'              => $user['mail'],
116
            'mobilePhone'       => $user['mobilePhone'],
117
            'officeLocation'    => $user['officeLocation'],
118
            'preferredLanguage' => $user['preferredLanguage'],
119
            'surname'           => $user['surname'],
120
            'userPrincipalName' => $user['userPrincipalName'],
121
        ]);
122
    }
123
}
124