AuthController   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 136
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 11
Bugs 0 Features 1
Metric Value
wmc 14
c 11
b 0
f 1
lcom 1
cbo 4
dl 0
loc 136
rs 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
A getKey() 0 4 1
A getIssuedBy() 0 4 1
A getAuthUrl() 0 4 1
A getTestToken() 0 4 1
A authorizationEncode() 0 11 2
A authorizationDecode() 0 9 2
A passwordEncrypt() 0 8 1
A passwordDecrypt() 0 8 2
A loadEnv() 0 8 2
1
<?php
2
3
/**
4
 * AuthController manages the authentication i.e generation of token
5
 *
6
 * @package Ibonly\NaijaEmoji\AuthController
7
 * @author  Ibraheem ADENIYI <[email protected]>
8
 * @license MIT <https://opensource.org/licenses/MIT>
9
 */
10
11
namespace Ibonly\NaijaEmoji;
12
13
use Exception;
14
use Slim\Slim;
15
use Dotenv\Dotenv;
16
use Firebase\JWT\JWT;
17
use Ibonly\NaijaEmoji\User;
18
use Ibonly\NaijaEmoji\AuthInterface;
19
use Ibonly\NaijaEmoji\InvalidTokenException;
20
21
class AuthController implements AuthInterface
22
{
23
    protected $key;
24
    protected $userID;
25
    protected $auth_url;
26
    protected $issued_by;
27
28
    public function __construct ()
29
    {
30
        $this->loadEnv();
31
        $this->key        = getenv('ISSUE_KEY');
32
        $this->issued_by  = getenv('ISSUED_BY');
33
        $this->auth_url   = getenv('AUTH_URL');
34
        $this->test_token = getenv('TEST_TOKEN');
0 ignored issues
show
Bug introduced by
The property test_token does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
35
    }
36
37
    /**
38
     * getKey Get the ISSUE_KEY value
39
     *
40
     * @return string
41
     */
42
    public function getKey ()
43
    {
44
        return $this->key;
45
    }
46
47
    /**
48
     * getIssuedBy Get the ISSUED_BY value
49
     *
50
     * @return string
51
     */
52
    public function getIssuedBy ()
53
    {
54
        return $this->issued_by;
55
    }
56
57
    /**
58
     * getAuthUrl Get the AUTH_URL value
59
     *
60
     * @return string
61
     */
62
    public function getAuthUrl ()
63
    {
64
        return $this->auth_url;
65
    }
66
67
    /**
68
     * getAuthUrl Get the TEST_TOKEN value
69
     *
70
     * @return string
71
     */
72
    public function getTestToken ()
73
    {
74
        return $this->test_token;
75
    }
76
77
    /**
78
     * authorizationEncode Generate token using $userID
79
     *
80
     * @param  $userID
81
     *
82
     * @return string
83
     */
84
    public function authorizationEncode ($userID)
85
    {
86
        if ( ! is_null($userID) )
87
            $token = array(
88
                "iss" => $this->getIssuedBy(),
89
                "aud" => $this->getAuthUrl(),
90
                "user" => $userID,
91
                "exp" => time() + 3600000
92
            );
93
            return JWT::encode($token, $this->getKey());
0 ignored issues
show
Bug introduced by
The variable $token does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
94
    }
95
96
    /**
97
     * authorizationDecode Decode token
98
     *
99
     * @param  $token
100
     *
101
     * @return json
102
     */
103
    public function authorizationDecode ($token)
104
    {
105
        try
106
        {
107
            return JWT::decode($token, $this->getKey(), array('HS256'));
108
        } catch ( Exception $e) {
109
            throw new InvalidTokenException();
110
        }
111
    }
112
113
    /**
114
     * Encrypt user password
115
     *
116
     * @param  $password
117
     *
118
     * @return string
119
     */
120
    public function passwordEncrypt ($password)
121
    {
122
        $options = [
123
            'cost' => 11,
124
            'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM),
125
        ];
126
        return password_hash($password, PASSWORD_BCRYPT, $options);
127
    }
128
129
    /**
130
     * Decrypt user password
131
     *
132
     * @param  $password
133
     *
134
     * @return bool
135
     */
136
    public function passwordDecrypt ($password, $hashPassword)
137
    {
138
        if ( password_verify($password, $hashPassword) )
139
        {
140
            return true;
141
        }
142
        throw new PasswordException();
143
    }
144
145
    /**
146
     * Load .env data
147
     */
148
    protected function loadEnv ()
0 ignored issues
show
Coding Style introduced by
loadEnv uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
149
    {
150
        if ( ! getenv("APP_ENV"))
151
        {
152
            $dotenv = new Dotenv($_SERVER['DOCUMENT_ROOT']);
153
            $dotenv->load();
154
        }
155
    }
156
}
157