Completed
Push — master ( c53012...534936 )
by Дмитрий
03:26
created

AbstractProvider::discover()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 40
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
dl 0
loc 40
ccs 0
cts 34
cp 0
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 22
nc 4
nop 1
crap 20
1
<?php
2
/**
3
 * SocialConnect project
4
 * @author: Patsura Dmitry https://github.com/ovr <[email protected]>
5
 */
6
7
namespace SocialConnect\Auth\Provider\OpenID;
8
9
use SocialConnect\Auth\Exception\InvalidAccessToken;
10
use SocialConnect\Auth\Exception\InvalidResponse;
11
use SocialConnect\Auth\Provider\AbstractBaseProvider;
12
use SocialConnect\Common\Entity\User;
13
use SocialConnect\Common\Http\Client\Client;
14
15
abstract class AbstractProvider extends AbstractBaseProvider
16
{
17
    /**
18
     * @return string
19
     */
20
    abstract public function getOpenIdUrl();
21
22
    /**
23
     * @var int
24
     */
25
    protected $version;
26
27
    /**
28
     * @var string
29
     */
30
    protected $loginEntrypoint;
31
32
    /**
33
     * @param bool $immediate
34
     * @return string
35
     */
36
    protected function makeAuthUrlV2($immediate)
37
    {
38
        $params = array(
39
            'openid.ns' => 'http://specs.openid.net/auth/2.0',
40
            'openid.mode' => $immediate ? 'checkid_immediate' : 'checkid_setup',
41
            'openid.return_to' => $this->getRedirectUrl(),
42
            'openid.realm' => $this->getRedirectUrl()
43
        );
44
45
        $params['openid.ns.sreg'] = 'http://openid.net/extensions/sreg/1.1';
46
        $params['openid.identity'] = $params['openid.claimed_id'] = 'http://specs.openid.net/auth/2.0/identifier_select';
47
48
        return $this->loginEntrypoint . '?' . http_build_query($params, '', '&');
49
    }
50
51
    /**
52
     * @param string $url
53
     * @return string
54
     * @throws \SocialConnect\Auth\Exception\InvalidResponse
55
     */
56
    protected function discover($url)
57
    {
58
        $response = $this->service->getHttpClient()->request(
59
            $url,
60
            [],
61
            Client::GET,
62
            [
63
                'Content-Type' => 'application/json'
64
            ]
65
        );
66
67
        if (!$response->isSuccess()) {
68
            throw new InvalidResponse(
69
                'API response with error code',
70
                $response
71
            );
72
        }
73
74
        if (!$response->hasHeader('Content-Type')) {
75
            throw new InvalidResponse(
76
                'Unknown Content-Type',
77
                $response
78
            );
79
        }
80
81
        $contentType = $response->getHeader('Content-Type');
82
        if (strpos($contentType, 'application/xrds+xml;charset=utf-8') === false) {
83
            throw new InvalidResponse(
84
                'Unexpected Content-Type',
85
                $response
86
            );
87
        }
88
89
        $xml = new \SimpleXMLElement($response->getBody());
90
91
        $this->version = 2;
92
        $this->loginEntrypoint = $xml->XRD->Service->URI;
93
94
        return $this->getOpenIdUrl();
95
    }
96
97
    public function makeAuthUrl()
98
    {
99
        $this->discover($this->getOpenIdUrl());
100
101
        return $this->makeAuthUrlV2(false);
102
    }
103
104
    /**
105
     * @link http://openid.net/specs/openid-authentication-2_0.html#verification
106
     *
107
     * @param $requestParameters
108
     * @return AccessToken
109
     * @throws \SocialConnect\Auth\Exception\InvalidAccessToken
110
     */
111
    public function getAccessTokenByRequestParameters($requestParameters)
112
    {
113
        $params = array(
114
            'openid.assoc_handle' => $requestParameters['openid_assoc_handle'],
115
            'openid.signed' => $requestParameters['openid_signed'],
116
            'openid.sig' => $requestParameters['openid_sig'],
117
            'openid.ns' => $requestParameters['openid_ns'],
118
            'openid.op_endpoint' => $requestParameters['openid_op_endpoint'],
119
            'openid.claimed_id' => $requestParameters['openid_claimed_id'],
120
            'openid.identity' => $requestParameters['openid_identity'],
121
            'openid.return_to' => $this->getRedirectUrl(),
122
            'openid.response_nonce' => $requestParameters['openid_response_nonce'],
123
            'openid.mode' => 'check_authentication'
124
        );
125
126
        if (isset($requestParameters['openid_claimed_id'])) {
127
            $claimedId = $requestParameters['openid_claimed_id'];
128
        } else {
129
            $claimedId = $requestParameters['openid_identity'];
130
        }
131
132
        $this->discover($claimedId);
133
134
        $response = $this->service->getHttpClient()->request(
135
            $this->loginEntrypoint,
136
            $params,
137
            Client::POST
138
        );
139
140
        if (preg_match('/is_valid\s*:\s*true/i', $response->getBody())) {
141
            return new AccessToken($requestParameters['openid_identity']);
142
        }
143
144
        throw new InvalidAccessToken;
145
    }
146
}
147