Passed
Push — master ( 6760ee...9e3b1c )
by Ion
02:46
created

LoginController::loginWithRememberToken()   A

Complexity

Conditions 5
Paths 16

Size

Total Lines 34
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 18
c 0
b 0
f 0
nc 16
nop 1
dl 0
loc 34
rs 9.3554
1
<?php
2
3
namespace App\Http\Controllers;
4
5
use App\Constants\TranslationCode;
6
use App\Models\User;
7
use App\Models\UserToken;
8
use App\Services\LogService;
9
use App\Services\UserService;
10
use Exception;
11
use Illuminate\Http\JsonResponse;
12
use Illuminate\Http\Request;
13
use Illuminate\Support\Facades\Auth;
14
use Illuminate\Support\Facades\DB;
15
use Illuminate\Support\Facades\Log;
16
use Laravel\Socialite\Facades\Socialite;
17
use Laravel\Socialite\Two\User as SocialiteUser;
18
19
/**
20
 * Class LoginController
21
 *
22
 * @package App\Http\Controllers
23
 */
24
class LoginController extends Controller
25
{
26
    /** @var UserService */
27
    private $userService;
28
29
    /**
30
     * UserController constructor.
31
     */
32
    public function __construct()
33
    {
34
        parent::__construct();
35
36
        $this->userService = new UserService();
37
    }
38
39
    /**
40
     * Login user with email and password or remember token
41
     *
42
     * @param Request $request
43
     *
44
     * @return JsonResponse
45
     */
46
    public function login(Request $request)
47
    {
48
        try {
49
            $validator = $this->userService->validateLoginRequest($request);
50
51
            if (!$validator->passes()) {
52
                return $this->userErrorResponse($validator->messages());
53
            }
54
55
            $user = $this->userService->loginUser($request->only('email', 'password'));
56
57
            if (!$user) {
58
                return $this->userErrorResponse(['credentials' => TranslationCode::ERROR_CREDENTIALS_INVALID]);
59
            }
60
61
            if ($user->status === User::STATUS_UNCONFIRMED) {
62
                return $this->userErrorResponse(['account' => TranslationCode::ERROR_ACCOUNT_UNACTIVATED]);
63
            }
64
65
            $loginData = $this->userService->generateLoginData($user, $request->has('remember'));
66
67
            return $this->successResponse($loginData);
68
        } catch (Exception $e) {
69
            Log::error(LogService::getExceptionTraceAsString($e, $request));
70
71
            return $this->errorResponse();
72
        }
73
    }
74
75
    /**
76
     * Login with remember token
77
     *
78
     * @param Request $request
79
     *
80
     * @return JsonResponse
81
     */
82
    public function loginWithRememberToken(Request $request)
83
    {
84
        try {
85
            $validator = $this->userService->validateTokenLoginRequest($request);
86
87
            if (!$validator->passes()) {
88
                return $this->userErrorResponse($validator->messages());
89
            }
90
91
            $rememberToken = $request->get('rememberToken');
92
93
            $user = $this->userService->loginUserWithRememberToken($rememberToken);
94
95
            if (!$user) {
96
                return $this->userErrorResponse(['rememberToken' => TranslationCode::ERROR_REMEMBER_TOKEN_INVALID]);
97
            }
98
99
            if ($user->status === User::STATUS_UNCONFIRMED) {
100
                return $this->userErrorResponse(['account' => TranslationCode::ERROR_ACCOUNT_UNACTIVATED]);
101
            }
102
103
            DB::beginTransaction();
104
105
            $this->userService->updateRememberTokenValability($rememberToken);
106
107
            $loginData = $this->userService->generateLoginData($user);
108
109
            DB::commit();
110
111
            return $this->successResponse($loginData);
112
        } catch (Exception $e) {
113
            Log::error(LogService::getExceptionTraceAsString($e, $request));
114
115
            return $this->errorResponse();
116
        }
117
    }
118
119
    /**
120
     * Login with facebook
121
     *
122
     * @param Request $request
123
     *
124
     * @return JsonResponse
125
     */
126
    public function loginWithFacebook(Request $request)
127
    {
128
        try {
129
            $validator = $this->userService->validateFacebookLoginRequest($request);
130
131
            if (!$validator->passes()) {
132
                return $this->userErrorResponse($validator->messages());
133
            }
134
135
            $token = $request->get('accessToken');
136
137
            try {
138
                /** @var SocialiteUser $facebookUser */
139
                $facebookUser = Socialite::driver('facebook')->userFromToken($token);
0 ignored issues
show
Bug introduced by
The method userFromToken() does not exist on Laravel\Socialite\Contracts\Provider. It seems like you code against a sub-type of Laravel\Socialite\Contracts\Provider such as Laravel\Socialite\Two\AbstractProvider. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

139
                $facebookUser = Socialite::driver('facebook')->/** @scrutinizer ignore-call */ userFromToken($token);
Loading history...
140
            } catch (Exception $e) {
141
                return $this->userErrorResponse(['token' => TranslationCode::ERROR_ACCESS_TOKEN_INVALID]);
142
            }
143
144
            if ($facebookUser->getId() !== $request->get('facebookId')) {
145
                return $this->userErrorResponse(['token' => TranslationCode::ERROR_TOKEN_MISMATCH]);
146
            }
147
148
            if (!$facebookUser->getEmail()) {
149
                return $this->userErrorResponse(['permission' => TranslationCode::ERROR_PERMISSION_EMAIL]);
150
            }
151
152
            DB::beginTransaction();
153
154
            $user = $this->userService->loginUserWithSocial($facebookUser, $this->baseService->getLanguage($request), 'facebook_id');
155
156
            $loginData = $this->userService->generateLoginData($user);
157
158
            DB::commit();
159
160
            return $this->successResponse($loginData);
161
        } catch (Exception $e) {
162
            Log::error(LogService::getExceptionTraceAsString($e, $request));
163
164
            return $this->errorResponse();
165
        }
166
    }
167
168
    /**
169
     * Login with google
170
     *
171
     * @param Request $request
172
     *
173
     * @return JsonResponse
174
     */
175
    public function loginWithGoogle(Request $request)
176
    {
177
        try {
178
            $validator = $this->userService->validateGoogleLoginRequest($request);
179
180
            if (!$validator->passes()) {
181
                return $this->userErrorResponse($validator->messages());
182
            }
183
184
            $token = $request->get('accessToken');
185
186
            try {
187
                /** @var SocialiteUser $googleUser */
188
                $googleUser = Socialite::driver('google')->userFromToken($token);
189
            } catch (Exception $e) {
190
                return $this->userErrorResponse(['token' => TranslationCode::ERROR_ACCESS_TOKEN_INVALID]);
191
            }
192
193
            if ($googleUser->getId() !== $request->get('google_id')) {
194
                return $this->userErrorResponse(['token' => TranslationCode::ERROR_TOKEN_MISMATCH]);
195
            }
196
197
            if (!$googleUser->getEmail()) {
198
                return $this->userErrorResponse(['permission' => TranslationCode::ERROR_PERMISSION_EMAIL]);
199
            }
200
201
            DB::beginTransaction();
202
203
            $user = $this->userService->loginUserWithSocial($googleUser, $this->baseService->getLanguage($request), 'google_id');
204
205
            $loginData = $this->userService->generateLoginData($user);
206
207
            DB::commit();
208
209
            return $this->successResponse($loginData);
210
        } catch (Exception $e) {
211
            Log::error(LogService::getExceptionTraceAsString($e, $request));
212
213
            return $this->errorResponse();
214
        }
215
    }
216
217
    /**
218
     * Logout user
219
     *
220
     * @param Request $request
221
     *
222
     * @return JsonResponse
223
     */
224
    public function logout(Request $request)
225
    {
226
        try {
227
            /** @var User $user */
228
            $user = Auth::user();
229
230
            if ($request->has('rememberToken')) {
231
                DB::beginTransaction();
232
233
                UserToken::where('token', $request->get('rememberToken'))
234
                    ->where('user_id', $user->id)
235
                    ->where('type', UserToken::TYPE_REMEMBER_ME)
236
                    ->delete();
237
238
                DB::commit();
239
            }
240
241
            return $this->successResponse();
242
        } catch (Exception $e) {
243
            Log::error(LogService::getExceptionTraceAsString($e, $request));
244
245
            return $this->errorResponse();
246
        }
247
    }
248
}
249