File: CredPairCache.hs

package info (click to toggle)
git-annex 5.20141125
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 37,828 kB
  • ctags: 583
  • sloc: haskell: 42,582; sh: 1,080; ansic: 498; makefile: 316; perl: 125
file content (53 lines) | stat: -rw-r--r-- 1,457 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
{- git-annex assistant CredPair cache.
 -
 - Copyright 2014 Joey Hess <joey@kitenet.net>
 -
 - Licensed under the GNU GPL version 3 or higher.
 -}

{-# LANGUAGE BangPatterns #-}

module Assistant.CredPairCache (
	cacheCred,
	getCachedCred,
	expireCachedCred,
) where

import Assistant.Types.CredPairCache
import Types.Creds
import Assistant.Common
import Utility.ThreadScheduler

import qualified Data.Map as M
import Control.Concurrent

{- Caches a CredPair, but only for a limited time, after which it
 - will expire.
 -
 - Note that repeatedly caching the same CredPair
 - does not reset its expiry time.
 -}
cacheCred :: CredPair -> Seconds -> Assistant ()
cacheCred (login, password) expireafter = do
	cache <- getAssistant credPairCache
	liftIO $ do
		changeStrict cache $ M.insert login password
		void $ forkIO $ do
			threadDelaySeconds expireafter
			changeStrict cache $ M.delete login

getCachedCred :: Login -> Assistant (Maybe Password)
getCachedCred login = do
	cache <- getAssistant credPairCache
	liftIO $ M.lookup login <$> readMVar cache

expireCachedCred :: Login -> Assistant ()
expireCachedCred login = do
	cache <- getAssistant credPairCache
	liftIO $ changeStrict cache $ M.delete login

{- Update map strictly to avoid keeping references to old creds in memory. -}
changeStrict :: CredPairCache -> (M.Map Login Password -> M.Map Login Password) -> IO ()
changeStrict cache a = modifyMVar_ cache $ \m -> do
	let !m' = a m
	return m'