1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- -module(oauth_request).
- -export([params_string/5]).
- -export([url/5]).
- -export([header/6]).
- % for testing:
- -export([plaintext_signature/2]).
- -export([hmac_sha1_signature/3]).
- -export([hmac_sha1_base_string/3]).
- -export([hmac_sha1_normalize/1]).
- -export([params_to_header_string/1]).
- -import(fmt, [sprintf/2, percent_encode/1]).
- -import(lists, [map/2]).
- params_string(Method, URL, ExtraParams, Consumer, Tokens) ->
- SignedParams = params(Method, URL, ExtraParams, Consumer, Tokens),
- params_to_string(SignedParams).
- url(Method, URL, ExtraParams, Consumer, Tokens) ->
- SignedParams = params(Method, URL, ExtraParams, Consumer, Tokens),
- sprintf("%s?%s", [URL, params_to_string(SignedParams)]).
- header(Realm, Method, URL, ExtraParams, Consumer, Tokens) ->
- SignedParams = params(Method, URL, ExtraParams, Consumer, Tokens),
- sprintf("Authorization: OAuth realm=\"%s\", %s", [Realm, params_to_header_string(SignedParams)]).
- params(Method, URL, ExtraParams, Consumer, Tokens) ->
- {Params, TokenSecret} = oauth_params(Tokens, Consumer, ExtraParams),
- [{oauth_signature, signature(Method, URL, Params, Consumer, TokenSecret)}|Params].
- oauth_params([], Consumer, ExtraParams) ->
- {oauth_params(Consumer, ExtraParams), ""};
- oauth_params(Tokens, Consumer, ExtraParams) ->
- Params = [proplists:lookup(oauth_token, Tokens)|oauth_params(Consumer, ExtraParams)],
- {Params, proplists:get_value(oauth_token_secret, Tokens)}.
- oauth_params(Consumer, ExtraParams) ->
- proplists_merge([
- {oauth_consumer_key, oauth_consumer:key(Consumer)},
- {oauth_signature_method, oauth_consumer:signature_method(Consumer)},
- {oauth_timestamp, oauth_util:unix_timestamp()},
- {oauth_nonce, oauth_util:nonce()},
- {oauth_version, "1.0"}
- ], ExtraParams).
- proplists_merge({K,V}, Merged) ->
- case proplists:is_defined(K, Merged) of
- true ->
- Merged;
- false ->
- [{K,V}|Merged]
- end;
- proplists_merge(A, B) ->
- lists:foldl(fun proplists_merge/2, A, B).
- signature(Method, URL, Params, Consumer, TokenSecret) ->
- ConsumerSecret = oauth_consumer:secret(Consumer),
- case signature_method(Params) of
- "PLAINTEXT" ->
- plaintext_signature(ConsumerSecret, TokenSecret);
- "HMAC-SHA1" ->
- MethodString = string:to_upper(atom_to_list(Method)),
- BaseString = hmac_sha1_base_string(MethodString, URL, Params),
- hmac_sha1_signature(BaseString, ConsumerSecret, TokenSecret)
- end.
- signature_method(Params) ->
- proplists:get_value(oauth_signature_method, Params).
- plaintext_signature(ConsumerSecret, TokenSecret) ->
- percent_encode(sprintf("%s&%s", [percent_encode(ConsumerSecret), percent_encode(TokenSecret)])).
- hmac_sha1_signature(BaseString, ConsumerSecret, TokenSecret) ->
- base64:encode_to_string(crypto:sha_mac(hmac_sha1_key(ConsumerSecret, TokenSecret), BaseString)).
- hmac_sha1_key(ConsumerSecret, TokenSecret) ->
- sprintf("%s&%s", [percent_encode(ConsumerSecret), percent_encode(TokenSecret)]).
- hmac_sha1_base_string(MethodString, URL, Params) ->
- string:join(map(fun fmt:percent_encode/1, [MethodString, URL, hmac_sha1_normalize(Params)]), "&").
- hmac_sha1_normalize(Params) ->
- params_to_string(lists:sort(fun({K,X},{K,Y}) -> X < Y; ({A,_},{B,_}) -> A < B end, Params)).
- params_to_string(Params) ->
- string:join(map(fun param_to_string/1, Params), "&").
- param_to_string({K,V}) ->
- sprintf("%s=%s", [percent_encode(K), percent_encode(V)]).
- params_to_header_string(Params) ->
- string:join(map(fun param_to_header_string/1, Params), ",").
- param_to_header_string({K,V}) ->
- sprintf("%s=\"%s\"", [percent_encode(K), percent_encode(V)]).
|