Passed
Push — master ( df6194...88909e )
by Raza
02:41
created

Authy::canSendToken()   B

Complexity

Conditions 5
Paths 3

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 7
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 12
rs 8.8571
1
<?php
2
3
namespace Srmklive\Authy\Services;
4
5
use Exception;
6
use GuzzleHttp\Client as HttpClient;
7
use Srmklive\Authy\Contracts\Auth\TwoFactor\Authenticatable as TwoFactorAuthenticatable;
8
use Srmklive\Authy\Contracts\Auth\TwoFactor\PhoneToken as SendPhoneTokenContract;
9
use Srmklive\Authy\Contracts\Auth\TwoFactor\Provider as BaseProvider;
10
use Srmklive\Authy\Contracts\Auth\TwoFactor\SMSToken as SendSMSTokenContract;
11
12
class Authy implements BaseProvider, SendSMSTokenContract, SendPhoneTokenContract
13
{
14
    use CanSendToken;
15
16
    /**
17
     * Array containing configuration data.
18
     *
19
     * @var array
20
     */
21
    private $config;
22
23
    /**
24
     * Authy constructor.
25
     */
26
    public function __construct()
27
    {
28
        if (!empty(config('authy.mode')) && (config('authy.mode') == 'sandbox')) {
29
            $this->config['api_key'] = config('authy.sandbox.key');
30
            $this->config['api_url'] = 'http://sandbox-api.authy.com';
31
        } else {
32
            $this->config['api_key'] = config('authy.live.key');
33
            $this->config['api_url'] = 'https://api.authy.com';
34
        }
35
    }
36
37
    /**
38
     * Determine if the given user has two-factor authentication enabled.
39
     *
40
     * @param \Srmklive\Authy\Contracts\Auth\TwoFactor\Authenticatable $user
41
     *
42
     * @return bool
43
     */
44
    public function isEnabled(TwoFactorAuthenticatable $user)
45
    {
46
        return isset($user->getTwoFactorAuthProviderOptions()['id']);
47
    }
48
49
    /**
50
     * Register the given user with the provider.
51
     *
52
     * @param \Srmklive\Authy\Contracts\Auth\TwoFactor\Authenticatable $user
53
     * @param bool                                                     $sms
54
     *
55
     * @return void
56
     */
57
    public function register(TwoFactorAuthenticatable $user, $sms = false)
58
    {
59
        $response = json_decode((new HttpClient())->post($this->config['api_url'].'/protected/json/users/new?api_key='.$this->config['api_key'], [
60
            'form_params' => [
61
                'user' => [
62
                    'email'        => $user->getEmailForTwoFactorAuth(),
63
                    'cellphone'    => preg_replace('/[^0-9]/', '', $user->getAuthPhoneNumber()),
64
                    'country_code' => $user->getAuthCountryCode(),
65
                ],
66
            ],
67
        ])->getBody(), true);
68
69
        $user->setTwoFactorAuthProviderOptions([
70
            'id'  => $response['user']['id'],
71
            'sms' => $sms,
72
        ]);
73
    }
74
75
    /**
76
     * Send the user two-factor authentication token via SMS.
77
     *
78
     * @param \Srmklive\Authy\Contracts\Auth\TwoFactor\Authenticatable $user
79
     *
80
     * @return void
81
     */
82 View Code Duplication
    public function sendSmsToken(TwoFactorAuthenticatable $user)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
83
    {
84
        try {
85
            $options = $user->getTwoFactorAuthProviderOptions();
86
87
            $response = json_decode((new HttpClient())->get(
88
                $this->config['api_url'].'/protected/json/sms/'.$options['id'].
89
                '?force=true&api_key='.$this->config['api_key']
90
            )->getBody(), true);
91
92
            return $response['success'] === true;
93
        } catch (Exception $e) {
94
            return false;
95
        }
96
    }
97
98
    /**
99
     * Start the user two-factor authentication via phone call.
100
     *
101
     * @param \Srmklive\Authy\Contracts\Auth\TwoFactor\Authenticatable $user
102
     *
103
     * @return void
104
     */
105 View Code Duplication
    public function sendPhoneCallToken(TwoFactorAuthenticatable $user)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
106
    {
107
        try {
108
            $options = $user->getTwoFactorAuthProviderOptions();
109
110
            $response = json_decode((new HttpClient())->get(
111
                $this->config['api_url'].'/protected/json/call/'.$options['id'].
112
                '?force=true&api_key='.$this->config['api_key']
113
            )->getBody(), true);
114
115
            return $response['success'] === true;
116
        } catch (Exception $e) {
117
            return false;
118
        }
119
    }
120
121
    /**
122
     * Determine if the given token is valid for the given user.
123
     *
124
     * @param \Srmklive\Authy\Contracts\Auth\TwoFactor\Authenticatable $user
125
     * @param string                                                   $token
126
     *
127
     * @return bool
128
     */
129
    public function tokenIsValid(TwoFactorAuthenticatable $user, $token)
130
    {
131
        try {
132
            $options = $user->getTwoFactorAuthProviderOptions();
133
134
            $response = json_decode((new HttpClient())->get(
135
                $this->config['api_url'].'/protected/json/verify/'.
136
                $token.'/'.$options['id'].'?force=true&api_key='.
137
                $this->config['api_key']
138
            )->getBody(), true);
139
140
            return $response['token'] === 'is valid';
141
        } catch (Exception $e) {
142
            return false;
143
        }
144
    }
145
146
    /**
147
     * Delete the given user from the provider.
148
     *
149
     * @param \Srmklive\Authy\Contracts\Auth\TwoFactor\Authenticatable $user
150
     *
151
     * @return bool
152
     */
153
    public function delete(TwoFactorAuthenticatable $user)
154
    {
155
        $options = $user->getTwoFactorAuthProviderOptions();
156
157
        (new HttpClient())->post(
158
            $this->config['api_url'].'/protected/json/users/delete/'.
159
            $options['id'].'?api_key='.$this->config['api_key']
160
        );
161
162
        $user->setTwoFactorAuthProviderOptions([]);
163
    }
164
165
    /**
166
     * Determine if the given user should be sent two-factor authentication token via SMS/phone call.
167
     *
168
     * @param \Srmklive\Authy\Contracts\Auth\TwoFactor\Authenticatable $user
169
     *
170
     * @return bool
171
     */
172
    public function canSendToken(TwoFactorAuthenticatable $user)
173
    {
174
        if ($this->isEnabled($user)) {
175
            if ($user->getTwoFactorAuthProviderOptions()['sms'] ||
176
                $user->getTwoFactorAuthProviderOptions()['phone'] ||
177
                $user->getTwoFactorAuthProviderOptions()['email']) {
178
                return true;
179
            }
180
        }
181
182
        return false;
183
    }
184
}
185