1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
module State (
loadLocalStateHead,
updateSharedIdentity,
interactiveIdentityUpdate,
) where
import Control.Monad.Except
import Control.Monad.IO.Class
import Data.Foldable
import Data.Maybe
import Data.Proxy
import Data.Text qualified as T
import Erebos.Error
import Erebos.Identity
import Erebos.PubKey
import Erebos.State
import Erebos.Storable
import Erebos.Storage
import Terminal
loadLocalStateHead :: MonadIO m => Terminal -> Storage -> m (Head LocalState)
loadLocalStateHead term st = loadHeads st >>= \case
(h:_) -> return h
[] -> liftIO $ do
setPrompt term "Name: "
name <- getInputLine term $ KeepPrompt . maybe T.empty T.pack
setPrompt term "Device: "
devName <- getInputLine term $ KeepPrompt . maybe T.empty T.pack
owner <- if
| T.null name -> return Nothing
| otherwise -> Just <$> createIdentity st (Just name) Nothing
identity <- createIdentity st (if T.null devName then Nothing else Just devName) owner
shared <- wrappedStore st $ SharedState
{ ssPrev = []
, ssType = Just $ sharedTypeID @(Maybe ComposedIdentity) Proxy
, ssValue = [ storedRef $ idExtData $ fromMaybe identity owner ]
}
storeHead st $ LocalState
{ lsIdentity = idExtData identity
, lsShared = [ shared ]
, lsOther = []
}
updateSharedIdentity :: (MonadHead LocalState m, MonadError e m, FromErebosError e) => Terminal -> m ()
updateSharedIdentity term = updateLocalHead_ $ updateSharedState_ $ \case
Just identity -> do
Just . toComposedIdentity <$> interactiveIdentityUpdate term identity
Nothing -> throwOtherError "no existing shared identity"
interactiveIdentityUpdate :: (Foldable f, MonadStorage m, MonadIO m, MonadError e m, FromErebosError e) => Terminal -> Identity f -> m UnifiedIdentity
interactiveIdentityUpdate term identity = do
let public = idKeyIdentity identity
name <- liftIO $ do
setPrompt term $ T.unpack $ T.concat $ concat
[ [ T.pack "Name" ]
, case idName identity of
Just name -> [T.pack " [", name, T.pack "]"]
Nothing -> []
, [ T.pack ": " ]
]
getInputLine term $ KeepPrompt . maybe T.empty T.pack
if | T.null name -> mergeIdentity identity
| otherwise -> do
secret <- loadKey public
maybe (throwOtherError "created invalid identity") return . validateIdentity =<<
mstore =<< sign secret =<< mstore (emptyIdentityData public)
{ iddPrev = toList $ idDataF identity
, iddName = Just name
}
|