NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

securecookie.py (4643B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\lib\werkzeug\contrib\securecookie.py
      2 import sys
      3 import cPickle as pickle
      4 from hmac import new as hmac
      5 from datetime import datetime
      6 from time import time, mktime, gmtime
      7 from werkzeug import url_quote_plus, url_unquote_plus
      8 from werkzeug._internal import _date_to_unix
      9 from werkzeug.contrib.sessions import ModificationTrackingDict
     10 _default_hash = None
     11 if sys.version_info >= (2, 5):
     12     try:
     13         from hashlib import sha1 as _default_hash
     14     except ImportError:
     15         pass
     16 
     17 if _default_hash is None:
     18     import sha as _default_hash
     19 
     20 class UnquoteError(Exception):
     21     pass
     22 
     23 
     24 class SecureCookie(ModificationTrackingDict):
     25     hash_method = _default_hash
     26     serialization_method = pickle
     27     quote_base64 = True
     28 
     29     def __init__(self, data = None, secret_key = None, new = True):
     30         ModificationTrackingDict.__init__(self, data or ())
     31         if secret_key is not None:
     32             secret_key = str(secret_key)
     33         self.secret_key = secret_key
     34         self.new = new
     35 
     36     def __repr__(self):
     37         return '<%s %s%s>' % (self.__class__.__name__, dict.__repr__(self), self.should_save and '*' or '')
     38 
     39     @property
     40     def should_save(self):
     41         return self.modified
     42 
     43     @classmethod
     44     def quote(cls, value):
     45         if cls.serialization_method is not None:
     46             value = cls.serialization_method.dumps(value)
     47         if cls.quote_base64:
     48             value = ''.join(value.encode('base64').splitlines()).strip()
     49         return value
     50 
     51     @classmethod
     52     def unquote(cls, value):
     53         try:
     54             if cls.quote_base64:
     55                 value = value.decode('base64')
     56             if cls.serialization_method is not None:
     57                 value = cls.serialization_method.loads(value)
     58             return value
     59         except:
     60             raise UnquoteError()
     61 
     62     def serialize(self, expires = None):
     63         if self.secret_key is None:
     64             raise RuntimeError('no secret key defined')
     65         if expires:
     66             self['_expires'] = _date_to_unix(expires)
     67         result = []
     68         mac = hmac(self.secret_key, None, self.hash_method)
     69         for key, value in sorted(self.items()):
     70             result.append('%s=%s' % (url_quote_plus(key), self.quote(value)))
     71             mac.update('|' + result[-1])
     72 
     73         return '%s?%s' % (mac.digest().encode('base64').strip(), '&'.join(result))
     74 
     75     @classmethod
     76     def unserialize(cls, string, secret_key):
     77         if isinstance(string, unicode):
     78             string = string.encode('utf-8', 'ignore')
     79         try:
     80             base64_hash, data = string.split('?', 1)
     81         except (ValueError, IndexError):
     82             items = ()
     83         else:
     84             items = {}
     85             mac = hmac(secret_key, None, cls.hash_method)
     86             for item in data.split('&'):
     87                 mac.update('|' + item)
     88                 if '=' not in item:
     89                     items = None
     90                     break
     91                 key, value = item.split('=', 1)
     92                 key = url_unquote_plus(key)
     93                 try:
     94                     key = str(key)
     95                 except UnicodeError:
     96                     pass
     97 
     98                 items[key] = value
     99 
    100             try:
    101                 client_hash = base64_hash.decode('base64')
    102             except Exception:
    103                 items = client_hash = None
    104 
    105             if items is not None and client_hash == mac.digest():
    106                 try:
    107                     for key, value in items.iteritems():
    108                         items[key] = cls.unquote(value)
    109 
    110                 except UnquoteError:
    111                     items = ()
    112                 else:
    113                     if '_expires' in items:
    114                         if time() > items['_expires']:
    115                             items = ()
    116                         else:
    117                             del items['_expires']
    118             else:
    119                 items = ()
    120 
    121         return cls(items, secret_key, False)
    122 
    123     @classmethod
    124     def load_cookie(cls, request, key = 'session', secret_key = None):
    125         data = request.cookies.get(key)
    126         if not data:
    127             return cls(secret_key=secret_key)
    128         return cls.unserialize(data, secret_key)
    129 
    130     def save_cookie(self, response, key = 'session', expires = None, session_expires = None, max_age = None, path = '/', domain = None, secure = None, httponly = False, force = False):
    131         if force or self.should_save:
    132             data = self.serialize(session_expires or expires)
    133             response.set_cookie(key, data, expires=expires, max_age=max_age, path=path, domain=domain, secure=secure, httponly=httponly)