Example #1
0
 def __init__(self, filename, **options):
     # Options
     self.timeout = options.get('timeout', 60*30) # 30 minutes
     self.ignore_environ = options.get('ignore_environ', True) # by default, ignore the environment variables
     self.cache_true_only = options.get('cache_true_only', True)
     self.salt = None
     
     # Connect to the database
     if not filename == ':memory:':
         filename = self._normalize_filename(filename)
     # TODO: Enforce 0600 perms on UNIX?
     self.conn = sqlite3.connect(filename)
     c = self.conn.cursor()
     attempts = 0
     while self.salt is None and attempts <= 1:
         try:
             c.execute("CREATE TABLE cache (key TEXT UNIQUE, value TEXT, expiration INTEGER);")
         except sqlite3.OperationalError:
             # Cache table exists
             c.execute('DELETE FROM cache WHERE expiration < ?;', (time.time(),))
             c.execute("SELECT value FROM cache WHERE key = ? LIMIT 1;", (Cache.SALT_NAME, ))
             for row in c:
                 self.salt = decode_value(row[0])
         else:
             # Cache table just created
             salt = os.urandom(hmac.HMAC.blocksize) # Default: 512-bit HMAC
             c.execute("CREATE INDEX IF NOT EXISTS expiration ON cache (expiration ASC);")
             c.execute('INSERT INTO cache(key, value) VALUES (?, ?);', (Cache.SALT_NAME, encode_value(salt)))
         finally:
             self.conn.commit()
         attempts += 1
     assert self.salt is not None, "wsgi_googleauth Error: Salt not initialized"
Example #2
0
        def wrapper(*args):
            # Invariant: cache is sorted by timeout
            # Requirement: time.time is a monotonically increasing function
            c = self.conn.cursor()

            # Generate Key
            hash_args = args[1:] if self.ignore_environ else args[:]
            key = hmac.new(self.salt, encode_value(hash_args), digestmod=hashlib.sha256).hexdigest()

            # Cache Lookup
            found = False
            c.execute("SELECT value FROM cache WHERE key = ? AND expiration > ? LIMIT 1;", (key, time.time()))
            for row in c:
                result = decode_value(row[0])
                found = True

            # Query Function
            if not found:
                result = f(*args)
                if not self.cache_true_only or (self.cache_true_only and result is True):
                    timeout = time.time() + self.timeout
                    try:
                        c.execute("INSERT INTO cache(key, value, expiration) VALUES (?, ?, ?);", (key, encode_value(result), timeout))
                    except sqlite3.IntegrityError:
                        c.execute("UPDATE cache SET expiration = ? WHERE key = ?;", (timeout, key))
                    self.conn.commit()
            return result