Passed
Pull Request — master (#17)
by Alberto
02:16
created

ApiIdentifier   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 65
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
eloc 28
c 2
b 0
f 1
dl 0
loc 65
rs 10
wmc 6

2 Methods

Rating   Name   Duplication   Size   Complexity  
A identify() 0 33 5
A setError() 0 3 1
1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * BEdita, API-first content management framework
6
 * Copyright 2020 ChannelWeb Srl, Chialab Srl
7
 *
8
 * This file is part of BEdita: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published
10
 * by the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * See LICENSE.LGPL or <http://gnu.org/licenses/lgpl-3.0.html> for more details.
14
 */
15
16
namespace BEdita\WebTools\Identifier;
17
18
use Authentication\Identifier\AbstractIdentifier;
19
use BEdita\SDK\BEditaClientException;
20
use BEdita\WebTools\ApiClientProvider;
21
use Cake\Log\LogTrait;
22
use Cake\Utility\Hash;
23
use Psr\Log\LogLevel;
24
25
/**
26
 * Identifier for authentication using BEdita 4 API /auth endpoint.
27
 */
28
class ApiIdentifier extends AbstractIdentifier
29
{
30
    use LogTrait;
31
32
    /**
33
     * Default configuration.
34
     *
35
     * - fields: the fields used for identify user
36
     *
37
     * @var array
38
     */
39
    protected $_defaultConfig = [
40
        'fields' => [
41
            self::CREDENTIAL_USERNAME => 'username',
42
            self::CREDENTIAL_PASSWORD => 'password',
43
        ],
44
    ];
45
46
    /**
47
     * {@inheritDoc}
48
     */
49
    public function identify(array $data)
50
    {
51
        $usernameField = $this->getConfig('fields.' . self::CREDENTIAL_USERNAME);
52
        $passwordField = $this->getConfig('fields.' . self::CREDENTIAL_PASSWORD);
53
        if (!isset($data[$usernameField]) || !isset($data[$passwordField])) {
54
            return null;
55
        }
56
57
        /** @var \BEdita\SDK\BEditaClient $apiClient */
58
        $apiClient = ApiClientProvider::getApiClient();
59
        try {
60
            $result = $apiClient->authenticate(
61
                $data[$usernameField],
62
                $data[$passwordField]
63
            );
64
            if (empty($result['meta'])) {
65
                $this->setError('Invalid username or password');
66
67
                return null;
68
            }
69
            $tokens = $result['meta'];
70
            $result = $apiClient->get('/auth/user', null, ['Authorization' => sprintf('Bearer %s', $tokens['jwt'])]);
71
        } catch (BEditaClientException $e) {
72
            $this->log('Login failed - ' . $e->getMessage(), LogLevel::INFO);
73
            $this->setError($e->getMessage());
74
75
            return null;
76
        }
77
78
        $roles = Hash::extract($result, 'included.{n}.attributes.name');
79
        $identity = $result['data'] + compact('tokens') + compact('roles');
80
81
        return $identity;
82
    }
83
84
    /**
85
     * Add error message to `self::_errors`
86
     *
87
     * @param string $message The error message
88
     * @return void
89
     */
90
    protected function setError($message)
91
    {
92
        $this->_errors[] = $message;
93
    }
94
}
95