TokenAuthenticate::getUser()   B
last analyzed

Complexity

Conditions 8
Paths 8

Size

Total Lines 32

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 8.0109

Importance

Changes 0
Metric Value
cc 8
nc 8
nop 1
dl 0
loc 32
rs 8.1635
c 0
b 0
f 0
ccs 17
cts 18
cp 0.9444
crap 8.0109
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\Utility\Hash;
18
use \OutOfBoundsException;
19
20
/**
21
 * Class TokenAuthenticate. Login the uses by Api Key
22
 */
23
class TokenAuthenticate 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 api key value from
35
        'name' => 'token',
36
        //db table where the key is stored
37
        'table' => 'users',
38
        //db field where the key is stored
39
        'field' => 'api_token',
40
        //require SSL to pass the token. You should always require SSL to use tokens for Auth
41
        'require_ssl' => true,
42
    ];
43
44
    /**
45
     * Authenticate callback
46
     * Reads the Api Key based on configuration and login the user
47
     *
48
     * @param ServerRequest $request Cake request object.
49
     * @param Response $response Cake response object.
50
     * @return mixed
51
     */
52 7
    public function authenticate(ServerRequest $request, Response $response)
53
    {
54 7
        return $this->getUser($request);
55
    }
56
57
    /**
58
     * Stateless Authentication System
59
     *
60
     * @param ServerRequest $request Cake request object.
61
     * @return mixed
62
     */
63 55
    public function getUser(ServerRequest $request)
64
    {
65 55
        $type = $this->getConfig('type');
66 55
        if (!in_array($type, $this->types)) {
67 1
            throw new OutOfBoundsException(__d('CakeDC/Api', 'Type {0} is not valid', $type));
68
        }
69
70 54
        if (!is_callable([$this, $type])) {
71
            throw new OutOfBoundsException(__d('CakeDC/Api', 'Type {0} has no associated callable', $type));
72
        }
73
74 54
        $apiKey = $this->$type($request);
75 54
        if (empty($apiKey)) {
76 3
            return false;
77
        }
78
79 52
        if ($this->getConfig('require_ssl') && !$request->is('ssl')) {
80 1
            throw new ForbiddenException(__d('CakeDC/Api', 'SSL is required for ApiKey Authentication', $type));
81
        }
82
83 51
        $this->_config['fields']['username'] = $this->getConfig('field');
84 51
        $this->_config['userModel'] = $this->getConfig('table');
85 51
        $this->_config['finder'] = $this->getConfig('finderAuth') ?: 'all';
86 51
        $result = $this->_query($apiKey)->first();
87
88 51
        if (empty($result)) {
89 2
            return false;
90
        }
91
92 49
        return $result->toArray();
93
        //idea: add array with checks to be passed to $request->is(...)
94
    }
95
96
    /**
97
     * Get the api key from the querystring
98
     *
99
     * @param ServerRequest $request request
100
     * @return string api key
101
     */
102 52
    public function querystring(ServerRequest $request)
103
    {
104 52
        $name = $this->getConfig('name');
105
106 52
        return $request->getQuery($name);
107
    }
108
109
    /**
110
     * Get the api key from the header
111
     *
112
     * @param ServerRequest $request request
113
     * @return string api key
114
     */
115 2
    public function header(ServerRequest $request)
116
    {
117 2
        $name = $this->getConfig('name');
118
119 2
        return Hash::get($request->getHeader($name), 0);
120
    }
121
}
122