Pure nix flake; replace crypto-simple with Saltine; update README and TODO
This commit is contained in:
parent
b4bbf6e5a7
commit
9efdc01828
@ -47,13 +47,13 @@ library
|
|||||||
, blaze-html >=0.9.1.0
|
, blaze-html >=0.9.1.0
|
||||||
, bytestring >=0.10.12.1
|
, bytestring >=0.10.12.1
|
||||||
, containers >=0.6.4.1
|
, containers >=0.6.4.1
|
||||||
, crypto-simple >=0.1.0.0
|
|
||||||
, dhall >=1.40
|
, dhall >=1.40
|
||||||
, file-embed ==0.0.15.0
|
, file-embed ==0.0.15.0
|
||||||
, http-types >=0.12.3
|
, http-types >=0.12.3
|
||||||
, iso8601-time >=0.1.5
|
, iso8601-time >=0.1.5
|
||||||
, mtl >=2.2.2
|
, mtl >=2.2.2
|
||||||
, random >=1.2
|
, random >=1.2
|
||||||
|
, saltine >=0.2.0.0
|
||||||
, scotty >=0.12
|
, scotty >=0.12
|
||||||
, shakespeare >=2.0.20
|
, shakespeare >=2.0.20
|
||||||
, split >=0.2.3.4
|
, split >=0.2.3.4
|
||||||
@ -87,13 +87,13 @@ executable Purr-musl
|
|||||||
, blaze-html >=0.9.1.0
|
, blaze-html >=0.9.1.0
|
||||||
, bytestring >=0.10.12.1
|
, bytestring >=0.10.12.1
|
||||||
, containers >=0.6.4.1
|
, containers >=0.6.4.1
|
||||||
, crypto-simple >=0.1.0.0
|
|
||||||
, dhall >=1.40
|
, dhall >=1.40
|
||||||
, file-embed ==0.0.15.0
|
, file-embed ==0.0.15.0
|
||||||
, http-types >=0.12.3
|
, http-types >=0.12.3
|
||||||
, iso8601-time >=0.1.5
|
, iso8601-time >=0.1.5
|
||||||
, mtl >=2.2.2
|
, mtl >=2.2.2
|
||||||
, random >=1.2
|
, random >=1.2
|
||||||
|
, saltine >=0.2.0.0
|
||||||
, scotty >=0.12
|
, scotty >=0.12
|
||||||
, shakespeare >=2.0.20
|
, shakespeare >=2.0.20
|
||||||
, split >=0.2.3.4
|
, split >=0.2.3.4
|
6
README
6
README
@ -27,12 +27,10 @@ DEPLOYMENT
|
|||||||
Use Nix with flakes enabled.
|
Use Nix with flakes enabled.
|
||||||
|
|
||||||
Build binary and run natively:
|
Build binary and run natively:
|
||||||
nix build --impure && ./result/bin/Purr-musl
|
nix build && ./result/bin/Purr-musl
|
||||||
|
|
||||||
Build and add Docker image to local registry:
|
Build and add Docker image to local registry:
|
||||||
nix build .#purrImage --impure && docker load < result
|
nix build .#purrImage && docker load < result
|
||||||
|
|
||||||
I'll get rid of the "--impure" requirement ASAP.
|
|
||||||
|
|
||||||
DEVELOPMENT & SUPPORT
|
DEVELOPMENT & SUPPORT
|
||||||
|
|
||||||
|
3
TODO
3
TODO
@ -1,2 +1 @@
|
|||||||
- Replace crypto-simple dependency
|
- Make the Docker images much smaller
|
||||||
- Make the Docker images much smaller again
|
|
||||||
|
@ -20,8 +20,6 @@
|
|||||||
in {
|
in {
|
||||||
packages.${packageName} =
|
packages.${packageName} =
|
||||||
haskellPackages.callCabal2nix packageName self rec {
|
haskellPackages.callCabal2nix packageName self rec {
|
||||||
crypto-simple =
|
|
||||||
pkgs.haskell.lib.dontCheck haskellPackages.crypto-simple;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
packages.default = self.packages.${system}.${packageName};
|
packages.default = self.packages.${system}.${packageName};
|
||||||
|
12
package.yaml
12
package.yaml
@ -33,14 +33,14 @@ dependencies:
|
|||||||
- blaze-html >= 0.9.1.0
|
- blaze-html >= 0.9.1.0
|
||||||
- bytestring >= 0.10.12.1
|
- bytestring >= 0.10.12.1
|
||||||
- containers >= 0.6.4.1
|
- containers >= 0.6.4.1
|
||||||
- crypto-simple >= 0.1.0.0
|
- dhall >= 1.40
|
||||||
- dhall >= 1.40 && < 1.41.2
|
|
||||||
- file-embed == 0.0.15.0
|
- file-embed == 0.0.15.0
|
||||||
- http-types >= 0.12.3
|
- http-types >= 0.12.3
|
||||||
- iso8601-time >= 0.1.5
|
- iso8601-time >= 0.1.5
|
||||||
- mtl >= 2.2.2
|
- mtl >= 2.2.2
|
||||||
- random >= 1.2
|
- random >= 1.2
|
||||||
- scotty == 0.12
|
- saltine >= 0.2.0.0
|
||||||
|
- scotty >= 0.12
|
||||||
- shakespeare >= 2.0.20
|
- shakespeare >= 2.0.20
|
||||||
- sqlite-simple >= 0.4.18.0
|
- sqlite-simple >= 0.4.18.0
|
||||||
- split >= 0.2.3.4
|
- split >= 0.2.3.4
|
||||||
@ -61,9 +61,9 @@ executables:
|
|||||||
- -threaded
|
- -threaded
|
||||||
- -rtsopts
|
- -rtsopts
|
||||||
- -with-rtsopts=-N
|
- -with-rtsopts=-N
|
||||||
- -static
|
#- -static
|
||||||
- -optl-static
|
#- -optl-static
|
||||||
- -optl-pthread
|
#- -optl-pthread
|
||||||
- -fPIC
|
- -fPIC
|
||||||
dependencies:
|
dependencies:
|
||||||
- Purr
|
- Purr
|
||||||
|
@ -4,18 +4,19 @@ import Core.SQLite
|
|||||||
import Core.Types
|
import Core.Types
|
||||||
import Feature.Generation.Passwords (Password)
|
import Feature.Generation.Passwords (Password)
|
||||||
|
|
||||||
import Control.Monad.Reader (ask, lift, liftIO)
|
import Control.Monad.Reader (ask, lift, liftIO)
|
||||||
import Crypto.Simple.CBC (decrypt, encrypt)
|
import Data.List.Split (splitOn)
|
||||||
import Data.List.Split (splitOn)
|
import Data.Maybe (listToMaybe, fromMaybe)
|
||||||
import Data.Maybe (listToMaybe)
|
import Data.Time.Clock.POSIX (getPOSIXTime)
|
||||||
import Data.Time.Clock.POSIX (getPOSIXTime)
|
|
||||||
import Database.SQLite.Simple
|
import Database.SQLite.Simple
|
||||||
|
|
||||||
import qualified Data.ByteString.Base64 as B64
|
import qualified Crypto.Saltine.Core.SecretBox as Box
|
||||||
import qualified Data.ByteString.Char8 as B
|
import qualified Crypto.Saltine.Internal.SecretBox as IBox
|
||||||
import qualified Data.Text as T
|
import qualified Data.ByteString.Base64 as B64
|
||||||
import qualified Data.Text.Encoding as ET
|
import qualified Data.ByteString.Char8 as B
|
||||||
import qualified Data.Text.Lazy as LT
|
import qualified Data.Text as T
|
||||||
|
import qualified Data.Text.Encoding as ET
|
||||||
|
import qualified Data.Text.Lazy as LT
|
||||||
|
|
||||||
findByLink :: String -> PurrAction (Maybe T.Text)
|
findByLink :: String -> PurrAction (Maybe T.Text)
|
||||||
findByLink link = do
|
findByLink link = do
|
||||||
@ -30,7 +31,8 @@ insertNewSecret :: T.Text -> Integer -> T.Text -> Integer -> PurrAction ()
|
|||||||
insertNewSecret sec life link maxViews = do
|
insertNewSecret sec life link maxViews = do
|
||||||
db <- dbPath
|
db <- dbPath
|
||||||
key <- encKey
|
key <- encKey
|
||||||
encSec <- liftIO $ encryptSecret key sec
|
nonce <- liftIO $ Box.newNonce
|
||||||
|
let encSec = encryptSecret key sec nonce
|
||||||
conn <- liftIO $ open db
|
conn <- liftIO $ open db
|
||||||
time <- liftIO $ epochTime
|
time <- liftIO $ epochTime
|
||||||
liftIO $ execute conn
|
liftIO $ execute conn
|
||||||
@ -41,12 +43,10 @@ insertNewSecret sec life link maxViews = do
|
|||||||
readEncryptedSecret :: String -> [SecretEntry] -> PurrAction (Maybe T.Text)
|
readEncryptedSecret :: String -> [SecretEntry] -> PurrAction (Maybe T.Text)
|
||||||
readEncryptedSecret key sec = do
|
readEncryptedSecret key sec = do
|
||||||
db <- dbPath
|
db <- dbPath
|
||||||
|
nonce <- liftIO $ Box.newNonce
|
||||||
liftIO $ incViews sec db
|
liftIO $ incViews sec db
|
||||||
delete <- liftIO $ deleteExpiredSecret sec db
|
delete <- liftIO $ deleteExpiredSecret sec db
|
||||||
decKey <- liftIO ( sequence
|
let decKey = decryptSecret key nonce $ decodeSecret $ safeHead failedSecret sec
|
||||||
$ decryptSecret key
|
|
||||||
<$> decodeSecret
|
|
||||||
<$> listToMaybe sec )
|
|
||||||
if (delete)
|
if (delete)
|
||||||
then return Nothing
|
then return Nothing
|
||||||
else return (ET.decodeLatin1 <$> decKey)
|
else return (ET.decodeLatin1 <$> decKey)
|
||||||
@ -83,11 +83,19 @@ encodeSecret b = ET.decodeUtf8 $ B64.encode b
|
|||||||
decodeSecret :: SecretEntry -> B.ByteString
|
decodeSecret :: SecretEntry -> B.ByteString
|
||||||
decodeSecret s = B64.decodeLenient $ ET.encodeUtf8 (secret s)
|
decodeSecret s = B64.decodeLenient $ ET.encodeUtf8 (secret s)
|
||||||
|
|
||||||
encryptSecret :: String -> T.Text -> IO B.ByteString
|
encryptSecret :: String -> T.Text -> Box.Nonce -> B.ByteString
|
||||||
encryptSecret k s = encrypt (B.pack k) (ET.encodeUtf8 s)
|
encryptSecret k s n = do
|
||||||
|
Box.secretbox (IBox.Key $ B.pack k) n (ET.encodeUtf8 s)
|
||||||
|
|
||||||
decryptSecret :: String -> B.ByteString -> IO B.ByteString
|
decryptSecret :: String -> Box.Nonce -> B.ByteString -> Maybe B.ByteString
|
||||||
decryptSecret k b = decrypt (B.pack k) b
|
decryptSecret k n b = Box.secretboxOpen (IBox.Key $ B.pack k) n b
|
||||||
|
|
||||||
epochTime :: IO Integer
|
epochTime :: IO Integer
|
||||||
epochTime = fmap round getPOSIXTime
|
epochTime = fmap round getPOSIXTime
|
||||||
|
|
||||||
|
failedSecret :: SecretEntry
|
||||||
|
failedSecret = SecretEntry "fail" "fail" 0 0 0 0
|
||||||
|
|
||||||
|
safeHead :: a -> [a] -> a
|
||||||
|
safeHead x [] = x
|
||||||
|
safeHead x l = head l
|
||||||
|
@ -6,12 +6,14 @@ import qualified Core.SQLite as DB
|
|||||||
import Core.Types
|
import Core.Types
|
||||||
|
|
||||||
import Control.Monad.Reader (lift, liftIO, runReaderT)
|
import Control.Monad.Reader (lift, liftIO, runReaderT)
|
||||||
|
import Crypto.Saltine (sodiumInit)
|
||||||
import GHC.Natural (popCountNatural)
|
import GHC.Natural (popCountNatural)
|
||||||
import Prelude hiding (id)
|
import Prelude hiding (id)
|
||||||
import Web.Scotty.Trans (scottyT)
|
import Web.Scotty.Trans (scottyT)
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = do
|
main = do
|
||||||
|
sodiumInit
|
||||||
dhallConf <- liftIO Configuration.main
|
dhallConf <- liftIO Configuration.main
|
||||||
DB.main (dbFile dhallConf)
|
DB.main (dbFile dhallConf)
|
||||||
scottyT (applicationPort dhallConf) (flip runApp dhallConf) HTTP.app where
|
scottyT (applicationPort dhallConf) (flip runApp dhallConf) HTTP.app where
|
||||||
|
Loading…
x
Reference in New Issue
Block a user