| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- package main
- import (
- "encoding/json"
- "errors"
- "io"
- "io/ioutil"
- "log"
- "net/http"
- "strings"
- "github.com/mrjones/oauth"
- "gopkg.in/mgo.v2"
- "gopkg.in/mgo.v2/bson"
- )
- func LoginWithTwitter(w http.ResponseWriter, r *http.Request) {
- c := oauth.NewConsumer(
- config.TWITTER_KEY,
- config.TWITTER_SECRET,
- oauth.ServiceProvider{
- RequestTokenUrl: "https://api.twitter.com/oauth/request_token",
- AuthorizeTokenUrl: "https://api.twitter.com/oauth/authenticate",
- AccessTokenUrl: "https://api.twitter.com/oauth/access_token",
- })
- profileUrl := "https://api.twitter.com/1.1/users/show.json"
- decoder := json.NewDecoder(r.Body)
- var requestPayload struct {
- OAuthToken string `json:"oauth_token"`
- OAuthVerifier string `json:"oauth_verifier"`
- }
- err := decoder.Decode(&requestPayload)
- if err != nil && err != io.EOF {
- log.Println(err)
- return
- }
- // Part 1/2: Initial request from Satellizer.
- if requestPayload.OAuthToken == "" || requestPayload.OAuthVerifier == "" {
- // Step 1. Obtain request token for the authorization popup.
- requestToken, _, err := c.GetRequestTokenAndUrl(config.TWITTER_CALLBACK)
- if err != nil {
- log.Println(err)
- return
- }
- // Step 2. Redirect to the authorization screen.
- ServeJSON(w, r, &Response{
- "oauth_token": requestToken.Token,
- "oauth_token_secret": requestToken.Secret,
- "oauth_callback_confirmed": "true",
- }, 200)
- } else {
- // Part 2/2: Second request after Authorize app is clicked.
- requestToken := &oauth.RequestToken{requestPayload.OAuthToken, config.TWITTER_SECRET}
- // Step 3. Exchange oauth token and oauth verifier for access token.
- accessToken, err := c.AuthorizeToken(requestToken, requestPayload.OAuthVerifier)
- if err != nil {
- log.Println(err)
- return
- }
- // Step 4. Retrieve profile information about the current user.
- response, err := c.Get(
- profileUrl,
- map[string]string{"screen_name": accessToken.AdditionalData["screen_name"]},
- accessToken)
- if err != nil {
- log.Fatal(err)
- }
- defer response.Body.Close()
- bits, err := ioutil.ReadAll(response.Body)
- var profileData map[string]interface{}
- err = json.Unmarshal(bits, &profileData)
- db := GetDB(w, r)
- if IsTokenSet(r) {
- // Step 5a. Link user accounts.
- existingUser, errM := FindUserByProvider(db, "twitter", accessToken.AdditionalData["user_id"])
- if existingUser != nil {
- ServeJSON(w, r, &Response{
- "message": "There is already a Twitter account that belongs to you",
- }, 409)
- return
- }
- if errM != nil && errM.Reason != mgo.ErrNotFound {
- HandleModelError(w, r, errM)
- return
- }
- tokenData := GetToken(w, r)
- user, errM := FindUserById(db, bson.ObjectIdHex(tokenData.ID))
- if user == nil {
- ServeJSON(w, r, &Response{
- "message": "User not found",
- }, 400)
- return
- }
- if errM != nil && errM.Reason != mgo.ErrNotFound {
- HandleModelError(w, r, errM)
- return
- }
- user.Twitter = accessToken.AdditionalData["user_id"]
- if user.DisplayName == "" {
- user.DisplayName = accessToken.AdditionalData["screen_name"]
- }
- if user.Picture == "" {
- user.Picture = strings.Replace(profileData["profile_image_url"].(string), "_normal", "", 1)
- }
- err = user.Save(db)
- if err != nil {
- ISR(w, r, errors.New("Couldn't save user profile informations"))
- }
- SetToken(w, r, user)
- } else {
- // Step 5b. Create a new user account or return an existing one.
- existingUser, errM := FindUserByProvider(db, "twitter", accessToken.AdditionalData["user_id"])
- if existingUser != nil {
- SetToken(w, r, existingUser)
- return
- }
- if errM != nil && errM.Reason != mgo.ErrNotFound {
- HandleModelError(w, r, errM)
- return
- }
- user := NewUser()
- user.Email = accessToken.AdditionalData["user_id"] + "-satellizer@twitter.com"
- user.Twitter = accessToken.AdditionalData["user_id"]
- user.DisplayName = accessToken.AdditionalData["screen_name"]
- user.Picture = strings.Replace(profileData["profile_image_url"].(string), "_normal", "", 1)
- err = user.Save(db)
- if err != nil {
- ISR(w, r, err)
- return
- }
- SetToken(w, r, user)
- }
- }
- }
|