oauth.erl 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. -module(oauth).
  2. -export([get/5, get/6, header/1, post/5, post/6, signature/5, signature_base_string/3,
  3. signed_params/6, token/1, token_secret/1, uri/2, verify/6]).
  4. get(URL, ExtraParams, Consumer, Token, TokenSecret) ->
  5. get(URL, ExtraParams, Consumer, Token, TokenSecret, []).
  6. get(URL, ExtraParams, Consumer, Token, TokenSecret, HttpcOptions) ->
  7. SignedParams = signed_params("GET", URL, ExtraParams, Consumer, Token, TokenSecret),
  8. oauth_http:get(uri(URL, SignedParams), HttpcOptions).
  9. post(URL, ExtraParams, Consumer, Token, TokenSecret) ->
  10. post(URL, ExtraParams, Consumer, Token, TokenSecret, []).
  11. post(URL, ExtraParams, Consumer, Token, TokenSecret, HttpcOptions) ->
  12. SignedParams = signed_params("POST", URL, ExtraParams, Consumer, Token, TokenSecret),
  13. oauth_http:post(URL, oauth_uri:params_to_string(SignedParams), HttpcOptions).
  14. uri(Base, []) ->
  15. Base;
  16. uri(Base, Params) ->
  17. lists:concat([Base, "?", oauth_uri:params_to_string(Params)]).
  18. header(Params) ->
  19. {"Authorization", "OAuth " ++ oauth_uri:params_to_header_string(Params)}.
  20. token(Params) ->
  21. proplists:get_value("oauth_token", Params).
  22. token_secret(Params) ->
  23. proplists:get_value("oauth_token_secret", Params).
  24. verify(Signature, HttpMethod, URL, Params, Consumer, TokenSecret) ->
  25. case signature_method(Consumer) of
  26. plaintext ->
  27. oauth_plaintext:verify(Signature, consumer_secret(Consumer), TokenSecret);
  28. hmac_sha1 ->
  29. BaseString = signature_base_string(HttpMethod, URL, Params),
  30. oauth_hmac_sha1:verify(Signature, BaseString, consumer_secret(Consumer), TokenSecret);
  31. rsa_sha1 ->
  32. BaseString = signature_base_string(HttpMethod, URL, Params),
  33. oauth_rsa_sha1:verify(Signature, BaseString, consumer_secret(Consumer))
  34. end.
  35. signed_params(HttpMethod, URL, ExtraParams, Consumer, Token, TokenSecret) ->
  36. Params = token_param(Token, params(Consumer, ExtraParams)),
  37. [{"oauth_signature", signature(HttpMethod, URL, Params, Consumer, TokenSecret)}|Params].
  38. signature(HttpMethod, URL, Params, Consumer, TokenSecret) ->
  39. case signature_method(Consumer) of
  40. plaintext ->
  41. oauth_plaintext:signature(consumer_secret(Consumer), TokenSecret);
  42. hmac_sha1 ->
  43. BaseString = signature_base_string(HttpMethod, URL, Params),
  44. oauth_hmac_sha1:signature(BaseString, consumer_secret(Consumer), TokenSecret);
  45. rsa_sha1 ->
  46. BaseString = signature_base_string(HttpMethod, URL, Params),
  47. oauth_rsa_sha1:signature(BaseString, consumer_secret(Consumer))
  48. end.
  49. signature_base_string(HttpMethod, URL, Params) ->
  50. NormalizedURL = oauth_uri:normalize(URL),
  51. NormalizedParams = normalized_params_string(Params),
  52. oauth_uri:calate("&", [HttpMethod, NormalizedURL, NormalizedParams]).
  53. normalized_params_string(Params) ->
  54. % cf. http://tools.ietf.org/html/rfc5849#section-3.4.1.3.2
  55. Encoded = [{oauth_uri:encode(K), oauth_uri:encode(V)} || {K, V} <- Params],
  56. Sorted = lists:sort(Encoded),
  57. Concatenated = [lists:concat([K, "=", V]) || {K, V} <- Sorted],
  58. string:join(Concatenated, "&").
  59. token_param("", Params) ->
  60. Params;
  61. token_param(Token, Params) ->
  62. [{"oauth_token", Token}|Params].
  63. params(Consumer, Params) ->
  64. Nonce = base64:encode_to_string(crypto:rand_bytes(32)), % cf. ruby-oauth
  65. params(Consumer, unix_timestamp(), Nonce, Params).
  66. params(Consumer, Timestamp, Nonce, Params) ->
  67. [ {"oauth_version", "1.0"}
  68. , {"oauth_nonce", Nonce}
  69. , {"oauth_timestamp", integer_to_list(Timestamp)}
  70. , {"oauth_signature_method", signature_method_string(Consumer)}
  71. , {"oauth_consumer_key", consumer_key(Consumer)}
  72. | Params
  73. ].
  74. unix_timestamp() ->
  75. unix_timestamp(calendar:universal_time()).
  76. unix_timestamp(DateTime) ->
  77. unix_seconds(DateTime) - unix_epoch().
  78. unix_epoch() ->
  79. unix_seconds({{1970,1,1},{00,00,00}}).
  80. unix_seconds(DateTime) ->
  81. calendar:datetime_to_gregorian_seconds(DateTime).
  82. signature_method_string(Consumer) ->
  83. case signature_method(Consumer) of
  84. plaintext ->
  85. "PLAINTEXT";
  86. hmac_sha1 ->
  87. "HMAC-SHA1";
  88. rsa_sha1 ->
  89. "RSA-SHA1"
  90. end.
  91. signature_method(_Consumer={_, _, Method}) ->
  92. Method.
  93. consumer_secret(_Consumer={_, Secret, _}) ->
  94. Secret.
  95. consumer_key(_Consumer={Key, _, _}) ->
  96. Key.