Skip to content

Commit b03b5a2

Browse files
committed
Merge pull request #6 from jbn/master
Refactor several methods and elaborate tests
2 parents 7423271 + 0a49fa1 commit b03b5a2

File tree

5 files changed

+153
-121
lines changed

5 files changed

+153
-121
lines changed

REQUIRE

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
julia 0.3
2-
URIParser
3-
Requests
2+
Compat
3+
FactCheck
44
Nettle
5-
Compat
5+
Requests
6+
URIParser

src/OAuth.jl

Lines changed: 42 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,16 @@ oauth_nonce,
99
oauth_sign_hmac_sha1,
1010
oauth_signing_key,
1111
oauth_signature_base_string,
12-
oauth_percent_encode_keys,
12+
oauth_percent_encode_keys!,
1313
oauth_serialize_url_parameters,
14-
encodeURI,
14+
encodeURI!,
1515
oauth_body_hash_file,
1616
oauth_body_hash_data,
1717
oauth_body_hash_encode,
1818
oauth_header,
1919
oauth_request_resource
2020

21+
2122
#############################################################
2223
#
2324
# OAuth Client Functions
@@ -52,71 +53,67 @@ function oauth_signature_base_string(httpmethod::String, url::String, parameters
5253
end
5354

5455
#URL-escape keys
55-
function oauth_percent_encode_keys(options::Dict)
56+
function oauth_percent_encode_keys!(options::Dict)
5657
#options encoded
5758
originalkeys = collect(keys(options))
5859

5960
for key in originalkeys
60-
options[encodeURI("$key")] = encodeURI(options["$key"])
61-
if encodeURI("$key") != key
62-
delete!(options, "$key")
63-
end
61+
key_str = string(key)
62+
encoded_key = encodeURI(key_str)
63+
64+
options[encoded_key] = encodeURI(options[key_str])
65+
if encodeURI(key_str) != key
66+
delete!(options, key_str)
67+
end
6468
end
6569

6670
options
6771
end
6872

69-
#Create query string from dictionary keys
70-
function oauth_serialize_url_parameters(options::Dict)
71-
#Sort keys
72-
keyssorted = sort!(collect(keys(options)))
73-
74-
#Build query string, remove trailing &
75-
parameterstring = ""
76-
for key in keyssorted
77-
parameterstring *= "$key=$(options["$key"])&"
78-
end
73+
@deprecate(
74+
oauth_percent_encode_keys(options::Dict),
75+
oauth_percent_encode_keys!(options::Dict)
76+
)
7977

80-
chop(parameterstring)
81-
end
78+
#Create query string from dictionary keys
79+
oauth_serialize_url_parameters(options::Dict) = join(
80+
["$key=$(options[key])" for key in sort!(collect(keys(options)))],
81+
"&"
82+
)
8283

8384
# See: https://github.com/randyzwitch/OAuth.jl/issues/3
8485
encodeURI(s) = URIParser.escape(s)
8586

86-
function encodeURI(dict_of_parameters::Dict)
87+
function encodeURI!(dict_of_parameters::Dict)
8788
for (k, v) in dict_of_parameters
8889
if typeof(v) <: String
89-
dict_of_parameters["$k"] = encodeURI(v)
90-
else
91-
dict_of_parameters["$k"] = v
90+
dict_of_parameters[k] = encodeURI(v)
9291
end
9392
end
9493
return dict_of_parameters
9594
end
9695

97-
#Combine with oauth_body_hash_file as one function with two methods?
96+
@deprecate(
97+
encodeURI(dict_of_parameters::Dict),
98+
encodeURI!(dict_of_parameters::Dict)
99+
)
100+
98101
function oauth_body_hash_file(filename::String)
99-
filecontents = readall(open(filename))
100-
oauth_body_hash_data(filecontents)
102+
oauth_body_hash_data(readall(open(filename)))
101103
end
102104

103-
#Combine with oauth_body_hash_file as one function with two methods?
104105
function oauth_body_hash_data(data::String)
105-
bodyhash = oauth_body_hash_encode(data)
106-
"oauth_body_hash=$(bodyhash)"
106+
"oauth_body_hash=$(oauth_body_hash_encode(data))"
107107
end
108108

109-
#Use functions from Nettle
110109
function oauth_body_hash_encode(data::String)
111110
h = HashState(SHA1)
112111
update!(h, data)
113112
base64encode(digest!(h))
114113
end
115114

116115
#Use this function to build the header for every OAuth call
117-
#This function assumes that options Dict has already been run through encodeURI
118-
#Use this function to build the header for every OAuth call
119-
#This function assumes that options Dict has already been run through encodeURI
116+
# This function assumes that options Dict has already been run through encodeURI!
120117
function oauth_header(httpmethod, baseurl, options, oauth_consumer_key, oauth_consumer_secret, oauth_token, oauth_token_secret;
121118
oauth_signature_method = "HMAC-SHA1",
122119
oauth_version = "1.0")
@@ -130,7 +127,7 @@ function oauth_header(httpmethod, baseurl, options, oauth_consumer_key, oauth_co
130127
options["oauth_version"] = oauth_version
131128

132129
#options encoded
133-
options = oauth_percent_encode_keys(options)
130+
oauth_percent_encode_keys!(options)
134131

135132
#Create ordered query string
136133
parameterstring = oauth_serialize_url_parameters(options)
@@ -149,31 +146,26 @@ function oauth_header(httpmethod, baseurl, options, oauth_consumer_key, oauth_co
149146
end
150147

151148
function oauth_request_resource(endpoint::String, httpmethod::String, options::Dict, oauth_consumer_key::String, oauth_consumer_secret::String, oauth_token::String, oauth_token_secret::String)
152-
153149
#Build query string
154150
query_str = Requests.format_query_str(options)
155151

156152
#Build oauth_header
157-
#oauth_header_val = oauth_header(httpmethod, endpoint, options)
158153
oauth_header_val = oauth_header(httpmethod, endpoint, options, oauth_consumer_key, oauth_consumer_secret, oauth_token, oauth_token_secret)
159154

160155
#Make request
161-
if uppercase(httpmethod) == "POST"
162-
return Requests.post(URI(endpoint),
163-
query_str;
164-
headers = @compat(Dict{String,String}(
165-
"Content-Type" => "application/x-www-form-urlencoded",
166-
"Authorization" => oauth_header_val,
167-
"Accept" => "*/*")))
156+
headers = @compat(
157+
Dict{String,String}(
158+
"Content-Type" => "application/x-www-form-urlencoded",
159+
"Authorization" => oauth_header_val,
160+
"Accept" => "*/*"
161+
)
162+
)
168163

164+
if uppercase(httpmethod) == "POST"
165+
return Requests.post(URI(endpoint), query_str; headers = headers)
169166
elseif uppercase(httpmethod) == "GET"
170-
return Requests.get(URI("$(endpoint)?$query_str");
171-
headers = @compat(Dict{String,String}(
172-
"Content-Type" => "application/x-www-form-urlencoded",
173-
"Authorization" => oauth_header_val,
174-
"Accept" => "*/*")))
167+
return Requests.get(URI("$(endpoint)?$query_str"); headers = headers)
175168
end
176-
177169
end
178170

179-
end # module
171+
end

test/auth_body_hash_file.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Hello, World!

test/randy.txt

Lines changed: 0 additions & 1 deletion
This file was deleted.

test/runtests.jl

Lines changed: 106 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,111 @@
11
using OAuth
22
using Compat
3-
using Base.Test
4-
5-
6-
7-
#Test that timestamp comes out as a string
8-
@test typeof(oauth_timestamp()) <: String
9-
10-
#Test that timestamp is greater than integer representing approx. 2014-01-25 20:25:00
11-
@test @compat parse(Int, oauth_timestamp()) > 1422235471
12-
13-
14-
15-
#Test that nonce comes out as a string
16-
@test typeof(oauth_nonce(15)) <: String
17-
18-
#Test that nonce comes out same length as passed argument
19-
@test length(oauth_nonce(15)) == 15
20-
@test length(oauth_nonce(20)) == 20
21-
@test length(oauth_nonce(25)) == 25
22-
@test length(oauth_nonce(30)) == 30
23-
@test length(oauth_nonce(32)) == 32
24-
25-
26-
27-
#Test that HMAC-SHA1 signature provides consistent string
28-
@test oauth_sign_hmac_sha1("randy","zwitch") == "WqKCG5iyhFiES3fWYVdWJWwinaY="
29-
30-
31-
32-
#Validate that signing key a concatenation of values, separated by &
33-
@test oauth_signing_key("9djdj82h48djs9d2", "kkk9d7dh3k39sjv7") == "9djdj82h48djs9d2&kkk9d7dh3k39sjv7"
34-
35-
36-
37-
#Test that base string is concatenated then percent-encoded
38-
@test oauth_signature_base_string("POST", "http://example.com", "?julia=fast&lang=elegant") == "POST&http%3A%2F%2Fexample.com&%3Fjulia%3Dfast%26lang%3Delegant"
39-
40-
41-
42-
#TODO
43-
#oauth_percent_encode_keys()
44-
45-
46-
47-
#TODO
48-
#oauth_serialize_url_parameters()
49-
50-
51-
52-
#TODO
53-
#encodeURI()
54-
55-
56-
57-
#TODO
58-
#oauth_body_hash_file(filename::String)
59-
60-
61-
62-
#TODO
63-
#oauth_body_hash_data(data::String)
64-
65-
66-
67-
#TODO
68-
#oauth_body_hash_encode(data::String)
69-
3+
using FactCheck
4+
5+
6+
facts("oauth_timestamp") do
7+
context("returns a string") do
8+
@fact typeof(oauth_timestamp()) <: String --> true
9+
end
10+
11+
context("returns a value representing a time after 2014-01-25 20:25:00") do
12+
@compat @fact parse(Int, oauth_timestamp()) > 1422235471 --> true
13+
end
14+
end
15+
16+
facts("ouath_nonce") do
17+
context("returns a string") do
18+
@fact typeof(oauth_nonce(15)) <: String --> true
19+
end
20+
21+
context("with a length equal to the parameter length") do
22+
@fact length(oauth_nonce(15)) --> 15
23+
@fact length(oauth_nonce(20)) --> 20
24+
@fact length(oauth_nonce(25)) --> 25
25+
@fact length(oauth_nonce(30)) --> 30
26+
@fact length(oauth_nonce(32)) --> 32
27+
end
28+
end
29+
30+
facts("oauth_sign_hmac_sha1") do
31+
context("provides a consistent string") do
32+
expected = "WqKCG5iyhFiES3fWYVdWJWwinaY="
33+
@fact oauth_sign_hmac_sha1("randy", "zwitch") --> expected
34+
end
35+
end
36+
37+
facts("oauth_signing_key") do
38+
context("returns a concatenation of values, seperated by &") do
39+
result = oauth_signing_key("9djdj82h48djs9d2", "kkk9d7dh3k39sjv7")
40+
expected = "9djdj82h48djs9d2&kkk9d7dh3k39sjv7"
41+
@fact result --> expected
42+
end
43+
end
44+
45+
facts("oauth_signature_base_string") do
46+
context("returns a concatinated and percent-encoded string") do
47+
result = oauth_signature_base_string(
48+
"POST", "http://example.com", "?julia=fast&lang=elegant"
49+
)
50+
expected = "POST&http%3A%2F%2Fexample.com&%3Fjulia%3Dfast%26lang%3Delegant"
51+
@fact result --> expected
52+
end
53+
end
54+
55+
facts("oauth_percent_encode_keys!") do
56+
context("replaces un-encoded keys with their encoded versions") do
57+
params = @compat Dict("badkey!" => "value", "goodkey" => "value")
58+
expected = @compat Dict("badkey%21" => "value", "goodkey" => "value")
59+
60+
@fact oauth_percent_encode_keys!(params) --> expected
61+
end
62+
end
63+
64+
facts("oauth_serialize_url_parameters") do
65+
context("returns an & concatinated string of key=value") do
66+
params = @compat Dict("language" => "julia", "result" => "awesome")
67+
expected = "language=julia&result=awesome"
68+
@fact oauth_serialize_url_parameters(params) --> expected
69+
end
70+
end
71+
72+
facts("encodeURI!") do
73+
context("escapes all values in the parameters that are strings") do
74+
params = @compat Dict("iv" => 10, "s" => "value!")
75+
expected = @compat Dict("iv" => 10, "s" => "value%21")
76+
77+
@fact encodeURI!(params) --> expected
78+
end
79+
end
80+
81+
facts("oauth_body_hash_encode") do
82+
context("returns the base64 encoded SHA1 digest of the data") do
83+
result = oauth_body_hash_encode("Hello, World!")
84+
expected = "CgqfKmdylCVXq1NV12r0Qvj2XgE="
85+
@fact result --> expected
86+
end
87+
end
88+
89+
facts("oauth_body_hash_data") do
90+
context("returns a string of the oauth_body_hash key-value pair ") do
91+
result = oauth_body_hash_data("Hello, World!")
92+
encoded_hash = "CgqfKmdylCVXq1NV12r0Qvj2XgE="
93+
expected = "oauth_body_hash=$encoded_hash"
94+
95+
@fact result --> expected
96+
end
97+
end
98+
99+
facts("oauth_body_hash_file") do
100+
context("returns a string of the oauth_body_hash key-value pair ") do
101+
test_file = joinpath(dirname(@__FILE__), "auth_body_hash_file.txt")
102+
result = oauth_body_hash_file(test_file)
103+
encoded_hash = "CgqfKmdylCVXq1NV12r0Qvj2XgE="
104+
expected = "oauth_body_hash=$encoded_hash"
105+
106+
@fact result --> expected
107+
end
108+
end
70109

71110

72111
#TODO

0 commit comments

Comments
 (0)