2016-11-30 14:35:24 -04:00
{- git - annex command
-
- Copyright 2016 Joey Hess < id @ joeyh . name >
-
- Licensed under the GNU GPL version 3 or higher .
- }
module Command.P2P where
import Command
import P2P.Address
import P2P.Auth
2016-12-07 12:38:21 -04:00
import P2P.IO
import qualified P2P.Protocol as P2P
2016-11-30 14:35:24 -04:00
import Utility.AuthToken
2016-11-30 15:14:54 -04:00
import Git.Types
import qualified Git.Remote
import qualified Git.Command
2016-12-07 12:38:21 -04:00
import qualified Annex
import Annex.UUID
import Config
2016-11-30 14:35:24 -04:00
cmd :: Command
cmd = command " p2p " SectionSetup
" configure peer-2-peer links between repositories "
paramNothing ( seek <$$> optParser )
data P2POpts
= GenAddresses
2016-11-30 15:14:54 -04:00
| LinkRemote RemoteName
2016-11-30 14:35:24 -04:00
optParser :: CmdParamsDesc -> Parser P2POpts
optParser _ = genaddresses <|> linkremote
where
genaddresses = flag' GenAddresses
( long " gen-addresses "
<> help " generate addresses that allow accessing this repository over P2P networks "
)
2016-11-30 15:14:54 -04:00
linkremote = LinkRemote <$> strOption
( long " link "
<> metavar paramRemote
<> help " specify name to use for git remote "
)
2016-11-30 14:35:24 -04:00
seek :: P2POpts -> CommandSeek
2016-11-30 15:14:54 -04:00
seek GenAddresses = genAddresses =<< loadP2PAddresses
seek ( LinkRemote name ) = commandAction $
linkRemote ( Git . Remote . makeLegalName name )
-- Only addresses are output to stdout, to allow scripting.
genAddresses :: [ P2PAddress ] -> Annex ()
genAddresses [] = giveup " No P2P networks are currrently available. "
genAddresses addrs = do
authtoken <- liftIO $ genAuthToken 128
storeP2PAuthToken authtoken
earlyWarning " These addresses allow access to this git-annex repository. Only share them with people you trust with that access, using trusted communication channels! "
liftIO $ putStr $ unlines $
map formatP2PAddress $
map ( ` P2PAddressAuth ` authtoken ) addrs
-- Address is read from stdin, to avoid leaking it in shell history.
linkRemote :: RemoteName -> CommandStart
linkRemote remotename = do
showStart " p2p link " remotename
next $ next prompt
where
prompt = do
liftIO $ putStrLn " "
2016-12-07 12:38:21 -04:00
liftIO $ putStr " Enter peer address: "
2016-11-30 15:14:54 -04:00
liftIO $ hFlush stdout
s <- liftIO getLine
if null s
then do
liftIO $ hPutStrLn stderr " Nothing entered, giving up. "
return False
else case unformatP2PAddress s of
Nothing -> do
liftIO $ hPutStrLn stderr " Unable to parse that address, please check its format and try again. "
prompt
Just addr -> setup addr
setup ( P2PAddressAuth addr authtoken ) = do
2016-12-07 12:38:21 -04:00
g <- Annex . gitRepo
conn <- liftIO $ connectPeer g addr
2016-12-08 14:14:08 -04:00
` catchNonAsync ` connerror
2016-12-07 12:38:21 -04:00
u <- getUUID
v <- liftIO $ runNetProto conn $ P2P . auth u authtoken
case v of
2016-12-08 15:47:49 -04:00
Right ( Just theiruuid ) -> do
2016-12-07 12:38:21 -04:00
ok <- inRepo $ Git . Command . runBool
[ Param " remote " , Param " add "
, Param remotename
, Param ( formatP2PAddress addr )
]
when ok $ do
storeUUIDIn ( remoteConfig remotename " uuid " ) theiruuid
storeP2PRemoteAuthToken addr authtoken
return ok
2016-12-08 15:47:49 -04:00
Right Nothing -> giveup " Unable to authenticate with peer. Please check the address and try again. "
Left e -> giveup $ " Unable to authenticate with peer: " ++ e
2016-12-08 14:14:08 -04:00
connerror e = giveup $ " Unable to connect with peer. Please check that the peer is connected to the network, and try again. ( " ++ show e ++ " ) "