Completed
Push — master ( d2c9b2...2cde9b )
by
unknown
08:05 queued 04:31
created

SocialAuthenticate::getUser()   D

Complexity

Conditions 9
Paths 7

Size

Total Lines 36
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 9.081

Importance

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