SocialAuthenticate::getUser()   B
last analyzed

Complexity

Conditions 9
Paths 7

Size

Total Lines 36

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 9.081

Importance

Changes 0
Metric Value
cc 9
nc 7
nop 1
dl 0
loc 36
rs 8.0555
c 0
b 0
f 0
ccs 18
cts 20
cp 0.9
crap 9.081
1
<?php
2
/**
3
 * Copyright 2016 - 2018, Cake Development Corporation (http://cakedc.com)
4
 *
5
 * Licensed under The MIT License
6
 * Redistributions of files must retain the above copyright notice.
7
 *
8
 * @copyright Copyright 2016 - 2018, Cake Development Corporation (http://cakedc.com)
9
 * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
10
 */
11
12
namespace CakeDC\Api\Service\Auth\Authenticate;
13
14
use Cake\Http\Exception\ForbiddenException;
15
use Cake\Http\Response;
16
use Cake\Http\ServerRequest;
17
use Cake\ORM\TableRegistry;
18
use Cake\Utility\Hash;
19
use \OutOfBoundsException;
20
21
/**
22
 * Class SocialAuthenticate. Login the uses by Api Key
23
 */
24
class SocialAuthenticate extends BaseAuthenticate
25
{
26
    const TYPE_QUERYSTRING = 'querystring';
27
    const TYPE_HEADER = 'header';
28
29
    public $types = [self::TYPE_QUERYSTRING, self::TYPE_HEADER];
30
31
    protected $_defaultConfig = [
32
        //type, can be either querystring or header
33
        'type' => self::TYPE_QUERYSTRING,
34
        //name to retrieve the provider value from
35
        'provider_name' => 'provider',
36
        //name to retrieve the token value from
37
        'token_name' => 'token',
38
        //name to retrieve the token secret value from
39
        'token_secret_name' => 'token_secret',
40
        //db table where the key is stored
41
        'table' => 'CakeDC/Users.SocialAccounts',
42
        //db table where the key is stored
43
        'userModel' => 'CakeDC/Users.Users',
44
        //db field where the provider is stored
45
        'provider_field' => 'provider',
46
        //db field where the token is stored
47
        'token_field' => 'token',
48
        //db field where the token secret is stored
49
        'token_secret_field' => 'token_secret',
50
        //require SSL to pass the token. You should always require SSL to use tokens for Auth
51
        'require_ssl' => true,
52
        //finder for social accounts,
53
        'finder' => 'active'
54
    ];
55
56
    /**
57
     * Authenticate callback
58
     * Reads the Api Key based on configuration and login the user
59
     *
60
     * @param ServerRequest $request Cake request object.
61
     * @param Response $response Cake response object.
62
     * @return mixed
63
     */
64
    public function authenticate(ServerRequest $request, Response $response)
65 7
    {
66
        return $this->getUser($request);
67 7
    }
68
69
    /**
70
     * Stateless Authentication System
71
     *
72
     * @param ServerRequest $request Cake request object.
73
     * @return mixed
74
     */
75
    public function getUser(ServerRequest $request)
76 7
    {
77
        $type = $this->getConfig('type');
78 7
        if (!in_array($type, $this->types)) {
79 7
            throw new OutOfBoundsException(__d('CakeDC/Api', 'Type {0} is not valid', $type));
80 1
        }
81
82
        if (!is_callable([$this, $type])) {
83 6
            throw new OutOfBoundsException(__d('CakeDC/Api', 'Type {0} has no associated callable', $type));
84
        }
85
86
        list($provider, $token, $tokenSecret) = $this->$type($request);
87 6
        if (empty($provider) || empty($token)) {
88 6
            return false;
89 2
        }
90
91
        if ($this->getConfig('require_ssl') && !$request->is('ssl')) {
92 5
            throw new ForbiddenException(__d('CakeDC/Api', 'SSL is required for ApiKey Authentication', $type));
93 1
        }
94
95
        $socialAccount = $this->_socialQuery($provider, $token, $tokenSecret)->first();
96 4
97
        if (empty($socialAccount)) {
98 4
            return false;
99 2
        }
100
101
        $this->_config['fields']['username'] = 'id';
102 2
        $this->_config['finder'] = 'all';
103 2
104
        $result = $this->_query($socialAccount->user_id)->first();
105 2
        if (empty($result)) {
106 2
            return false;
107
        }
108
109
        return $result->toArray();
110 2
    }
111
112
    /**
113
     * Get query object for fetching user from database.
114
     *
115
     * @param string $provider provider
116
     * @param string $token token
117
     * @param string $tokenSecret secret
118
     * @return \Cake\ORM\Query
119
     */
120
    protected function _socialQuery($provider, $token, $tokenSecret)
121 4
    {
122
        $table = TableRegistry::getTableLocator()->get($this->getConfig('table'));
123 4
124
        $conditions = [
125
            $table->aliasField($this->getConfig('provider_field')) => $provider,
126 4
            $table->aliasField($this->getConfig('token_field')) => $token,
127 4
            $table->aliasField($this->getConfig('token_secret_field')) . ' IS' => $tokenSecret,
128 4
        ];
129 4
        $query = $table->find($this->getConfig('finder'))->where($conditions);
130 4
131
        return $query;
132 4
    }
133
134
    /**
135
     * Get the api key from the querystring
136
     *
137
     * @param ServerRequest $request request
138
     * @return string api key
139
     */
140
    public function querystring(ServerRequest $request)
141 4
    {
142
        $providerName = $this->getConfig('provider_name');
143 4
        $tokenName = $this->getConfig('token_name');
144 4
        $tokenSecret = $this->getConfig('token_secret_name');
145 4
146
        return [$request->getQuery($providerName), $request->getQuery($tokenName), $request->getQuery($tokenSecret)];
147 4
    }
148
149
    /**
150
     * Get the api key from the header
151
     *
152
     * @param ServerRequest $request request
153
     * @return string api key
154
     */
155
    public function header(ServerRequest $request)
156 2
    {
157
        $providerName = $this->getConfig('provider_name');
158 2
        $tokenName = $this->getConfig('token_name');
159 2
        $tokenSecret = $this->getConfig('token_secret_name');
160 2
161
        return [Hash::get($request->getHeader($providerName), 0), Hash::get($request->getHeader($tokenName), 0), Hash::get($request->getHeader($tokenSecret), 0)];
162 2
    }
163
}
164