summaryrefslogtreecommitdiffhomepage
path: root/Role
diff options
context:
space:
mode:
authorJoey Hess <joeyh@joeyh.name>2017-04-21 22:23:00 -0400
committerJoey Hess <joeyh@joeyh.name>2017-04-21 22:24:51 -0400
commit75c8b6b9745ea8e64383e28d3f18b1609be00fa3 (patch)
tree3cdbe871bf78eddb38307def309e5a982234fdc1 /Role
parent51702e72de15637653f8cc153ffeb43cdb194827 (diff)
downloaddebug-me-75c8b6b9745ea8e64383e28d3f18b1609be00fa3.tar.gz
add --download mode
Nice, was able to reuse all the protocol stuff from Role.Developer for this. This commit was sponsored by Fernando Jimenez on Patreon.
Diffstat (limited to 'Role')
-rw-r--r--Role/Developer.hs65
-rw-r--r--Role/Downloader.hs31
2 files changed, 65 insertions, 31 deletions
diff --git a/Role/Developer.hs b/Role/Developer.hs
index 4ff0cda..90f7606 100644
--- a/Role/Developer.hs
+++ b/Role/Developer.hs
@@ -23,36 +23,7 @@ run os = runClientApp $ clientApp (ConnectMode (T.pack (debugUrl os))) developer
developer :: TChan (Message Entered) -> TChan (Message Seen) -> SessionID -> IO ()
developer ichan ochan _ = inRawMode $ withLogger "debug-me-developer.log" $ \logger -> do
- -- Start by reading the initial two messages from the user side,
- -- their session key and the startup message.
- sessionmsg <- atomically $ readTChan ochan
- logger $ User sessionmsg
- sigverifier <- case sessionmsg of
- ControlMessage c@(Control (SessionKey pk) _) ->
- let sv = mkSigVerifier pk
- in if verifySigned sv c
- then return sv
- else error "Badly signed session initialization message"
- _ -> error $ "Unexpected session initialization message: " ++ show sessionmsg
- startmsg <- atomically $ readTChan ochan
- logger $ User startmsg
- starthash <- case startmsg of
- ActivityMessage act@(Activity (Seen (Val b)) Nothing _)
- | verifySigned sigverifier act -> do
- B.hPut stdout b
- hFlush stdout
- return (hash act)
- _ -> error $ "Unexpected startup message: " ++ show startmsg
-
- sk <- genMySessionKey
- devstate <- newTVarIO $ DeveloperState
- { lastSeen = starthash
- , sentSince = mempty
- , enteredSince = mempty
- , lastActivity = starthash
- , developerSessionKey = sk
- , developerSigVerifier = sigverifier
- }
+ devstate <- processSessionStart ochan logger
ok <- authUser ichan ochan devstate logger
if ok
then do
@@ -150,7 +121,7 @@ data Output
emitOutput :: Output -> IO ()
emitOutput (ProtocolError e) =
- error e
+ error ("Protocol error: " ++ e)
emitOutput (TtyOutput b) = do
B.hPut stdout b
hFlush stdout
@@ -241,3 +212,35 @@ isLegalSeen act@(Activity (Seen (Val b)) (Just hp) _) ds
where
acth = hash act
yes ds' = (True, ds')
+
+-- | Start by reading the initial two messages from the user side,
+-- their session key and the startup message.
+processSessionStart :: TChan (Message Seen) -> Logger -> IO (TVar DeveloperState)
+processSessionStart ochan logger = do
+ sessionmsg <- atomically $ readTChan ochan
+ logger $ User sessionmsg
+ sigverifier <- case sessionmsg of
+ ControlMessage c@(Control (SessionKey pk) _) ->
+ let sv = mkSigVerifier pk
+ in if verifySigned sv c
+ then return sv
+ else error "Badly signed session initialization message"
+ _ -> error $ "Unexpected session initialization message: " ++ show sessionmsg
+ startmsg <- atomically $ readTChan ochan
+ logger $ User startmsg
+ starthash <- case startmsg of
+ ActivityMessage act@(Activity (Seen (Val b)) Nothing _)
+ | verifySigned sigverifier act -> do
+ B.hPut stdout b
+ hFlush stdout
+ return (hash act)
+ _ -> error $ "Unexpected startup message: " ++ show startmsg
+ sk <- genMySessionKey
+ newTVarIO $ DeveloperState
+ { lastSeen = starthash
+ , sentSince = mempty
+ , enteredSince = mempty
+ , lastActivity = starthash
+ , developerSessionKey = sk
+ , developerSigVerifier = sigverifier
+ }
diff --git a/Role/Downloader.hs b/Role/Downloader.hs
new file mode 100644
index 0000000..3981227
--- /dev/null
+++ b/Role/Downloader.hs
@@ -0,0 +1,31 @@
+module Role.Downloader where
+
+import Types
+import Log
+import CmdLine
+import WebSockets
+import SessionID
+
+import Control.Concurrent.STM
+import qualified Data.Text as T
+import Role.Developer (processSessionStart, getUserMessage, Output(..))
+
+run :: DownloadOpts -> IO ()
+run os = runClientApp $ clientApp (ConnectMode (T.pack (downloadUrl os))) downloader
+
+downloader :: TChan (Message Entered) -> TChan (Message Seen) -> SessionID -> IO ()
+downloader _ichan ochan sid = do
+ let logfile = sessionLogFile "." sid
+ putStrLn $ "Starting download to " ++ logfile
+ putStrLn "(Will keep downloading until the debug-me session is done.)"
+ withLogger logfile $ \logger -> do
+ st <- processSessionStart ochan logger
+ go logger st
+ where
+ go logger st = do
+ (o, msg) <- atomically $ getUserMessage ochan st
+ _ <- logger $ User msg
+ case o of
+ ProtocolError e -> error ("Protocol error: " ++ e)
+ _ -> return ()
+ go logger st