packages feed

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 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