Test Failed
Pull Request — master (#14)
by
unknown
07:58
created

SocialAuthenticate::getUser()   D

Complexity

Conditions 9
Paths 7

Size

Total Lines 36
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 9
eloc 20
nc 7
nop 1
dl 0
loc 36
rs 4.909
c 1
b 0
f 0
1
<?php
2
/**
3
 * Copyright 2016, 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, 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\Network\Exception\ForbiddenException;
15
use Cake\Network\Request;
16
use Cake\Network\Response;
17
use Cake\ORM\TableRegistry;
18
use \OutOfBoundsException;
19
20
/**
21
 * Class SocialAuthenticate. Login the uses by Api Key
22
 */
23
class SocialAuthenticate extends BaseAuthenticate
24
{
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 Request $request Cake request object.
61
     * @param Response $response Cake response object.
62
     * @return mixed
63
     */
64
    public function authenticate(Request $request, Response $response)
65
    {
66
        return $this->getUser($request);
67
    }
68
69
    /**
70
     * Stateless Authentication System
71
     *
72
     * @param Request $request Cake request object.
73
     * @return mixed
74
     */
75
    public function getUser(Request $request)
76
    {
77
        $type = $this->getConfig('type');
78
        if (!in_array($type, $this->types)) {
79
            throw new OutOfBoundsException(__d('CakeDC/Api', 'Type {0} is not valid', $type));
80
        }
81
82
        if (!is_callable([$this, $type])) {
83
            throw new OutOfBoundsException(__d('CakeDC/Api', 'Type {0} has no associated callable', $type));
84
        }
85
86
        list($provider, $token, $tokenSecret) = $this->$type($request);
87
        if (empty($provider) || empty($token)) {
88
            return false;
89
        }
90
91
        if ($this->config('require_ssl') && !$request->is('ssl')) {
0 ignored issues
show
Deprecated Code introduced by
The method Cake\Core\InstanceConfigTrait::config() has been deprecated with message: 3.4.0 use setConfig()/getConfig() instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
92
            throw new ForbiddenException(__d('CakeDC/Api', 'SSL is required for ApiKey Authentication', $type));
93
        }
94
95
        $socialAccount = $this->_socialQuery($provider, $token, $tokenSecret)->first();
96
97
        if (empty($socialAccount)) {
98
            return false;
99
        }
100
101
        $this->_config['fields']['username'] = 'id';
102
        $this->_config['finder'] = 'all';
103
104
        $result = $this->_query($socialAccount->user_id)->first();
105
        if (empty($result)) {
106
            return false;
107
        }
108
109
        return $result->toArray();
110
    }
111
112
    /**
113
     * Get query object for fetching user from database.
114
     *
115
     * @param string $provider
116
     * @param $token
117
     * @param $tokenSecret
118
     * @return \Cake\ORM\Query
119
     */
120
    protected function _socialQuery($provider, $token, $tokenSecret)
121
    {
122
        $table = TableRegistry::get($this->getConfig('table'));
123
124
        $conditions = [
125
            $table->aliasField($this->getConfig('provider_field')) => $provider,
126
            $table->aliasField($this->getConfig('token_field')) => $token,
127
            $table->aliasField($this->getConfig('token_secret_field')) . ' IS' => $tokenSecret,
128
        ];
129
        $query = $table->find($this->getConfig('finder'))->where($conditions);
130
        return $query;
131
    }
132
133
    /**
134
     * Get the api key from the querystring
135
     *
136
     * @param Request $request request
137
     * @return string api key
138
     */
139
    public function querystring(Request $request)
140
    {
141
        $providerName = $this->getConfig('provider_name');
142
        $tokenName = $this->getConfig('token_name');
143
        $tokenSecret = $this->getConfig('token_secret_name');
144
145
        return [$request->getQuery($providerName), $request->getQuery($tokenName), $request->getQuery($tokenSecret)];
146
    }
147
148
    /**
149
     * Get the api key from the header
150
     *
151
     * @param Request $request request
152
     * @return string api key
153
     */
154
    public function header(Request $request)
155
    {
156
        $providerName = $this->getConfig('provider_name');
157
        $tokenName = $this->getConfig('token_name');
158
        $tokenSecret = $this->getConfig('token_secret_name');
159
160
        return [$request->getHeader($providerName), $request->getHeader($tokenName), $request->getHeader($tokenSecret)];
161
    }
162
}
163