s3-signer 0.1.0.0 → 0.2.0.0
raw patch · 5 files changed
+30/−15 lines, 5 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Network.S3.Types: S3GET :: S3Method
- Network.S3.Types: S3Keys :: ByteString -> ByteString -> S3Keys
- Network.S3.Types: S3PUT :: S3Method
- Network.S3.Types: S3Request :: S3Method -> ByteString -> ByteString -> Integer -> S3Request
- Network.S3.Types: S3URL :: ByteString -> S3URL
- Network.S3.Types: bucketName :: S3Request -> ByteString
- Network.S3.Types: data S3Keys
- Network.S3.Types: data S3Method
- Network.S3.Types: data S3Request
- Network.S3.Types: instance Constructor C1_0S3Keys
- Network.S3.Types: instance Constructor C1_0S3Method
- Network.S3.Types: instance Constructor C1_0S3Request
- Network.S3.Types: instance Constructor C1_0S3URL
- Network.S3.Types: instance Constructor C1_1S3Method
- Network.S3.Types: instance Datatype D1S3Keys
- Network.S3.Types: instance Datatype D1S3Method
- Network.S3.Types: instance Datatype D1S3Request
- Network.S3.Types: instance Datatype D1S3URL
- Network.S3.Types: instance Generic S3Keys
- Network.S3.Types: instance Generic S3Method
- Network.S3.Types: instance Generic S3Request
- Network.S3.Types: instance Generic S3URL
- Network.S3.Types: instance Selector S1_0_0S3Keys
- Network.S3.Types: instance Selector S1_0_0S3Request
- Network.S3.Types: instance Selector S1_0_0S3URL
- Network.S3.Types: instance Selector S1_0_1S3Keys
- Network.S3.Types: instance Selector S1_0_1S3Request
- Network.S3.Types: instance Selector S1_0_2S3Request
- Network.S3.Types: instance Selector S1_0_3S3Request
- Network.S3.Types: instance Show S3Keys
- Network.S3.Types: instance Show S3Method
- Network.S3.Types: instance Show S3Request
- Network.S3.Types: instance Show S3URL
- Network.S3.Types: newtype S3URL
- Network.S3.Types: objectName :: S3Request -> ByteString
- Network.S3.Types: publicKey :: S3Keys -> ByteString
- Network.S3.Types: s3method :: S3Request -> S3Method
- Network.S3.Types: secondsToExpire :: S3Request -> Integer
- Network.S3.Types: secretKey :: S3Keys -> ByteString
- Network.S3.Types: signedRequest :: S3URL -> ByteString
+ Network.S3: S3GET :: S3Method
+ Network.S3: S3Keys :: ByteString -> ByteString -> S3Keys
+ Network.S3: S3PUT :: S3Method
+ Network.S3: S3Request :: S3Method -> ByteString -> ByteString -> ByteString -> Integer -> S3Request
+ Network.S3: S3URL :: ByteString -> S3URL
+ Network.S3: bucketName :: S3Request -> ByteString
+ Network.S3: data S3Keys
+ Network.S3: data S3Method
+ Network.S3: data S3Request
+ Network.S3: mimeType :: S3Request -> ByteString
+ Network.S3: newtype S3URL
+ Network.S3: objectName :: S3Request -> ByteString
+ Network.S3: publicKey :: S3Keys -> ByteString
+ Network.S3: s3method :: S3Request -> S3Method
+ Network.S3: secondsToExpire :: S3Request -> Integer
+ Network.S3: secretKey :: S3Keys -> ByteString
+ Network.S3: signedRequest :: S3URL -> ByteString
Files
- README.md +20/−8
- s3-signer.cabal +3/−3
- src/Network/S3.hs +1/−1
- src/Network/S3/Types.hs +1/−0
- src/Network/S3/URL.hs +5/−3
README.md view
@@ -9,7 +9,8 @@ ### Features - Minimal depedencies - Web framework agnostic- - Reduced web server load+ - Reduces web server load+ - Simple API - Ideal for AJAX direct-to-s3 upload scenarios ### Documentation@@ -50,7 +51,7 @@ main = print =<< generateS3URL credentials request where credentials = S3Keys "<public-key-goes-here>" "<secret-key-goes-here>"- request = S3Request S3GET "bucket-name" "file-name.extension" 3 -- 3 secs until expired+ request = S3Request S3GET "application/zip" "bucket-name" "file-name.extension" 3 -- 3 secs until expired ``` ### Result ```haskell@@ -69,7 +70,7 @@ makeS3URL fileId = generateS3URL credentials request where credentials = S3Keys "<public-key-goes-here>" "<secret-key-goes-here>"- request = S3Request S3GET "bucket-name" (fileId <> ".zip") 3 + request = S3Request S3GET "application/zip" "bucket-name" (fileId <> ".zip") 3 downloadFile :: Handler App (AuthManager App) () downloadFile = method POST $ currentUserId >>= maybe the404 handleDownload@@ -102,15 +103,13 @@ makeS3URL fileId = generateS3URL credentials request where credentials = S3Keys "<public-key-goes-here>" "<secret-key-goes-here>"- request = S3Request S3PUT "bucket-name" (fileId <> ".zip") 3 --instance ToJSON S3URL+ request = S3Request S3PUT "application/zip" "bucket-name" (fileId <> ".zip") 3 getUploadURL :: Handler App (AuthManager App) () getUploadURL = method POST $ currentUserId >>= maybe the404 handleDownload where handleDownload _ = do Just fileId <- getParam "fileId"- writeJSON =<< liftIO (makeS3URL fileId)+ writeJSON =<< Data.Text.Encoding.decodeUtf8 <$> liftIO (makeS3URL fileId) ``` - Embed FileReader blob data to request - Send upload request@@ -159,7 +158,20 @@ ### FAQ - Why didn't you use HMAC-SHA256?- * It's 30% slower, and no less secure than HMAC-SHA1+ * It's 30% slower, and for all intents and purposes no more secure+ than HMAC-SHA1 (no known vulnerabilities exist for it, to my knowledge). Plain+ SHA1 is a different story. Collisions can be found, but there is+ no known way to apply those to HMAC-SHA1.+ * For the curious [SHA-1 is broken](https://www.schneier.com/blog/archives/2005/02/sha1_broken.html)+ * For the paranoid (Schneier quote from same article above)+ * [Relevant SO Post](http://stackoverflow.com/questions/3334524/hmac-security-is-the-security-of-the-hmac-based-on-sha-1-affected-by-the-colli)++> This attack builds on previous attacks on SHA-0 and SHA-1, and is+> a major, major cryptanalytic result. It pretty much puts a bullet+> into SHA-1 as a hash function for digital signatures (although it+> **doesn't** **affect** applications such as **HMAC** where collisions aren't important).++
s3-signer.cabal view
@@ -1,5 +1,5 @@ name: s3-signer-version: 0.1.0.0+version: 0.2.0.0 homepage: https://github.com/dmjio/s3-signer bug-reports: https://github.com/dmjio/s3-signer/issues synopsis: Pre-signed Amazon S3 URLs@@ -15,7 +15,7 @@ > main :: IO () > main = print =<< generateS3URL credentials request > where- > credentials = S3Creds "<public-key-goes-here>" "<secret-key-goes-here>"+ > credentials = S3Keys "<public-key-goes-here>" "<secret-key-goes-here>" > request = S3Request S3GET "bucket-name" "file-name.extension" 3 -- three seconds until expiration . Result@@ -27,7 +27,7 @@ author: David Johnson <djohnson.m@gmail.com> maintainer: David Johnson <djohnson.m@gmail.com> copyright: 2014 David Johnson-category: Network+category: AWS, Network build-type: Simple cabal-version: >=1.18 extra-source-files: README.md
src/Network/S3.hs view
@@ -24,7 +24,7 @@ time <- getExpirationTimeStamp secondsToExpire let url = case s3method of S3GET -> getURL bucketName objectName time- S3PUT -> putURL bucketName objectName time+ S3PUT -> putURL bucketName objectName time mimeType req = s3URL bucketName objectName publicKey time (sign secretKey url) return (S3URL req)
src/Network/S3/Types.hs view
@@ -25,6 +25,7 @@ data S3Request = S3Request { s3method :: S3Method -- ^ Type of HTTP Method+ , mimeType :: ByteString -- ^ MIME Type , bucketName :: ByteString -- ^ Name of Amazon S3 Bucket , objectName :: ByteString -- ^ Name of Amazon S3 File , secondsToExpire :: Integer -- ^ Number of seconds until expiration
src/Network/S3/URL.hs view
@@ -10,9 +10,11 @@ import Data.String -- | S3 Upload URL Template-putURL :: (Monoid m, IsString m) => m -> m -> m -> m-putURL bucket object expires =- mconcat [ "PUT\n\napplication/zip\n"+putURL :: (Monoid m, IsString m) => m -> m -> m -> m -> m+putURL bucket object expires mimetype =+ mconcat [ "PUT\n\n"+ , mimetype + ,"\n" , expires , "\nx-amz-acl:public-read\n/" , bucket