hoauth (empty) → 0.0.1
raw patch · 7 files changed
+591/−0 lines, 7 filesdep +HUnitdep +SHAdep +basesetup-changed
Dependencies added: HUnit, SHA, base, base64-string, bytestring, utf8-string
Files
- COPYING +165/−0
- Setup.hs +21/−0
- hoauth.cabal +40/−0
- src/main/haskell/Network/Protocol/OAuth/Consumer.hs +73/−0
- src/main/haskell/Network/Protocol/OAuth/Request.hs +169/−0
- src/main/haskell/Network/Protocol/OAuth/Signature.hs +98/−0
- src/test/haskell/Tests.hs +25/−0
+ COPYING view
@@ -0,0 +1,165 @@+ GNU LESSER GENERAL PUBLIC LICENSE+ Version 3, 29 June 2007++ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>+ Everyone is permitted to copy and distribute verbatim copies+ of this license document, but changing it is not allowed.+++ This version of the GNU Lesser General Public License incorporates+the terms and conditions of version 3 of the GNU General Public+License, supplemented by the additional permissions listed below.++ 0. Additional Definitions.++ As used herein, "this License" refers to version 3 of the GNU Lesser+General Public License, and the "GNU GPL" refers to version 3 of the GNU+General Public License.++ "The Library" refers to a covered work governed by this License,+other than an Application or a Combined Work as defined below.++ An "Application" is any work that makes use of an interface provided+by the Library, but which is not otherwise based on the Library.+Defining a subclass of a class defined by the Library is deemed a mode+of using an interface provided by the Library.++ A "Combined Work" is a work produced by combining or linking an+Application with the Library. The particular version of the Library+with which the Combined Work was made is also called the "Linked+Version".++ The "Minimal Corresponding Source" for a Combined Work means the+Corresponding Source for the Combined Work, excluding any source code+for portions of the Combined Work that, considered in isolation, are+based on the Application, and not on the Linked Version.++ The "Corresponding Application Code" for a Combined Work means the+object code and/or source code for the Application, including any data+and utility programs needed for reproducing the Combined Work from the+Application, but excluding the System Libraries of the Combined Work.++ 1. Exception to Section 3 of the GNU GPL.++ You may convey a covered work under sections 3 and 4 of this License+without being bound by section 3 of the GNU GPL.++ 2. Conveying Modified Versions.++ If you modify a copy of the Library, and, in your modifications, a+facility refers to a function or data to be supplied by an Application+that uses the facility (other than as an argument passed when the+facility is invoked), then you may convey a copy of the modified+version:++ a) under this License, provided that you make a good faith effort to+ ensure that, in the event an Application does not supply the+ function or data, the facility still operates, and performs+ whatever part of its purpose remains meaningful, or++ b) under the GNU GPL, with none of the additional permissions of+ this License applicable to that copy.++ 3. Object Code Incorporating Material from Library Header Files.++ The object code form of an Application may incorporate material from+a header file that is part of the Library. You may convey such object+code under terms of your choice, provided that, if the incorporated+material is not limited to numerical parameters, data structure+layouts and accessors, or small macros, inline functions and templates+(ten or fewer lines in length), you do both of the following:++ a) Give prominent notice with each copy of the object code that the+ Library is used in it and that the Library and its use are+ covered by this License.++ b) Accompany the object code with a copy of the GNU GPL and this license+ document.++ 4. Combined Works.++ You may convey a Combined Work under terms of your choice that,+taken together, effectively do not restrict modification of the+portions of the Library contained in the Combined Work and reverse+engineering for debugging such modifications, if you also do each of+the following:++ a) Give prominent notice with each copy of the Combined Work that+ the Library is used in it and that the Library and its use are+ covered by this License.++ b) Accompany the Combined Work with a copy of the GNU GPL and this license+ document.++ c) For a Combined Work that displays copyright notices during+ execution, include the copyright notice for the Library among+ these notices, as well as a reference directing the user to the+ copies of the GNU GPL and this license document.++ d) Do one of the following:++ 0) Convey the Minimal Corresponding Source under the terms of this+ License, and the Corresponding Application Code in a form+ suitable for, and under terms that permit, the user to+ recombine or relink the Application with a modified version of+ the Linked Version to produce a modified Combined Work, in the+ manner specified by section 6 of the GNU GPL for conveying+ Corresponding Source.++ 1) Use a suitable shared library mechanism for linking with the+ Library. A suitable mechanism is one that (a) uses at run time+ a copy of the Library already present on the user's computer+ system, and (b) will operate properly with a modified version+ of the Library that is interface-compatible with the Linked+ Version.++ e) Provide Installation Information, but only if you would otherwise+ be required to provide such information under section 6 of the+ GNU GPL, and only to the extent that such information is+ necessary to install and execute a modified version of the+ Combined Work produced by recombining or relinking the+ Application with a modified version of the Linked Version. (If+ you use option 4d0, the Installation Information must accompany+ the Minimal Corresponding Source and Corresponding Application+ Code. If you use option 4d1, you must provide the Installation+ Information in the manner specified by section 6 of the GNU GPL+ for conveying Corresponding Source.)++ 5. Combined Libraries.++ You may place library facilities that are a work based on the+Library side by side in a single library together with other library+facilities that are not Applications and are not covered by this+License, and convey such a combined library under terms of your+choice, if you do both of the following:++ a) Accompany the combined library with a copy of the same work based+ on the Library, uncombined with any other library facilities,+ conveyed under the terms of this License.++ b) Give prominent notice with the combined library that part of it+ is a work based on the Library, and explaining where to find the+ accompanying uncombined form of the same work.++ 6. Revised Versions of the GNU Lesser General Public License.++ The Free Software Foundation may publish revised and/or new versions+of the GNU Lesser General Public License from time to time. Such new+versions will be similar in spirit to the present version, but may+differ in detail to address new problems or concerns.++ Each version is given a distinguishing version number. If the+Library as you received it specifies that a certain numbered version+of the GNU Lesser General Public License "or any later version"+applies to it, you have the option of following the terms and+conditions either of that published version or of any later version+published by the Free Software Foundation. If the Library as you+received it does not specify a version number of the GNU Lesser+General Public License, you may choose any version of the GNU Lesser+General Public License ever published by the Free Software Foundation.++ If the Library as you received it specifies that a proxy can decide+whether future versions of the GNU Lesser General Public License shall+apply, that proxy's public statement of acceptance of any version is+permanent authorization for you to choose that version for the+Library.
+ Setup.hs view
@@ -0,0 +1,21 @@+-- Copyright (C) 2009 Diego Souza <dsouza at bitforest dot org>+-- +-- This program is free software: you can redistribute it and/or modify+-- it under the terms of the GNU Lesser General Public License as published by+-- the Free Software Foundation, either version 3 of the License, or+-- (at your option) any later version.+-- +-- This program is distributed in the hope that it will be useful,+-- but WITHOUT ANY WARRANTY; without even the implied warranty of+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+-- GNU Lesser General Public License for more details.+-- +-- You should have received a copy of the GNU Lesser General Public License+-- along with this program. If not, see <http://www.gnu.org/licenses/>.++import Distribution.Simple+import System.Cmd(system)++main = defaultMainWithHooks (simpleUserHooks { runTests = tests' })+ where+ tests' _ _ _ _ = system ("runhaskell -i./src/main/haskell -i./src/test/haskell ./src/test/haskell/Tests.hs") >> return()
+ hoauth.cabal view
@@ -0,0 +1,40 @@+name: hoauth+version: 0.0.1+category: Network,Protocol,OAuth+license: LGPL+license-file: COPYING+author: Diego Souza+maintainer: Diego Souza <dsouza@bitforest.org>+stability: experimental+build-type: Simple+cabal-version: >= 1.6+tested-with: GHC == 6.8.2+synopsis: A Haskell implementation of OAuth 1.0 protocol.+description: This library implements both PLAINTEXT and HMAC-SHA1 signatures+ as defined in the specification 1.0. Currently it supports only+ /consumer/ related functions, but there are plans to add support+ /service providers/ as well.++ More info at: <http://oauth.net/>++library+ build-depends: base>=3&&<4,bytestring,SHA,base64-string,utf8-string+ exposed-modules: Network.Protocol.OAuth.Consumer,Network.Protocol.OAuth.Request,Network.Protocol.OAuth.Signature+ hs-source-dirs: src/main/haskell+ ghc-options: -Wall -fwarn-tabs++flag test+ Description: Build the hoauth test suite.+ Default: False++executable test_hoauth+ build-depends: base>=3&&<4,bytestring,SHA,base64-string,HUnit+ ghc-options: -fno-ignore-asserts -fwarn-tabs+ hs-source-dirs: src/main/haskell,src/test/haskell+ main-is: Tests.hs+ if !flag(test)+ buildable: False++source-repository head+ type: darcs+ location: http://projects.bitforest.org/hoauth/
+ src/main/haskell/Network/Protocol/OAuth/Consumer.hs view
@@ -0,0 +1,73 @@+-- Copyright (C) 2009 Diego Souza <dsouza at bitforest dot org>+-- +-- This program is free software: you can redistribute it and/or modify+-- it under the terms of the GNU Lesser General Public License as published by+-- the Free Software Foundation, either version 3 of the License, or+-- (at your option) any later version.+-- +-- This program is distributed in the hope that it will be useful,+-- but WITHOUT ANY WARRANTY; without even the implied warranty of+-- MERCHANTABILITY or FITNESha S FOR A PARTICULAR PURPOSE. See the+-- GNU Lesser General Public License for more details.+-- +-- You should have received a copy of the GNU Lesser General Public License+-- along with this program. If not, see <http://www.gnu.org/licenses/>.++-- | A pure library that implements oauth authentication protocol as defined in <http://oauth.net/core/1.0a>.+--+-- Refer to <http://oauth.net/> for more information about the oauth protocol.+module Network.Protocol.OAuth.Consumer (Token(),Consumer(..),request,response,oauth_token,oauth_token_secret,oauth_extra) where++import Network.Protocol.OAuth.Request as R+import qualified Data.ByteString.Lazy as B+import qualified Network.Protocol.OAuth.Signature as S+import qualified Data.List as L++-- | OAuth uses Tokens generated by the Service Provider instead of the User's credentials in Protected Resources requests.+data Token = Token { oauth_token :: String,+ oauth_token_secret :: String,+ oauth_extra :: [R.Parameter]+ }+ deriving (Show,Read,Eq)++-- | The application which needs to authenticate using oauth.+data Consumer = + -- | Creates a consumer with /consumer_key/ and /consumer_secret/+ Unauthenticated String String+ -- | A consumer with /consumer_key/, /consumer_secret/ and a 'Token'+ | Authenticated String String Token+ deriving (Show,Read,Eq)++-- | Sign a request for oauth request. Use this either to sign requests with a proper Access token or to use the oauth protocol to get a token from service provider.+--+-- The request you provide /must/ contain /oauth_nonce/ and /oauth_timestamp/ parameters properly defined.+request :: (S.Signer s,Show s) => Consumer -> s -> R.Request -> R.Request+request (Unauthenticated ckey csec) s r = _oauth ckey csec Nothing s r+request (Authenticated ckey csec tk) s r = let req = r >>+ ("oauth_token", (Just . oauth_token) tk) + in _oauth ckey csec ((Just . oauth_token_secret) tk) s req++-- | Process the response of the service provider. The response should be an urlencoded string.+response :: Consumer -> B.ByteString -> Maybe Consumer+response cons u = let postdata = R.read_urlencoded u+ otken0 = lookup "oauth_token" postdata+ otkensec0 = lookup "oauth_token_secret" postdata+ otkextra0 = Just $ filter (\(k,_) -> k/="oauth_token"&&k/="oauth_token_secret") postdata+ in otken0 >>= \otken1 -> + otken1 >>= \otken -> + otkensec0 >>= \otkensec1 ->+ otkensec1 >>= \otkensec ->+ otkextra0 >>= \otkextra ->+ case cons+ of (Unauthenticated ckey csec) -> Just $ Authenticated ckey csec (Token otken otkensec otkextra)+ (Authenticated ckey csec _) -> Just $ Authenticated ckey csec (Token otken otkensec otkextra)++_oauth :: (S.Signer s,Show s) => String -> String -> Maybe String -> s -> R.Request -> R.Request+_oauth ckey csec tsec met req = req >>+ ("oauth_consumer_key",Just ckey)+ >>+ ("oauth_version",Just "1.0")+ >>+ ("oauth_signature_method",(Just . show) met)+ >>| _sign csec tsec met++_sign :: (S.Signer s,Show s) => String -> Maybe String -> s -> R.Request -> R.Request+_sign csec tsec met req = let sig = S.sign met csec tsec req+ in req >>+ ("oauth_signature",Just sig)+
+ src/main/haskell/Network/Protocol/OAuth/Request.hs view
@@ -0,0 +1,169 @@+-- Copyright (C) 2009 Diego Souza <dsouza at bitforest dot org>+-- +-- This program is free software: you can redistribute it and/or modify+-- it under the terms of the GNU Lesser General Public License as published by+-- the Free Software Foundation, either version 3 of the License, or+-- (at your option) any later version.+-- +-- This program is distributed in the hope that it will be useful,+-- but WITHOUT ANY WARRANTY; without even the implied warranty of+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+-- GNU Lesser General Public License for more details.+-- You should have received a copy of the GNU Lesser General Public License+-- along with this program. If not, see <http://www.gnu.org/licenses/>.++module Network.Protocol.OAuth.Request (Request(..),HTTPMethod(..),Parameter,PercentEncoding,encode,encodes,decode,decodes,append_param,apply,show_url,show_oauthurl,show_oauthheader,show_urlencoded,read_urlencoded,(>>+),(>>|)) where++import Data.Bits as B+import qualified Data.ByteString.Lazy as B1+import qualified Data.ByteString.Lazy.UTF8 as B2+import qualified Data.ByteString.Lazy.Char8 as B3+import qualified Data.Word as W+import qualified Data.Char as C+import qualified Data.List as L++-- | A pair which represents a parameter (key,value).+type Parameter = (String,Maybe String)++-- | The possible HTTP methods+data HTTPMethod = GET+ | POST+ | DELETE+ | PUT+ deriving (Show,Read,Eq)++-- | Refer to <http://en.wikipedia.org/wiki/Percent-encoding> for more information+class PercentEncoding a where+ -- | Encodes an /a/ type to bytestring.+ encode :: a -> B1.ByteString+ + -- | Encodes a list of /a/ types into bytestring.+ encodes :: [a] -> B1.ByteString+ encodes = B1.concat . map encode+ + -- | Decodes a single /a/ type out of an encoded string.+ decode :: B1.ByteString -> (a,B1.ByteString)+ + -- | Decodes the whole string into a list of /a/ types.+ decodes :: B1.ByteString -> [a]+ decodes = L.unfoldr decode'+ where+ decode' bs | B1.null bs = Nothing+ | otherwise = (Just . decode) bs++-- | The HTTP request which must be properly authenticated with oauth. It is not meant to represent the full HTTP request, instead the data which matters for oauth authentication.+data Request = HTTP { ssl :: Bool, -- ^ True means /HTTPS/ and false means /HTTP/+ method :: HTTPMethod,+ host :: String, -- ^ The hostname or ip address (e.g. bitforest.org)+ port :: Int, -- ^ The tcp port (e.g. 80)+ path :: String, -- ^ The request path (e.g. \/foo\/bar\/)+ params :: [Parameter] -- ^ The request parameters (both GET and POST)+ }+ deriving (Show,Read,Eq)++-- | Convenience function to append an item in request's parameters list+append_param :: Request -> String -> Maybe String -> Request+append_param r k v = let o_params = params r+ n_params = (k,v) : o_params+ in r { params = n_params }++-- | Parses a urlencoded string.+read_urlencoded :: B1.ByteString -> [Parameter]+read_urlencoded u | B1.null u = []+ | otherwise = (map param' . map keyval' . B1.split 0x26) u+ where+ keyval' s = let (k,v) = B1.break (==0x3d) s+ in (k, B1.drop 1 v)++ param' (k,v) | B1.null v = (decodes k,Nothing)+ | otherwise = (decodes k,(Just . decodes) v)++-- | Show the entire url, including possibly any oauth parameter which may be present.+show_url :: Request -> B1.ByteString+show_url (HTTP s m h p0 p1 ps) = B1.concat [endpoint', path', query']+ where+ endpoint' | s && p0==443 = B3.pack $ "https://" ++ h+ | s = B3.pack $ "https://" ++ h ++ (':':(show p0))+ | not s && p0==80 = B3.pack $ "http://" ++ h+ | otherwise = B3.pack $ "http://" ++ h ++ (':':(show p0))++ path' = (B1.cons 0x2f . B1.concat . L.intersperse (B1.singleton 0x2f) . map encodes . _path_comp) p1++ query' | m/=GET || null ps = B1.empty+ | otherwise = (B1.cons 0x3f . show_urlencoded) ps++-- | The URL to perform the oauth request+show_oauthurl :: Request -> B1.ByteString+show_oauthurl req = let params' = params req+ req' = req { params = filter (not . L.isPrefixOf "oauth_" . fst) params' }+ in show_url req'++-- | The Authorization or WWW-Authenticated headers to perform oauth authentication. +show_oauthheader :: String -- ^ The realm+ -> Request+ -> B1.ByteString -- ^ The Authorization\/WWW-Authenticate header+show_oauthheader realm (HTTP _ _ _ _ _ p) | B1.null params' = realm'+ | otherwise = B1.concat [realm', B1.singleton 0x2c, params']+ where+ encodes' s = B1.concat [B1.singleton 0x22, encodes s, B1.singleton 0x22]++ params' = (_urlencode encodes' 0x2c . filter (L.isPrefixOf "oauth_" . fst)) p++ realm' = B3.pack ("OAuth realm=\"" ++ realm ++ "\"")++-- | Produces a urlencoded string.+-- For convenience, it sorts the parameters first, as demands the oauth protocol.+show_urlencoded :: [Parameter] -> B1.ByteString+show_urlencoded = _urlencode encodes 0x26++-- | Applies a function to the request+apply :: Request -> (Request -> Request) -> Request+apply r f = f r++-- | Convenience operator to append an item in request's parameters list+(>>+) :: Request -> (String,Maybe String) -> Request+(>>+) r = uncurry (append_param r)++-- | Applies a function to the request+(>>|) :: Request -> (Request -> Request) -> Request+(>>|) = apply++instance PercentEncoding Char where+ encode = B1.pack . concat . map enc' . B1.unpack . B2.fromString . (:[])+ where+ enc' b | elem b whitelist' = [b]+ | otherwise = let b0 = b .&. 0x0F+ b1 = B.shiftR (b .&. 0xF0) 4+ in ((37:) . map (fromIntegral . C.ord . C.toUpper . C.intToDigit . fromIntegral)) [b1,b0]+ whitelist' = [0x61..0x7a] ++ [0x41..0x5a] ++ [0x30..0x39] ++ [0x2d,0x2e,0x5f,0x7e]++ decode bytes = let c0 = (head . decodes) bytes+ b0 = encode c0+ in (c0, B1.drop (B1.length b0) bytes)+ + decodes = B2.toString . B1.pack . fold' . B1.unpack+ where+ fold' (37:b1:b0:bs) = let b1' = (fromIntegral . C.digitToInt . C.chr . fromIntegral) b1 + b0' = (fromIntegral . C.digitToInt . C.chr . fromIntegral) b0+ bl = (B.shiftL b1' 4) .&. 0xF0+ br = b0' .&. 0x0F+ in (bl .|. br) : fold' bs+ fold' (b:bs) = b : fold' bs+ fold' [] = []++_urlencode :: (String -> B1.ByteString) -> W.Word8 -> [Parameter] -> B1.ByteString+_urlencode ve s p | null p = B1.empty+ | otherwise = (B1.init . foldr fold' B1.empty . L.sort) p+ where + fold' (k,Nothing) = B1.append (B1.concat [encodes k, B1.singleton 0x3d, B1.singleton s])+ fold' (k,Just v) = B1.append (B1.concat [encodes k, B1.singleton 0x3d, ve v, B1.singleton s])++_path_comp :: String -> [String]+_path_comp p = (filter (not . null) . L.unfoldr unfold') p ++ trailing'+ where+ unfold' p1 = case (break (=='/') p1)+ of ([],[]) -> Nothing+ (l,r) -> Just (l,drop 1 r)+ + trailing' | last p=='/' = [[]]+ | otherwise = []
+ src/main/haskell/Network/Protocol/OAuth/Signature.hs view
@@ -0,0 +1,98 @@+-- Copyright (C) 2009 Diego Souza <dsouza at bitforest dot org>+-- +-- This program is free software: you can redistribute it and/or modify+-- it under the terms of the GNU Lesser General Public License as published by+-- the Free Software Foundation, either version 3 of the License, or+-- (at your option) any later version.+-- +-- This program is distributed in the hope that it will be useful,+-- but WITHOUT ANY WARRANTY; without even the implied warranty of+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+-- GNU Lesser General Public License for more details.+-- +-- You should have received a copy of the GNU Lesser General Public License+-- along with this program. If not, see <http://www.gnu.org/licenses/>.++-- | Implements PLAINTEXT and HMAC-SHA1 signatures of oauth spec <http://oauth.net/core/1.0a#signing_process>+module Network.Protocol.OAuth.Signature (Method(..),Signer,sign) where++import qualified Network.Protocol.OAuth.Request as R+import qualified Data.Digest.Pure.SHA as S+import qualified Data.Char as C+import qualified Data.ByteString.Lazy as B+import qualified Data.ByteString.Lazy.Char8 as B1+import qualified Codec.Binary.Base64.String as B2++-- | The signature method which will be used to sign requests.+data Method = + {-| The 'PLAINTEXT' method does not provide any security protection and+ SHOULD only be used over a secure channel such as /HTTPS/. It does+ not use the Signature Base String.+ -}+ PLAINTEXT + {-| The 'HMAC_SHA1' signature method uses the /HMAC-SHA1/ signature+ algorithm as defined in <http://tools.ietf.org/html/rfc2104> where+ the Signature Base String is the text and the key is the+ concatenated values (each first encoded per Parameter Encoding) of+ the Consumer Secret and Token Secret, separated by an /&/ character+ (ASCII code 38) even if empty.+ -}+ | HMAC_SHA1 + deriving (Eq)++-- | Functions to sign requests according oauth spec.+class Signer a where+ {-| For a given request, this function is able sign it using the method+ specified. The full description of this process is described in depth+ at <http://oauth.net/core/1.0a#signing_process>.+ -}+ sign :: a -- ^ The signature method to use+ -> String -- ^ The consumer secret+ -> Maybe String -- ^ The token secret+ -> R.Request + -> String -- ^ The signature++instance Signer Method where+ sign PLAINTEXT k (Just s) _ = k ++ "&" ++ s+ sign PLAINTEXT k Nothing _ = k ++ "&"++ sign HMAC_SHA1 k Nothing r = let secret = B.concat [R.encodes k, _froms "&"]+ in (B2.encode . B1.unpack . S.bytestringDigest . S.hmacSha1 secret . _basestr) r+ sign HMAC_SHA1 k (Just s) r = let secret = B.concat [R.encodes k, _froms "&", R.encodes s]+ in (B2.encode . B1.unpack . S.bytestringDigest . S.hmacSha1 secret . _basestr) r++instance Show Method where+ showsPrec _ PLAINTEXT = showString "PLAINTEXT"+ showsPrec _ HMAC_SHA1 = showString "HMAC-SHA1"++instance Read Method where+ readsPrec _ ('P':'L':'A':'I':'N':'T':'E':'X':'T':r) = (PLAINTEXT,r) : []+ readsPrec _ ('H':'M':'A':'C':'-':'S':'H':'A':'1':r) = (HMAC_SHA1,r) : []+ readsPrec _ _ = []++_basestr :: R.Request -> B.ByteString+_basestr r = let endpoint' = (R.encodes . _endpoint) r+ params' = (R.encodes . _params) r+ method' = (R.encodes . show . R.method) r+ in B.concat [method', _froms "&", endpoint', _froms "&", params']++_endpoint :: R.Request -> String+_endpoint r | R.ssl r = ssl_endpoint'+ | otherwise = endpoint'+ where+ host' = (map C.toLower . R.host) r++ port' = ((':':) . show . R.port) r++ ssl_endpoint' | R.port r == 443 = "https://" ++ host' ++ (R.path r)+ | otherwise = "https://" ++ host' ++ port' ++ (R.path r)++ endpoint' | R.port r == 80 = "http://" ++ host' ++ (R.path r)+ | otherwise = "http://" ++ host' ++ port' ++ (R.path r)++_params :: R.Request -> String+_params = map (C.chr . fromIntegral) . B.unpack . R.show_urlencoded . R.params++_froms :: String -> B.ByteString+_froms = B.pack . map (fromIntegral . C.ord)+
+ src/test/haskell/Tests.hs view
@@ -0,0 +1,25 @@+-- Copyright (C) 2009 Diego Souza <dsouza at bitforest dot org>+-- +-- This program is free software: you can redistribute it and/or modify+-- it under the terms of the GNU Lesser General Public License as published by+-- the Free Software Foundation, either version 3 of the License, or+-- (at your option) any later version.+-- +-- This program is distributed in the hope that it will be useful,+-- but WITHOUT ANY WARRANTY; without even the implied warranty of+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+-- GNU Lesser General Public License for more details.+-- +-- You should have received a copy of the GNU Lesser General Public License+-- along with this program. If not, see <http://www.gnu.org/licenses/>.++import qualified Test.HUnit as T+import qualified Test.Network.Protocol.OAuth.Request as R+import qualified Test.Network.Protocol.OAuth.Signature as S+import qualified Test.Network.Protocol.OAuth.Consumer as C++all_tests = let fast = [R.fast_tests, S.fast_tests, C.fast_tests]+ slow = [R.slow_tests, S.slow_tests, C.slow_tests]+ in T.runTestTT . T.TestList . concat $ (fast ++ slow)++main = all_tests