Permalink
Browse files

more OAuth

  • Loading branch information...
1 parent 7d35e03 commit bcdffd500d788e050055247df8af85737834fe0c @fperrad fperrad committed Jul 7, 2011
Showing with 184 additions and 30 deletions.
  1. +3 −0 CHANGES
  2. +2 −2 eg/echo_lab_madgex_com.lua
  3. +1 −1 src/Spore/Middleware/Auth/OAuth.lua
  4. +23 −16 src/Spore/Request.lua
  5. +155 −11 test/22-oauth.t
View
@@ -1,5 +1,8 @@
Revision history for lua-Spore
+0.1.4
+ - refactor Auth.OAuth
+
0.1.3 Wed Jul 6 12:30:00 2011
- add middleware Auth.Digest
@@ -60,11 +60,11 @@ assert(keys.oauth_token_secret == 'accesssecret')
local r = client:echo{ method = 'foo bar', bar = 'baz' }
print(r.body)
-assert(r.body == 'bar=baz&method=foo bar')
+assert(r.body == 'method=foo bar&bar=baz')
local r = client:echo_p{ method = 'foo bar', bar = 'baz' }
print(r.body)
-assert(r.body == 'bar=baz&method=foo bar')
+assert(r.body == 'method=foo bar&bar=baz')
print 'ok - http://echo.lab.madgex.com'
print '1..1'
@@ -68,7 +68,7 @@ function m:call (req)
local signature_key = escape(self.oauth_consumer_secret) .. '&' .. escape(self.oauth_token_secret or '')
local oauth_signature
if params.oauth_signature_method == 'PLAINTEXT' then
- oauth_signature = escape(escape(signature_key))
+ oauth_signature = escape(signature_key)
else
if params.oauth_signature_method == 'HMAC-SHA1' then
local hmac_binary = crypto.digest('sha1', req.oauth_signature_base_string, signature_key, true)
View
@@ -76,13 +76,18 @@ function m:finalize (oauth)
local payload = spore.payload
local query, query_keys, query_vals = {}, {}, {}
if query_string then
+ query[1] = query_string
if oauth then
- for k, v in query_string:gmatch '([^=]+)=([^&]+)&?' do
+ for k, v in query_string:gmatch '([^=]+)=([^&]*)&?' do
query_keys[#query_keys+1] = k
query_vals[k] = v
end
- else
- query[1] = query_string
+ end
+ end
+ if oauth and payload then -- TODO: content-type
+ for k, v in payload:gmatch '([^=&]+)=?([^&]*)&?' do
+ query_keys[#query_keys+1] = k
+ query_vals[k] = v:gsub('+', '%%20')
end
end
local form = {}
@@ -102,6 +107,9 @@ function m:finalize (oauth)
end
for kk, vv in pairs(headers) do
local nn
+ if oauth and k:match'^oauth_' then
+ v = escape(v)
+ end
vv, nn = vv:gsub(':' .. k, (v:gsub('%%', '%%%%')))
if nn > 0 then
headers[kk] = vv
@@ -110,24 +118,15 @@ function m:finalize (oauth)
end
end
if n == 0 then
+ query[#query+1] = escape(k) .. '=' .. escape(v)
if oauth then
- if not k:match'^oauth_' or payload ~= '@oauth' then
+ if not k:match'^oauth_' then
query_keys[#query_keys+1] = escape5849(k)
query_vals[k] = escape5849(v)
end
- else
- query[#query+1] = escape(k) .. '=' .. escape(v)
end
end
end
- if oauth then
- tsort(query_keys)
- for i = 1, #query_keys do
- local k = query_keys[i]
- local v = query_vals[k]
- query[#query+1] = k .. '=' .. v
- end
- end
if #query > 0 then
query_string = tconcat(query, '&')
end
@@ -138,10 +137,18 @@ function m:finalize (oauth)
end
self.method = env.REQUEST_METHOD
if oauth then
+ local scheme = env.spore.url_scheme
+ local port = env.SERVER_PORT
+ if port == '80' and scheme == 'http' then
+ port = nil
+ end
+ if port == '443' and scheme == 'https' then
+ port = nil
+ end
local base_url = url.build {
- scheme = env.spore.url_scheme,
+ scheme = scheme,
host = env.SERVER_NAME,
- port = env.SERVER_PORT,
+ port = port,
path = path_info,
-- no query
}
View
@@ -6,21 +6,12 @@ if not pcall(require, 'crypto') then
skip_all 'no crypto'
end
-plan(8)
+plan(27)
local response = { status = 200, headers = {} }
require 'Spore.Protocols'.request = function (req)
- is(req.url, 'http://services.org:9999/restapi/show?dummy')
return response
end -- mock
-require 'Spore.Request'.finalize = function (self)
- self.method = 'GET'
- self.url = 'http://services.org:9999/restapi/show?dummy'
- self.oauth_signature_base_string = self.url
- self.headers = {
- authorization = 'Oauth',
- }
-end -- mock
if not require_ok 'Spore.Middleware.Auth.OAuth' then
skip_rest "no Spore.Middleware.Auth.OAuth"
@@ -44,11 +35,164 @@ local data = {
r = mw.call(data, req)
is( r, nil )
-req.env.spore.authentication = true
+local old_generate_timestamp = mw.generate_timestamp
+local old_generate_nonce = mw.generate_nonce
+
+local data = {
+ realm = 'Photos',
+ oauth_consumer_key = 'dpf43f3p2l4k3l03',
+ oauth_consumer_secret = 'kd94hf93k423kf44',
+ oauth_callback = 'http://printer.example.com/ready',
+}
+local req = require 'Spore.Request'.new({
+ REQUEST_METHOD = 'POST',
+ SERVER_NAME = 'photos.example.net',
+ PATH_INFO = '/initiate',
+ spore = {
+ authentication = true,
+ url_scheme = 'https',
+ params = {},
+ }
+})
+mw.generate_timestamp = function () return '137131200' end
+mw.generate_nonce = function () return 'wIjqoS' end
+r = mw.call(data, req)
+is( r, response )
+is( req.url, 'https://photos.example.net/initiate' )
+is( req.oauth_signature_base_string, "POST&https%3A%2F%2Fphotos.example.net%2Finitiate&oauth_callback%3Dhttp%253A%252F%252Fprinter.example.com%252Fready%26oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3DwIjqoS%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D137131200" )
+is( req.headers['authorization'], [[OAuth realm="Photos", oauth_consumer_key="dpf43f3p2l4k3l03", oauth_signature_method="HMAC-SHA1", oauth_signature="74KNZJeDHnMBp0EMJ9ZHt%2FXKycU%3D", oauth_timestamp="137131200", oauth_nonce="wIjqoS", oauth_callback="http%3a%2f%2fprinter.example.com%2fready"]] )
+
+local data = {
+ realm = 'Photos',
+ oauth_consumer_key = 'dpf43f3p2l4k3l03',
+ oauth_consumer_secret = 'kd94hf93k423kf44',
+ oauth_token = 'hh5s93j4hdidpola',
+ oauth_token_secret = 'hdhd0244k9j7ao03',
+ oauth_verifier = 'hfdp7dh39dks9884',
+}
+local req = require 'Spore.Request'.new({
+ REQUEST_METHOD = 'POST',
+ SERVER_NAME = 'photos.example.net',
+ PATH_INFO = '/token',
+ spore = {
+ authentication = true,
+ url_scheme = 'https',
+ params = {},
+ }
+})
+mw.generate_timestamp = function () return '137131201' end
+mw.generate_nonce = function () return 'walatlh' end
+r = mw.call(data, req)
+is( r, response )
+is( req.url, 'https://photos.example.net/token' )
+is(req.oauth_signature_base_string, "POST&https%3A%2F%2Fphotos.example.net%2Ftoken&oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dwalatlh%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D137131201%26oauth_token%3Dhh5s93j4hdidpola%26oauth_verifier%3Dhfdp7dh39dks9884")
+is(req.headers['authorization'], [[OAuth realm="Photos", oauth_consumer_key="dpf43f3p2l4k3l03", oauth_signature_method="HMAC-SHA1", oauth_signature="gKgrFCywp7rO0OXSjdot%2FIHF7IU%3D", oauth_timestamp="137131201", oauth_nonce="walatlh", oauth_token="hh5s93j4hdidpola", oauth_verifier="hfdp7dh39dks9884"]])
+local data = {
+ realm = 'Photos',
+ oauth_consumer_key = 'dpf43f3p2l4k3l03',
+ oauth_consumer_secret = 'kd94hf93k423kf44',
+ oauth_token = 'nnch734d00sl2jdk',
+ oauth_token_secret = 'pfkkdhi9sl3r4s00',
+}
+local req = require 'Spore.Request'.new({
+ REQUEST_METHOD = 'GET',
+ SERVER_NAME = 'photos.example.net',
+ PATH_INFO = '/photos',
+ QUERY_STRING = 'file=vacation.jpg&size=original',
+ spore = {
+ authentication = true,
+ url_scheme = 'http',
+ params = {},
+ }
+})
+mw.generate_timestamp = function () return '137131202' end
+mw.generate_nonce = function () return 'chapoH' end
+r = mw.call(data, req)
+is( r, response )
+is( req.url, 'http://photos.example.net/photos?file=vacation.jpg&size=original' )
+is( req.oauth_signature_base_string, "GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacation.jpg%26oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3DchapoH%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D137131202%26oauth_token%3Dnnch734d00sl2jdk%26size%3Doriginal")
+is( req.headers['authorization'], [[OAuth realm="Photos", oauth_consumer_key="dpf43f3p2l4k3l03", oauth_signature_method="HMAC-SHA1", oauth_signature="MdpQcU8iPSUjWoN%2FUDMsK2sui9I%3D", oauth_timestamp="137131202", oauth_nonce="chapoH", oauth_token="nnch734d00sl2jdk"]] )
+
+local data = {
+ realm = 'Example',
+ oauth_signature_method= 'PLAINTEXT',
+ oauth_consumer_key = 'jd83jd92dhsh93js',
+ oauth_consumer_secret = 'ja893SD9',
+ oauth_callback = 'http://client.example.net/cb?x=1',
+}
+local req = require 'Spore.Request'.new({
+ REQUEST_METHOD = 'POST',
+ SERVER_NAME = 'server.example.com',
+ PATH_INFO = '/request_temp_credentials',
+ spore = {
+ authentication = true,
+ url_scheme = 'https',
+ params = {},
+ }
+})
+r = mw.call(data, req)
+is( r, response )
+is( req.url, 'https://server.example.com/request_temp_credentials' )
+is( req.headers['authorization'], [[OAuth realm="Example", oauth_consumer_key="jd83jd92dhsh93js", oauth_signature_method="PLAINTEXT", oauth_signature="ja893SD9%26", oauth_callback="http%3a%2f%2fclient.example.net%2fcb%3fx%3d1"]] )
+
+local data = {
+ realm = 'Example',
+ oauth_signature_method= 'PLAINTEXT',
+ oauth_consumer_key = 'jd83jd92dhsh93js',
+ oauth_consumer_secret = 'ja893SD9',
+ oauth_token = 'hdk48Djdsa',
+ oauth_token_secret = 'xyz4992k83j47x0b',
+ oauth_verifier = '473f82d3',
+}
+local req = require 'Spore.Request'.new({
+ REQUEST_METHOD = 'POST',
+ SERVER_NAME = 'server.example.com',
+ SERVER_PORT = '443',
+ PATH_INFO = '/request_token',
+ spore = {
+ authentication = true,
+ url_scheme = 'https',
+ params = {},
+ }
+})
+r = mw.call(data, req)
+is( r, response )
+is( req.url, 'https://server.example.com:443/request_token' )
+is( req.headers['authorization'], [[OAuth realm="Example", oauth_consumer_key="jd83jd92dhsh93js", oauth_signature_method="PLAINTEXT", oauth_signature="ja893SD9%26xyz4992k83j47x0b", oauth_token="hdk48Djdsa", oauth_verifier="473f82d3"]])
+
+local data = {
+ realm = 'Example',
+ oauth_consumer_key = '9djdj82h48djs9d2',
+ oauth_consumer_secret = 'j49sk3j29djd',
+ oauth_token = 'kkk9d7dh3k39sjv7',
+ oauth_token_secret = 'dh893hdasih9',
+}
+local req = require 'Spore.Request'.new({
+ REQUEST_METHOD = 'POST',
+ SERVER_NAME = 'example.com',
+ SERVER_PORT = '80',
+ PATH_INFO = '/request',
+ QUERY_STRING = 'b5=%3D%253D&a3=a&c%40=&a2=r%20b',
+ spore = {
+ authentication = true,
+ url_scheme = 'http',
+ payload = 'c2&a4=2+q',
+ params = {},
+ }
+})
+req.headers['content-type'] = 'application/x-www-form-urlencoded'
+mw.generate_timestamp = function () return '137131201' end
+mw.generate_nonce = function () return '7d8f3e4a' end
r = mw.call(data, req)
is( r, response )
+is( req.url, 'http://example.com:80/request?b5=%3D%253D&a3=a&c%40=&a2=r%20b' )
+is( req.oauth_signature_base_string, "POST&http%3A%2F%2Fexample.com%2Frequest&a2%3Dr%2520b%26a3%3Da%26a4%3D2%2520q%26b5%3D%253D%25253D%26c%2540%3D%26c2%3D%26oauth_consumer_key%3D9djdj82h48djs9d2%26oauth_nonce%3D7d8f3e4a%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D137131201%26oauth_token%3Dkkk9d7dh3k39sjv7" )
+
+mw.generate_timestamp = old_generate_timestamp
+mw.generate_nonce = old_generate_nonce
error_like( function ()
+ data.realm = nil
data.oauth_signature_method = 'UNKNOWN'
mw.call(data, req)
end, "UNKNOWN is not supported" )

0 comments on commit bcdffd5

Please sign in to comment.