diff options
author | Roman Smrž <roman.smrz@seznam.cz> | 2025-08-03 19:28:01 +0200 |
---|---|---|
committer | Roman Smrž <roman.smrz@seznam.cz> | 2025-08-03 19:28:01 +0200 |
commit | 469e1be7381a5739e89cc5277853a532d7a3a063 (patch) | |
tree | 3b70c724b3fd4d285dee9fec9491e628080aec88 | |
parent | 7deb4043e385f7e16b59c7c22711b9941bb73005 (diff) |
Add create-identity/owner command-line options
-rw-r--r-- | main/Main.hs | 26 | ||||
-rw-r--r-- | main/State.hs | 22 |
2 files changed, 44 insertions, 4 deletions
diff --git a/main/Main.hs b/main/Main.hs index ace3403..31523ca 100644 --- a/main/Main.hs +++ b/main/Main.hs @@ -2,7 +2,6 @@ module Main (main) where -import Control.Arrow (first) import Control.Concurrent import Control.Exception import Control.Monad @@ -14,8 +13,9 @@ import Control.Monad.Writer import Crypto.Random -import qualified Data.ByteString.Char8 as BC -import qualified Data.ByteString.Lazy as BL +import Data.Bifunctor +import Data.ByteString.Char8 qualified as BC +import Data.ByteString.Lazy qualified as BL import Data.Char import Data.List import Data.Maybe @@ -64,6 +64,7 @@ data Options = Options { optServer :: ServerOptions , optServices :: [ServiceOption] , optStorage :: StorageOption + , optCreateIdentity :: Maybe ( Maybe Text, [ Maybe Text ] ) , optChatroomAutoSubscribe :: Maybe Int , optDmBotEcho :: Maybe Text , optWebSocketServer :: Maybe Int @@ -87,6 +88,7 @@ defaultOptions = Options { optServer = defaultServerOptions , optServices = availableServices , optStorage = DefaultStorage + , optCreateIdentity = Nothing , optChatroomAutoSubscribe = Nothing , optDmBotEcho = Nothing , optWebSocketServer = Nothing @@ -124,6 +126,20 @@ options = , Option [] [ "memory-storage" ] (NoArg (\opts -> return opts { optStorage = MemoryStorage })) "use memory storage" + , Option [] [ "create-identity" ] + (OptArg (\value -> \opts -> return opts + { optCreateIdentity = + let devName = T.pack <$> value + in maybe (Just ( devName, [] )) (Just . first (const devName)) (optCreateIdentity opts) + }) "<name>") + "create a new (device) identity in a new local state" + , Option [] [ "create-owner" ] + (OptArg (\value -> \opts -> return opts + { optCreateIdentity = + let ownerName = T.pack <$> value + in maybe (Just ( Nothing, [ ownerName ] )) (Just . second (ownerName :)) (optCreateIdentity opts) + }) "<name>") + "create owner for a new device identity" , Option [] ["chatroom-auto-subscribe"] (ReqArg (\count -> \opts -> return opts { optChatroomAutoSubscribe = Just (read count) }) "<count>") "automatically subscribe for up to <count> chatrooms" @@ -313,7 +329,9 @@ main = do interactiveLoop :: Storage -> Options -> IO () interactiveLoop st opts = withTerminal commandCompletion $ \term -> do - erebosHead <- liftIO $ loadLocalStateHead term st + erebosHead <- case optCreateIdentity opts of + Nothing -> loadLocalStateHead term st + Just ( devName, names ) -> createLocalStateHead st (names ++ [ devName ]) void $ printLine term $ T.unpack $ displayIdentity $ headLocalIdentity erebosHead let tui = hasTerminalUI term diff --git a/main/State.hs b/main/State.hs index 150178e..f7bc367 100644 --- a/main/State.hs +++ b/main/State.hs @@ -1,15 +1,18 @@ module State ( loadLocalStateHead, + createLocalStateHead, updateSharedIdentity, interactiveIdentityUpdate, ) where +import Control.Monad import Control.Monad.Except import Control.Monad.IO.Class import Data.Foldable import Data.Maybe import Data.Proxy +import Data.Text (Text) import Data.Text qualified as T import Erebos.Error @@ -50,6 +53,25 @@ loadLocalStateHead term st = loadHeads st >>= \case , lsOther = [] } +createLocalStateHead :: (MonadIO m, MonadFail m) => Storage -> [ Maybe Text ] -> m (Head LocalState) +createLocalStateHead _ [] = fail "createLocalStateHead: empty name list" +createLocalStateHead st ( ownerName : names ) = liftIO $ do + owner <- createIdentity st ownerName Nothing + identity <- foldM createSingleIdentity owner names + shared <- wrappedStore st $ SharedState + { ssPrev = [] + , ssType = Just $ sharedTypeID @(Maybe ComposedIdentity) Proxy + , ssValue = [ storedRef $ idExtData owner ] + } + storeHead st $ LocalState + { lsPrev = Nothing + , lsIdentity = idExtData identity + , lsShared = [ shared ] + , lsOther = [] + } + where + createSingleIdentity owner name = createIdentity st name (Just owner) + updateSharedIdentity :: (MonadHead LocalState m, MonadError e m, FromErebosError e) => Terminal -> m () updateSharedIdentity term = updateLocalState_ $ updateSharedState_ $ \case |