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) }
// 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 }
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) }
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 } }
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 } }
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) } }
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) } }
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 }
// 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 }
// 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 }