From 910859bce6bdb37e9724c61211f5d510a43bed2b Mon Sep 17 00:00:00 2001 From: James Eversole Date: Fri, 5 Aug 2022 15:42:37 -0500 Subject: [PATCH] Track the number of views for secrets, delete secrets on next lookup attempt when the lifespan or max viewcount is exceeded. --- src/Feature/Sharing/SQLite.hs | 40 ++++++++++++++++++++++++++++++++--- views/gen.hamlet | 24 +++++++++++++++++++++ 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/src/Feature/Sharing/SQLite.hs b/src/Feature/Sharing/SQLite.hs index fc7afb5..4e0ea08 100644 --- a/src/Feature/Sharing/SQLite.hs +++ b/src/Feature/Sharing/SQLite.hs @@ -39,10 +39,44 @@ insertNewSecret sec life link maxViews = do readEncryptedSecret :: String -> [SecretEntry] -> PurrAction (Maybe T.Text) readEncryptedSecret key sec = do - decKey <- liftIO - (sequence $ decryptSecret key <$> decodeSecret <$> listToMaybe sec) - return (ET.decodeLatin1 <$> decKey) + db <- dbPath + liftIO $ incViews sec db + delete <- liftIO $ deleteExpiredSecret sec db + decKey <- liftIO ( sequence + $ decryptSecret key + <$> decodeSecret + <$> listToMaybe sec ) + if (delete) + then return Nothing + else return (ET.decodeLatin1 <$> decKey) + where + incViews :: [SecretEntry] -> String -> IO () + incViews [] _ = return () + incViews (sec : _) db = do + conn <- liftIO $ open db + liftIO $ execute conn + "UPDATE pws SET views = views + 1 WHERE link = ?" (Only (link sec)) + liftIO $ close conn +-- Returns True if deletion occurs, informing the caller to not provide +-- the successfully retrieved secret to the requestor. +deleteExpiredSecret :: [SecretEntry] -> String -> IO Bool +deleteExpiredSecret [] _ = return False +deleteExpiredSecret (sec : _) db = do + time <- liftIO $ epochTime + if ((date sec) + ((life sec) * 86400) < time) || + (views sec >= maxViews sec) + then deleteSec sec db + else return False + where + deleteSec :: SecretEntry -> String -> IO Bool + deleteSec sec db = do + conn <- liftIO $ open db + liftIO $ execute conn + "DELETE FROM pws WHERE link = ?" (Only (link sec)) + liftIO $ close conn + return True + encodeSecret :: B.ByteString -> T.Text encodeSecret b = ET.decodeUtf8 $ B64.encode b diff --git a/views/gen.hamlet b/views/gen.hamlet index ad06b58..aba30ae 100644 --- a/views/gen.hamlet +++ b/views/gen.hamlet @@ -9,11 +9,35 @@ /> Generate New Password
+