func handleOAuthCallback(oauthClient *oauth.Client, s sessions.Session, w http.ResponseWriter, r *http.Request) {
	nextURL := getNextURL(r)

	tempToken, err := unmarshalCredentials(s, keyTempToken)
	if err != nil {
		// missing temp token
		params := url.Values{}
		params.Add(KeyNextURL, nextURL)
		http.Redirect(w, r, PathLogin+"?"+params.Encode(), codeRedirect)
		return
	}

	if tempToken.Token != r.FormValue("oauth_token") {
		// TODO: add error handling
		log.Fatal("oauth token mismatch")
	}

	token, _, err := oauthClient.RequestToken(http.DefaultClient, tempToken, r.FormValue("oauth_verifier"))
	if err != nil {
		// TODO: add error handling
		log.Fatal("oauth-callback error:", err)
		// http.Redirect(w, r, PathError, codeRedirect)
		return
	}

	// Store the credentials in the session.
	marshalCredentials(token, s, keyToken)
	http.Redirect(w, r, nextURL, codeRedirect)
}
示例#2
0
// Post issues a POST with the specified form.
func multipartPost(c *oauth.Client, client *http.Client,
	credentials *oauth.Credentials, urlStr string, form url.Values,
	files map[string]struct {
		filename string
		r        io.Reader
	}) (*http.Response, error) {
	var bf = &bytes.Buffer{}
	mw := multipart.NewWriter(bf)
	contentType := mw.FormDataContentType()
	for k := range form {
		mw.WriteField(k, form.Get(k))
	}

	for field, entry := range files {
		w, err := mw.CreateFormFile(field, filepath.Base(entry.filename))
		if err != nil {
			return nil, err
		}

		_, err = io.Copy(w, entry.r)
		if err != nil {
			return nil, err
		}
	}
	mw.Close()

	req, err := http.NewRequest("POST", urlStr, bf)
	if err != nil {
		return nil, err
	}
	req.Header.Set("Content-Type", contentType)

	req.Header.Set("Authorization", c.AuthorizationHeader(credentials, "POST", req.URL, nil))
	return client.Do(req)
}
// This example shows how to sign a request when the URL Opaque field is used.
// See the note at http://golang.org/pkg/net/url/#URL for information on the
// use of the URL Opaque field.
func ExampleClient_AuthorizationHeader(client *oauth.Client, credentials *oauth.Credentials) error {
	form := url.Values{"maxResults": {"100"}}

	// The last element of path contains a "/".
	path := "/document/encoding%2gizp"

	// Create the request with the temporary path "/".
	req, err := http.NewRequest("GET", "http://api.example.com/", strings.NewReader(form.Encode()))
	if err != nil {
		return err
	}

	// Overwrite the temporary path with the actual request path.
	req.URL.Opaque = path

	// Sign the request.
	req.Header.Set("Authorization", client.AuthorizationHeader(credentials, "GET", req.URL, form))

	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	// process the response
	return nil
}
示例#4
0
func (bs *BossSearch) signQuery(url string, values *url.Values) {
	cred := oauth.Credentials{}
	cred.Token = bs.Token
	cred.Secret = bs.Secret

	client := oauth.Client{}
	client.SignatureMethod = oauth.HMACSHA1
	client.Credentials = cred

	client.SignForm(nil, "GET", url, *values)
}
示例#5
0
func NewOAuth1Encoder(config OAuthConfig) HeaderEncoder {
	var client oauth.Client = oauth.Client{Credentials: config.Consumer}
	var token oauth.Credentials = config.Token
	return func(r *rpc.Request, v interface{}, req *http.Request) error {
		var signUrl url.URL = *req.URL
		var params = signUrl.Query()
		// OAuth library appends the full set of signed params to the signing url.
		signUrl.RawQuery = ""
		client.SignParam(&token, req.Method, signUrl.String(), params)

		req.URL.RawQuery = params.Encode()
		return nil
	}
}
示例#6
0
func post(client *oauth.Client, cred *oauth.Credentials, s string) {
	param := make(url.Values)
	param.Set("status", s)
	uri := "https://api.twitter.com/1.1/statuses/update.json"
	client.SignParam(cred, "POST", uri, param)
	res, err := http.PostForm(uri, url.Values(param))
	if err != nil {
		log.Println("failed to post tweet:", err)
		return
	}
	defer res.Body.Close()
	if res.StatusCode != 200 {
		log.Println("failed to get timeline:", err)
		return
	}
}
示例#7
0
func show(client *oauth.Client, cred *oauth.Credentials, f func(t *tweet)) {
	param := make(url.Values)
	uri := "https://api.twitter.com/1.1/statuses/home_timeline.json"
	client.SignParam(cred, "GET", uri, param)
	uri = uri + "?" + param.Encode()
	res, err := http.Get(uri)
	if err != nil {
		return
	}
	defer res.Body.Close()
	if res.StatusCode != 200 {
		return
	}
	var tweets []tweet
	json.NewDecoder(res.Body).Decode(&tweets)
	for _, t := range tweets {
		f(&t)
	}
}
示例#8
0
func stream(client *oauth.Client, cred *oauth.Credentials, f func(*tweet)) {
	param := make(url.Values)
	uri := "https://userstream.twitter.com/1.1/user.json"
	client.SignParam(cred, "GET", uri, param)
	uri = uri + "?" + param.Encode()
	res, err := http.Get(uri)
	if err != nil {
		log.Fatal("failed to get tweets:", err)
	}
	defer res.Body.Close()
	if res.StatusCode != 200 {
		log.Fatal("failed to get tweets:", err)
	}
	var buf *bufio.Reader
	if res.Header.Get("Content-Encoding") == "gzip" {
		gr, err := gzip.NewReader(res.Body)
		if err != nil {
			log.Fatal("failed to make gzip decoder:", err)
		}
		buf = bufio.NewReader(gr)
	} else {
		buf = bufio.NewReader(res.Body)
	}
	var last []byte
	for alive {
		b, _, err := buf.ReadLine()
		last = append(last, b...)
		var t tweet
		err = json.Unmarshal(last, &t)
		if err != nil {
			continue
		}
		last = []byte{}
		if t.Text == "" {
			continue
		}
		f(&t)
	}
}
示例#9
0
func getTweets(username string, count string, consumer oauth.Credentials, access oauth.Credentials) (tweets []Tweet, err error) {
	// Pull a X number of tweets associated with a user.
	// Docs: https://dev.twitter.com/rest/reference/get/statuses/user_timeline
	client := oauth.Client{Credentials: consumer}
	params := url.Values{"screen_name": {username}, "count": {count}}
	resp, err := client.Get(
		http.DefaultClient,
		&access,
		"https://api.twitter.com/1.1/statuses/user_timeline.json",
		params)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	err = json.Unmarshal(body, &tweets)
	if err != nil {
		return nil, err
	}
	return tweets, nil
}
示例#10
0
// You get a token for your App from Twitter.  Put this within the App section
// of the  JSON token file.  The user's token will be requested, then written
// and saved to this file.
func (t *ClientTokens) Token(oc *oauth.Client) (*oauth.Credentials, error) {
	if t.TokenFile == "" {
		return nil, &ClientTokensError{
			Msg: "no token file supplied",
		}
	}

	cf, err := ioutil.ReadFile(t.TokenFile)
	if err != nil {
		return nil, err
	}
	if err := json.Unmarshal(cf, t); err != nil {
		return nil, err
	}

	if t.App == nil {
		return nil, &ClientTokensError{
			Msg: "missing \"App\" token",
		}
	}

	if t.App.Token == "" || t.App.Secret == "" {
		return nil, &ClientTokensError{
			Msg: "missing app's Token or Secret",
		}
	}
	oc.Credentials = *t.App

	var token *oauth.Credentials
	if t.User == nil {
		token = &oauth.Credentials{}
	} else {
		token = t.User
	}

	if token.Token == "" || token.Secret == "" {
		tempCredentials, err := oc.RequestTemporaryCredentials(http.DefaultClient, "oob", nil)
		if err != nil {
			return nil, err
		}

		url := oc.AuthorizationURL(tempCredentials, nil)
		fmt.Fprintf(os.Stdout, "Before we can continue ...\nGo to:\n\n\t%s\n\nAuthorize the application and enter in the verification code: ", url)

		var authCode string
		fmt.Scanln(&authCode)

		token, _, err = oc.RequestToken(http.DefaultClient, tempCredentials, authCode)
		if err != nil {
			return nil, err
		}

		// Save the user token within our token file
		t.User = token
		save, err := json.Marshal(t)
		if err != nil {
			return nil, err
		}

		if err := ioutil.WriteFile(t.TokenFile, save, tokenFilePermission); err != nil {
			return nil, err
		}
	}

	return token, nil
}
示例#11
0
// Open opens a new stream.
func Open(oauthClient *oauth.Client, accessToken *oauth.Credentials, urlStr string, params url.Values) (*Stream, error) {
	ts := new(Stream)

	u, err := url.Parse(urlStr)
	if err != nil {
		return nil, err
	}

	addr := u.Host
	if strings.LastIndex(addr, ":") <= strings.LastIndex(addr, "]") {
		if u.Scheme == "http" {
			addr = addr + ":80"
		} else {
			addr = addr + ":443"
		}
	}

	if u.Scheme == "http" {
		ts.conn, err = net.Dial("tcp", addr)
		if err != nil {
			return nil, err
		}
	} else {
		ts.conn, err = tls.Dial("tcp", addr, nil)
		if err != nil {
			return nil, err
		}
		if err = ts.conn.(*tls.Conn).VerifyHostname(addr[:strings.LastIndex(addr, ":")]); err != nil {
			return nil, ts.fatal(err)
		}
	}

	// Setup request body.
	pcopy := url.Values{}
	for key, values := range params {
		pcopy[key] = values
	}
	oauthClient.SignParam(accessToken, "POST", urlStr, pcopy)
	body := pcopy.Encode()

	var req bytes.Buffer
	req.WriteString("POST ")
	req.WriteString(u.RequestURI())
	req.WriteString(" HTTP/1.1")
	req.WriteString("\r\nHost: ")
	req.WriteString(u.Host)
	req.WriteString("\r\nContent-Type: application/x-www-form-urlencoded")
	req.WriteString("\r\nContent-Length: ")
	req.WriteString(strconv.Itoa(len(body)))
	req.WriteString("\r\n\r\n")
	req.WriteString(body)
	_, err = ts.conn.Write(req.Bytes())
	if err != nil {
		return nil, ts.fatal(err)
	}

	// Must connect in 60 seconds.
	err = ts.conn.SetReadDeadline(time.Now().Add(60 * time.Second))
	if err != nil {
		return nil, ts.fatal(err)
	}

	ts.r = bufio.NewReaderSize(ts.conn, 8192)
	p, err := ts.r.ReadSlice('\n')
	if err != nil {
		return nil, ts.fatal(err)
	}

	m := responseLineRegexp.FindSubmatch(p)
	if m == nil {
		return nil, ts.fatal(errors.New("twitterstream: bad http response line"))
	}

	// Skip headers
	for {
		p, err = ts.r.ReadSlice('\n')
		if err != nil {
			return nil, ts.fatal(err)
		}
		if len(p) <= 2 {
			break
		}
	}

	statusCode, _ := strconv.Atoi(string(m[1]))
	if statusCode != 200 {
		p, _ := ioutil.ReadAll(ts.r)
		return nil, HTTPStatusError{statusCode, string(p)}
	}

	ts.chunkState = stateStart
	return ts, nil
}