refactor
This commit is contained in:
parent
98e3817466
commit
991efddfa1
2 changed files with 86 additions and 65 deletions
|
@ -42,17 +42,20 @@ gen :: Git.Repo -> UUID -> Maybe RemoteConfig -> Annex (Remote Annex)
|
||||||
gen r u c = do
|
gen r u c = do
|
||||||
dir <- getConfig r "directory" (error "missing directory")
|
dir <- getConfig r "directory" (error "missing directory")
|
||||||
cst <- remoteCost r cheapRemoteCost
|
cst <- remoteCost r cheapRemoteCost
|
||||||
return $ Remote {
|
return $ encryptedRemote c
|
||||||
uuid = u,
|
(storeEncrypted dir)
|
||||||
cost = cst,
|
(retrieveEncrypted dir)
|
||||||
name = Git.repoDescribe r,
|
Remote {
|
||||||
storeKey = storeKeyEncrypted c $ store dir,
|
uuid = u,
|
||||||
retrieveKeyFile = retrieveKeyFileEncrypted c $ retrieve dir,
|
cost = cst,
|
||||||
removeKey = removeKeyEncrypted c $ remove dir,
|
name = Git.repoDescribe r,
|
||||||
hasKey = hasKeyEncrypted c $ checkPresent dir,
|
storeKey = store dir,
|
||||||
hasKeyCheap = True,
|
retrieveKeyFile = retrieve dir,
|
||||||
config = Nothing
|
removeKey = remove dir,
|
||||||
}
|
hasKey = checkPresent dir,
|
||||||
|
hasKeyCheap = True,
|
||||||
|
config = Nothing
|
||||||
|
}
|
||||||
|
|
||||||
directorySetup :: UUID -> RemoteConfig -> Annex RemoteConfig
|
directorySetup :: UUID -> RemoteConfig -> Annex RemoteConfig
|
||||||
directorySetup u c = do
|
directorySetup u c = do
|
||||||
|
@ -74,43 +77,47 @@ dirKey d k = d </> hashDirMixed k </> f </> f
|
||||||
where
|
where
|
||||||
f = keyFile k
|
f = keyFile k
|
||||||
|
|
||||||
store :: FilePath -> Key -> Maybe (Cipher, Key) -> Annex Bool
|
store :: FilePath -> Key -> Annex Bool
|
||||||
store d k c = do
|
store d k = do
|
||||||
g <- Annex.gitRepo
|
g <- Annex.gitRepo
|
||||||
let src = gitAnnexLocation g k
|
let src = gitAnnexLocation g k
|
||||||
liftIO $ catch (copy src) (const $ return False)
|
let dest = dirKey d k
|
||||||
where
|
liftIO $ catch (storeHelper dest $ copyFile src dest) (const $ return False)
|
||||||
copy src = case c of
|
|
||||||
Just (cipher, enckey) -> do
|
|
||||||
content <- L.readFile src
|
|
||||||
let dest = dirKey d enckey
|
|
||||||
prep dest
|
|
||||||
withEncryptedContent cipher content $ \s -> do
|
|
||||||
L.writeFile dest s
|
|
||||||
cleanup True dest
|
|
||||||
_ -> do
|
|
||||||
let dest = dirKey d k
|
|
||||||
prep dest
|
|
||||||
ok <- copyFile src dest
|
|
||||||
cleanup ok dest
|
|
||||||
prep dest = liftIO $ do
|
|
||||||
let dir = parentDir dest
|
|
||||||
createDirectoryIfMissing True dir
|
|
||||||
allowWrite dir
|
|
||||||
cleanup ok dest = do
|
|
||||||
when ok $ do
|
|
||||||
let dir = parentDir dest
|
|
||||||
preventWrite dest
|
|
||||||
preventWrite dir
|
|
||||||
return ok
|
|
||||||
|
|
||||||
retrieve :: FilePath -> Key -> FilePath -> Maybe (Cipher, Key) -> Annex Bool
|
storeEncrypted :: FilePath -> (Cipher, Key) -> Key -> Annex Bool
|
||||||
retrieve d k f Nothing = liftIO $ copyFile (dirKey d k) f
|
storeEncrypted d (cipher, enck) k = do
|
||||||
retrieve d k f (Just (cipher, enckey)) =
|
g <- Annex.gitRepo
|
||||||
liftIO $ flip catch (const $ return False) $ do
|
let src = gitAnnexLocation g k
|
||||||
content <- L.readFile (dirKey d enckey)
|
let dest = dirKey d enck
|
||||||
withDecryptedContent cipher content $ L.writeFile f
|
liftIO $ catch (storeHelper dest $ encrypt src dest) (const $ return False)
|
||||||
return True
|
where
|
||||||
|
encrypt src dest = do
|
||||||
|
content <- L.readFile src
|
||||||
|
withEncryptedContent cipher content $ L.writeFile dest
|
||||||
|
return True
|
||||||
|
|
||||||
|
storeHelper :: FilePath -> IO Bool -> IO Bool
|
||||||
|
storeHelper dest a = do
|
||||||
|
let dir = parentDir dest
|
||||||
|
createDirectoryIfMissing True dir
|
||||||
|
allowWrite dir
|
||||||
|
ok <- a
|
||||||
|
when ok $ do
|
||||||
|
preventWrite dest
|
||||||
|
preventWrite dir
|
||||||
|
return ok
|
||||||
|
|
||||||
|
retrieve :: FilePath -> Key -> FilePath -> Annex Bool
|
||||||
|
retrieve d k f = liftIO $ copyFile (dirKey d k) f
|
||||||
|
|
||||||
|
retrieveEncrypted :: FilePath -> (Cipher, Key) -> FilePath -> Annex Bool
|
||||||
|
retrieveEncrypted d (cipher, enck) f =
|
||||||
|
liftIO $ catch decrypt (const $ return False)
|
||||||
|
where
|
||||||
|
decrypt = do
|
||||||
|
content <- L.readFile (dirKey d enck)
|
||||||
|
withDecryptedContent cipher content $ L.writeFile f
|
||||||
|
return True
|
||||||
|
|
||||||
remove :: FilePath -> Key -> Annex Bool
|
remove :: FilePath -> Key -> Annex Bool
|
||||||
remove d k = liftIO $ catch del (const $ return False)
|
remove d k = liftIO $ catch del (const $ return False)
|
||||||
|
|
|
@ -33,16 +33,39 @@ encryptionSetup c =
|
||||||
cipher <- liftIO a
|
cipher <- liftIO a
|
||||||
return $ M.delete "encryption" $ storeCipher c cipher
|
return $ M.delete "encryption" $ storeCipher c cipher
|
||||||
|
|
||||||
{- Helpers that can be applied to a Remote's normal actions to
|
{- Modifies a Remote to support encryption.
|
||||||
- add crypto support. -}
|
-
|
||||||
storeKeyEncrypted :: Maybe RemoteConfig -> (Key -> Maybe (Cipher, Key) -> Annex a) -> Key -> Annex a
|
- Two additional functions must be provided by the remote,
|
||||||
storeKeyEncrypted c a k = a k =<< cipherKey c k
|
- to support storing and retrieving encrypted content. -}
|
||||||
retrieveKeyFileEncrypted :: Maybe RemoteConfig -> (Key -> FilePath -> Maybe (Cipher, Key) -> Annex a) -> Key -> FilePath -> Annex a
|
encryptedRemote
|
||||||
retrieveKeyFileEncrypted c a k f = a k f =<< cipherKey c k
|
:: Maybe RemoteConfig
|
||||||
removeKeyEncrypted :: Maybe RemoteConfig -> (Key -> Annex a) -> Key -> Annex a
|
-> ((Cipher, Key) -> Key -> Annex Bool)
|
||||||
removeKeyEncrypted = withEncryptedKey
|
-> ((Cipher, Key) -> FilePath -> Annex Bool)
|
||||||
hasKeyEncrypted :: Maybe RemoteConfig -> (Key -> Annex a) -> Key -> Annex a
|
-> Remote Annex
|
||||||
hasKeyEncrypted = withEncryptedKey
|
-> Remote Annex
|
||||||
|
encryptedRemote c storeKeyEncrypted retrieveKeyFileEncrypted r =
|
||||||
|
r {
|
||||||
|
storeKey = store,
|
||||||
|
retrieveKeyFile = retrieve,
|
||||||
|
removeKey = withkey $ removeKey r,
|
||||||
|
hasKey = withkey $ hasKey r
|
||||||
|
}
|
||||||
|
where
|
||||||
|
store k = do
|
||||||
|
v <- cipherKey c k
|
||||||
|
case v of
|
||||||
|
Nothing -> (storeKey r) k
|
||||||
|
Just x -> storeKeyEncrypted x k
|
||||||
|
retrieve k f = do
|
||||||
|
v <- cipherKey c k
|
||||||
|
case v of
|
||||||
|
Nothing -> (retrieveKeyFile r) k f
|
||||||
|
Just x -> retrieveKeyFileEncrypted x f
|
||||||
|
withkey a k = do
|
||||||
|
v <- cipherKey c k
|
||||||
|
case v of
|
||||||
|
Nothing -> a k
|
||||||
|
Just (_, k') -> a k'
|
||||||
|
|
||||||
{- Gets encryption Cipher, and encrypted version of Key.
|
{- Gets encryption Cipher, and encrypted version of Key.
|
||||||
-
|
-
|
||||||
|
@ -64,12 +87,3 @@ cipherKey (Just c) k = do
|
||||||
ret cipher = do
|
ret cipher = do
|
||||||
k' <- liftIO $ encryptKey cipher k
|
k' <- liftIO $ encryptKey cipher k
|
||||||
return $ Just (cipher, k')
|
return $ Just (cipher, k')
|
||||||
|
|
||||||
{- Passes the encrypted version of the key to the action when encryption
|
|
||||||
- is enabled, and the non-encrypted version otherwise. -}
|
|
||||||
withEncryptedKey :: Maybe RemoteConfig -> (Key -> Annex a) -> Key -> Annex a
|
|
||||||
withEncryptedKey c a k = do
|
|
||||||
v <- cipherKey c k
|
|
||||||
case v of
|
|
||||||
Nothing -> a k
|
|
||||||
Just (_, k') -> a k'
|
|
||||||
|
|
Loading…
Reference in a new issue