/engine/vcs/bitbucketserver/oauth_consumer_token.go

https://github.com/ovh/cds · Go · 197 lines · 133 code · 30 blank · 34 comment · 26 complexity · 968e499eb004076fdabb0f16546c98b7 MD5 · raw file

  1. package bitbucketserver
  2. import (
  3. "errors"
  4. "io"
  5. "io/ioutil"
  6. "net/http"
  7. "net/url"
  8. "strconv"
  9. )
  10. // Token is an interface for RequestToken and AccessToken
  11. type Token interface {
  12. Token() string // Gets the oauth_token value.
  13. Secret() string // Gets the oauth_token_secret.
  14. Encode() string // Encode encodes the token into “URL encoded” form.
  15. }
  16. // AccessToken represents a value used by the Consumer to gain access
  17. // to the Protected Resources on behalf of the User, instead of using
  18. // the User's Service Provider credentials.
  19. type AccessToken struct {
  20. token string // the oauth_token value
  21. secret string // the oauth_token_secret value
  22. params map[string]string // additional params, as defined by the Provider.
  23. }
  24. // NewAccessToken returns a new instance of AccessToken with the specified
  25. // token, secret and additional parameters.
  26. func NewAccessToken(token, secret string, params map[string]string) *AccessToken {
  27. return &AccessToken{
  28. token: token,
  29. secret: secret,
  30. params: params,
  31. }
  32. }
  33. // ParseAccessToken parses the URL-encoded query string from the Reader
  34. // and returns an AccessToken.
  35. func ParseAccessToken(reader io.ReadCloser) (*AccessToken, error) {
  36. body, err := ioutil.ReadAll(reader)
  37. reader.Close()
  38. if err != nil {
  39. return nil, err
  40. }
  41. return ParseAccessTokenStr(string(body))
  42. }
  43. // ParseAccessTokenStr parses the URL-encoded query string and returns
  44. // an AccessToken.
  45. func ParseAccessTokenStr(str string) (*AccessToken, error) {
  46. token := AccessToken{}
  47. token.params = map[string]string{}
  48. //parse the request token from the body
  49. parts, err := url.ParseQuery(str)
  50. if err != nil {
  51. return nil, err
  52. }
  53. //loop through parts to create Token
  54. for key, val := range parts {
  55. switch key {
  56. case "oauth_token":
  57. token.token = val[0]
  58. case "oauth_token_secret":
  59. token.secret = val[0]
  60. default:
  61. token.params[key] = val[0]
  62. }
  63. }
  64. //some error checking ...
  65. switch {
  66. case len(token.token) == 0:
  67. return nil, errors.New(str)
  68. case len(token.secret) == 0:
  69. return nil, errors.New(str)
  70. }
  71. return &token, nil
  72. }
  73. // Encode encodes the values into “URL encoded” form of the AccessToken.
  74. // e.g. "oauth_token=foo&oauth_token_secret=baz"
  75. func (a *AccessToken) Encode() string {
  76. values := url.Values{}
  77. values.Set("oauth_token", a.token)
  78. values.Set("oauth_token_secret", a.secret)
  79. if a.params != nil {
  80. for key, val := range a.params {
  81. values.Set(key, val)
  82. }
  83. }
  84. return values.Encode()
  85. }
  86. // Token gets the oauth_token value
  87. func (a *AccessToken) Token() string { return a.token }
  88. // Secret gets the oauth_token_secret value
  89. func (a *AccessToken) Secret() string { return a.secret }
  90. // Params gets any additional parameters, as defined by the Service Provider.
  91. func (a *AccessToken) Params() map[string]string { return a.params }
  92. // RequestToken represents a value used by the Consumer to obtain
  93. // authorization from the User, and exchanged for an Access Token.
  94. type RequestToken struct {
  95. token string // the oauth_token value
  96. secret string // the oauth_token_secret value
  97. callbackConfirmed bool
  98. }
  99. // ParseRequestToken parses the URL-encoded query string from the Reader
  100. // and returns a RequestToken.
  101. func ParseRequestToken(reader io.ReadCloser) (*RequestToken, error) {
  102. body, err := ioutil.ReadAll(reader)
  103. reader.Close()
  104. if err != nil {
  105. return nil, err
  106. }
  107. return ParseRequestTokenStr(string(body))
  108. }
  109. // ParseRequestTokenStr parses the URL-encoded query string and returns
  110. // a RequestToken.
  111. func ParseRequestTokenStr(str string) (*RequestToken, error) {
  112. //parse the request token from the body
  113. parts, err := url.ParseQuery(str)
  114. if err != nil {
  115. return nil, err
  116. }
  117. token := RequestToken{}
  118. token.token = parts.Get("oauth_token")
  119. token.secret = parts.Get("oauth_token_secret")
  120. token.callbackConfirmed = parts.Get("oauth_callback_confirmed") == "true"
  121. //some error checking ...
  122. switch {
  123. case len(token.token) == 0:
  124. return nil, errors.New(str)
  125. case len(token.secret) == 0:
  126. return nil, errors.New(str)
  127. }
  128. return &token, nil
  129. }
  130. // Encode encodes the values into “URL encoded” form of the ReqeustToken.
  131. // e.g. "oauth_token=foo&oauth_token_secret=baz"
  132. func (r *RequestToken) Encode() string {
  133. values := url.Values{}
  134. values.Set("oauth_token_secret", r.secret)
  135. values.Set("oauth_token", r.token)
  136. values.Set("oauth_callback_confirmed", strconv.FormatBool(r.callbackConfirmed))
  137. return values.Encode()
  138. }
  139. func (c *bitbucketConsumer) RequestToken() (*RequestToken, error) {
  140. // create the http request to fetch a Request Token.
  141. requestTokenURL, _ := url.Parse(c.requestTokenURL)
  142. req := http.Request{
  143. URL: requestTokenURL,
  144. Method: "POST",
  145. Close: true,
  146. }
  147. // sign the request
  148. err := c.SignParams(&req, nil, map[string]string{"oauth_callback": c.callbackURL})
  149. if err != nil {
  150. return nil, err
  151. }
  152. // make the http request and get the response
  153. resp, err := http.DefaultClient.Do(&req)
  154. if err != nil {
  155. return nil, err
  156. }
  157. // parse the Request's Body
  158. requestToken, err := ParseRequestToken(resp.Body)
  159. if err != nil {
  160. return nil, err
  161. }
  162. return requestToken, nil
  163. }
  164. // Token gets the oauth_token value
  165. func (r *RequestToken) Token() string { return r.token }
  166. // Secret gets the oauth_token_secret value
  167. func (r *RequestToken) Secret() string { return r.secret }