social.go 2.7 KB

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