{-# LANGUAGE UndecidableInstances #-}

module Erebos.Identity (
    Identity, ComposedIdentity, UnifiedIdentity,
    IdentityData(..), ExtendedIdentityData(..), IdentityExtension(..),
    idData, idDataF, idExtData, idExtDataF,
    idName, idOwner, idUpdates, idKeyIdentity, idKeyMessage,
    eiddBase, eiddStoredBase,
    eiddName, eiddOwner, eiddKeyIdentity, eiddKeyMessage,

    emptyIdentityData,
    emptyIdentityExtension,
    createIdentity,
    validateIdentity, validateIdentityF, validateIdentityFE,
    validateExtendedIdentity, validateExtendedIdentityF, validateExtendedIdentityFE,
    loadIdentity, loadUnifiedIdentity,

    mergeIdentity, toUnifiedIdentity, toComposedIdentity,
    updateIdentity, updateOwners,
    sameIdentity,

    unfoldOwners,
    finalOwner,
    displayIdentity,
) where

import Control.Arrow
import Control.Monad
import Control.Monad.Except
import Control.Monad.Identity qualified as I
import Control.Monad.Reader

import Data.Either
import Data.Foldable
import Data.Function
import Data.List
import Data.Maybe
import Data.Ord
import Data.Set (Set)
import qualified Data.Set as S
import Data.Text (Text)
import qualified Data.Text as T

import Erebos.PubKey
import Erebos.Storage
import Erebos.Storage.Merge
import Erebos.Util

data Identity m = IdentityKind m => Identity
    { forall (m :: * -> *).
Identity m -> m (Stored (Signed ExtendedIdentityData))
idData_ :: m (Stored (Signed ExtendedIdentityData))
    , forall (m :: * -> *). Identity m -> Maybe Text
idName_ :: Maybe Text
    , forall (m :: * -> *). Identity m -> Maybe ComposedIdentity
idOwner_ :: Maybe ComposedIdentity
    , forall (m :: * -> *).
Identity m -> [Stored (Signed ExtendedIdentityData)]
idUpdates_ :: [Stored (Signed ExtendedIdentityData)]
    , forall (m :: * -> *). Identity m -> Stored PublicKey
idKeyIdentity_ :: Stored PublicKey
    , forall (m :: * -> *). Identity m -> Stored PublicKey
idKeyMessage_ :: Stored PublicKey
    }

deriving instance Show (m (Stored (Signed ExtendedIdentityData))) => Show (Identity m)

class (Functor f, Foldable f) => IdentityKind f where
    ikFilterAncestors :: Storable a => f (Stored a) -> f (Stored a)

instance IdentityKind I.Identity where
    ikFilterAncestors :: forall a. Storable a => Identity (Stored a) -> Identity (Stored a)
ikFilterAncestors = Identity (Stored a) -> Identity (Stored a)
forall a. a -> a
id

instance IdentityKind [] where
    ikFilterAncestors :: forall a. Storable a => [Stored a] -> [Stored a]
ikFilterAncestors = [Stored a] -> [Stored a]
forall a. Storable a => [Stored a] -> [Stored a]
filterAncestors

type ComposedIdentity = Identity []
type UnifiedIdentity = Identity I.Identity

instance Eq (m (Stored (Signed ExtendedIdentityData))) => Eq (Identity m) where
    == :: Identity m -> Identity m -> Bool
(==) = (m (Stored (Signed ExtendedIdentityData)),
 [Stored (Signed ExtendedIdentityData)])
-> (m (Stored (Signed ExtendedIdentityData)),
    [Stored (Signed ExtendedIdentityData)])
-> Bool
forall a. Eq a => a -> a -> Bool
(==) ((m (Stored (Signed ExtendedIdentityData)),
  [Stored (Signed ExtendedIdentityData)])
 -> (m (Stored (Signed ExtendedIdentityData)),
     [Stored (Signed ExtendedIdentityData)])
 -> Bool)
-> (Identity m
    -> (m (Stored (Signed ExtendedIdentityData)),
        [Stored (Signed ExtendedIdentityData)]))
-> Identity m
-> Identity m
-> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` (Identity m -> m (Stored (Signed ExtendedIdentityData))
forall (m :: * -> *).
Identity m -> m (Stored (Signed ExtendedIdentityData))
idData_ (Identity m -> m (Stored (Signed ExtendedIdentityData)))
-> (Identity m -> [Stored (Signed ExtendedIdentityData)])
-> Identity m
-> (m (Stored (Signed ExtendedIdentityData)),
    [Stored (Signed ExtendedIdentityData)])
forall b c c'. (b -> c) -> (b -> c') -> b -> (c, c')
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& Identity m -> [Stored (Signed ExtendedIdentityData)]
forall (m :: * -> *).
Identity m -> [Stored (Signed ExtendedIdentityData)]
idUpdates_)

data IdentityData = IdentityData
    { IdentityData -> [Stored (Signed IdentityData)]
iddPrev :: [Stored (Signed IdentityData)]
    , IdentityData -> Maybe Text
iddName :: Maybe Text
    , IdentityData -> Maybe (Stored (Signed IdentityData))
iddOwner :: Maybe (Stored (Signed IdentityData))
    , IdentityData -> Stored PublicKey
iddKeyIdentity :: Stored PublicKey
    , IdentityData -> Maybe (Stored PublicKey)
iddKeyMessage :: Maybe (Stored PublicKey)
    }
    deriving (Int -> IdentityData -> ShowS
[IdentityData] -> ShowS
IdentityData -> String
(Int -> IdentityData -> ShowS)
-> (IdentityData -> String)
-> ([IdentityData] -> ShowS)
-> Show IdentityData
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> IdentityData -> ShowS
showsPrec :: Int -> IdentityData -> ShowS
$cshow :: IdentityData -> String
show :: IdentityData -> String
$cshowList :: [IdentityData] -> ShowS
showList :: [IdentityData] -> ShowS
Show)

data IdentityExtension = IdentityExtension
    { IdentityExtension -> [Stored (Signed ExtendedIdentityData)]
idePrev :: [Stored (Signed ExtendedIdentityData)]
    , IdentityExtension -> Stored (Signed IdentityData)
ideBase :: Stored (Signed IdentityData)
    , IdentityExtension -> Maybe Text
ideName :: Maybe Text
    , IdentityExtension -> Maybe (Stored (Signed ExtendedIdentityData))
ideOwner :: Maybe (Stored (Signed ExtendedIdentityData))
    }
    deriving (Int -> IdentityExtension -> ShowS
[IdentityExtension] -> ShowS
IdentityExtension -> String
(Int -> IdentityExtension -> ShowS)
-> (IdentityExtension -> String)
-> ([IdentityExtension] -> ShowS)
-> Show IdentityExtension
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> IdentityExtension -> ShowS
showsPrec :: Int -> IdentityExtension -> ShowS
$cshow :: IdentityExtension -> String
show :: IdentityExtension -> String
$cshowList :: [IdentityExtension] -> ShowS
showList :: [IdentityExtension] -> ShowS
Show)

data ExtendedIdentityData = BaseIdentityData IdentityData
                          | ExtendedIdentityData IdentityExtension
    deriving (Int -> ExtendedIdentityData -> ShowS
[ExtendedIdentityData] -> ShowS
ExtendedIdentityData -> String
(Int -> ExtendedIdentityData -> ShowS)
-> (ExtendedIdentityData -> String)
-> ([ExtendedIdentityData] -> ShowS)
-> Show ExtendedIdentityData
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ExtendedIdentityData -> ShowS
showsPrec :: Int -> ExtendedIdentityData -> ShowS
$cshow :: ExtendedIdentityData -> String
show :: ExtendedIdentityData -> String
$cshowList :: [ExtendedIdentityData] -> ShowS
showList :: [ExtendedIdentityData] -> ShowS
Show)

baseToExtended :: Stored (Signed IdentityData) -> Stored (Signed ExtendedIdentityData)
baseToExtended :: Stored (Signed IdentityData)
-> Stored (Signed ExtendedIdentityData)
baseToExtended = (Signed IdentityData -> Signed ExtendedIdentityData)
-> Stored (Signed IdentityData)
-> Stored (Signed ExtendedIdentityData)
forall a b. (a -> b) -> Stored a -> Stored b
unsafeMapStored ((IdentityData -> ExtendedIdentityData)
-> Signed IdentityData -> Signed ExtendedIdentityData
forall a b. (a -> b) -> Signed a -> Signed b
unsafeMapSigned IdentityData -> ExtendedIdentityData
BaseIdentityData)

instance Storable IdentityData where
    store' :: IdentityData -> Store
store' IdentityData
idt = (forall (c :: * -> *). StorageCompleteness c => StoreRec c)
-> Store
storeRec ((forall (c :: * -> *). StorageCompleteness c => StoreRec c)
 -> Store)
-> (forall (c :: * -> *). StorageCompleteness c => StoreRec c)
-> Store
forall a b. (a -> b) -> a -> b
$ do
        (Stored (Signed IdentityData) -> StoreRec c)
-> [Stored (Signed IdentityData)] -> StoreRec c
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (String -> Stored (Signed IdentityData) -> StoreRec c
forall a (c :: * -> *).
(Storable a, StorageCompleteness c) =>
String -> a -> StoreRec c
storeRef String
"SPREV") ([Stored (Signed IdentityData)] -> StoreRec c)
-> [Stored (Signed IdentityData)] -> StoreRec c
forall a b. (a -> b) -> a -> b
$ IdentityData -> [Stored (Signed IdentityData)]
iddPrev IdentityData
idt
        String -> Maybe Text -> StoreRec c
forall a (c :: * -> *).
StorableText a =>
String -> Maybe a -> StoreRec c
storeMbText String
"name" (Maybe Text -> StoreRec c) -> Maybe Text -> StoreRec c
forall a b. (a -> b) -> a -> b
$ IdentityData -> Maybe Text
iddName IdentityData
idt
        String -> Maybe (Stored (Signed IdentityData)) -> StoreRec c
forall a (c :: * -> *).
(Storable a, StorageCompleteness c) =>
String -> Maybe a -> StoreRec c
storeMbRef String
"owner" (Maybe (Stored (Signed IdentityData)) -> StoreRec c)
-> Maybe (Stored (Signed IdentityData)) -> StoreRec c
forall a b. (a -> b) -> a -> b
$ IdentityData -> Maybe (Stored (Signed IdentityData))
iddOwner IdentityData
idt
        String -> Stored PublicKey -> StoreRec c
forall a (c :: * -> *).
(Storable a, StorageCompleteness c) =>
String -> a -> StoreRec c
storeRef String
"key-id" (Stored PublicKey -> StoreRec c) -> Stored PublicKey -> StoreRec c
forall a b. (a -> b) -> a -> b
$ IdentityData -> Stored PublicKey
iddKeyIdentity IdentityData
idt
        String -> Maybe (Stored PublicKey) -> StoreRec c
forall a (c :: * -> *).
(Storable a, StorageCompleteness c) =>
String -> Maybe a -> StoreRec c
storeMbRef String
"key-msg" (Maybe (Stored PublicKey) -> StoreRec c)
-> Maybe (Stored PublicKey) -> StoreRec c
forall a b. (a -> b) -> a -> b
$ IdentityData -> Maybe (Stored PublicKey)
iddKeyMessage IdentityData
idt

    load' :: Load IdentityData
load' = LoadRec IdentityData -> Load IdentityData
forall a. LoadRec a -> Load a
loadRec (LoadRec IdentityData -> Load IdentityData)
-> LoadRec IdentityData -> Load IdentityData
forall a b. (a -> b) -> a -> b
$ [Stored (Signed IdentityData)]
-> Maybe Text
-> Maybe (Stored (Signed IdentityData))
-> Stored PublicKey
-> Maybe (Stored PublicKey)
-> IdentityData
IdentityData
        ([Stored (Signed IdentityData)]
 -> Maybe Text
 -> Maybe (Stored (Signed IdentityData))
 -> Stored PublicKey
 -> Maybe (Stored PublicKey)
 -> IdentityData)
-> LoadRec [Stored (Signed IdentityData)]
-> LoadRec
     (Maybe Text
      -> Maybe (Stored (Signed IdentityData))
      -> Stored PublicKey
      -> Maybe (Stored PublicKey)
      -> IdentityData)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> LoadRec [Stored (Signed IdentityData)]
forall a. Storable a => String -> LoadRec [a]
loadRefs String
"SPREV"
        LoadRec
  (Maybe Text
   -> Maybe (Stored (Signed IdentityData))
   -> Stored PublicKey
   -> Maybe (Stored PublicKey)
   -> IdentityData)
-> LoadRec (Maybe Text)
-> LoadRec
     (Maybe (Stored (Signed IdentityData))
      -> Stored PublicKey -> Maybe (Stored PublicKey) -> IdentityData)
forall a b. LoadRec (a -> b) -> LoadRec a -> LoadRec b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> LoadRec (Maybe Text)
forall a. StorableText a => String -> LoadRec (Maybe a)
loadMbText String
"name"
        LoadRec
  (Maybe (Stored (Signed IdentityData))
   -> Stored PublicKey -> Maybe (Stored PublicKey) -> IdentityData)
-> LoadRec (Maybe (Stored (Signed IdentityData)))
-> LoadRec
     (Stored PublicKey -> Maybe (Stored PublicKey) -> IdentityData)
forall a b. LoadRec (a -> b) -> LoadRec a -> LoadRec b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> LoadRec (Maybe (Stored (Signed IdentityData)))
forall a. Storable a => String -> LoadRec (Maybe a)
loadMbRef String
"owner"
        LoadRec
  (Stored PublicKey -> Maybe (Stored PublicKey) -> IdentityData)
-> LoadRec (Stored PublicKey)
-> LoadRec (Maybe (Stored PublicKey) -> IdentityData)
forall a b. LoadRec (a -> b) -> LoadRec a -> LoadRec b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> LoadRec (Stored PublicKey)
forall a. Storable a => String -> LoadRec a
loadRef String
"key-id"
        LoadRec (Maybe (Stored PublicKey) -> IdentityData)
-> LoadRec (Maybe (Stored PublicKey)) -> LoadRec IdentityData
forall a b. LoadRec (a -> b) -> LoadRec a -> LoadRec b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> LoadRec (Maybe (Stored PublicKey))
forall a. Storable a => String -> LoadRec (Maybe a)
loadMbRef String
"key-msg"

instance Storable IdentityExtension where
    store' :: IdentityExtension -> Store
store' IdentityExtension {[Stored (Signed ExtendedIdentityData)]
Maybe Text
Maybe (Stored (Signed ExtendedIdentityData))
Stored (Signed IdentityData)
idePrev :: IdentityExtension -> [Stored (Signed ExtendedIdentityData)]
ideBase :: IdentityExtension -> Stored (Signed IdentityData)
ideName :: IdentityExtension -> Maybe Text
ideOwner :: IdentityExtension -> Maybe (Stored (Signed ExtendedIdentityData))
idePrev :: [Stored (Signed ExtendedIdentityData)]
ideBase :: Stored (Signed IdentityData)
ideName :: Maybe Text
ideOwner :: Maybe (Stored (Signed ExtendedIdentityData))
..} = (forall (c :: * -> *). StorageCompleteness c => StoreRec c)
-> Store
storeRec ((forall (c :: * -> *). StorageCompleteness c => StoreRec c)
 -> Store)
-> (forall (c :: * -> *). StorageCompleteness c => StoreRec c)
-> Store
forall a b. (a -> b) -> a -> b
$ do
        (Stored (Signed ExtendedIdentityData) -> StoreRec c)
-> [Stored (Signed ExtendedIdentityData)] -> StoreRec c
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (String -> Stored (Signed ExtendedIdentityData) -> StoreRec c
forall a (c :: * -> *).
(Storable a, StorageCompleteness c) =>
String -> a -> StoreRec c
storeRef String
"SPREV") [Stored (Signed ExtendedIdentityData)]
idePrev
        String -> Stored (Signed IdentityData) -> StoreRec c
forall a (c :: * -> *).
(Storable a, StorageCompleteness c) =>
String -> a -> StoreRec c
storeRef String
"SBASE" Stored (Signed IdentityData)
ideBase
        String -> Maybe Text -> StoreRec c
forall a (c :: * -> *).
StorableText a =>
String -> Maybe a -> StoreRec c
storeMbText String
"name" Maybe Text
ideName
        String
-> Maybe (Stored (Signed ExtendedIdentityData)) -> StoreRec c
forall a (c :: * -> *).
(Storable a, StorageCompleteness c) =>
String -> Maybe a -> StoreRec c
storeMbRef String
"owner" Maybe (Stored (Signed ExtendedIdentityData))
ideOwner

    load' :: Load IdentityExtension
load' = LoadRec IdentityExtension -> Load IdentityExtension
forall a. LoadRec a -> Load a
loadRec (LoadRec IdentityExtension -> Load IdentityExtension)
-> LoadRec IdentityExtension -> Load IdentityExtension
forall a b. (a -> b) -> a -> b
$ [Stored (Signed ExtendedIdentityData)]
-> Stored (Signed IdentityData)
-> Maybe Text
-> Maybe (Stored (Signed ExtendedIdentityData))
-> IdentityExtension
IdentityExtension
        ([Stored (Signed ExtendedIdentityData)]
 -> Stored (Signed IdentityData)
 -> Maybe Text
 -> Maybe (Stored (Signed ExtendedIdentityData))
 -> IdentityExtension)
-> LoadRec [Stored (Signed ExtendedIdentityData)]
-> LoadRec
     (Stored (Signed IdentityData)
      -> Maybe Text
      -> Maybe (Stored (Signed ExtendedIdentityData))
      -> IdentityExtension)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> LoadRec [Stored (Signed ExtendedIdentityData)]
forall a. Storable a => String -> LoadRec [a]
loadRefs String
"SPREV"
        LoadRec
  (Stored (Signed IdentityData)
   -> Maybe Text
   -> Maybe (Stored (Signed ExtendedIdentityData))
   -> IdentityExtension)
-> LoadRec (Stored (Signed IdentityData))
-> LoadRec
     (Maybe Text
      -> Maybe (Stored (Signed ExtendedIdentityData))
      -> IdentityExtension)
forall a b. LoadRec (a -> b) -> LoadRec a -> LoadRec b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> LoadRec (Stored (Signed IdentityData))
forall a. Storable a => String -> LoadRec a
loadRef String
"SBASE"
        LoadRec
  (Maybe Text
   -> Maybe (Stored (Signed ExtendedIdentityData))
   -> IdentityExtension)
-> LoadRec (Maybe Text)
-> LoadRec
     (Maybe (Stored (Signed ExtendedIdentityData)) -> IdentityExtension)
forall a b. LoadRec (a -> b) -> LoadRec a -> LoadRec b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> LoadRec (Maybe Text)
forall a. StorableText a => String -> LoadRec (Maybe a)
loadMbText String
"name"
        LoadRec
  (Maybe (Stored (Signed ExtendedIdentityData)) -> IdentityExtension)
-> LoadRec (Maybe (Stored (Signed ExtendedIdentityData)))
-> LoadRec IdentityExtension
forall a b. LoadRec (a -> b) -> LoadRec a -> LoadRec b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> LoadRec (Maybe (Stored (Signed ExtendedIdentityData)))
forall a. Storable a => String -> LoadRec (Maybe a)
loadMbRef String
"owner"

instance Storable ExtendedIdentityData where
    store' :: ExtendedIdentityData -> Store
store' (BaseIdentityData IdentityData
idata) = IdentityData -> Store
forall a. Storable a => a -> Store
store' IdentityData
idata
    store' (ExtendedIdentityData IdentityExtension
idata) = IdentityExtension -> Store
forall a. Storable a => a -> Store
store' IdentityExtension
idata

    load' :: Load ExtendedIdentityData
load' = [Load ExtendedIdentityData] -> Load ExtendedIdentityData
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, MonadPlus m) =>
t (m a) -> m a
msum
        [ IdentityData -> ExtendedIdentityData
BaseIdentityData (IdentityData -> ExtendedIdentityData)
-> Load IdentityData -> Load ExtendedIdentityData
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Load IdentityData
forall a. Storable a => Load a
load'
        , IdentityExtension -> ExtendedIdentityData
ExtendedIdentityData (IdentityExtension -> ExtendedIdentityData)
-> Load IdentityExtension -> Load ExtendedIdentityData
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Load IdentityExtension
forall a. Storable a => Load a
load'
        ]

instance Mergeable (Maybe ComposedIdentity) where
    type Component (Maybe ComposedIdentity) = Signed ExtendedIdentityData
    mergeSorted :: [Stored (Component (Maybe ComposedIdentity))]
-> Maybe ComposedIdentity
mergeSorted = [Stored (Signed ExtendedIdentityData)] -> Maybe ComposedIdentity
[Stored (Component (Maybe ComposedIdentity))]
-> Maybe ComposedIdentity
forall (m :: * -> *).
IdentityKind m =>
m (Stored (Signed ExtendedIdentityData)) -> Maybe (Identity m)
validateExtendedIdentityF
    toComponents :: Maybe ComposedIdentity
-> [Stored (Component (Maybe ComposedIdentity))]
toComponents = [Stored (Signed ExtendedIdentityData)]
-> (ComposedIdentity -> [Stored (Signed ExtendedIdentityData)])
-> Maybe ComposedIdentity
-> [Stored (Signed ExtendedIdentityData)]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] ComposedIdentity -> [Stored (Signed ExtendedIdentityData)]
forall (m :: * -> *).
Identity m -> m (Stored (Signed ExtendedIdentityData))
idExtDataF

idData :: UnifiedIdentity -> Stored (Signed IdentityData)
idData :: UnifiedIdentity -> Stored (Signed IdentityData)
idData = Identity (Stored (Signed IdentityData))
-> Stored (Signed IdentityData)
forall a. Identity a -> a
I.runIdentity (Identity (Stored (Signed IdentityData))
 -> Stored (Signed IdentityData))
-> (UnifiedIdentity -> Identity (Stored (Signed IdentityData)))
-> UnifiedIdentity
-> Stored (Signed IdentityData)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UnifiedIdentity -> Identity (Stored (Signed IdentityData))
forall (m :: * -> *).
Identity m -> m (Stored (Signed IdentityData))
idDataF

idDataF :: Identity m -> m (Stored (Signed IdentityData))
idDataF :: forall (m :: * -> *).
Identity m -> m (Stored (Signed IdentityData))
idDataF idt :: Identity m
idt@Identity {} = m (Stored (Signed IdentityData))
-> m (Stored (Signed IdentityData))
forall a. Storable a => m (Stored a) -> m (Stored a)
forall (f :: * -> *) a.
(IdentityKind f, Storable a) =>
f (Stored a) -> f (Stored a)
ikFilterAncestors (m (Stored (Signed IdentityData))
 -> m (Stored (Signed IdentityData)))
-> (Identity m -> m (Stored (Signed IdentityData)))
-> Identity m
-> m (Stored (Signed IdentityData))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Stored (Signed ExtendedIdentityData)
 -> Stored (Signed IdentityData))
-> m (Stored (Signed ExtendedIdentityData))
-> m (Stored (Signed IdentityData))
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Stored (Signed ExtendedIdentityData)
-> Stored (Signed IdentityData)
eiddStoredBase (m (Stored (Signed ExtendedIdentityData))
 -> m (Stored (Signed IdentityData)))
-> (Identity m -> m (Stored (Signed ExtendedIdentityData)))
-> Identity m
-> m (Stored (Signed IdentityData))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Identity m -> m (Stored (Signed ExtendedIdentityData))
forall (m :: * -> *).
Identity m -> m (Stored (Signed ExtendedIdentityData))
idData_ (Identity m -> m (Stored (Signed IdentityData)))
-> Identity m -> m (Stored (Signed IdentityData))
forall a b. (a -> b) -> a -> b
$ Identity m
idt

idExtData :: UnifiedIdentity -> Stored (Signed ExtendedIdentityData)
idExtData :: UnifiedIdentity -> Stored (Signed ExtendedIdentityData)
idExtData = Identity (Stored (Signed ExtendedIdentityData))
-> Stored (Signed ExtendedIdentityData)
forall a. Identity a -> a
I.runIdentity (Identity (Stored (Signed ExtendedIdentityData))
 -> Stored (Signed ExtendedIdentityData))
-> (UnifiedIdentity
    -> Identity (Stored (Signed ExtendedIdentityData)))
-> UnifiedIdentity
-> Stored (Signed ExtendedIdentityData)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UnifiedIdentity -> Identity (Stored (Signed ExtendedIdentityData))
forall (m :: * -> *).
Identity m -> m (Stored (Signed ExtendedIdentityData))
idExtDataF

idExtDataF :: Identity m -> m (Stored (Signed ExtendedIdentityData))
idExtDataF :: forall (m :: * -> *).
Identity m -> m (Stored (Signed ExtendedIdentityData))
idExtDataF = Identity m -> m (Stored (Signed ExtendedIdentityData))
forall (m :: * -> *).
Identity m -> m (Stored (Signed ExtendedIdentityData))
idData_

idName :: Identity m -> Maybe Text
idName :: forall (m :: * -> *). Identity m -> Maybe Text
idName = Identity m -> Maybe Text
forall (m :: * -> *). Identity m -> Maybe Text
idName_

idOwner :: Identity m -> Maybe ComposedIdentity
idOwner :: forall (m :: * -> *). Identity m -> Maybe ComposedIdentity
idOwner = Identity m -> Maybe ComposedIdentity
forall (m :: * -> *). Identity m -> Maybe ComposedIdentity
idOwner_

idUpdates :: Identity m -> [Stored (Signed ExtendedIdentityData)]
idUpdates :: forall (m :: * -> *).
Identity m -> [Stored (Signed ExtendedIdentityData)]
idUpdates = Identity m -> [Stored (Signed ExtendedIdentityData)]
forall (m :: * -> *).
Identity m -> [Stored (Signed ExtendedIdentityData)]
idUpdates_

idKeyIdentity :: Identity m -> Stored PublicKey
idKeyIdentity :: forall (m :: * -> *). Identity m -> Stored PublicKey
idKeyIdentity = Identity m -> Stored PublicKey
forall (m :: * -> *). Identity m -> Stored PublicKey
idKeyIdentity_

idKeyMessage :: Identity m -> Stored PublicKey
idKeyMessage :: forall (m :: * -> *). Identity m -> Stored PublicKey
idKeyMessage = Identity m -> Stored PublicKey
forall (m :: * -> *). Identity m -> Stored PublicKey
idKeyMessage_

eiddPrev :: ExtendedIdentityData -> [Stored (Signed ExtendedIdentityData)]
eiddPrev :: ExtendedIdentityData -> [Stored (Signed ExtendedIdentityData)]
eiddPrev (BaseIdentityData IdentityData
idata) = Stored (Signed IdentityData)
-> Stored (Signed ExtendedIdentityData)
baseToExtended (Stored (Signed IdentityData)
 -> Stored (Signed ExtendedIdentityData))
-> [Stored (Signed IdentityData)]
-> [Stored (Signed ExtendedIdentityData)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IdentityData -> [Stored (Signed IdentityData)]
iddPrev IdentityData
idata
eiddPrev (ExtendedIdentityData IdentityExtension {[Stored (Signed ExtendedIdentityData)]
Maybe Text
Maybe (Stored (Signed ExtendedIdentityData))
Stored (Signed IdentityData)
idePrev :: IdentityExtension -> [Stored (Signed ExtendedIdentityData)]
ideBase :: IdentityExtension -> Stored (Signed IdentityData)
ideName :: IdentityExtension -> Maybe Text
ideOwner :: IdentityExtension -> Maybe (Stored (Signed ExtendedIdentityData))
idePrev :: [Stored (Signed ExtendedIdentityData)]
ideBase :: Stored (Signed IdentityData)
ideName :: Maybe Text
ideOwner :: Maybe (Stored (Signed ExtendedIdentityData))
..}) = Stored (Signed IdentityData)
-> Stored (Signed ExtendedIdentityData)
baseToExtended Stored (Signed IdentityData)
ideBase Stored (Signed ExtendedIdentityData)
-> [Stored (Signed ExtendedIdentityData)]
-> [Stored (Signed ExtendedIdentityData)]
forall a. a -> [a] -> [a]
: [Stored (Signed ExtendedIdentityData)]
idePrev

eiddBase :: ExtendedIdentityData -> IdentityData
eiddBase :: ExtendedIdentityData -> IdentityData
eiddBase (BaseIdentityData IdentityData
idata) = IdentityData
idata
eiddBase (ExtendedIdentityData IdentityExtension {[Stored (Signed ExtendedIdentityData)]
Maybe Text
Maybe (Stored (Signed ExtendedIdentityData))
Stored (Signed IdentityData)
idePrev :: IdentityExtension -> [Stored (Signed ExtendedIdentityData)]
ideBase :: IdentityExtension -> Stored (Signed IdentityData)
ideName :: IdentityExtension -> Maybe Text
ideOwner :: IdentityExtension -> Maybe (Stored (Signed ExtendedIdentityData))
idePrev :: [Stored (Signed ExtendedIdentityData)]
ideBase :: Stored (Signed IdentityData)
ideName :: Maybe Text
ideOwner :: Maybe (Stored (Signed ExtendedIdentityData))
..}) = Stored (Signed IdentityData) -> IdentityData
forall a. Stored (Signed a) -> a
fromSigned Stored (Signed IdentityData)
ideBase

eiddStoredBase :: Stored (Signed ExtendedIdentityData) -> Stored (Signed IdentityData)
eiddStoredBase :: Stored (Signed ExtendedIdentityData)
-> Stored (Signed IdentityData)
eiddStoredBase Stored (Signed ExtendedIdentityData)
ext = case Stored (Signed ExtendedIdentityData) -> ExtendedIdentityData
forall a. Stored (Signed a) -> a
fromSigned Stored (Signed ExtendedIdentityData)
ext of
                          (BaseIdentityData IdentityData
idata) -> (Signed ExtendedIdentityData -> Signed IdentityData)
-> Stored (Signed ExtendedIdentityData)
-> Stored (Signed IdentityData)
forall a b. (a -> b) -> Stored a -> Stored b
unsafeMapStored ((ExtendedIdentityData -> IdentityData)
-> Signed ExtendedIdentityData -> Signed IdentityData
forall a b. (a -> b) -> Signed a -> Signed b
unsafeMapSigned (IdentityData -> ExtendedIdentityData -> IdentityData
forall a b. a -> b -> a
const IdentityData
idata)) Stored (Signed ExtendedIdentityData)
ext
                          (ExtendedIdentityData IdentityExtension {[Stored (Signed ExtendedIdentityData)]
Maybe Text
Maybe (Stored (Signed ExtendedIdentityData))
Stored (Signed IdentityData)
idePrev :: IdentityExtension -> [Stored (Signed ExtendedIdentityData)]
ideBase :: IdentityExtension -> Stored (Signed IdentityData)
ideName :: IdentityExtension -> Maybe Text
ideOwner :: IdentityExtension -> Maybe (Stored (Signed ExtendedIdentityData))
idePrev :: [Stored (Signed ExtendedIdentityData)]
ideBase :: Stored (Signed IdentityData)
ideName :: Maybe Text
ideOwner :: Maybe (Stored (Signed ExtendedIdentityData))
..}) -> Stored (Signed IdentityData)
ideBase

eiddName :: ExtendedIdentityData -> Maybe Text
eiddName :: ExtendedIdentityData -> Maybe Text
eiddName (BaseIdentityData IdentityData
idata) = IdentityData -> Maybe Text
iddName IdentityData
idata
eiddName (ExtendedIdentityData IdentityExtension {[Stored (Signed ExtendedIdentityData)]
Maybe Text
Maybe (Stored (Signed ExtendedIdentityData))
Stored (Signed IdentityData)
idePrev :: IdentityExtension -> [Stored (Signed ExtendedIdentityData)]
ideBase :: IdentityExtension -> Stored (Signed IdentityData)
ideName :: IdentityExtension -> Maybe Text
ideOwner :: IdentityExtension -> Maybe (Stored (Signed ExtendedIdentityData))
idePrev :: [Stored (Signed ExtendedIdentityData)]
ideBase :: Stored (Signed IdentityData)
ideName :: Maybe Text
ideOwner :: Maybe (Stored (Signed ExtendedIdentityData))
..}) = Maybe Text
ideName

eiddOwner :: ExtendedIdentityData -> Maybe (Stored (Signed ExtendedIdentityData))
eiddOwner :: ExtendedIdentityData
-> Maybe (Stored (Signed ExtendedIdentityData))
eiddOwner (BaseIdentityData IdentityData
idata) = Stored (Signed IdentityData)
-> Stored (Signed ExtendedIdentityData)
baseToExtended (Stored (Signed IdentityData)
 -> Stored (Signed ExtendedIdentityData))
-> Maybe (Stored (Signed IdentityData))
-> Maybe (Stored (Signed ExtendedIdentityData))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IdentityData -> Maybe (Stored (Signed IdentityData))
iddOwner IdentityData
idata
eiddOwner (ExtendedIdentityData IdentityExtension {[Stored (Signed ExtendedIdentityData)]
Maybe Text
Maybe (Stored (Signed ExtendedIdentityData))
Stored (Signed IdentityData)
idePrev :: IdentityExtension -> [Stored (Signed ExtendedIdentityData)]
ideBase :: IdentityExtension -> Stored (Signed IdentityData)
ideName :: IdentityExtension -> Maybe Text
ideOwner :: IdentityExtension -> Maybe (Stored (Signed ExtendedIdentityData))
idePrev :: [Stored (Signed ExtendedIdentityData)]
ideBase :: Stored (Signed IdentityData)
ideName :: Maybe Text
ideOwner :: Maybe (Stored (Signed ExtendedIdentityData))
..}) = Maybe (Stored (Signed ExtendedIdentityData))
ideOwner

eiddKeyIdentity :: ExtendedIdentityData -> Stored PublicKey
eiddKeyIdentity :: ExtendedIdentityData -> Stored PublicKey
eiddKeyIdentity = IdentityData -> Stored PublicKey
iddKeyIdentity (IdentityData -> Stored PublicKey)
-> (ExtendedIdentityData -> IdentityData)
-> ExtendedIdentityData
-> Stored PublicKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ExtendedIdentityData -> IdentityData
eiddBase

eiddKeyMessage :: ExtendedIdentityData -> Maybe (Stored PublicKey)
eiddKeyMessage :: ExtendedIdentityData -> Maybe (Stored PublicKey)
eiddKeyMessage = IdentityData -> Maybe (Stored PublicKey)
iddKeyMessage (IdentityData -> Maybe (Stored PublicKey))
-> (ExtendedIdentityData -> IdentityData)
-> ExtendedIdentityData
-> Maybe (Stored PublicKey)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ExtendedIdentityData -> IdentityData
eiddBase


emptyIdentityData :: Stored PublicKey -> IdentityData
emptyIdentityData :: Stored PublicKey -> IdentityData
emptyIdentityData Stored PublicKey
key = IdentityData
    { iddName :: Maybe Text
iddName = Maybe Text
forall a. Maybe a
Nothing
    , iddPrev :: [Stored (Signed IdentityData)]
iddPrev = []
    , iddOwner :: Maybe (Stored (Signed IdentityData))
iddOwner = Maybe (Stored (Signed IdentityData))
forall a. Maybe a
Nothing
    , iddKeyIdentity :: Stored PublicKey
iddKeyIdentity = Stored PublicKey
key
    , iddKeyMessage :: Maybe (Stored PublicKey)
iddKeyMessage = Maybe (Stored PublicKey)
forall a. Maybe a
Nothing
    }

emptyIdentityExtension :: Stored (Signed IdentityData) -> IdentityExtension
emptyIdentityExtension :: Stored (Signed IdentityData) -> IdentityExtension
emptyIdentityExtension Stored (Signed IdentityData)
base = IdentityExtension
    { idePrev :: [Stored (Signed ExtendedIdentityData)]
idePrev = []
    , ideBase :: Stored (Signed IdentityData)
ideBase = Stored (Signed IdentityData)
base
    , ideName :: Maybe Text
ideName = Maybe Text
forall a. Maybe a
Nothing
    , ideOwner :: Maybe (Stored (Signed ExtendedIdentityData))
ideOwner = Maybe (Stored (Signed ExtendedIdentityData))
forall a. Maybe a
Nothing
    }

isExtension :: Stored (Signed ExtendedIdentityData) -> Bool
isExtension :: Stored (Signed ExtendedIdentityData) -> Bool
isExtension Stored (Signed ExtendedIdentityData)
x = case Stored (Signed ExtendedIdentityData) -> ExtendedIdentityData
forall a. Stored (Signed a) -> a
fromSigned Stored (Signed ExtendedIdentityData)
x of BaseIdentityData {} -> Bool
False
                                     ExtendedIdentityData
_ -> Bool
True


createIdentity :: Storage -> Maybe Text -> Maybe UnifiedIdentity -> IO UnifiedIdentity
createIdentity :: Storage
-> Maybe Text -> Maybe UnifiedIdentity -> IO UnifiedIdentity
createIdentity Storage
st Maybe Text
name Maybe UnifiedIdentity
owner = do
    (SecretKey
secret, Stored PublicKey
public) <- Storage -> IO (SecretKey, Stored PublicKey)
forall sec pub. KeyPair sec pub => Storage -> IO (sec, Stored pub)
generateKeys Storage
st
    (SecretKey
_secretMsg, Stored PublicKey
publicMsg) <- Storage -> IO (SecretKey, Stored PublicKey)
forall sec pub. KeyPair sec pub => Storage -> IO (sec, Stored pub)
generateKeys Storage
st

    let signOwner :: Signed a -> ReaderT Storage IO (Signed a)
        signOwner :: forall a. Signed a -> ReaderT Storage IO (Signed a)
signOwner Signed a
idd
            | Just UnifiedIdentity
o <- Maybe UnifiedIdentity
owner = do
                Just SecretKey
ownerSecret <- Stored PublicKey -> ReaderT Storage IO (Maybe SecretKey)
forall sec pub (m :: * -> *).
(KeyPair sec pub, MonadIO m) =>
Stored pub -> m (Maybe sec)
loadKeyMb (IdentityData -> Stored PublicKey
iddKeyIdentity (IdentityData -> Stored PublicKey)
-> IdentityData -> Stored PublicKey
forall a b. (a -> b) -> a -> b
$ Stored (Signed IdentityData) -> IdentityData
forall a. Stored (Signed a) -> a
fromSigned (Stored (Signed IdentityData) -> IdentityData)
-> Stored (Signed IdentityData) -> IdentityData
forall a b. (a -> b) -> a -> b
$ UnifiedIdentity -> Stored (Signed IdentityData)
idData UnifiedIdentity
o)
                SecretKey -> Signed a -> ReaderT Storage IO (Signed a)
forall (m :: * -> *) a.
MonadStorage m =>
SecretKey -> Signed a -> m (Signed a)
signAdd SecretKey
ownerSecret Signed a
idd
            | Bool
otherwise = Signed a -> ReaderT Storage IO (Signed a)
forall a. a -> ReaderT Storage IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Signed a
idd

    Just UnifiedIdentity
identity <- (ReaderT Storage IO (Maybe UnifiedIdentity)
 -> Storage -> IO (Maybe UnifiedIdentity))
-> Storage
-> ReaderT Storage IO (Maybe UnifiedIdentity)
-> IO (Maybe UnifiedIdentity)
forall a b c. (a -> b -> c) -> b -> a -> c
flip ReaderT Storage IO (Maybe UnifiedIdentity)
-> Storage -> IO (Maybe UnifiedIdentity)
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT Storage
st (ReaderT Storage IO (Maybe UnifiedIdentity)
 -> IO (Maybe UnifiedIdentity))
-> ReaderT Storage IO (Maybe UnifiedIdentity)
-> IO (Maybe UnifiedIdentity)
forall a b. (a -> b) -> a -> b
$ do
        Stored (Signed IdentityData)
baseData <- Signed IdentityData
-> ReaderT Storage IO (Stored (Signed IdentityData))
forall a. Storable a => a -> ReaderT Storage IO (Stored a)
forall (m :: * -> *) a.
(MonadStorage m, Storable a) =>
a -> m (Stored a)
mstore (Signed IdentityData
 -> ReaderT Storage IO (Stored (Signed IdentityData)))
-> ReaderT Storage IO (Signed IdentityData)
-> ReaderT Storage IO (Stored (Signed IdentityData))
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Signed IdentityData -> ReaderT Storage IO (Signed IdentityData)
forall a. Signed a -> ReaderT Storage IO (Signed a)
signOwner (Signed IdentityData -> ReaderT Storage IO (Signed IdentityData))
-> ReaderT Storage IO (Signed IdentityData)
-> ReaderT Storage IO (Signed IdentityData)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< SecretKey
-> Stored IdentityData -> ReaderT Storage IO (Signed IdentityData)
forall (m :: * -> *) a.
MonadStorage m =>
SecretKey -> Stored a -> m (Signed a)
sign SecretKey
secret (Stored IdentityData -> ReaderT Storage IO (Signed IdentityData))
-> ReaderT Storage IO (Stored IdentityData)
-> ReaderT Storage IO (Signed IdentityData)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
            IdentityData -> ReaderT Storage IO (Stored IdentityData)
forall a. Storable a => a -> ReaderT Storage IO (Stored a)
forall (m :: * -> *) a.
(MonadStorage m, Storable a) =>
a -> m (Stored a)
mstore (Stored PublicKey -> IdentityData
emptyIdentityData Stored PublicKey
public)
                { iddOwner = idData <$> owner
                , iddKeyMessage = Just publicMsg
                }
        let extOwner :: Maybe (Stored (Signed ExtendedIdentityData))
extOwner = do
                Stored (Signed ExtendedIdentityData)
odata <- UnifiedIdentity -> Stored (Signed ExtendedIdentityData)
idExtData (UnifiedIdentity -> Stored (Signed ExtendedIdentityData))
-> Maybe UnifiedIdentity
-> Maybe (Stored (Signed ExtendedIdentityData))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe UnifiedIdentity
owner
                Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ Stored (Signed ExtendedIdentityData) -> Bool
isExtension Stored (Signed ExtendedIdentityData)
odata
                Stored (Signed ExtendedIdentityData)
-> Maybe (Stored (Signed ExtendedIdentityData))
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return Stored (Signed ExtendedIdentityData)
odata

        Identity (Stored (Signed ExtendedIdentityData))
-> Maybe UnifiedIdentity
forall (m :: * -> *).
IdentityKind m =>
m (Stored (Signed ExtendedIdentityData)) -> Maybe (Identity m)
validateExtendedIdentityF (Identity (Stored (Signed ExtendedIdentityData))
 -> Maybe UnifiedIdentity)
-> (Stored (Signed ExtendedIdentityData)
    -> Identity (Stored (Signed ExtendedIdentityData)))
-> Stored (Signed ExtendedIdentityData)
-> Maybe UnifiedIdentity
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Stored (Signed ExtendedIdentityData)
-> Identity (Stored (Signed ExtendedIdentityData))
forall a. a -> Identity a
I.Identity (Stored (Signed ExtendedIdentityData) -> Maybe UnifiedIdentity)
-> ReaderT Storage IO (Stored (Signed ExtendedIdentityData))
-> ReaderT Storage IO (Maybe UnifiedIdentity)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
            if Maybe Text -> Bool
forall a. Maybe a -> Bool
isJust Maybe Text
name Bool -> Bool -> Bool
|| Maybe (Stored (Signed ExtendedIdentityData)) -> Bool
forall a. Maybe a -> Bool
isJust Maybe (Stored (Signed ExtendedIdentityData))
extOwner
               then Signed ExtendedIdentityData
-> ReaderT Storage IO (Stored (Signed ExtendedIdentityData))
forall a. Storable a => a -> ReaderT Storage IO (Stored a)
forall (m :: * -> *) a.
(MonadStorage m, Storable a) =>
a -> m (Stored a)
mstore (Signed ExtendedIdentityData
 -> ReaderT Storage IO (Stored (Signed ExtendedIdentityData)))
-> ReaderT Storage IO (Signed ExtendedIdentityData)
-> ReaderT Storage IO (Stored (Signed ExtendedIdentityData))
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Signed ExtendedIdentityData
-> ReaderT Storage IO (Signed ExtendedIdentityData)
forall a. Signed a -> ReaderT Storage IO (Signed a)
signOwner (Signed ExtendedIdentityData
 -> ReaderT Storage IO (Signed ExtendedIdentityData))
-> ReaderT Storage IO (Signed ExtendedIdentityData)
-> ReaderT Storage IO (Signed ExtendedIdentityData)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< SecretKey
-> Stored ExtendedIdentityData
-> ReaderT Storage IO (Signed ExtendedIdentityData)
forall (m :: * -> *) a.
MonadStorage m =>
SecretKey -> Stored a -> m (Signed a)
sign SecretKey
secret (Stored ExtendedIdentityData
 -> ReaderT Storage IO (Signed ExtendedIdentityData))
-> ReaderT Storage IO (Stored ExtendedIdentityData)
-> ReaderT Storage IO (Signed ExtendedIdentityData)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
                       ExtendedIdentityData
-> ReaderT Storage IO (Stored ExtendedIdentityData)
forall a. Storable a => a -> ReaderT Storage IO (Stored a)
forall (m :: * -> *) a.
(MonadStorage m, Storable a) =>
a -> m (Stored a)
mstore (ExtendedIdentityData
 -> ReaderT Storage IO (Stored ExtendedIdentityData))
-> (IdentityExtension -> ExtendedIdentityData)
-> IdentityExtension
-> ReaderT Storage IO (Stored ExtendedIdentityData)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IdentityExtension -> ExtendedIdentityData
ExtendedIdentityData (IdentityExtension
 -> ReaderT Storage IO (Stored ExtendedIdentityData))
-> ReaderT Storage IO IdentityExtension
-> ReaderT Storage IO (Stored ExtendedIdentityData)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IdentityExtension -> ReaderT Storage IO IdentityExtension
forall a. a -> ReaderT Storage IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Stored (Signed IdentityData) -> IdentityExtension
emptyIdentityExtension Stored (Signed IdentityData)
baseData)
                       { ideName = name
                       , ideOwner = extOwner
                       }
               else Stored (Signed ExtendedIdentityData)
-> ReaderT Storage IO (Stored (Signed ExtendedIdentityData))
forall a. a -> ReaderT Storage IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Stored (Signed ExtendedIdentityData)
 -> ReaderT Storage IO (Stored (Signed ExtendedIdentityData)))
-> Stored (Signed ExtendedIdentityData)
-> ReaderT Storage IO (Stored (Signed ExtendedIdentityData))
forall a b. (a -> b) -> a -> b
$ Stored (Signed IdentityData)
-> Stored (Signed ExtendedIdentityData)
baseToExtended Stored (Signed IdentityData)
baseData
    UnifiedIdentity -> IO UnifiedIdentity
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return UnifiedIdentity
identity

validateIdentity :: Stored (Signed IdentityData) -> Maybe UnifiedIdentity
validateIdentity :: Stored (Signed IdentityData) -> Maybe UnifiedIdentity
validateIdentity = Identity (Stored (Signed IdentityData)) -> Maybe UnifiedIdentity
forall (m :: * -> *).
IdentityKind m =>
m (Stored (Signed IdentityData)) -> Maybe (Identity m)
validateIdentityF (Identity (Stored (Signed IdentityData)) -> Maybe UnifiedIdentity)
-> (Stored (Signed IdentityData)
    -> Identity (Stored (Signed IdentityData)))
-> Stored (Signed IdentityData)
-> Maybe UnifiedIdentity
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Stored (Signed IdentityData)
-> Identity (Stored (Signed IdentityData))
forall a. a -> Identity a
I.Identity

validateIdentityF :: IdentityKind m => m (Stored (Signed IdentityData)) -> Maybe (Identity m)
validateIdentityF :: forall (m :: * -> *).
IdentityKind m =>
m (Stored (Signed IdentityData)) -> Maybe (Identity m)
validateIdentityF = (String -> Maybe (Identity m))
-> (Identity m -> Maybe (Identity m))
-> Either String (Identity m)
-> Maybe (Identity m)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Maybe (Identity m) -> String -> Maybe (Identity m)
forall a b. a -> b -> a
const Maybe (Identity m)
forall a. Maybe a
Nothing) Identity m -> Maybe (Identity m)
forall a. a -> Maybe a
Just (Either String (Identity m) -> Maybe (Identity m))
-> (m (Stored (Signed IdentityData)) -> Either String (Identity m))
-> m (Stored (Signed IdentityData))
-> Maybe (Identity m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Except String (Identity m) -> Either String (Identity m)
forall e a. Except e a -> Either e a
runExcept (Except String (Identity m) -> Either String (Identity m))
-> (m (Stored (Signed IdentityData)) -> Except String (Identity m))
-> m (Stored (Signed IdentityData))
-> Either String (Identity m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m (Stored (Signed IdentityData)) -> Except String (Identity m)
forall (m :: * -> *).
IdentityKind m =>
m (Stored (Signed IdentityData)) -> Except String (Identity m)
validateIdentityFE

validateIdentityFE :: IdentityKind m => m (Stored (Signed IdentityData)) -> Except String (Identity m)
validateIdentityFE :: forall (m :: * -> *).
IdentityKind m =>
m (Stored (Signed IdentityData)) -> Except String (Identity m)
validateIdentityFE = m (Stored (Signed ExtendedIdentityData))
-> Except String (Identity m)
forall (m :: * -> *).
IdentityKind m =>
m (Stored (Signed ExtendedIdentityData))
-> Except String (Identity m)
validateExtendedIdentityFE (m (Stored (Signed ExtendedIdentityData))
 -> Except String (Identity m))
-> (m (Stored (Signed IdentityData))
    -> m (Stored (Signed ExtendedIdentityData)))
-> m (Stored (Signed IdentityData))
-> Except String (Identity m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Stored (Signed IdentityData)
 -> Stored (Signed ExtendedIdentityData))
-> m (Stored (Signed IdentityData))
-> m (Stored (Signed ExtendedIdentityData))
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Stored (Signed IdentityData)
-> Stored (Signed ExtendedIdentityData)
baseToExtended

validateExtendedIdentity :: Stored (Signed ExtendedIdentityData) -> Maybe UnifiedIdentity
validateExtendedIdentity :: Stored (Signed ExtendedIdentityData) -> Maybe UnifiedIdentity
validateExtendedIdentity = Identity (Stored (Signed ExtendedIdentityData))
-> Maybe UnifiedIdentity
forall (m :: * -> *).
IdentityKind m =>
m (Stored (Signed ExtendedIdentityData)) -> Maybe (Identity m)
validateExtendedIdentityF (Identity (Stored (Signed ExtendedIdentityData))
 -> Maybe UnifiedIdentity)
-> (Stored (Signed ExtendedIdentityData)
    -> Identity (Stored (Signed ExtendedIdentityData)))
-> Stored (Signed ExtendedIdentityData)
-> Maybe UnifiedIdentity
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Stored (Signed ExtendedIdentityData)
-> Identity (Stored (Signed ExtendedIdentityData))
forall a. a -> Identity a
I.Identity

validateExtendedIdentityF :: IdentityKind m => m (Stored (Signed ExtendedIdentityData)) -> Maybe (Identity m)
validateExtendedIdentityF :: forall (m :: * -> *).
IdentityKind m =>
m (Stored (Signed ExtendedIdentityData)) -> Maybe (Identity m)
validateExtendedIdentityF = (String -> Maybe (Identity m))
-> (Identity m -> Maybe (Identity m))
-> Either String (Identity m)
-> Maybe (Identity m)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Maybe (Identity m) -> String -> Maybe (Identity m)
forall a b. a -> b -> a
const Maybe (Identity m)
forall a. Maybe a
Nothing) Identity m -> Maybe (Identity m)
forall a. a -> Maybe a
Just (Either String (Identity m) -> Maybe (Identity m))
-> (m (Stored (Signed ExtendedIdentityData))
    -> Either String (Identity m))
-> m (Stored (Signed ExtendedIdentityData))
-> Maybe (Identity m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Except String (Identity m) -> Either String (Identity m)
forall e a. Except e a -> Either e a
runExcept (Except String (Identity m) -> Either String (Identity m))
-> (m (Stored (Signed ExtendedIdentityData))
    -> Except String (Identity m))
-> m (Stored (Signed ExtendedIdentityData))
-> Either String (Identity m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m (Stored (Signed ExtendedIdentityData))
-> Except String (Identity m)
forall (m :: * -> *).
IdentityKind m =>
m (Stored (Signed ExtendedIdentityData))
-> Except String (Identity m)
validateExtendedIdentityFE

validateExtendedIdentityFE :: IdentityKind m => m (Stored (Signed ExtendedIdentityData)) -> Except String (Identity m)
validateExtendedIdentityFE :: forall (m :: * -> *).
IdentityKind m =>
m (Stored (Signed ExtendedIdentityData))
-> Except String (Identity m)
validateExtendedIdentityFE m (Stored (Signed ExtendedIdentityData))
mdata = do
    let idata :: m (Stored (Signed ExtendedIdentityData))
idata = m (Stored (Signed ExtendedIdentityData))
-> m (Stored (Signed ExtendedIdentityData))
forall a. Storable a => m (Stored a) -> m (Stored a)
forall (f :: * -> *) a.
(IdentityKind f, Storable a) =>
f (Stored a) -> f (Stored a)
ikFilterAncestors m (Stored (Signed ExtendedIdentityData))
mdata
    Bool -> ExceptT String Identity () -> ExceptT String Identity ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (m (Stored (Signed ExtendedIdentityData)) -> Bool
forall a. m a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null m (Stored (Signed ExtendedIdentityData))
idata) (ExceptT String Identity () -> ExceptT String Identity ())
-> ExceptT String Identity () -> ExceptT String Identity ()
forall a b. (a -> b) -> a -> b
$ String -> ExceptT String Identity ()
forall a. String -> ExceptT String Identity a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError String
"null data"
    (Stored (Signed ExtendedIdentityData)
 -> ExceptT String Identity ())
-> Set (Stored (Signed ExtendedIdentityData))
-> ExceptT String Identity ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ Stored (Signed ExtendedIdentityData) -> ExceptT String Identity ()
verifySignatures (Set (Stored (Signed ExtendedIdentityData))
 -> ExceptT String Identity ())
-> Set (Stored (Signed ExtendedIdentityData))
-> ExceptT String Identity ()
forall a b. (a -> b) -> a -> b
$ Set (Stored (Signed ExtendedIdentityData))
-> [Stored (Signed ExtendedIdentityData)]
-> Set (Stored (Signed ExtendedIdentityData))
gatherPrevious Set (Stored (Signed ExtendedIdentityData))
forall a. Set a
S.empty ([Stored (Signed ExtendedIdentityData)]
 -> Set (Stored (Signed ExtendedIdentityData)))
-> [Stored (Signed ExtendedIdentityData)]
-> Set (Stored (Signed ExtendedIdentityData))
forall a b. (a -> b) -> a -> b
$ m (Stored (Signed ExtendedIdentityData))
-> [Stored (Signed ExtendedIdentityData)]
forall a. m a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList m (Stored (Signed ExtendedIdentityData))
idata
    m (Stored (Signed ExtendedIdentityData))
-> Maybe Text
-> Maybe ComposedIdentity
-> [Stored (Signed ExtendedIdentityData)]
-> Stored PublicKey
-> Stored PublicKey
-> Identity m
forall (m :: * -> *).
IdentityKind m =>
m (Stored (Signed ExtendedIdentityData))
-> Maybe Text
-> Maybe ComposedIdentity
-> [Stored (Signed ExtendedIdentityData)]
-> Stored PublicKey
-> Stored PublicKey
-> Identity m
Identity
        (m (Stored (Signed ExtendedIdentityData))
 -> Maybe Text
 -> Maybe ComposedIdentity
 -> [Stored (Signed ExtendedIdentityData)]
 -> Stored PublicKey
 -> Stored PublicKey
 -> Identity m)
-> ExceptT
     String Identity (m (Stored (Signed ExtendedIdentityData)))
-> ExceptT
     String
     Identity
     (Maybe Text
      -> Maybe ComposedIdentity
      -> [Stored (Signed ExtendedIdentityData)]
      -> Stored PublicKey
      -> Stored PublicKey
      -> Identity m)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (Stored (Signed ExtendedIdentityData))
-> ExceptT
     String Identity (m (Stored (Signed ExtendedIdentityData)))
forall a. a -> ExceptT String Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure m (Stored (Signed ExtendedIdentityData))
idata
        ExceptT
  String
  Identity
  (Maybe Text
   -> Maybe ComposedIdentity
   -> [Stored (Signed ExtendedIdentityData)]
   -> Stored PublicKey
   -> Stored PublicKey
   -> Identity m)
-> ExceptT String Identity (Maybe Text)
-> ExceptT
     String
     Identity
     (Maybe ComposedIdentity
      -> [Stored (Signed ExtendedIdentityData)]
      -> Stored PublicKey
      -> Stored PublicKey
      -> Identity m)
forall a b.
ExceptT String Identity (a -> b)
-> ExceptT String Identity a -> ExceptT String Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe Text -> ExceptT String Identity (Maybe Text)
forall a. a -> ExceptT String Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((ExtendedIdentityData -> Maybe Text)
-> m (Stored (Signed ExtendedIdentityData)) -> Maybe Text
forall a (m :: * -> *).
Foldable m =>
(ExtendedIdentityData -> Maybe a)
-> m (Stored (Signed ExtendedIdentityData)) -> Maybe a
lookupProperty ExtendedIdentityData -> Maybe Text
eiddName m (Stored (Signed ExtendedIdentityData))
idata)
        ExceptT
  String
  Identity
  (Maybe ComposedIdentity
   -> [Stored (Signed ExtendedIdentityData)]
   -> Stored PublicKey
   -> Stored PublicKey
   -> Identity m)
-> ExceptT String Identity (Maybe ComposedIdentity)
-> ExceptT
     String
     Identity
     ([Stored (Signed ExtendedIdentityData)]
      -> Stored PublicKey -> Stored PublicKey -> Identity m)
forall a b.
ExceptT String Identity (a -> b)
-> ExceptT String Identity a -> ExceptT String Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> case (ExtendedIdentityData
 -> Maybe (Stored (Signed ExtendedIdentityData)))
-> m (Stored (Signed ExtendedIdentityData))
-> Maybe (Stored (Signed ExtendedIdentityData))
forall a (m :: * -> *).
Foldable m =>
(ExtendedIdentityData -> Maybe a)
-> m (Stored (Signed ExtendedIdentityData)) -> Maybe a
lookupProperty ExtendedIdentityData
-> Maybe (Stored (Signed ExtendedIdentityData))
eiddOwner m (Stored (Signed ExtendedIdentityData))
idata of
                 Maybe (Stored (Signed ExtendedIdentityData))
Nothing    -> Maybe ComposedIdentity
-> ExceptT String Identity (Maybe ComposedIdentity)
forall a. a -> ExceptT String Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe ComposedIdentity
forall a. Maybe a
Nothing
                 Just Stored (Signed ExtendedIdentityData)
owner -> ComposedIdentity -> Maybe ComposedIdentity
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return (ComposedIdentity -> Maybe ComposedIdentity)
-> ExceptT String Identity ComposedIdentity
-> ExceptT String Identity (Maybe ComposedIdentity)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Stored (Signed ExtendedIdentityData)]
-> ExceptT String Identity ComposedIdentity
forall (m :: * -> *).
IdentityKind m =>
m (Stored (Signed ExtendedIdentityData))
-> Except String (Identity m)
validateExtendedIdentityFE [Stored (Signed ExtendedIdentityData)
owner]
        ExceptT
  String
  Identity
  ([Stored (Signed ExtendedIdentityData)]
   -> Stored PublicKey -> Stored PublicKey -> Identity m)
-> ExceptT String Identity [Stored (Signed ExtendedIdentityData)]
-> ExceptT
     String
     Identity
     (Stored PublicKey -> Stored PublicKey -> Identity m)
forall a b.
ExceptT String Identity (a -> b)
-> ExceptT String Identity a -> ExceptT String Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [Stored (Signed ExtendedIdentityData)]
-> ExceptT String Identity [Stored (Signed ExtendedIdentityData)]
forall a. a -> ExceptT String Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
        ExceptT
  String
  Identity
  (Stored PublicKey -> Stored PublicKey -> Identity m)
-> ExceptT String Identity (Stored PublicKey)
-> ExceptT String Identity (Stored PublicKey -> Identity m)
forall a b.
ExceptT String Identity (a -> b)
-> ExceptT String Identity a -> ExceptT String Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Stored PublicKey -> ExceptT String Identity (Stored PublicKey)
forall a. a -> ExceptT String Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ExtendedIdentityData -> Stored PublicKey
eiddKeyIdentity (ExtendedIdentityData -> Stored PublicKey)
-> ExtendedIdentityData -> Stored PublicKey
forall a b. (a -> b) -> a -> b
$ Stored (Signed ExtendedIdentityData) -> ExtendedIdentityData
forall a. Stored (Signed a) -> a
fromSigned (Stored (Signed ExtendedIdentityData) -> ExtendedIdentityData)
-> Stored (Signed ExtendedIdentityData) -> ExtendedIdentityData
forall a b. (a -> b) -> a -> b
$ m (Stored (Signed ExtendedIdentityData))
-> Stored (Signed ExtendedIdentityData)
forall a. Ord a => m a -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
minimum m (Stored (Signed ExtendedIdentityData))
idata)
        ExceptT String Identity (Stored PublicKey -> Identity m)
-> ExceptT String Identity (Stored PublicKey)
-> Except String (Identity m)
forall a b.
ExceptT String Identity (a -> b)
-> ExceptT String Identity a -> ExceptT String Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> case (ExtendedIdentityData -> Maybe (Stored PublicKey))
-> m (Stored (Signed ExtendedIdentityData))
-> Maybe (Stored PublicKey)
forall a (m :: * -> *).
Foldable m =>
(ExtendedIdentityData -> Maybe a)
-> m (Stored (Signed ExtendedIdentityData)) -> Maybe a
lookupProperty ExtendedIdentityData -> Maybe (Stored PublicKey)
eiddKeyMessage m (Stored (Signed ExtendedIdentityData))
idata of
                 Maybe (Stored PublicKey)
Nothing -> String -> ExceptT String Identity (Stored PublicKey)
forall a. String -> ExceptT String Identity a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError String
"no message key"
                 Just Stored PublicKey
mk -> Stored PublicKey -> ExceptT String Identity (Stored PublicKey)
forall a. a -> ExceptT String Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return Stored PublicKey
mk

loadIdentity :: String -> LoadRec ComposedIdentity
loadIdentity :: String -> LoadRec ComposedIdentity
loadIdentity String
name = LoadRec ComposedIdentity
-> (ComposedIdentity -> LoadRec ComposedIdentity)
-> Maybe ComposedIdentity
-> LoadRec ComposedIdentity
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String -> LoadRec ComposedIdentity
forall a. String -> LoadRec a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError String
"identity validation failed") ComposedIdentity -> LoadRec ComposedIdentity
forall a. a -> LoadRec a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe ComposedIdentity -> LoadRec ComposedIdentity)
-> ([Stored (Signed ExtendedIdentityData)]
    -> Maybe ComposedIdentity)
-> [Stored (Signed ExtendedIdentityData)]
-> LoadRec ComposedIdentity
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Stored (Signed ExtendedIdentityData)] -> Maybe ComposedIdentity
forall (m :: * -> *).
IdentityKind m =>
m (Stored (Signed ExtendedIdentityData)) -> Maybe (Identity m)
validateExtendedIdentityF ([Stored (Signed ExtendedIdentityData)]
 -> LoadRec ComposedIdentity)
-> LoadRec [Stored (Signed ExtendedIdentityData)]
-> LoadRec ComposedIdentity
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< String -> LoadRec [Stored (Signed ExtendedIdentityData)]
forall a. Storable a => String -> LoadRec [a]
loadRefs String
name

loadUnifiedIdentity :: String -> LoadRec UnifiedIdentity
loadUnifiedIdentity :: String -> LoadRec UnifiedIdentity
loadUnifiedIdentity String
name = LoadRec UnifiedIdentity
-> (UnifiedIdentity -> LoadRec UnifiedIdentity)
-> Maybe UnifiedIdentity
-> LoadRec UnifiedIdentity
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String -> LoadRec UnifiedIdentity
forall a. String -> LoadRec a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError String
"identity validation failed") UnifiedIdentity -> LoadRec UnifiedIdentity
forall a. a -> LoadRec a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe UnifiedIdentity -> LoadRec UnifiedIdentity)
-> (Stored (Signed ExtendedIdentityData) -> Maybe UnifiedIdentity)
-> Stored (Signed ExtendedIdentityData)
-> LoadRec UnifiedIdentity
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Stored (Signed ExtendedIdentityData) -> Maybe UnifiedIdentity
validateExtendedIdentity (Stored (Signed ExtendedIdentityData) -> LoadRec UnifiedIdentity)
-> LoadRec (Stored (Signed ExtendedIdentityData))
-> LoadRec UnifiedIdentity
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< String -> LoadRec (Stored (Signed ExtendedIdentityData))
forall a. Storable a => String -> LoadRec a
loadRef String
name


gatherPrevious :: Set (Stored (Signed ExtendedIdentityData)) -> [Stored (Signed ExtendedIdentityData)] -> Set (Stored (Signed ExtendedIdentityData))
gatherPrevious :: Set (Stored (Signed ExtendedIdentityData))
-> [Stored (Signed ExtendedIdentityData)]
-> Set (Stored (Signed ExtendedIdentityData))
gatherPrevious Set (Stored (Signed ExtendedIdentityData))
res (Stored (Signed ExtendedIdentityData)
n:[Stored (Signed ExtendedIdentityData)]
ns) | Stored (Signed ExtendedIdentityData)
n Stored (Signed ExtendedIdentityData)
-> Set (Stored (Signed ExtendedIdentityData)) -> Bool
forall a. Ord a => a -> Set a -> Bool
`S.member` Set (Stored (Signed ExtendedIdentityData))
res = Set (Stored (Signed ExtendedIdentityData))
-> [Stored (Signed ExtendedIdentityData)]
-> Set (Stored (Signed ExtendedIdentityData))
gatherPrevious Set (Stored (Signed ExtendedIdentityData))
res [Stored (Signed ExtendedIdentityData)]
ns
                          | Bool
otherwise        = Set (Stored (Signed ExtendedIdentityData))
-> [Stored (Signed ExtendedIdentityData)]
-> Set (Stored (Signed ExtendedIdentityData))
gatherPrevious (Stored (Signed ExtendedIdentityData)
-> Set (Stored (Signed ExtendedIdentityData))
-> Set (Stored (Signed ExtendedIdentityData))
forall a. Ord a => a -> Set a -> Set a
S.insert Stored (Signed ExtendedIdentityData)
n Set (Stored (Signed ExtendedIdentityData))
res) ([Stored (Signed ExtendedIdentityData)]
 -> Set (Stored (Signed ExtendedIdentityData)))
-> [Stored (Signed ExtendedIdentityData)]
-> Set (Stored (Signed ExtendedIdentityData))
forall a b. (a -> b) -> a -> b
$ (ExtendedIdentityData -> [Stored (Signed ExtendedIdentityData)]
eiddPrev (ExtendedIdentityData -> [Stored (Signed ExtendedIdentityData)])
-> ExtendedIdentityData -> [Stored (Signed ExtendedIdentityData)]
forall a b. (a -> b) -> a -> b
$ Stored (Signed ExtendedIdentityData) -> ExtendedIdentityData
forall a. Stored (Signed a) -> a
fromSigned Stored (Signed ExtendedIdentityData)
n) [Stored (Signed ExtendedIdentityData)]
-> [Stored (Signed ExtendedIdentityData)]
-> [Stored (Signed ExtendedIdentityData)]
forall a. [a] -> [a] -> [a]
++ [Stored (Signed ExtendedIdentityData)]
ns
gatherPrevious Set (Stored (Signed ExtendedIdentityData))
res [] = Set (Stored (Signed ExtendedIdentityData))
res

verifySignatures :: Stored (Signed ExtendedIdentityData) -> Except String ()
verifySignatures :: Stored (Signed ExtendedIdentityData) -> ExceptT String Identity ()
verifySignatures Stored (Signed ExtendedIdentityData)
sidd = do
    let idd :: ExtendedIdentityData
idd = Stored (Signed ExtendedIdentityData) -> ExtendedIdentityData
forall a. Stored (Signed a) -> a
fromSigned Stored (Signed ExtendedIdentityData)
sidd
        required :: [Stored PublicKey]
required = [[Stored PublicKey]] -> [Stored PublicKey]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
            [ [ ExtendedIdentityData -> Stored PublicKey
eiddKeyIdentity ExtendedIdentityData
idd ]
            , (Stored (Signed ExtendedIdentityData) -> Stored PublicKey)
-> [Stored (Signed ExtendedIdentityData)] -> [Stored PublicKey]
forall a b. (a -> b) -> [a] -> [b]
map (ExtendedIdentityData -> Stored PublicKey
eiddKeyIdentity (ExtendedIdentityData -> Stored PublicKey)
-> (Stored (Signed ExtendedIdentityData) -> ExtendedIdentityData)
-> Stored (Signed ExtendedIdentityData)
-> Stored PublicKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Stored (Signed ExtendedIdentityData) -> ExtendedIdentityData
forall a. Stored (Signed a) -> a
fromSigned) ([Stored (Signed ExtendedIdentityData)] -> [Stored PublicKey])
-> [Stored (Signed ExtendedIdentityData)] -> [Stored PublicKey]
forall a b. (a -> b) -> a -> b
$ ExtendedIdentityData -> [Stored (Signed ExtendedIdentityData)]
eiddPrev ExtendedIdentityData
idd
            , (Stored (Signed ExtendedIdentityData) -> Stored PublicKey)
-> [Stored (Signed ExtendedIdentityData)] -> [Stored PublicKey]
forall a b. (a -> b) -> [a] -> [b]
map (ExtendedIdentityData -> Stored PublicKey
eiddKeyIdentity (ExtendedIdentityData -> Stored PublicKey)
-> (Stored (Signed ExtendedIdentityData) -> ExtendedIdentityData)
-> Stored (Signed ExtendedIdentityData)
-> Stored PublicKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Stored (Signed ExtendedIdentityData) -> ExtendedIdentityData
forall a. Stored (Signed a) -> a
fromSigned) ([Stored (Signed ExtendedIdentityData)] -> [Stored PublicKey])
-> [Stored (Signed ExtendedIdentityData)] -> [Stored PublicKey]
forall a b. (a -> b) -> a -> b
$ Maybe (Stored (Signed ExtendedIdentityData))
-> [Stored (Signed ExtendedIdentityData)]
forall a. Maybe a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (Maybe (Stored (Signed ExtendedIdentityData))
 -> [Stored (Signed ExtendedIdentityData)])
-> Maybe (Stored (Signed ExtendedIdentityData))
-> [Stored (Signed ExtendedIdentityData)]
forall a b. (a -> b) -> a -> b
$ ExtendedIdentityData
-> Maybe (Stored (Signed ExtendedIdentityData))
eiddOwner ExtendedIdentityData
idd
            ]
    Bool -> ExceptT String Identity () -> ExceptT String Identity ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ((Stored PublicKey -> Bool) -> [Stored PublicKey] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Stored (Signed ExtendedIdentityData) -> Signed ExtendedIdentityData
forall a. Stored a -> a
fromStored Stored (Signed ExtendedIdentityData)
sidd Signed ExtendedIdentityData -> Stored PublicKey -> Bool
forall a. Signed a -> Stored PublicKey -> Bool
`isSignedBy`) [Stored PublicKey]
required) (ExceptT String Identity () -> ExceptT String Identity ())
-> ExceptT String Identity () -> ExceptT String Identity ()
forall a b. (a -> b) -> a -> b
$ do
        String -> ExceptT String Identity ()
forall a. String -> ExceptT String Identity a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError String
"signature verification failed"

lookupProperty :: forall a m. Foldable m => (ExtendedIdentityData -> Maybe a) -> m (Stored (Signed ExtendedIdentityData)) -> Maybe a
lookupProperty :: forall a (m :: * -> *).
Foldable m =>
(ExtendedIdentityData -> Maybe a)
-> m (Stored (Signed ExtendedIdentityData)) -> Maybe a
lookupProperty ExtendedIdentityData -> Maybe a
sel m (Stored (Signed ExtendedIdentityData))
topHeads = [[(Stored (Signed ExtendedIdentityData), a)]] -> Maybe a
forall {a} {a}. Ord a => [[(a, a)]] -> Maybe a
findResult [[(Stored (Signed ExtendedIdentityData), a)]]
filteredLayers
    where findPropHeads :: Stored (Signed ExtendedIdentityData) -> [(Stored (Signed ExtendedIdentityData), a)]
          findPropHeads :: Stored (Signed ExtendedIdentityData)
-> [(Stored (Signed ExtendedIdentityData), a)]
findPropHeads Stored (Signed ExtendedIdentityData)
sobj | Just a
x <- ExtendedIdentityData -> Maybe a
sel (ExtendedIdentityData -> Maybe a)
-> ExtendedIdentityData -> Maybe a
forall a b. (a -> b) -> a -> b
$ Stored (Signed ExtendedIdentityData) -> ExtendedIdentityData
forall a. Stored (Signed a) -> a
fromSigned Stored (Signed ExtendedIdentityData)
sobj = [(Stored (Signed ExtendedIdentityData)
sobj, a
x)]
                             | Bool
otherwise = Stored (Signed ExtendedIdentityData)
-> [(Stored (Signed ExtendedIdentityData), a)]
findPropHeads (Stored (Signed ExtendedIdentityData)
 -> [(Stored (Signed ExtendedIdentityData), a)])
-> [Stored (Signed ExtendedIdentityData)]
-> [(Stored (Signed ExtendedIdentityData), a)]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (ExtendedIdentityData -> [Stored (Signed ExtendedIdentityData)]
eiddPrev (ExtendedIdentityData -> [Stored (Signed ExtendedIdentityData)])
-> ExtendedIdentityData -> [Stored (Signed ExtendedIdentityData)]
forall a b. (a -> b) -> a -> b
$ Stored (Signed ExtendedIdentityData) -> ExtendedIdentityData
forall a. Stored (Signed a) -> a
fromSigned Stored (Signed ExtendedIdentityData)
sobj)

          propHeads :: [(Stored (Signed ExtendedIdentityData), a)]
          propHeads :: [(Stored (Signed ExtendedIdentityData), a)]
propHeads = Stored (Signed ExtendedIdentityData)
-> [(Stored (Signed ExtendedIdentityData), a)]
findPropHeads (Stored (Signed ExtendedIdentityData)
 -> [(Stored (Signed ExtendedIdentityData), a)])
-> [Stored (Signed ExtendedIdentityData)]
-> [(Stored (Signed ExtendedIdentityData), a)]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< m (Stored (Signed ExtendedIdentityData))
-> [Stored (Signed ExtendedIdentityData)]
forall a. m a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList m (Stored (Signed ExtendedIdentityData))
topHeads

          historyLayers :: [Set (Stored (Signed ExtendedIdentityData))]
          historyLayers :: [Set (Stored (Signed ExtendedIdentityData))]
historyLayers = [Stored (Signed ExtendedIdentityData)]
-> [Set (Stored (Signed ExtendedIdentityData))]
forall a. Storable a => [Stored a] -> [Set (Stored a)]
generations ([Stored (Signed ExtendedIdentityData)]
 -> [Set (Stored (Signed ExtendedIdentityData))])
-> [Stored (Signed ExtendedIdentityData)]
-> [Set (Stored (Signed ExtendedIdentityData))]
forall a b. (a -> b) -> a -> b
$ ((Stored (Signed ExtendedIdentityData), a)
 -> Stored (Signed ExtendedIdentityData))
-> [(Stored (Signed ExtendedIdentityData), a)]
-> [Stored (Signed ExtendedIdentityData)]
forall a b. (a -> b) -> [a] -> [b]
map (Stored (Signed ExtendedIdentityData), a)
-> Stored (Signed ExtendedIdentityData)
forall a b. (a, b) -> a
fst [(Stored (Signed ExtendedIdentityData), a)]
propHeads

          filteredLayers :: [[(Stored (Signed ExtendedIdentityData), a)]]
          filteredLayers :: [[(Stored (Signed ExtendedIdentityData), a)]]
filteredLayers = ([(Stored (Signed ExtendedIdentityData), a)]
 -> Set (Stored (Signed ExtendedIdentityData))
 -> [(Stored (Signed ExtendedIdentityData), a)])
-> [(Stored (Signed ExtendedIdentityData), a)]
-> [Set (Stored (Signed ExtendedIdentityData))]
-> [[(Stored (Signed ExtendedIdentityData), a)]]
forall b a. (b -> a -> b) -> b -> [a] -> [b]
scanl (\[(Stored (Signed ExtendedIdentityData), a)]
cur Set (Stored (Signed ExtendedIdentityData))
obsolete -> ((Stored (Signed ExtendedIdentityData), a) -> Bool)
-> [(Stored (Signed ExtendedIdentityData), a)]
-> [(Stored (Signed ExtendedIdentityData), a)]
forall a. (a -> Bool) -> [a] -> [a]
filter ((Stored (Signed ExtendedIdentityData)
-> Set (Stored (Signed ExtendedIdentityData)) -> Bool
forall a. Ord a => a -> Set a -> Bool
`S.notMember` Set (Stored (Signed ExtendedIdentityData))
obsolete) (Stored (Signed ExtendedIdentityData) -> Bool)
-> ((Stored (Signed ExtendedIdentityData), a)
    -> Stored (Signed ExtendedIdentityData))
-> (Stored (Signed ExtendedIdentityData), a)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Stored (Signed ExtendedIdentityData), a)
-> Stored (Signed ExtendedIdentityData)
forall a b. (a, b) -> a
fst) [(Stored (Signed ExtendedIdentityData), a)]
cur) [(Stored (Signed ExtendedIdentityData), a)]
propHeads [Set (Stored (Signed ExtendedIdentityData))]
historyLayers

          findResult :: [[(a, a)]] -> Maybe a
findResult ([(a
_, a
x)] : [[(a, a)]]
_) = a -> Maybe a
forall a. a -> Maybe a
Just a
x
          findResult ([] : [[(a, a)]]
_) = Maybe a
forall a. Maybe a
Nothing
          findResult [] = Maybe a
forall a. Maybe a
Nothing
          findResult [[(a, a)]
xs] = a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> a -> Maybe a
forall a b. (a -> b) -> a -> b
$ (a, a) -> a
forall a b. (a, b) -> b
snd ((a, a) -> a) -> (a, a) -> a
forall a b. (a -> b) -> a -> b
$ ((a, a) -> (a, a) -> Ordering) -> [(a, a)] -> (a, a)
forall (t :: * -> *) a.
Foldable t =>
(a -> a -> Ordering) -> t a -> a
minimumBy (((a, a) -> a) -> (a, a) -> (a, a) -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing (a, a) -> a
forall a b. (a, b) -> a
fst) [(a, a)]
xs
          findResult ([(a, a)]
_:[[(a, a)]]
rest) = [[(a, a)]] -> Maybe a
findResult [[(a, a)]]
rest

mergeIdentity :: (MonadStorage m, MonadError String m, MonadIO m) => Identity f -> m UnifiedIdentity
mergeIdentity :: forall (m :: * -> *) (f :: * -> *).
(MonadStorage m, MonadError String m, MonadIO m) =>
Identity f -> m UnifiedIdentity
mergeIdentity Identity f
idt | Just UnifiedIdentity
idt' <- Identity f -> Maybe UnifiedIdentity
forall (m :: * -> *). Identity m -> Maybe UnifiedIdentity
toUnifiedIdentity Identity f
idt = UnifiedIdentity -> m UnifiedIdentity
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return UnifiedIdentity
idt'
mergeIdentity idt :: Identity f
idt@Identity {f (Stored (Signed ExtendedIdentityData))
[Stored (Signed ExtendedIdentityData)]
Maybe Text
Maybe ComposedIdentity
Stored PublicKey
idData_ :: forall (m :: * -> *).
Identity m -> m (Stored (Signed ExtendedIdentityData))
idName_ :: forall (m :: * -> *). Identity m -> Maybe Text
idOwner_ :: forall (m :: * -> *). Identity m -> Maybe ComposedIdentity
idUpdates_ :: forall (m :: * -> *).
Identity m -> [Stored (Signed ExtendedIdentityData)]
idKeyIdentity_ :: forall (m :: * -> *). Identity m -> Stored PublicKey
idKeyMessage_ :: forall (m :: * -> *). Identity m -> Stored PublicKey
idData_ :: f (Stored (Signed ExtendedIdentityData))
idName_ :: Maybe Text
idOwner_ :: Maybe ComposedIdentity
idUpdates_ :: [Stored (Signed ExtendedIdentityData)]
idKeyIdentity_ :: Stored PublicKey
idKeyMessage_ :: Stored PublicKey
..} = do
    (Maybe UnifiedIdentity
owner, Maybe (Stored (Signed IdentityData))
ownerData) <- case Maybe ComposedIdentity
idOwner_ of
        Maybe ComposedIdentity
Nothing -> (Maybe UnifiedIdentity, Maybe (Stored (Signed IdentityData)))
-> m (Maybe UnifiedIdentity, Maybe (Stored (Signed IdentityData)))
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe UnifiedIdentity
forall a. Maybe a
Nothing, Maybe (Stored (Signed IdentityData))
forall a. Maybe a
Nothing)
        Just ComposedIdentity
cowner | Just UnifiedIdentity
owner <- ComposedIdentity -> Maybe UnifiedIdentity
forall (m :: * -> *). Identity m -> Maybe UnifiedIdentity
toUnifiedIdentity ComposedIdentity
cowner -> (Maybe UnifiedIdentity, Maybe (Stored (Signed IdentityData)))
-> m (Maybe UnifiedIdentity, Maybe (Stored (Signed IdentityData)))
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (UnifiedIdentity -> Maybe UnifiedIdentity
forall a. a -> Maybe a
Just UnifiedIdentity
owner, Maybe (Stored (Signed IdentityData))
forall a. Maybe a
Nothing)
                    | Bool
otherwise -> do UnifiedIdentity
owner <- ComposedIdentity -> m UnifiedIdentity
forall (m :: * -> *) (f :: * -> *).
(MonadStorage m, MonadError String m, MonadIO m) =>
Identity f -> m UnifiedIdentity
mergeIdentity ComposedIdentity
cowner
                                      (Maybe UnifiedIdentity, Maybe (Stored (Signed IdentityData)))
-> m (Maybe UnifiedIdentity, Maybe (Stored (Signed IdentityData)))
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (UnifiedIdentity -> Maybe UnifiedIdentity
forall a. a -> Maybe a
Just UnifiedIdentity
owner, Stored (Signed IdentityData)
-> Maybe (Stored (Signed IdentityData))
forall a. a -> Maybe a
Just (Stored (Signed IdentityData)
 -> Maybe (Stored (Signed IdentityData)))
-> Stored (Signed IdentityData)
-> Maybe (Stored (Signed IdentityData))
forall a b. (a -> b) -> a -> b
$ UnifiedIdentity -> Stored (Signed IdentityData)
idData UnifiedIdentity
owner)

    let public :: Stored PublicKey
public = Identity f -> Stored PublicKey
forall (m :: * -> *). Identity m -> Stored PublicKey
idKeyIdentity Identity f
idt
    SecretKey
secret <- Stored PublicKey -> m SecretKey
forall sec pub (m :: * -> *).
(KeyPair sec pub, MonadIO m, MonadError String m) =>
Stored pub -> m sec
loadKey Stored PublicKey
public

    Stored (Signed IdentityData)
unifiedBaseData <-
        case f (Stored (Signed IdentityData)) -> [Stored (Signed IdentityData)]
forall a. f a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (f (Stored (Signed IdentityData))
 -> [Stored (Signed IdentityData)])
-> f (Stored (Signed IdentityData))
-> [Stored (Signed IdentityData)]
forall a b. (a -> b) -> a -> b
$ Identity f -> f (Stored (Signed IdentityData))
forall (m :: * -> *).
Identity m -> m (Stored (Signed IdentityData))
idDataF Identity f
idt of
            [Stored (Signed IdentityData)
idata] -> Stored (Signed IdentityData) -> m (Stored (Signed IdentityData))
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Stored (Signed IdentityData)
idata
            [Stored (Signed IdentityData)]
idatas -> Signed IdentityData -> m (Stored (Signed IdentityData))
forall a. Storable a => a -> m (Stored a)
forall (m :: * -> *) a.
(MonadStorage m, Storable a) =>
a -> m (Stored a)
mstore (Signed IdentityData -> m (Stored (Signed IdentityData)))
-> m (Signed IdentityData) -> m (Stored (Signed IdentityData))
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< SecretKey -> Stored IdentityData -> m (Signed IdentityData)
forall (m :: * -> *) a.
MonadStorage m =>
SecretKey -> Stored a -> m (Signed a)
sign SecretKey
secret (Stored IdentityData -> m (Signed IdentityData))
-> m (Stored IdentityData) -> m (Signed IdentityData)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IdentityData -> m (Stored IdentityData)
forall a. Storable a => a -> m (Stored a)
forall (m :: * -> *) a.
(MonadStorage m, Storable a) =>
a -> m (Stored a)
mstore (Stored PublicKey -> IdentityData
emptyIdentityData Stored PublicKey
public)
                { iddPrev = idatas, iddOwner = ownerData }

    case (Stored (Signed ExtendedIdentityData) -> Bool)
-> [Stored (Signed ExtendedIdentityData)]
-> [Stored (Signed ExtendedIdentityData)]
forall a. (a -> Bool) -> [a] -> [a]
filter Stored (Signed ExtendedIdentityData) -> Bool
isExtension ([Stored (Signed ExtendedIdentityData)]
 -> [Stored (Signed ExtendedIdentityData)])
-> [Stored (Signed ExtendedIdentityData)]
-> [Stored (Signed ExtendedIdentityData)]
forall a b. (a -> b) -> a -> b
$ f (Stored (Signed ExtendedIdentityData))
-> [Stored (Signed ExtendedIdentityData)]
forall a. f a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (f (Stored (Signed ExtendedIdentityData))
 -> [Stored (Signed ExtendedIdentityData)])
-> f (Stored (Signed ExtendedIdentityData))
-> [Stored (Signed ExtendedIdentityData)]
forall a b. (a -> b) -> a -> b
$ Identity f -> f (Stored (Signed ExtendedIdentityData))
forall (m :: * -> *).
Identity m -> m (Stored (Signed ExtendedIdentityData))
idExtDataF Identity f
idt of
        [] -> UnifiedIdentity -> m UnifiedIdentity
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Identity { idData_ :: Identity (Stored (Signed ExtendedIdentityData))
idData_ = Stored (Signed ExtendedIdentityData)
-> Identity (Stored (Signed ExtendedIdentityData))
forall a. a -> Identity a
I.Identity (Stored (Signed IdentityData)
-> Stored (Signed ExtendedIdentityData)
baseToExtended Stored (Signed IdentityData)
unifiedBaseData), idOwner_ :: Maybe ComposedIdentity
idOwner_ = UnifiedIdentity -> ComposedIdentity
forall (m :: * -> *). Identity m -> ComposedIdentity
toComposedIdentity (UnifiedIdentity -> ComposedIdentity)
-> Maybe UnifiedIdentity -> Maybe ComposedIdentity
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe UnifiedIdentity
owner, [Stored (Signed ExtendedIdentityData)]
Maybe Text
Stored PublicKey
idName_ :: Maybe Text
idUpdates_ :: [Stored (Signed ExtendedIdentityData)]
idKeyIdentity_ :: Stored PublicKey
idKeyMessage_ :: Stored PublicKey
idName_ :: Maybe Text
idUpdates_ :: [Stored (Signed ExtendedIdentityData)]
idKeyIdentity_ :: Stored PublicKey
idKeyMessage_ :: Stored PublicKey
.. }
        [Stored (Signed ExtendedIdentityData)]
extdata -> do
            Stored (Signed ExtendedIdentityData)
unifiedExtendedData <- Signed ExtendedIdentityData
-> m (Stored (Signed ExtendedIdentityData))
forall a. Storable a => a -> m (Stored a)
forall (m :: * -> *) a.
(MonadStorage m, Storable a) =>
a -> m (Stored a)
mstore (Signed ExtendedIdentityData
 -> m (Stored (Signed ExtendedIdentityData)))
-> m (Signed ExtendedIdentityData)
-> m (Stored (Signed ExtendedIdentityData))
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< SecretKey
-> Stored ExtendedIdentityData -> m (Signed ExtendedIdentityData)
forall (m :: * -> *) a.
MonadStorage m =>
SecretKey -> Stored a -> m (Signed a)
sign SecretKey
secret (Stored ExtendedIdentityData -> m (Signed ExtendedIdentityData))
-> m (Stored ExtendedIdentityData)
-> m (Signed ExtendedIdentityData)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
                (ExtendedIdentityData -> m (Stored ExtendedIdentityData)
forall a. Storable a => a -> m (Stored a)
forall (m :: * -> *) a.
(MonadStorage m, Storable a) =>
a -> m (Stored a)
mstore (ExtendedIdentityData -> m (Stored ExtendedIdentityData))
-> (IdentityExtension -> ExtendedIdentityData)
-> IdentityExtension
-> m (Stored ExtendedIdentityData)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IdentityExtension -> ExtendedIdentityData
ExtendedIdentityData) (Stored (Signed IdentityData) -> IdentityExtension
emptyIdentityExtension Stored (Signed IdentityData)
unifiedBaseData)
                    { idePrev = extdata }
            UnifiedIdentity -> m UnifiedIdentity
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Identity { idData_ :: Identity (Stored (Signed ExtendedIdentityData))
idData_ = Stored (Signed ExtendedIdentityData)
-> Identity (Stored (Signed ExtendedIdentityData))
forall a. a -> Identity a
I.Identity Stored (Signed ExtendedIdentityData)
unifiedExtendedData, idOwner_ :: Maybe ComposedIdentity
idOwner_ = UnifiedIdentity -> ComposedIdentity
forall (m :: * -> *). Identity m -> ComposedIdentity
toComposedIdentity (UnifiedIdentity -> ComposedIdentity)
-> Maybe UnifiedIdentity -> Maybe ComposedIdentity
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe UnifiedIdentity
owner, [Stored (Signed ExtendedIdentityData)]
Maybe Text
Stored PublicKey
idName_ :: Maybe Text
idUpdates_ :: [Stored (Signed ExtendedIdentityData)]
idKeyIdentity_ :: Stored PublicKey
idKeyMessage_ :: Stored PublicKey
idName_ :: Maybe Text
idUpdates_ :: [Stored (Signed ExtendedIdentityData)]
idKeyIdentity_ :: Stored PublicKey
idKeyMessage_ :: Stored PublicKey
.. }


toUnifiedIdentity :: Identity m -> Maybe UnifiedIdentity
toUnifiedIdentity :: forall (m :: * -> *). Identity m -> Maybe UnifiedIdentity
toUnifiedIdentity Identity {m (Stored (Signed ExtendedIdentityData))
[Stored (Signed ExtendedIdentityData)]
Maybe Text
Maybe ComposedIdentity
Stored PublicKey
idData_ :: forall (m :: * -> *).
Identity m -> m (Stored (Signed ExtendedIdentityData))
idName_ :: forall (m :: * -> *). Identity m -> Maybe Text
idOwner_ :: forall (m :: * -> *). Identity m -> Maybe ComposedIdentity
idUpdates_ :: forall (m :: * -> *).
Identity m -> [Stored (Signed ExtendedIdentityData)]
idKeyIdentity_ :: forall (m :: * -> *). Identity m -> Stored PublicKey
idKeyMessage_ :: forall (m :: * -> *). Identity m -> Stored PublicKey
idData_ :: m (Stored (Signed ExtendedIdentityData))
idName_ :: Maybe Text
idOwner_ :: Maybe ComposedIdentity
idUpdates_ :: [Stored (Signed ExtendedIdentityData)]
idKeyIdentity_ :: Stored PublicKey
idKeyMessage_ :: Stored PublicKey
..}
    | [Stored (Signed ExtendedIdentityData)
sdata] <- m (Stored (Signed ExtendedIdentityData))
-> [Stored (Signed ExtendedIdentityData)]
forall a. m a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList m (Stored (Signed ExtendedIdentityData))
idData_ = UnifiedIdentity -> Maybe UnifiedIdentity
forall a. a -> Maybe a
Just Identity { idData_ :: Identity (Stored (Signed ExtendedIdentityData))
idData_ = Stored (Signed ExtendedIdentityData)
-> Identity (Stored (Signed ExtendedIdentityData))
forall a. a -> Identity a
I.Identity Stored (Signed ExtendedIdentityData)
sdata, [Stored (Signed ExtendedIdentityData)]
Maybe Text
Maybe ComposedIdentity
Stored PublicKey
idName_ :: Maybe Text
idOwner_ :: Maybe ComposedIdentity
idUpdates_ :: [Stored (Signed ExtendedIdentityData)]
idKeyIdentity_ :: Stored PublicKey
idKeyMessage_ :: Stored PublicKey
idName_ :: Maybe Text
idOwner_ :: Maybe ComposedIdentity
idUpdates_ :: [Stored (Signed ExtendedIdentityData)]
idKeyIdentity_ :: Stored PublicKey
idKeyMessage_ :: Stored PublicKey
.. }
    | Bool
otherwise = Maybe UnifiedIdentity
forall a. Maybe a
Nothing

toComposedIdentity :: Identity m -> ComposedIdentity
toComposedIdentity :: forall (m :: * -> *). Identity m -> ComposedIdentity
toComposedIdentity Identity {m (Stored (Signed ExtendedIdentityData))
[Stored (Signed ExtendedIdentityData)]
Maybe Text
Maybe ComposedIdentity
Stored PublicKey
idData_ :: forall (m :: * -> *).
Identity m -> m (Stored (Signed ExtendedIdentityData))
idName_ :: forall (m :: * -> *). Identity m -> Maybe Text
idOwner_ :: forall (m :: * -> *). Identity m -> Maybe ComposedIdentity
idUpdates_ :: forall (m :: * -> *).
Identity m -> [Stored (Signed ExtendedIdentityData)]
idKeyIdentity_ :: forall (m :: * -> *). Identity m -> Stored PublicKey
idKeyMessage_ :: forall (m :: * -> *). Identity m -> Stored PublicKey
idData_ :: m (Stored (Signed ExtendedIdentityData))
idName_ :: Maybe Text
idOwner_ :: Maybe ComposedIdentity
idUpdates_ :: [Stored (Signed ExtendedIdentityData)]
idKeyIdentity_ :: Stored PublicKey
idKeyMessage_ :: Stored PublicKey
..} = Identity { idData_ :: [Stored (Signed ExtendedIdentityData)]
idData_ = m (Stored (Signed ExtendedIdentityData))
-> [Stored (Signed ExtendedIdentityData)]
forall a. m a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList m (Stored (Signed ExtendedIdentityData))
idData_
                                            , idOwner_ :: Maybe ComposedIdentity
idOwner_ = ComposedIdentity -> ComposedIdentity
forall (m :: * -> *). Identity m -> ComposedIdentity
toComposedIdentity (ComposedIdentity -> ComposedIdentity)
-> Maybe ComposedIdentity -> Maybe ComposedIdentity
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe ComposedIdentity
idOwner_
                                            , [Stored (Signed ExtendedIdentityData)]
Maybe Text
Stored PublicKey
idName_ :: Maybe Text
idUpdates_ :: [Stored (Signed ExtendedIdentityData)]
idKeyIdentity_ :: Stored PublicKey
idKeyMessage_ :: Stored PublicKey
idName_ :: Maybe Text
idUpdates_ :: [Stored (Signed ExtendedIdentityData)]
idKeyIdentity_ :: Stored PublicKey
idKeyMessage_ :: Stored PublicKey
..
                                            }

updateIdentity :: [Stored (Signed ExtendedIdentityData)] -> Identity m -> ComposedIdentity
updateIdentity :: forall (m :: * -> *).
[Stored (Signed ExtendedIdentityData)]
-> Identity m -> ComposedIdentity
updateIdentity [] Identity m
orig = Identity m -> ComposedIdentity
forall (m :: * -> *). Identity m -> ComposedIdentity
toComposedIdentity Identity m
orig
updateIdentity [Stored (Signed ExtendedIdentityData)]
updates orig :: Identity m
orig@Identity {} =
    case [Stored (Signed ExtendedIdentityData)] -> Maybe ComposedIdentity
forall (m :: * -> *).
IdentityKind m =>
m (Stored (Signed ExtendedIdentityData)) -> Maybe (Identity m)
validateExtendedIdentityF ([Stored (Signed ExtendedIdentityData)] -> Maybe ComposedIdentity)
-> [Stored (Signed ExtendedIdentityData)] -> Maybe ComposedIdentity
forall a b. (a -> b) -> a -> b
$ [Stored (Signed ExtendedIdentityData)]
ourUpdates [Stored (Signed ExtendedIdentityData)]
-> [Stored (Signed ExtendedIdentityData)]
-> [Stored (Signed ExtendedIdentityData)]
forall a. [a] -> [a] -> [a]
++ [Stored (Signed ExtendedIdentityData)]
idata of
         Just ComposedIdentity
updated -> ComposedIdentity
updated
             { idOwner_ = updateIdentity ownerUpdates <$> idOwner_ updated
             , idUpdates_ = ownerUpdates
             }
         Maybe ComposedIdentity
Nothing -> Identity m -> ComposedIdentity
forall (m :: * -> *). Identity m -> ComposedIdentity
toComposedIdentity Identity m
orig
    where idata :: [Stored (Signed ExtendedIdentityData)]
idata = m (Stored (Signed ExtendedIdentityData))
-> [Stored (Signed ExtendedIdentityData)]
forall a. m a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (m (Stored (Signed ExtendedIdentityData))
 -> [Stored (Signed ExtendedIdentityData)])
-> m (Stored (Signed ExtendedIdentityData))
-> [Stored (Signed ExtendedIdentityData)]
forall a b. (a -> b) -> a -> b
$ Identity m -> m (Stored (Signed ExtendedIdentityData))
forall (m :: * -> *).
Identity m -> m (Stored (Signed ExtendedIdentityData))
idData_ Identity m
orig
          idataRoots :: [Stored (Signed ExtendedIdentityData)]
idataRoots = ([Stored (Signed ExtendedIdentityData)]
 -> [Stored (Signed ExtendedIdentityData)]
 -> [Stored (Signed ExtendedIdentityData)])
-> [Stored (Signed ExtendedIdentityData)]
-> [[Stored (Signed ExtendedIdentityData)]]
-> [Stored (Signed ExtendedIdentityData)]
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' [Stored (Signed ExtendedIdentityData)]
-> [Stored (Signed ExtendedIdentityData)]
-> [Stored (Signed ExtendedIdentityData)]
forall a. Ord a => [a] -> [a] -> [a]
mergeUniq [] ([[Stored (Signed ExtendedIdentityData)]]
 -> [Stored (Signed ExtendedIdentityData)])
-> [[Stored (Signed ExtendedIdentityData)]]
-> [Stored (Signed ExtendedIdentityData)]
forall a b. (a -> b) -> a -> b
$ (Stored (Signed ExtendedIdentityData)
 -> [Stored (Signed ExtendedIdentityData)])
-> [Stored (Signed ExtendedIdentityData)]
-> [[Stored (Signed ExtendedIdentityData)]]
forall a b. (a -> b) -> [a] -> [b]
map Stored (Signed ExtendedIdentityData)
-> [Stored (Signed ExtendedIdentityData)]
forall a. Storable a => Stored a -> [Stored a]
storedRoots [Stored (Signed ExtendedIdentityData)]
idata
          ([Stored (Signed ExtendedIdentityData)]
ourUpdates, [Stored (Signed ExtendedIdentityData)]
ownerUpdates) = [Either
   (Stored (Signed ExtendedIdentityData))
   (Stored (Signed ExtendedIdentityData))]
-> ([Stored (Signed ExtendedIdentityData)],
    [Stored (Signed ExtendedIdentityData)])
forall a b. [Either a b] -> ([a], [b])
partitionEithers ([Either
    (Stored (Signed ExtendedIdentityData))
    (Stored (Signed ExtendedIdentityData))]
 -> ([Stored (Signed ExtendedIdentityData)],
     [Stored (Signed ExtendedIdentityData)]))
-> [Either
      (Stored (Signed ExtendedIdentityData))
      (Stored (Signed ExtendedIdentityData))]
-> ([Stored (Signed ExtendedIdentityData)],
    [Stored (Signed ExtendedIdentityData)])
forall a b. (a -> b) -> a -> b
$ ((Stored (Signed ExtendedIdentityData)
  -> Either
       (Stored (Signed ExtendedIdentityData))
       (Stored (Signed ExtendedIdentityData)))
 -> [Stored (Signed ExtendedIdentityData)]
 -> [Either
       (Stored (Signed ExtendedIdentityData))
       (Stored (Signed ExtendedIdentityData))])
-> [Stored (Signed ExtendedIdentityData)]
-> (Stored (Signed ExtendedIdentityData)
    -> Either
         (Stored (Signed ExtendedIdentityData))
         (Stored (Signed ExtendedIdentityData)))
-> [Either
      (Stored (Signed ExtendedIdentityData))
      (Stored (Signed ExtendedIdentityData))]
forall a b c. (a -> b -> c) -> b -> a -> c
flip (Stored (Signed ExtendedIdentityData)
 -> Either
      (Stored (Signed ExtendedIdentityData))
      (Stored (Signed ExtendedIdentityData)))
-> [Stored (Signed ExtendedIdentityData)]
-> [Either
      (Stored (Signed ExtendedIdentityData))
      (Stored (Signed ExtendedIdentityData))]
forall a b. (a -> b) -> [a] -> [b]
map ([Stored (Signed ExtendedIdentityData)]
-> [Stored (Signed ExtendedIdentityData)]
forall a. Storable a => [Stored a] -> [Stored a]
filterAncestors ([Stored (Signed ExtendedIdentityData)]
 -> [Stored (Signed ExtendedIdentityData)])
-> [Stored (Signed ExtendedIdentityData)]
-> [Stored (Signed ExtendedIdentityData)]
forall a b. (a -> b) -> a -> b
$ [Stored (Signed ExtendedIdentityData)]
updates [Stored (Signed ExtendedIdentityData)]
-> [Stored (Signed ExtendedIdentityData)]
-> [Stored (Signed ExtendedIdentityData)]
forall a. [a] -> [a] -> [a]
++ Identity m -> [Stored (Signed ExtendedIdentityData)]
forall (m :: * -> *).
Identity m -> [Stored (Signed ExtendedIdentityData)]
idUpdates_ Identity m
orig) ((Stored (Signed ExtendedIdentityData)
  -> Either
       (Stored (Signed ExtendedIdentityData))
       (Stored (Signed ExtendedIdentityData)))
 -> [Either
       (Stored (Signed ExtendedIdentityData))
       (Stored (Signed ExtendedIdentityData))])
-> (Stored (Signed ExtendedIdentityData)
    -> Either
         (Stored (Signed ExtendedIdentityData))
         (Stored (Signed ExtendedIdentityData)))
-> [Either
      (Stored (Signed ExtendedIdentityData))
      (Stored (Signed ExtendedIdentityData))]
forall a b. (a -> b) -> a -> b
$
              -- if an update is related to anything in idData_, use it here, otherwise push to owners
              \Stored (Signed ExtendedIdentityData)
u -> if Stored (Signed ExtendedIdentityData)
-> [Stored (Signed ExtendedIdentityData)]
forall a. Storable a => Stored a -> [Stored a]
storedRoots Stored (Signed ExtendedIdentityData)
u [Stored (Signed ExtendedIdentityData)]
-> [Stored (Signed ExtendedIdentityData)] -> Bool
forall a. Ord a => [a] -> [a] -> Bool
`intersectsSorted` [Stored (Signed ExtendedIdentityData)]
idataRoots
                       then Stored (Signed ExtendedIdentityData)
-> Either
     (Stored (Signed ExtendedIdentityData))
     (Stored (Signed ExtendedIdentityData))
forall a b. a -> Either a b
Left Stored (Signed ExtendedIdentityData)
u
                       else Stored (Signed ExtendedIdentityData)
-> Either
     (Stored (Signed ExtendedIdentityData))
     (Stored (Signed ExtendedIdentityData))
forall a b. b -> Either a b
Right Stored (Signed ExtendedIdentityData)
u

updateOwners :: [Stored (Signed ExtendedIdentityData)] -> Identity m -> Identity m
updateOwners :: forall (m :: * -> *).
[Stored (Signed ExtendedIdentityData)] -> Identity m -> Identity m
updateOwners [Stored (Signed ExtendedIdentityData)]
updates orig :: Identity m
orig@Identity { idOwner_ :: forall (m :: * -> *). Identity m -> Maybe ComposedIdentity
idOwner_ = Just ComposedIdentity
owner, idUpdates_ :: forall (m :: * -> *).
Identity m -> [Stored (Signed ExtendedIdentityData)]
idUpdates_ = [Stored (Signed ExtendedIdentityData)]
cupdates } =
    Identity m
orig { idOwner_ = Just $ updateIdentity updates owner, idUpdates_ = filterAncestors (updates ++ cupdates) }
updateOwners [Stored (Signed ExtendedIdentityData)]
_ orig :: Identity m
orig@Identity { idOwner_ :: forall (m :: * -> *). Identity m -> Maybe ComposedIdentity
idOwner_ = Maybe ComposedIdentity
Nothing } = Identity m
orig

sameIdentity :: (Foldable m, Foldable m') => Identity m -> Identity m' -> Bool
sameIdentity :: forall (m :: * -> *) (m' :: * -> *).
(Foldable m, Foldable m') =>
Identity m -> Identity m' -> Bool
sameIdentity Identity m
x Identity m'
y = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Set (Stored (Signed IdentityData)) -> Bool
forall a. Set a -> Bool
S.null (Set (Stored (Signed IdentityData)) -> Bool)
-> Set (Stored (Signed IdentityData)) -> Bool
forall a b. (a -> b) -> a -> b
$ Set (Stored (Signed IdentityData))
-> Set (Stored (Signed IdentityData))
-> Set (Stored (Signed IdentityData))
forall a. Ord a => Set a -> Set a -> Set a
S.intersection (Identity m -> Set (Stored (Signed IdentityData))
forall {t :: * -> *}.
Foldable t =>
Identity t -> Set (Stored (Signed IdentityData))
refset Identity m
x) (Identity m' -> Set (Stored (Signed IdentityData))
forall {t :: * -> *}.
Foldable t =>
Identity t -> Set (Stored (Signed IdentityData))
refset Identity m'
y)
    where refset :: Identity t -> Set (Stored (Signed IdentityData))
refset Identity t
idt = (Stored (Signed IdentityData)
 -> Set (Stored (Signed IdentityData))
 -> Set (Stored (Signed IdentityData)))
-> Set (Stored (Signed IdentityData))
-> t (Stored (Signed IdentityData))
-> Set (Stored (Signed IdentityData))
forall a b. (a -> b -> b) -> b -> t a -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Stored (Signed IdentityData)
-> Set (Stored (Signed IdentityData))
-> Set (Stored (Signed IdentityData))
forall a. Ord a => a -> Set a -> Set a
S.insert ([Stored (Signed IdentityData)]
-> Set (Stored (Signed IdentityData))
forall a. Storable a => [Stored a] -> Set (Stored a)
ancestors ([Stored (Signed IdentityData)]
 -> Set (Stored (Signed IdentityData)))
-> [Stored (Signed IdentityData)]
-> Set (Stored (Signed IdentityData))
forall a b. (a -> b) -> a -> b
$ t (Stored (Signed IdentityData)) -> [Stored (Signed IdentityData)]
forall a. t a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (t (Stored (Signed IdentityData))
 -> [Stored (Signed IdentityData)])
-> t (Stored (Signed IdentityData))
-> [Stored (Signed IdentityData)]
forall a b. (a -> b) -> a -> b
$ Identity t -> t (Stored (Signed IdentityData))
forall (m :: * -> *).
Identity m -> m (Stored (Signed IdentityData))
idDataF Identity t
idt) (Identity t -> t (Stored (Signed IdentityData))
forall (m :: * -> *).
Identity m -> m (Stored (Signed IdentityData))
idDataF Identity t
idt)


unfoldOwners :: (Foldable m) => Identity m -> [ComposedIdentity]
unfoldOwners :: forall (m :: * -> *).
Foldable m =>
Identity m -> [ComposedIdentity]
unfoldOwners = (Maybe ComposedIdentity
 -> Maybe (ComposedIdentity, Maybe ComposedIdentity))
-> Maybe ComposedIdentity -> [ComposedIdentity]
forall b a. (b -> Maybe (a, b)) -> b -> [a]
unfoldr ((ComposedIdentity -> (ComposedIdentity, Maybe ComposedIdentity))
-> Maybe ComposedIdentity
-> Maybe (ComposedIdentity, Maybe ComposedIdentity)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\ComposedIdentity
i -> (ComposedIdentity
i, ComposedIdentity -> Maybe ComposedIdentity
forall (m :: * -> *). Identity m -> Maybe ComposedIdentity
idOwner ComposedIdentity
i))) (Maybe ComposedIdentity -> [ComposedIdentity])
-> (Identity m -> Maybe ComposedIdentity)
-> Identity m
-> [ComposedIdentity]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ComposedIdentity -> Maybe ComposedIdentity
forall a. a -> Maybe a
Just (ComposedIdentity -> Maybe ComposedIdentity)
-> (Identity m -> ComposedIdentity)
-> Identity m
-> Maybe ComposedIdentity
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Identity m -> ComposedIdentity
forall (m :: * -> *). Identity m -> ComposedIdentity
toComposedIdentity

finalOwner :: (Foldable m, Applicative m) => Identity m -> ComposedIdentity
finalOwner :: forall (m :: * -> *).
(Foldable m, Applicative m) =>
Identity m -> ComposedIdentity
finalOwner = [ComposedIdentity] -> ComposedIdentity
forall a. HasCallStack => [a] -> a
last ([ComposedIdentity] -> ComposedIdentity)
-> (Identity m -> [ComposedIdentity])
-> Identity m
-> ComposedIdentity
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Identity m -> [ComposedIdentity]
forall (m :: * -> *).
Foldable m =>
Identity m -> [ComposedIdentity]
unfoldOwners

displayIdentity :: (Foldable m, Applicative m) => Identity m -> Text
displayIdentity :: forall (m :: * -> *).
(Foldable m, Applicative m) =>
Identity m -> Text
displayIdentity Identity m
identity = [Text] -> Text
T.concat
    [ Text -> [Text] -> Text
T.intercalate (String -> Text
T.pack String
" / ") ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ (ComposedIdentity -> Text) -> [ComposedIdentity] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (Text -> Maybe Text -> Text
forall a. a -> Maybe a -> a
fromMaybe (String -> Text
T.pack String
"<unnamed>") (Maybe Text -> Text)
-> (ComposedIdentity -> Maybe Text) -> ComposedIdentity -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ComposedIdentity -> Maybe Text
forall (m :: * -> *). Identity m -> Maybe Text
idName) [ComposedIdentity]
owners
    ]
    where owners :: [ComposedIdentity]
owners = [ComposedIdentity] -> [ComposedIdentity]
forall a. [a] -> [a]
reverse ([ComposedIdentity] -> [ComposedIdentity])
-> [ComposedIdentity] -> [ComposedIdentity]
forall a b. (a -> b) -> a -> b
$ Identity m -> [ComposedIdentity]
forall (m :: * -> *).
Foldable m =>
Identity m -> [ComposedIdentity]
unfoldOwners Identity m
identity