social.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // Copyright 2014 The Gogs Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package user
  5. import (
  6. "encoding/json"
  7. "strconv"
  8. "code.google.com/p/goauth2/oauth"
  9. "github.com/gogits/gogs/models"
  10. "github.com/gogits/gogs/modules/base"
  11. "github.com/gogits/gogs/modules/log"
  12. "github.com/gogits/gogs/modules/middleware"
  13. "github.com/gogits/gogs/modules/oauth2"
  14. )
  15. type SocialConnector interface {
  16. Identity() string
  17. Type() int
  18. Name() string
  19. Email() string
  20. Token() string
  21. }
  22. type SocialGithub struct {
  23. data struct {
  24. Id int `json:"id"`
  25. Name string `json:"login"`
  26. Email string `json:"email"`
  27. }
  28. WebToken *oauth.Token
  29. }
  30. func (s *SocialGithub) Identity() string {
  31. return strconv.Itoa(s.data.Id)
  32. }
  33. func (s *SocialGithub) Type() int {
  34. return models.OT_GITHUB
  35. }
  36. func (s *SocialGithub) Name() string {
  37. return s.data.Name
  38. }
  39. func (s *SocialGithub) Email() string {
  40. return s.data.Email
  41. }
  42. func (s *SocialGithub) Token() string {
  43. data, _ := json.Marshal(s.WebToken)
  44. return string(data)
  45. }
  46. // Github API refer: https://developer.github.com/v3/users/
  47. func (s *SocialGithub) Update() error {
  48. scope := "https://api.github.com/user"
  49. transport := &oauth.Transport{
  50. Token: s.WebToken,
  51. }
  52. log.Debug("update github info")
  53. r, err := transport.Client().Get(scope)
  54. if err != nil {
  55. return err
  56. }
  57. defer r.Body.Close()
  58. return json.NewDecoder(r.Body).Decode(&s.data)
  59. }
  60. // github && google && ...
  61. func SocialSignIn(ctx *middleware.Context, tokens oauth2.Tokens) {
  62. gh := &SocialGithub{
  63. WebToken: &oauth.Token{
  64. AccessToken: tokens.Access(),
  65. RefreshToken: tokens.Refresh(),
  66. Expiry: tokens.ExpiryTime(),
  67. Extra: tokens.ExtraData(),
  68. },
  69. }
  70. if len(tokens.Access()) == 0 {
  71. log.Error("empty access")
  72. return
  73. }
  74. var err error
  75. var u *models.User
  76. if err = gh.Update(); err != nil {
  77. // FIXME: handle error page
  78. log.Error("connect with github error: %s", err)
  79. return
  80. }
  81. var soc SocialConnector = gh
  82. log.Info("login: %s", soc.Name())
  83. // FIXME: login here, user email to check auth, if not registe, then generate a uniq username
  84. if u, err = models.GetOauth2User(soc.Identity()); err != nil {
  85. u = &models.User{
  86. Name: soc.Name(),
  87. Email: soc.Email(),
  88. Passwd: "123456",
  89. IsActive: !base.Service.RegisterEmailConfirm,
  90. }
  91. if u, err = models.RegisterUser(u); err != nil {
  92. log.Error("register user: %v", err)
  93. return
  94. }
  95. oa := &models.Oauth2{}
  96. oa.Uid = u.Id
  97. oa.Type = soc.Type()
  98. oa.Token = soc.Token()
  99. oa.Identity = soc.Identity()
  100. log.Info("oa: %v", oa)
  101. if err = models.AddOauth2(oa); err != nil {
  102. log.Error("add oauth2 %v", err)
  103. return
  104. }
  105. }
  106. ctx.Session.Set("userId", u.Id)
  107. ctx.Session.Set("userName", u.Name)
  108. ctx.Redirect("/")
  109. }