Initial commit
This commit is contained in:
161
vendor/gopkg.in/masci/flickr.v3/client.go
generated
vendored
Normal file
161
vendor/gopkg.in/masci/flickr.v3/client.go
generated
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
package flickr
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/hmac"
|
||||
"crypto/md5"
|
||||
"crypto/sha1"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Generate a random string of 8 chars, needed for OAuth signature
|
||||
func generateNonce() string {
|
||||
rand.Seed(time.Now().UTC().UnixNano())
|
||||
// For convenience, use a set of chars we don't need to url-escape
|
||||
var letters = []rune("123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ")
|
||||
b := make([]rune, 8)
|
||||
for i := range b {
|
||||
b[i] = letters[rand.Intn(len(letters))]
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
// An utility type to wrap all resources and data needed to complete requests
|
||||
// to the Flickr API
|
||||
type FlickrClient struct {
|
||||
// Flickr application api key
|
||||
ApiKey string
|
||||
// Flickr application api secret
|
||||
ApiSecret string
|
||||
// A generic HTTP client to perform GET and POST requests
|
||||
HTTPClient *http.Client
|
||||
// The base url for API endpoints
|
||||
EndpointUrl string
|
||||
// A string containing POST or GET, needed for OAuth signing
|
||||
HTTPVerb string
|
||||
// A set of url params to query the API
|
||||
Args url.Values
|
||||
// User access token
|
||||
OAuthToken string
|
||||
// User secret token
|
||||
OAuthTokenSecret string
|
||||
// User flickr ID
|
||||
Id string
|
||||
}
|
||||
|
||||
// Create a Flickr client, apiKey and apiSecret are mandatory
|
||||
func NewFlickrClient(apiKey string, apiSecret string) *FlickrClient {
|
||||
return &FlickrClient{
|
||||
ApiKey: apiKey,
|
||||
ApiSecret: apiSecret,
|
||||
HTTPClient: &http.Client{},
|
||||
HTTPVerb: "GET",
|
||||
Args: url.Values{},
|
||||
}
|
||||
}
|
||||
|
||||
// Sign the next request performed by the FlickrClient
|
||||
func (c *FlickrClient) Sign(tokenSecret string) {
|
||||
// the "oauth_signature" param must not be included in the signing process
|
||||
c.Args.Del("oauth_signature")
|
||||
c.Args.Set("oauth_signature", c.getSignature(tokenSecret))
|
||||
}
|
||||
|
||||
// Set the mandatory params for an OAuth request
|
||||
func (c *FlickrClient) SetOAuthDefaults() {
|
||||
c.Args.Add("oauth_version", "1.0")
|
||||
c.Args.Add("oauth_signature_method", "HMAC-SHA1")
|
||||
c.Args.Add("oauth_nonce", generateNonce())
|
||||
c.Args.Add("oauth_timestamp", fmt.Sprintf("%d", time.Now().Unix()))
|
||||
}
|
||||
|
||||
// Sign the request with a default set of OAuth parameters, needed to authorize
|
||||
// users for certain writing/destructive operations.
|
||||
func (c *FlickrClient) OAuthSign() {
|
||||
c.SetOAuthDefaults()
|
||||
c.Args.Set("oauth_token", c.OAuthToken)
|
||||
c.Args.Set("oauth_consumer_key", c.ApiKey)
|
||||
c.Args.Set("api_key", c.ApiKey)
|
||||
|
||||
c.Sign(c.OAuthTokenSecret)
|
||||
}
|
||||
|
||||
// Specific signing process for API calls: not the same as OAuth sign, used
|
||||
// for requests that don't need user authorizations.
|
||||
func (c *FlickrClient) ApiSign() {
|
||||
c.Args.Set("api_key", c.ApiKey)
|
||||
// the "api_sig" param must not be included in the signing process
|
||||
c.Args.Del("api_sig")
|
||||
c.Args.Set("api_sig", c.getApiSignature(c.ApiSecret))
|
||||
}
|
||||
|
||||
// Evaluate the complete URL to make requests (base url + params)
|
||||
func (c *FlickrClient) GetUrl() string {
|
||||
return fmt.Sprintf("%s?%s", c.EndpointUrl, c.Args.Encode())
|
||||
}
|
||||
|
||||
// Remove all query params
|
||||
func (c *FlickrClient) ClearArgs() {
|
||||
c.Args = url.Values{}
|
||||
}
|
||||
|
||||
// Reset Args and set the default endpoint
|
||||
func (c *FlickrClient) Init() {
|
||||
c.ClearArgs()
|
||||
c.EndpointUrl = API_ENDPOINT
|
||||
}
|
||||
|
||||
// Get the base string to compose the signature
|
||||
func (c *FlickrClient) getSigningBaseString() string {
|
||||
request_url := url.QueryEscape(c.EndpointUrl)
|
||||
flickr_encoded := strings.Replace(c.Args.Encode(), "+", "%20", -1)
|
||||
query := url.QueryEscape(flickr_encoded)
|
||||
|
||||
ret := fmt.Sprintf("%s&%s&%s", c.HTTPVerb, request_url, query)
|
||||
return ret
|
||||
}
|
||||
|
||||
// Compute the signature of a signed request
|
||||
func (c *FlickrClient) getSignature(token_secret string) string {
|
||||
key := fmt.Sprintf("%s&%s", url.QueryEscape(c.ApiSecret), url.QueryEscape(token_secret))
|
||||
base_string := c.getSigningBaseString()
|
||||
|
||||
mac := hmac.New(sha1.New, []byte(key))
|
||||
mac.Write([]byte(base_string))
|
||||
|
||||
ret := base64.StdEncoding.EncodeToString(mac.Sum(nil))
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
// Sign API requests. This method differs from the signing process needed for
|
||||
// OAuth authenticated requests.
|
||||
func (c *FlickrClient) getApiSignature(token_secret string) string {
|
||||
var buf bytes.Buffer
|
||||
buf.WriteString(token_secret)
|
||||
|
||||
keys := make([]string, 0, len(c.Args))
|
||||
for k := range c.Args {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
// args needs to be in alphabetical order
|
||||
sort.Strings(keys)
|
||||
|
||||
for _, k := range keys {
|
||||
arg := c.Args[k][0]
|
||||
buf.WriteString(k)
|
||||
buf.WriteString(arg)
|
||||
}
|
||||
|
||||
base := buf.String()
|
||||
|
||||
data := []byte(base)
|
||||
return fmt.Sprintf("%x", md5.Sum(data))
|
||||
}
|
||||
Reference in New Issue
Block a user