@@ -9,9 +9,10 @@ package logic
9
9
import (
10
10
"encoding/json"
11
11
"errors"
12
+ "io/ioutil"
13
+
12
14
. "github.com/studygolang/studygolang/db"
13
15
"github.com/studygolang/studygolang/model"
14
- "io/ioutil"
15
16
16
17
"github.com/polaris1119/logger"
17
18
@@ -21,8 +22,10 @@ import (
21
22
)
22
23
23
24
var githubConf * oauth2.Config
25
+ var giteaConf * oauth2.Config
24
26
25
27
const GithubAPIBaseUrl = "https://api.github.com"
28
+ const GiteaAPIBaseUrl = "https://gitea.com/api/v1"
26
29
27
30
func init () {
28
31
githubConf = & oauth2.Config {
@@ -34,6 +37,15 @@ func init() {
34
37
TokenURL : "https://github.com/login/oauth/access_token" ,
35
38
},
36
39
}
40
+
41
+ giteaConf = & oauth2.Config {
42
+ ClientID : config .ConfigFile .MustValue ("gitea" , "client_id" ),
43
+ ClientSecret : config .ConfigFile .MustValue ("gitea" , "client_secret" ),
44
+ Endpoint : oauth2.Endpoint {
45
+ AuthURL : "https://gitea.com/login/oauth/authorize" ,
46
+ TokenURL : "https://gitea.com/login/oauth/access_token" ,
47
+ },
48
+ }
37
49
}
38
50
39
51
type ThirdUserLogic struct {}
@@ -200,6 +212,166 @@ func (self ThirdUserLogic) BindGithub(ctx context.Context, code string, me *mode
200
212
return nil
201
213
}
202
214
215
+ func (ThirdUserLogic ) GiteaAuthCodeUrl (ctx context.Context , redirectURL string ) string {
216
+ // Redirect user to consent page to ask for permission
217
+ // for the scopes specified above.
218
+ giteaConf .RedirectURL = redirectURL
219
+ return giteaConf .AuthCodeURL ("state" , oauth2 .AccessTypeOffline )
220
+ }
221
+
222
+ func (self ThirdUserLogic ) LoginFromGitea (ctx context.Context , code string ) (* model.User , error ) {
223
+ objLog := GetLogger (ctx )
224
+
225
+ giteaUser , token , err := self .giteaTokenAndUser (ctx , code )
226
+ if err != nil {
227
+ objLog .Errorln ("LoginFromGithub githubTokenAndUser error:" , err )
228
+ return nil , err
229
+ }
230
+
231
+ bindUser := & model.BindUser {}
232
+ // 是否已经授权过了
233
+ _ , err = MasterDB .Where ("username=? AND type=?" , giteaUser .UserName , model .BindTypeGitea ).Get (bindUser )
234
+ if err != nil {
235
+ objLog .Errorln ("LoginFromGithub Get BindUser error:" , err )
236
+ return nil , err
237
+ }
238
+
239
+ if bindUser .Uid > 0 {
240
+ // 更新 token 信息
241
+ change := map [string ]interface {}{
242
+ "access_token" : token .AccessToken ,
243
+ "refresh_token" : token .RefreshToken ,
244
+ }
245
+ if ! token .Expiry .IsZero () {
246
+ change ["expire" ] = int (token .Expiry .Unix ())
247
+ }
248
+ _ , err = MasterDB .Table (new (model.BindUser )).Where ("uid=?" , bindUser .Uid ).Update (change )
249
+ if err != nil {
250
+ objLog .Errorln ("LoginFromGithub update token error:" , err )
251
+ return nil , err
252
+ }
253
+
254
+ user := DefaultUser .FindOne (ctx , "uid" , bindUser .Uid )
255
+ return user , nil
256
+ }
257
+
258
+ exists := DefaultUser .EmailOrUsernameExists (ctx , giteaUser .Email , giteaUser .UserName )
259
+ if exists {
260
+ // TODO: 考虑改进?
261
+ objLog .Errorln ("LoginFromGithub Github 对应的用户信息被占用" )
262
+ return nil , errors .New ("Github 对应的用户信息被占用,可能你注册过本站,用户名密码登录试试!" )
263
+ }
264
+
265
+ session := MasterDB .NewSession ()
266
+ defer session .Close ()
267
+ session .Begin ()
268
+
269
+ // 有可能获取不到 email?加上 @gitea.com做邮箱后缀
270
+ if giteaUser .Email == "" {
271
+ giteaUser .Email = giteaUser .UserName + "@gitea.com"
272
+ }
273
+ // 生成本站用户
274
+ user := & model.User {
275
+ Email : giteaUser .Email ,
276
+ Username : giteaUser .UserName ,
277
+ Name : model .DisplayName (giteaUser ),
278
+ City : "" ,
279
+ Company : "" ,
280
+ Gitea : giteaUser .UserName ,
281
+ Website : "" ,
282
+ Avatar : giteaUser .AvatarURL ,
283
+ IsThird : 1 ,
284
+ Status : model .UserStatusAudit ,
285
+ }
286
+ err = DefaultUser .doCreateUser (ctx , session , user )
287
+ if err != nil {
288
+ session .Rollback ()
289
+ objLog .Errorln ("LoginFromGithub doCreateUser error:" , err )
290
+ return nil , err
291
+ }
292
+
293
+ bindUser = & model.BindUser {
294
+ Uid : user .Uid ,
295
+ Type : model .BindTypeGithub ,
296
+ Email : user .Email ,
297
+ Tuid : int (giteaUser .ID ),
298
+ Username : giteaUser .UserName ,
299
+ Name : model .DisplayName (giteaUser ),
300
+ AccessToken : token .AccessToken ,
301
+ RefreshToken : token .RefreshToken ,
302
+ Avatar : giteaUser .AvatarURL ,
303
+ }
304
+ if ! token .Expiry .IsZero () {
305
+ bindUser .Expire = int (token .Expiry .Unix ())
306
+ }
307
+ _ , err = session .Insert (bindUser )
308
+ if err != nil {
309
+ session .Rollback ()
310
+ objLog .Errorln ("LoginFromGitea bindUser error:" , err )
311
+ return nil , err
312
+ }
313
+
314
+ session .Commit ()
315
+
316
+ return user , nil
317
+ }
318
+
319
+ func (self ThirdUserLogic ) BindGitea (ctx context.Context , code string , me * model.Me ) error {
320
+ objLog := GetLogger (ctx )
321
+
322
+ giteaUser , token , err := self .giteaTokenAndUser (ctx , code )
323
+ if err != nil {
324
+ objLog .Errorln ("LoginFromGitea githubTokenAndUser error:" , err )
325
+ return err
326
+ }
327
+
328
+ bindUser := & model.BindUser {}
329
+ // 是否已经授权过了
330
+ _ , err = MasterDB .Where ("username=? AND type=?" , giteaUser .UserName , model .BindTypeGitea ).Get (bindUser )
331
+ if err != nil {
332
+ objLog .Errorln ("LoginFromGitea Get BindUser error:" , err )
333
+ return err
334
+ }
335
+
336
+ if bindUser .Uid > 0 {
337
+ // 更新 token 信息
338
+ bindUser .AccessToken = token .AccessToken
339
+ bindUser .RefreshToken = token .RefreshToken
340
+ if ! token .Expiry .IsZero () {
341
+ bindUser .Expire = int (token .Expiry .Unix ())
342
+ }
343
+ _ , err = MasterDB .Where ("uid=?" , bindUser .Uid ).Update (bindUser )
344
+ if err != nil {
345
+ objLog .Errorln ("LoginFromGitea update token error:" , err )
346
+ return err
347
+ }
348
+
349
+ return nil
350
+ }
351
+
352
+ bindUser = & model.BindUser {
353
+ Uid : me .Uid ,
354
+ Type : model .BindTypeGithub ,
355
+ Email : giteaUser .Email ,
356
+ Tuid : int (giteaUser .ID ),
357
+ Username : giteaUser .UserName ,
358
+ Name : model .DisplayName (giteaUser ),
359
+ AccessToken : token .AccessToken ,
360
+ RefreshToken : token .RefreshToken ,
361
+ Avatar : giteaUser .AvatarURL ,
362
+ }
363
+ if ! token .Expiry .IsZero () {
364
+ bindUser .Expire = int (token .Expiry .Unix ())
365
+ }
366
+ _ , err = MasterDB .Insert (bindUser )
367
+ if err != nil {
368
+ objLog .Errorln ("LoginFromGitea insert bindUser error:" , err )
369
+ return err
370
+ }
371
+
372
+ return nil
373
+ }
374
+
203
375
func (ThirdUserLogic ) UnBindUser (ctx context.Context , bindId interface {}, me * model.Me ) error {
204
376
if ! DefaultUser .HasPasswd (ctx , me .Uid ) {
205
377
return errors .New ("请先设置密码!" )
@@ -243,8 +415,39 @@ func (ThirdUserLogic) githubTokenAndUser(ctx context.Context, code string) (*mod
243
415
}
244
416
245
417
if githubUser .Id == 0 {
246
- return nil , nil , errors .New ("get github user info error" )
418
+ return nil , nil , errors .New ("get gitea user info error" )
247
419
}
248
420
249
421
return githubUser , token , nil
250
422
}
423
+
424
+ func (ThirdUserLogic ) giteaTokenAndUser (ctx context.Context , code string ) (* model.GiteaUser , * oauth2.Token , error ) {
425
+ token , err := giteaConf .Exchange (ctx , code )
426
+ if err != nil {
427
+ return nil , nil , err
428
+ }
429
+
430
+ httpClient := giteaConf .Client (ctx , token )
431
+ resp , err := httpClient .Get (GiteaAPIBaseUrl + "/user" )
432
+ if err != nil {
433
+ return nil , nil , err
434
+ }
435
+ defer resp .Body .Close ()
436
+
437
+ respBytes , err := ioutil .ReadAll (resp .Body )
438
+ if err != nil {
439
+ return nil , nil , err
440
+ }
441
+
442
+ giteaUser := & model.GiteaUser {}
443
+ err = json .Unmarshal (respBytes , giteaUser )
444
+ if err != nil {
445
+ return nil , nil , err
446
+ }
447
+
448
+ if giteaUser .ID == 0 {
449
+ return nil , nil , errors .New ("get gitea user info error" )
450
+ }
451
+
452
+ return giteaUser , token , nil
453
+ }
0 commit comments