diff options
author | Joe Crayne <joe@jerkface.net> | 2019-07-13 21:18:22 -0400 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2019-07-13 21:18:22 -0400 |
commit | 3f29bdc88a068ec3eab91a8bac12757e3a106ceb (patch) | |
tree | 09507dcfed5524694a2280fd11fb607023f7ce8b /lib/KeyDB.hs | |
parent | cc6775a52107f5425d668a4831f475d05dc113b5 (diff) |
Finished encapsulation of KeyDB.
Diffstat (limited to 'lib/KeyDB.hs')
-rw-r--r-- | lib/KeyDB.hs | 110 |
1 files changed, 107 insertions, 3 deletions
diff --git a/lib/KeyDB.hs b/lib/KeyDB.hs index f5a4357..1f0849c 100644 --- a/lib/KeyDB.hs +++ b/lib/KeyDB.hs | |||
@@ -1,5 +1,4 @@ | |||
1 | module KeyDB | 1 | module KeyDB |
2 | {- | ||
3 | ( TrustMap | 2 | ( TrustMap |
4 | , SigAndTrust | 3 | , SigAndTrust |
5 | , SubKey(..) | 4 | , SubKey(..) |
@@ -7,15 +6,31 @@ module KeyDB | |||
7 | , KeyDB | 6 | , KeyDB |
8 | , emptyKeyDB | 7 | , emptyKeyDB |
9 | , keyData | 8 | , keyData |
9 | , kkData | ||
10 | , lookupKeyData | ||
10 | , transmute | 11 | , transmute |
11 | ) -} where | 12 | , transmuteAt |
13 | , alterKeyDB | ||
14 | , mergeKeyDB | ||
15 | , mapKeyDB | ||
16 | -- These probably don't belong here | ||
17 | , selectKey0 | ||
18 | , flattenTop | ||
19 | , flattenAllUids | ||
20 | , flattenSub | ||
21 | , sortByHint | ||
22 | , flattenKeys | ||
23 | , flattenFiltered | ||
24 | ) where | ||
12 | 25 | ||
13 | import Control.Monad | 26 | import Control.Monad |
14 | import Data.Functor | 27 | import Data.Functor |
28 | import Data.List | ||
15 | import qualified Data.Map.Strict as Map | 29 | import qualified Data.Map.Strict as Map |
30 | import Data.Maybe | ||
16 | import Data.OpenPGP | 31 | import Data.OpenPGP |
32 | import Data.Ord | ||
17 | 33 | ||
18 | import FunctorToMaybe | ||
19 | import KeyRing.Types | 34 | import KeyRing.Types |
20 | 35 | ||
21 | type TrustMap = Map.Map FilePath Packet | 36 | type TrustMap = Map.Map FilePath Packet |
@@ -43,6 +58,11 @@ emptyKeyDB = KeyDB { byKeyKey = Map.empty } | |||
43 | keyData :: KeyDB -> [KeyData] | 58 | keyData :: KeyDB -> [KeyData] |
44 | keyData db = Map.elems (byKeyKey db) | 59 | keyData db = Map.elems (byKeyKey db) |
45 | 60 | ||
61 | kkData :: KeyDB -> [(KeyKey, KeyData)] | ||
62 | kkData db = Map.toList (byKeyKey db) | ||
63 | |||
64 | lookupKeyData :: KeyKey -> KeyDB -> Maybe KeyData | ||
65 | lookupKeyData kk db = Map.lookup kk (byKeyKey db) | ||
46 | 66 | ||
47 | transmute :: (Monad m, Monad kiki, Traversable kiki) => | 67 | transmute :: (Monad m, Monad kiki, Traversable kiki) => |
48 | ((KeyData, [info]) -> opcode -> m (kiki (KeyData, [info]))) -- ^ interpreter | 68 | ((KeyData, [info]) -> opcode -> m (kiki (KeyData, [info]))) -- ^ interpreter |
@@ -56,3 +76,87 @@ transmute perform update db = do | |||
56 | r <- sequenceA <$> mapM performAll (byKeyKey db) | 76 | r <- sequenceA <$> mapM performAll (byKeyKey db) |
57 | return $ r <&> \bkk -> ( db { byKeyKey = fst <$> bkk } | 77 | return $ r <&> \bkk -> ( db { byKeyKey = fst <$> bkk } |
58 | , concatMap snd $ Map.elems bkk ) | 78 | , concatMap snd $ Map.elems bkk ) |
79 | |||
80 | alterKeyDB :: (Maybe KeyData -> Maybe KeyData) -> KeyKey -> KeyDB -> KeyDB | ||
81 | alterKeyDB update kk db = db { byKeyKey = Map.alter update kk (byKeyKey db) } | ||
82 | |||
83 | transmuteAt :: ( Monad m | ||
84 | , Functor kiki | ||
85 | ) => (Maybe KeyData -> m (kiki (KeyData,[info]))) -> KeyKey -> KeyDB -> m (kiki (KeyDB,[info])) | ||
86 | transmuteAt go kk db = do | ||
87 | kdr <- go (Map.lookup kk $ byKeyKey db) | ||
88 | return $ kdr <&> \(kd',rrs) -> ( alterKeyDB (const $ Just kd') kk db | ||
89 | , rrs ) | ||
90 | |||
91 | mergeKeyDB :: (KeyData -> KeyData -> KeyData) -> KeyDB -> KeyDB -> KeyDB | ||
92 | mergeKeyDB mergeKeyData db dbtrans = | ||
93 | KeyDB { byKeyKey = Map.unionWith mergeKeyData (byKeyKey db) (byKeyKey dbtrans) } | ||
94 | |||
95 | mapKeyDB :: Monad m => (KeyData -> m KeyData) -> KeyDB -> m KeyDB | ||
96 | mapKeyDB f db = fmap (\m -> db { byKeyKey = m }) $ mapM f (byKeyKey db) | ||
97 | |||
98 | selectKey0 :: Bool -> (KeySpec,Maybe String) -> KeyDB -> Maybe Packet | ||
99 | selectKey0 wantPublic (spec,mtag) db = do | ||
100 | let Message ps = flattenKeys wantPublic $ byKeyKey db | ||
101 | ys = snd $ seek_key spec ps | ||
102 | flip (maybe (listToMaybe ys)) mtag $ \tag -> do | ||
103 | case ys of | ||
104 | y:ys1 -> listToMaybe $ snd $ seek_key (KeyTag y tag) ys1 | ||
105 | [] -> Nothing | ||
106 | |||
107 | |||
108 | flattenKeys :: Bool -> Map.Map KeyKey KeyData -> Message | ||
109 | flattenKeys isPublic db = Message $ concatMap (map packet . flattenTop "" isPublic . snd) | ||
110 | (prefilter . Map.assocs $ db) | ||
111 | where | ||
112 | prefilter = if isPublic then id else filter isSecret | ||
113 | where | ||
114 | isSecret (_,(KeyData | ||
115 | (MappedPacket { packet=(SecretKeyPacket {})}) | ||
116 | _ | ||
117 | _ | ||
118 | _)) = True | ||
119 | isSecret _ = False | ||
120 | |||
121 | flattenUid :: FilePath -> Bool -> (String,([SigAndTrust],OriginMap)) -> [MappedPacket] | ||
122 | flattenUid fname ispub (str,(sigs,om)) = | ||
123 | (mappedPacket "" $ UserIDPacket str) {locations=om} : concatSort fname head (unsig fname ispub) sigs | ||
124 | |||
125 | flattenSub :: FilePath -> Bool -> SubKey -> [MappedPacket] | ||
126 | flattenSub fname ispub (SubKey key sigs) = unk ispub key: concatSort fname head (unsig fname ispub) sigs | ||
127 | |||
128 | flattenAllUids :: FilePath -> Bool -> Map.Map String ([SigAndTrust],OriginMap) -> [MappedPacket] | ||
129 | flattenAllUids fname ispub uids = | ||
130 | concatSort fname head (flattenUid fname ispub) (Map.assocs uids) | ||
131 | |||
132 | flattenTop :: FilePath -> Bool -> KeyData -> [MappedPacket] | ||
133 | flattenTop fname ispub (KeyData key sigs uids subkeys) = | ||
134 | unk ispub key : | ||
135 | ( flattenAllUids fname ispub uids | ||
136 | ++ concatSort fname head (flattenSub fname ispub) (Map.elems subkeys)) | ||
137 | |||
138 | sortByHint :: FilePath -> (a -> MappedPacket) -> [a] -> [a] | ||
139 | sortByHint fname f = sortBy (comparing gethint) | ||
140 | where | ||
141 | gethint = maybe defnum originalNum . Map.lookup fname . locations . f | ||
142 | defnum = -1 | ||
143 | |||
144 | concatSort :: | ||
145 | FilePath -> ([a] -> MappedPacket) -> (b -> [a]) -> [b] -> [a] | ||
146 | concatSort fname getp f = concat . sortByHint fname getp . map f | ||
147 | |||
148 | unk :: Bool -> MappedPacket -> MappedPacket | ||
149 | unk isPublic = if isPublic then toPacket secretToPublic else id | ||
150 | where toPacket f mp@(MappedPacket {packet=p}) = mp {packet=(f p)} | ||
151 | |||
152 | |||
153 | unsig :: FilePath -> Bool -> SigAndTrust -> [MappedPacket] | ||
154 | unsig fname isPublic (sig,trustmap) = | ||
155 | sig : map (asMapped (-1)) ( take 1 . Map.elems $ Map.filterWithKey f trustmap) | ||
156 | where | ||
157 | f n _ = n==fname -- && trace ("fname=n="++show n) True | ||
158 | asMapped n p = let m = mappedPacket fname p | ||
159 | in m { locations = fmap (\x->x {originalNum=n}) (locations m) } | ||
160 | |||
161 | flattenFiltered :: Bool -> (KeyData -> Bool) -> KeyDB -> Message | ||
162 | flattenFiltered wantPublic pred db = flattenKeys wantPublic $ Map.filter pred (byKeyKey db) | ||