SocialiteUsersController   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 145
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 40
dl 0
loc 145
rs 10
c 0
b 0
f 0
wmc 8

5 Methods

Rating   Name   Duplication   Size   Complexity  
A socialAuth() 0 35 4
A createUser() 0 7 1
A updateSocialiteUser() 0 5 1
A __construct() 0 8 1
A addSocialiteUser() 0 20 1
1
<?php
2
3
namespace Yeelight\Http\Controllers\Api\Controllers;
4
5
use Illuminate\Support\Facades\DB;
6
use Illuminate\Validation\Rule;
7
use Yeelight\Http\Requests\Api\SocialiteAuthRequest;
8
use Yeelight\Models\Foundation\User;
9
use Yeelight\Models\SocialiteUser;
10
use Yeelight\Repositories\Criteria\GetUserByUsernameOrEmailCriteria;
11
use Yeelight\Repositories\Criteria\SocialiteAuthUserCriteria;
12
use Yeelight\Repositories\Interfaces\SocialiteUserRepository;
13
use Yeelight\Repositories\Interfaces\UserRepository;
14
use Yeelight\Validators\SocialiteUserValidator;
15
16
/**
17
 * Class SocialiteUsersController
18
 *
19
 * @category Yeelight
20
 *
21
 * @package Yeelight\Http\Controllers\Api\Controllers
22
 *
23
 * @author Sheldon Lee <[email protected]>
24
 *
25
 * @license https://opensource.org/licenses/MIT MIT
26
 *
27
 * @link https://www.yeelight.com
28
 */
29
class SocialiteUsersController extends BaseController
30
{
31
    /**
32
     * SocialiteUserRepository
33
     *
34
     * @var SocialiteUserRepository
35
     */
36
    protected $repository;
37
38
    /**
39
     * SocialiteUserValidator
40
     *
41
     * @var SocialiteUserValidator
42
     */
43
    protected $validator;
44
45
    /**
46
     * UserRepository
47
     *
48
     * @var UserRepository
49
     */
50
    protected $userRepository;
51
52
    /**
53
     * SocialiteUsersController constructor.
54
     *
55
     * @param SocialiteUserRepository $repository SocialiteUserRepository
56
     * @param SocialiteUserValidator $validator SocialiteUserValidator
57
     * @param UserRepository $userRepository UserRepository
58
     */
59
    public function __construct(
60
        SocialiteUserRepository $repository,
61
        SocialiteUserValidator $validator,
62
        UserRepository $userRepository
63
    ) {
64
        $this->repository = $repository;
65
        $this->validator = $validator;
66
        $this->userRepository = $userRepository;
67
    }
68
69
    /**
70
     * 第三方登录.
71
     *
72
     * @param SocialiteAuthRequest $request SocialiteAuthRequest
73
     *
74
     * @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\JsonResponse|\Illuminate\Http\Response|\Symfony\Component\HttpFoundation\Response
75
     */
76
    public function socialAuth(SocialiteAuthRequest $request)
77
    {
78
79
        // 默认信任客户端的第三方认证
80
        // 为保险起见,也可以使用客户端获取到的AccessToken再去第三方验证
81
        // TODO 使用客户端获取到的AccessToken去第三方验证
82
83
        $socialiteAuthUser = $this->repository->pushCriteria(
0 ignored issues
show
Bug introduced by
The method pushCriteria() does not exist on Yeelight\Repositories\In...SocialiteUserRepository. Since it exists in all sub-types, consider adding an abstract or default implementation to Yeelight\Repositories\In...SocialiteUserRepository. ( Ignorable by Annotation )

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

83
        $socialiteAuthUser = $this->repository->/** @scrutinizer ignore-call */ pushCriteria(
Loading history...
84
            new SocialiteAuthUserCriteria($request)
85
        )->skipPresenter()->first();
86
87
        if (!empty($socialiteAuthUser)) {
88
            // 更新第三方账号信息
89
            $this->updateSocialiteUser($request, $socialiteAuthUser);
90
91
            return $this->issueToken($request);
92
        }
93
94
        $authUser = $this->userRepository->pushCriteria(
0 ignored issues
show
Bug introduced by
The method pushCriteria() does not exist on Yeelight\Repositories\Interfaces\UserRepository. Since it exists in all sub-types, consider adding an abstract or default implementation to Yeelight\Repositories\Interfaces\UserRepository. ( Ignorable by Annotation )

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

94
        $authUser = $this->userRepository->/** @scrutinizer ignore-call */ pushCriteria(
Loading history...
95
            new GetUserByUsernameOrEmailCriteria($request)
96
        )->skipPresenter()->first();
97
98
        if (!empty($authUser)) {
99
            // 用户状态是否为禁止
100
            if ($authUser->status == 0) {
101
                return $this->response->errorForbidden('User Are Forbidden');
102
            }
103
            // 添加第三方账号和user的关联
104
            $this->addSocialiteUser($request, $authUser);
105
        } else {
106
            // 根据第三方信息创建新用户
107
            $this->createUser($request);
108
        }
109
110
        return $this->issueToken($request);
111
    }
112
113
    /**
114
     * 添加第三方账号和user的关联.
115
     *
116
     * @param SocialiteAuthRequest $request SocialiteAuthRequest
117
     * @param User $user User
118
     *
119
     * @return void
120
     */
121
    private function addSocialiteUser(SocialiteAuthRequest $request, User $user)
122
    {
123
        $data = $request->all();
124
125
        // 验证 provider + provider_user_id 唯一性
126
        $this->validate(
127
            $request,
128
            [
129
                'provider' => [
130
                    'required',
131
                    Rule::unique('socialite_users')->where(function ($query) use ($user) {
132
                        return $query->where('user_id', $user->user_id);
133
                    }),
134
                ],
135
                'provider_user_id' => 'required',
136
            ]
137
        );
138
139
        $data['user_id'] = $user->user_id;
140
        $this->repository->create($data);
141
    }
142
143
    /**
144
     * 更新第三方账号信息.
145
     *
146
     * @param SocialiteAuthRequest $request SocialiteAuthRequest
147
     * @param SocialiteUser $socialiteUser SocialiteUser
148
     *
149
     * @return void
150
     */
151
    private function updateSocialiteUser(SocialiteAuthRequest $request, SocialiteUser $socialiteUser)
152
    {
153
        $data = $request->all();
154
        $data['user_id'] = $socialiteUser->user_id;
155
        $this->repository->update($data, $socialiteUser->id);
156
    }
157
158
    /**
159
     * 创建用户和对应的第三方账号并关联.
160
     *
161
     * @param SocialiteAuthRequest $request SocialiteAuthRequest
162
     *
163
     * @throws \Throwable
164
     *
165
     * @return void
166
     */
167
    private function createUser(SocialiteAuthRequest $request)
168
    {
169
        $data = $request->all();
170
171
        DB::transaction(function () use ($request, $data) {
172
            $user = $this->userRepository->create($data);
173
            $this->addSocialiteUser($request, $user);
174
        });
175
    }
176
}
177