module Gnome.Keyring.ItemInfo
( ItemInfo (..)
, ItemType (..)
, ItemID (..)
, GetItemInfoCallbackPtr
, itemIDOperation
, itemIDListOperation
, stealItemIDList
, itemInfoOperation
, fromItemType
, withItemInfo
, stealItemInfo
, peekItemID
) where
import Data.Text.Lazy (Text)
import Data.Time (UTCTime)
import Control.Exception (bracket)
import Gnome.Keyring.Internal.FFI
import Gnome.Keyring.Internal.Operation
newtype ItemID = ItemID Word32
deriving (Show, Eq, Ord)
peekItemID :: (Storable a, Integral a) => Ptr a -> IO ItemID
peekItemID = fmap (ItemID . fromIntegral) . peek
data RawType = ITEM_GENERIC_SECRET
| ITEM_NETWORK_PASSWORD
| ITEM_NOTE
| ITEM_CHAINED_KEYRING_PASSWORD
| ITEM_ENCRYPTION_KEY_PASSWORD
| ITEM_PK_STORAGE
| ITEM_LAST_TYPE
deriving (Show)
instance Enum RawType where
fromEnum ITEM_GENERIC_SECRET = 0
fromEnum ITEM_NETWORK_PASSWORD = 1
fromEnum ITEM_NOTE = 2
fromEnum ITEM_CHAINED_KEYRING_PASSWORD = 3
fromEnum ITEM_ENCRYPTION_KEY_PASSWORD = 4
fromEnum ITEM_PK_STORAGE = 256
fromEnum ITEM_LAST_TYPE = 257
toEnum 0 = ITEM_GENERIC_SECRET
toEnum 1 = ITEM_NETWORK_PASSWORD
toEnum 2 = ITEM_NOTE
toEnum 3 = ITEM_CHAINED_KEYRING_PASSWORD
toEnum 4 = ITEM_ENCRYPTION_KEY_PASSWORD
toEnum 256 = ITEM_PK_STORAGE
toEnum 257 = ITEM_LAST_TYPE
toEnum unmatched = error ("RawType.toEnum: Cannot match " ++ show unmatched)
data ItemType
= ItemGenericSecret
| ItemNetworkPassword
| ItemNote
| ItemChainedKeyringPassword
| ItemEncryptionKeyPassword
| ItemPublicKeyStorage
deriving (Show, Eq)
fromItemType :: ItemType -> CInt
fromItemType = fromIntegral . fromEnum . toRaw where
toRaw ItemGenericSecret = ITEM_GENERIC_SECRET
toRaw ItemNetworkPassword = ITEM_NETWORK_PASSWORD
toRaw ItemNote = ITEM_NOTE
toRaw ItemChainedKeyringPassword = ITEM_CHAINED_KEYRING_PASSWORD
toRaw ItemEncryptionKeyPassword = ITEM_ENCRYPTION_KEY_PASSWORD
toRaw ItemPublicKeyStorage = ITEM_PK_STORAGE
toItemType :: RawType -> ItemType
toItemType ITEM_GENERIC_SECRET = ItemGenericSecret
toItemType ITEM_NETWORK_PASSWORD = ItemNetworkPassword
toItemType ITEM_NOTE = ItemNote
toItemType ITEM_CHAINED_KEYRING_PASSWORD = ItemChainedKeyringPassword
toItemType ITEM_ENCRYPTION_KEY_PASSWORD = ItemEncryptionKeyPassword
toItemType ITEM_PK_STORAGE = ItemPublicKeyStorage
toItemType x = error $ "Unknown item type: " ++ show x
data ItemInfo = ItemInfo
{ itemType :: ItemType
, itemSecret :: Maybe Text
, itemDisplayName :: Maybe Text
, itemMTime :: UTCTime
, itemCTime :: UTCTime
}
deriving (Show, Eq)
peekItemInfo :: Ptr () -> IO ItemInfo
peekItemInfo info = do
cType <- gnome_keyring_item_info_get_type info
secret <- stealNullableText =<< gnome_keyring_item_info_get_secret info
name <- stealNullableText =<< gnome_keyring_item_info_get_display_name info
mtime <- cToUTC `fmap` gnome_keyring_item_info_get_mtime info
ctime <- cToUTC `fmap` gnome_keyring_item_info_get_ctime info
let type' = toItemType . toEnum . fromIntegral $ cType
return $ ItemInfo type' secret name mtime ctime
stealItemInfo :: Ptr (Ptr ()) -> IO ItemInfo
stealItemInfo ptr = bracket (peek ptr) freeItemInfo peekItemInfo
freeItemInfo :: Ptr () -> IO ()
freeItemInfo = gnome_keyring_item_info_free
foreign import ccall "gnome-keyring.h &gnome_keyring_item_info_free"
finalizeItemInfo :: FunPtr (Ptr a -> IO ())
withItemInfo :: ItemInfo -> (Ptr () -> IO a) -> IO a
withItemInfo info io = do
fptr <- newForeignPtr finalizeItemInfo =<< gnome_keyring_item_info_new
withForeignPtr fptr $ \ptr -> do
gnome_keyring_item_info_set_type ptr . fromItemType . itemType $ info
withNullableText (itemSecret info) $ gnome_keyring_item_info_set_secret ptr
withNullableText (itemDisplayName info) $ gnome_keyring_item_info_set_display_name ptr
io ptr
itemIDListOperation :: OperationImpl GetListCallback [ItemID]
itemIDListOperation = operationImpl $ \checkResult ->
wrapGetListCallback $ \cres ptr _ ->
checkResult cres $ peekItemIDList ptr
peekItemIDList :: Ptr () -> IO [ItemID]
peekItemIDList = mapGList $ return . ItemID . fromIntegral . ptrToWordPtr
stealItemIDList :: Ptr (Ptr ()) -> IO [ItemID]
stealItemIDList ptr = bracket (peek ptr) freeList peekItemIDList where
freeList = g_list_free
type GetItemInfoCallback = CInt -> Ptr () -> Ptr () -> IO ()
type GetItemInfoCallbackPtr = FunPtr ((CInt -> ((Ptr ()) -> ((Ptr ()) -> (IO ())))))
foreign import ccall "wrapper"
wrapGetItemInfoCallback :: GetItemInfoCallback -> IO GetItemInfoCallbackPtr
itemIDOperation :: OperationImpl GetIntCallback ItemID
itemIDOperation = operationImpl $ \checkResult ->
wrapGetIntCallback $ \cres cint _ ->
checkResult cres $ return . ItemID . fromIntegral $ cint
itemInfoOperation :: OperationImpl GetItemInfoCallback ItemInfo
itemInfoOperation = operationImpl $ \checkResult ->
wrapGetItemInfoCallback $ \cres ptr _ ->
checkResult cres $ peekItemInfo ptr
foreign import ccall safe "Gnome/Keyring/ItemInfo.chs.h gnome_keyring_item_info_get_type"
gnome_keyring_item_info_get_type :: ((Ptr ()) -> (IO CInt))
foreign import ccall safe "Gnome/Keyring/ItemInfo.chs.h gnome_keyring_item_info_get_secret"
gnome_keyring_item_info_get_secret :: ((Ptr ()) -> (IO (Ptr CChar)))
foreign import ccall safe "Gnome/Keyring/ItemInfo.chs.h gnome_keyring_item_info_get_display_name"
gnome_keyring_item_info_get_display_name :: ((Ptr ()) -> (IO (Ptr CChar)))
foreign import ccall safe "Gnome/Keyring/ItemInfo.chs.h gnome_keyring_item_info_get_mtime"
gnome_keyring_item_info_get_mtime :: ((Ptr ()) -> (IO CLong))
foreign import ccall safe "Gnome/Keyring/ItemInfo.chs.h gnome_keyring_item_info_get_ctime"
gnome_keyring_item_info_get_ctime :: ((Ptr ()) -> (IO CLong))
foreign import ccall safe "Gnome/Keyring/ItemInfo.chs.h gnome_keyring_item_info_free"
gnome_keyring_item_info_free :: ((Ptr ()) -> (IO ()))
foreign import ccall safe "Gnome/Keyring/ItemInfo.chs.h gnome_keyring_item_info_new"
gnome_keyring_item_info_new :: (IO (Ptr ()))
foreign import ccall safe "Gnome/Keyring/ItemInfo.chs.h gnome_keyring_item_info_set_type"
gnome_keyring_item_info_set_type :: ((Ptr ()) -> (CInt -> (IO ())))
foreign import ccall safe "Gnome/Keyring/ItemInfo.chs.h gnome_keyring_item_info_set_secret"
gnome_keyring_item_info_set_secret :: ((Ptr ()) -> ((Ptr CChar) -> (IO ())))
foreign import ccall safe "Gnome/Keyring/ItemInfo.chs.h gnome_keyring_item_info_set_display_name"
gnome_keyring_item_info_set_display_name :: ((Ptr ()) -> ((Ptr CChar) -> (IO ())))
foreign import ccall safe "Gnome/Keyring/ItemInfo.chs.h g_list_free"
g_list_free :: ((Ptr ()) -> (IO ()))