forked from masci/flickr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathauthentication.go
153 lines (126 loc) · 4.08 KB
/
authentication.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package flickr
import (
"io/ioutil"
"net/url"
"strconv"
"strings"
flickErr "gopkg.in/masci/flickr.v2/error"
)
// Type representing a request token during the exchange process
type RequestToken struct {
// Whether the callback url matches the one provided in Flickr dashboard
OauthCallbackConfirmed bool
// Request token
OauthToken string
// Request token secret
OauthTokenSecret string
// OAuth failing reason in case of errors
OAuthProblem string
}
// Extract a RequestToken from the response body
func ParseRequestToken(response string) (*RequestToken, error) {
val, err := url.ParseQuery(strings.TrimSpace(response))
if err != nil {
return nil, err
}
ret := &RequestToken{}
oauth_problem := val.Get("oauth_problem")
if oauth_problem != "" {
ret.OAuthProblem = oauth_problem
return ret, flickErr.NewError(flickErr.RequestTokenError, oauth_problem)
}
confirmed, _ := strconv.ParseBool(val.Get("oauth_callback_confirmed"))
ret.OauthCallbackConfirmed = confirmed
ret.OauthToken = val.Get("oauth_token")
ret.OauthTokenSecret = val.Get("oauth_token_secret")
return ret, nil
}
// Type representing a OAuth access token along with its owner's data
type OAuthToken struct {
// OAuth access token
OAuthToken string
// OAuth access token secret
OAuthTokenSecret string
// Flickr ID of token's owner
UserNsid string
// Flickr Username of token's owner
Username string
// Flickr full name of token's owner
Fullname string
// OAuth failing reason in case of errors
OAuthProblem string
}
// Extract a OAuthToken from the response body
func ParseOAuthToken(response string) (*OAuthToken, error) {
val, err := url.ParseQuery(strings.TrimSpace(response))
if err != nil {
return nil, err
}
ret := &OAuthToken{}
oauth_problem := val.Get("oauth_problem")
if oauth_problem != "" {
ret.OAuthProblem = oauth_problem
return ret, flickErr.NewError(flickErr.OAuthTokenError, oauth_problem)
}
ret.OAuthToken = val.Get("oauth_token")
ret.OAuthTokenSecret = val.Get("oauth_token_secret")
ret.Fullname = val.Get("fullname")
ret.UserNsid = val.Get("user_nsid")
ret.Username = val.Get("username")
return ret, nil
}
// Retrieve a request token: this is the first step to get a fully functional
// access token from Flickr
func GetRequestToken(client *FlickrClient) (*RequestToken, error) {
client.EndpointUrl = REQUEST_TOKEN_URL
client.SetOAuthDefaults()
client.Args.Set("oauth_consumer_key", client.ApiKey)
client.Args.Set("oauth_callback", "oob")
// we don't have token secret at this stage, pass an empty string
client.Sign("")
res, err := client.HTTPClient.Get(client.GetUrl())
if err != nil {
return nil, err
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
return ParseRequestToken(string(body))
}
// Returns the URL users need to reach to grant permission to our application
func GetAuthorizeUrl(client *FlickrClient, reqToken *RequestToken) (string, error) {
client.EndpointUrl = AUTHORIZE_URL
client.Args = url.Values{}
client.Args.Set("oauth_token", reqToken.OauthToken)
// TODO make permission value parametric
client.Args.Set("perms", "delete")
return client.GetUrl(), nil
}
// Get an access token providing an OAuth verifier provided by Flickr once the user
// authorizes your application
func GetAccessToken(client *FlickrClient, reqToken *RequestToken, oauthVerifier string) (*OAuthToken, error) {
client.EndpointUrl = ACCESS_TOKEN_URL
client.SetOAuthDefaults()
client.Args.Set("oauth_verifier", oauthVerifier)
client.Args.Set("oauth_consumer_key", client.ApiKey)
client.Args.Set("oauth_token", reqToken.OauthToken)
// use the request token for signing
client.Sign(reqToken.OauthTokenSecret)
res, err := client.HTTPClient.Get(client.GetUrl())
if err != nil {
return nil, err
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
accessTok, err := ParseOAuthToken(string(body))
// set client params for convenience
client.OAuthToken = accessTok.OAuthToken
client.OAuthTokenSecret = accessTok.OAuthTokenSecret
client.Id = accessTok.UserNsid
return accessTok, err
}