No Description

oauth.go 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. package main
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "io"
  6. "io/ioutil"
  7. "log"
  8. "net/http"
  9. "strings"
  10. "github.com/mrjones/oauth"
  11. "gopkg.in/mgo.v2"
  12. "gopkg.in/mgo.v2/bson"
  13. )
  14. func LoginWithTwitter(w http.ResponseWriter, r *http.Request) {
  15. c := oauth.NewConsumer(
  16. config.TWITTER_KEY,
  17. config.TWITTER_SECRET,
  18. oauth.ServiceProvider{
  19. RequestTokenUrl: "https://api.twitter.com/oauth/request_token",
  20. AuthorizeTokenUrl: "https://api.twitter.com/oauth/authenticate",
  21. AccessTokenUrl: "https://api.twitter.com/oauth/access_token",
  22. })
  23. profileUrl := "https://api.twitter.com/1.1/users/show.json"
  24. decoder := json.NewDecoder(r.Body)
  25. var requestPayload struct {
  26. OAuthToken string `json:"oauth_token"`
  27. OAuthVerifier string `json:"oauth_verifier"`
  28. }
  29. err := decoder.Decode(&requestPayload)
  30. if err != nil && err != io.EOF {
  31. log.Println(err)
  32. return
  33. }
  34. // Part 1/2: Initial request from Satellizer.
  35. if requestPayload.OAuthToken == "" || requestPayload.OAuthVerifier == "" {
  36. // Step 1. Obtain request token for the authorization popup.
  37. requestToken, _, err := c.GetRequestTokenAndUrl(config.TWITTER_CALLBACK)
  38. if err != nil {
  39. log.Println(err)
  40. return
  41. }
  42. // Step 2. Redirect to the authorization screen.
  43. ServeJSON(w, r, &Response{
  44. "oauth_token": requestToken.Token,
  45. "oauth_token_secret": requestToken.Secret,
  46. "oauth_callback_confirmed": "true",
  47. }, 200)
  48. } else {
  49. // Part 2/2: Second request after Authorize app is clicked.
  50. requestToken := &oauth.RequestToken{requestPayload.OAuthToken, config.TWITTER_SECRET}
  51. // Step 3. Exchange oauth token and oauth verifier for access token.
  52. accessToken, err := c.AuthorizeToken(requestToken, requestPayload.OAuthVerifier)
  53. if err != nil {
  54. log.Println(err)
  55. return
  56. }
  57. // Step 4. Retrieve profile information about the current user.
  58. response, err := c.Get(
  59. profileUrl,
  60. map[string]string{"screen_name": accessToken.AdditionalData["screen_name"]},
  61. accessToken)
  62. if err != nil {
  63. log.Fatal(err)
  64. }
  65. defer response.Body.Close()
  66. bits, err := ioutil.ReadAll(response.Body)
  67. var profileData map[string]interface{}
  68. err = json.Unmarshal(bits, &profileData)
  69. db := GetDB(w, r)
  70. if IsTokenSet(r) {
  71. // Step 5a. Link user accounts.
  72. existingUser, errM := FindUserByProvider(db, "twitter", accessToken.AdditionalData["user_id"])
  73. if existingUser != nil {
  74. ServeJSON(w, r, &Response{
  75. "message": "There is already a Twitter account that belongs to you",
  76. }, 409)
  77. return
  78. }
  79. if errM != nil && errM.Reason != mgo.ErrNotFound {
  80. HandleModelError(w, r, errM)
  81. return
  82. }
  83. tokenData := GetToken(w, r)
  84. user, errM := FindUserById(db, bson.ObjectIdHex(tokenData.ID))
  85. if user == nil {
  86. ServeJSON(w, r, &Response{
  87. "message": "User not found",
  88. }, 400)
  89. return
  90. }
  91. if errM != nil && errM.Reason != mgo.ErrNotFound {
  92. HandleModelError(w, r, errM)
  93. return
  94. }
  95. user.Twitter = accessToken.AdditionalData["user_id"]
  96. if user.DisplayName == "" {
  97. user.DisplayName = accessToken.AdditionalData["screen_name"]
  98. }
  99. if user.Picture == "" {
  100. user.Picture = strings.Replace(profileData["profile_image_url"].(string), "_normal", "", 1)
  101. }
  102. err = user.Save(db)
  103. if err != nil {
  104. ISR(w, r, errors.New("Couldn't save user profile informations"))
  105. }
  106. SetToken(w, r, user)
  107. } else {
  108. // Step 5b. Create a new user account or return an existing one.
  109. existingUser, errM := FindUserByProvider(db, "twitter", accessToken.AdditionalData["user_id"])
  110. if existingUser != nil {
  111. SetToken(w, r, existingUser)
  112. return
  113. }
  114. if errM != nil && errM.Reason != mgo.ErrNotFound {
  115. HandleModelError(w, r, errM)
  116. return
  117. }
  118. user := NewUser()
  119. user.Email = accessToken.AdditionalData["user_id"] + "-satellizer@twitter.com"
  120. user.Twitter = accessToken.AdditionalData["user_id"]
  121. user.DisplayName = accessToken.AdditionalData["screen_name"]
  122. user.Picture = strings.Replace(profileData["profile_image_url"].(string), "_normal", "", 1)
  123. err = user.Save(db)
  124. if err != nil {
  125. ISR(w, r, err)
  126. return
  127. }
  128. SetToken(w, r, user)
  129. }
  130. }
  131. }