diff options
author | James Taylor <user234683@users.noreply.github.com> | 2019-09-06 16:31:13 -0700 |
---|---|---|
committer | James Taylor <user234683@users.noreply.github.com> | 2019-09-06 16:31:13 -0700 |
commit | 3d57e14df7ba5f14a634295caf3b2e60da50bfe2 (patch) | |
tree | 4903bcb79a49ad714a1a9129765b9545405c9978 /python/flask/sessions.py | |
parent | ac32b24b2a011292b704a3f27e8fd08a7ae9424b (diff) | |
download | yt-local-3d57e14df7ba5f14a634295caf3b2e60da50bfe2.tar.lz yt-local-3d57e14df7ba5f14a634295caf3b2e60da50bfe2.tar.xz yt-local-3d57e14df7ba5f14a634295caf3b2e60da50bfe2.zip |
Remove windows python distribution from repo and add requirements.txt
Diffstat (limited to 'python/flask/sessions.py')
-rw-r--r-- | python/flask/sessions.py | 385 |
1 files changed, 0 insertions, 385 deletions
diff --git a/python/flask/sessions.py b/python/flask/sessions.py deleted file mode 100644 index c8b7d4e..0000000 --- a/python/flask/sessions.py +++ /dev/null @@ -1,385 +0,0 @@ -# -*- coding: utf-8 -*- -""" - flask.sessions - ~~~~~~~~~~~~~~ - - Implements cookie based sessions based on itsdangerous. - - :copyright: © 2010 by the Pallets team. - :license: BSD, see LICENSE for more details. -""" - -import hashlib -import warnings -from datetime import datetime - -from itsdangerous import BadSignature, URLSafeTimedSerializer -from werkzeug.datastructures import CallbackDict - -from flask._compat import collections_abc -from flask.helpers import is_ip, total_seconds -from flask.json.tag import TaggedJSONSerializer - - -class SessionMixin(collections_abc.MutableMapping): - """Expands a basic dictionary with session attributes.""" - - @property - def permanent(self): - """This reflects the ``'_permanent'`` key in the dict.""" - return self.get('_permanent', False) - - @permanent.setter - def permanent(self, value): - self['_permanent'] = bool(value) - - #: Some implementations can detect whether a session is newly - #: created, but that is not guaranteed. Use with caution. The mixin - # default is hard-coded ``False``. - new = False - - #: Some implementations can detect changes to the session and set - #: this when that happens. The mixin default is hard coded to - #: ``True``. - modified = True - - #: Some implementations can detect when session data is read or - #: written and set this when that happens. The mixin default is hard - #: coded to ``True``. - accessed = True - - -class SecureCookieSession(CallbackDict, SessionMixin): - """Base class for sessions based on signed cookies. - - This session backend will set the :attr:`modified` and - :attr:`accessed` attributes. It cannot reliably track whether a - session is new (vs. empty), so :attr:`new` remains hard coded to - ``False``. - """ - - #: When data is changed, this is set to ``True``. Only the session - #: dictionary itself is tracked; if the session contains mutable - #: data (for example a nested dict) then this must be set to - #: ``True`` manually when modifying that data. The session cookie - #: will only be written to the response if this is ``True``. - modified = False - - #: When data is read or written, this is set to ``True``. Used by - # :class:`.SecureCookieSessionInterface` to add a ``Vary: Cookie`` - #: header, which allows caching proxies to cache different pages for - #: different users. - accessed = False - - def __init__(self, initial=None): - def on_update(self): - self.modified = True - self.accessed = True - - super(SecureCookieSession, self).__init__(initial, on_update) - - def __getitem__(self, key): - self.accessed = True - return super(SecureCookieSession, self).__getitem__(key) - - def get(self, key, default=None): - self.accessed = True - return super(SecureCookieSession, self).get(key, default) - - def setdefault(self, key, default=None): - self.accessed = True - return super(SecureCookieSession, self).setdefault(key, default) - - -class NullSession(SecureCookieSession): - """Class used to generate nicer error messages if sessions are not - available. Will still allow read-only access to the empty session - but fail on setting. - """ - - def _fail(self, *args, **kwargs): - raise RuntimeError('The session is unavailable because no secret ' - 'key was set. Set the secret_key on the ' - 'application to something unique and secret.') - __setitem__ = __delitem__ = clear = pop = popitem = \ - update = setdefault = _fail - del _fail - - -class SessionInterface(object): - """The basic interface you have to implement in order to replace the - default session interface which uses werkzeug's securecookie - implementation. The only methods you have to implement are - :meth:`open_session` and :meth:`save_session`, the others have - useful defaults which you don't need to change. - - The session object returned by the :meth:`open_session` method has to - provide a dictionary like interface plus the properties and methods - from the :class:`SessionMixin`. We recommend just subclassing a dict - and adding that mixin:: - - class Session(dict, SessionMixin): - pass - - If :meth:`open_session` returns ``None`` Flask will call into - :meth:`make_null_session` to create a session that acts as replacement - if the session support cannot work because some requirement is not - fulfilled. The default :class:`NullSession` class that is created - will complain that the secret key was not set. - - To replace the session interface on an application all you have to do - is to assign :attr:`flask.Flask.session_interface`:: - - app = Flask(__name__) - app.session_interface = MySessionInterface() - - .. versionadded:: 0.8 - """ - - #: :meth:`make_null_session` will look here for the class that should - #: be created when a null session is requested. Likewise the - #: :meth:`is_null_session` method will perform a typecheck against - #: this type. - null_session_class = NullSession - - #: A flag that indicates if the session interface is pickle based. - #: This can be used by Flask extensions to make a decision in regards - #: to how to deal with the session object. - #: - #: .. versionadded:: 0.10 - pickle_based = False - - def make_null_session(self, app): - """Creates a null session which acts as a replacement object if the - real session support could not be loaded due to a configuration - error. This mainly aids the user experience because the job of the - null session is to still support lookup without complaining but - modifications are answered with a helpful error message of what - failed. - - This creates an instance of :attr:`null_session_class` by default. - """ - return self.null_session_class() - - def is_null_session(self, obj): - """Checks if a given object is a null session. Null sessions are - not asked to be saved. - - This checks if the object is an instance of :attr:`null_session_class` - by default. - """ - return isinstance(obj, self.null_session_class) - - def get_cookie_domain(self, app): - """Returns the domain that should be set for the session cookie. - - Uses ``SESSION_COOKIE_DOMAIN`` if it is configured, otherwise - falls back to detecting the domain based on ``SERVER_NAME``. - - Once detected (or if not set at all), ``SESSION_COOKIE_DOMAIN`` is - updated to avoid re-running the logic. - """ - - rv = app.config['SESSION_COOKIE_DOMAIN'] - - # set explicitly, or cached from SERVER_NAME detection - # if False, return None - if rv is not None: - return rv if rv else None - - rv = app.config['SERVER_NAME'] - - # server name not set, cache False to return none next time - if not rv: - app.config['SESSION_COOKIE_DOMAIN'] = False - return None - - # chop off the port which is usually not supported by browsers - # remove any leading '.' since we'll add that later - rv = rv.rsplit(':', 1)[0].lstrip('.') - - if '.' not in rv: - # Chrome doesn't allow names without a '.' - # this should only come up with localhost - # hack around this by not setting the name, and show a warning - warnings.warn( - '"{rv}" is not a valid cookie domain, it must contain a ".".' - ' Add an entry to your hosts file, for example' - ' "{rv}.localdomain", and use that instead.'.format(rv=rv) - ) - app.config['SESSION_COOKIE_DOMAIN'] = False - return None - - ip = is_ip(rv) - - if ip: - warnings.warn( - 'The session cookie domain is an IP address. This may not work' - ' as intended in some browsers. Add an entry to your hosts' - ' file, for example "localhost.localdomain", and use that' - ' instead.' - ) - - # if this is not an ip and app is mounted at the root, allow subdomain - # matching by adding a '.' prefix - if self.get_cookie_path(app) == '/' and not ip: - rv = '.' + rv - - app.config['SESSION_COOKIE_DOMAIN'] = rv - return rv - - def get_cookie_path(self, app): - """Returns the path for which the cookie should be valid. The - default implementation uses the value from the ``SESSION_COOKIE_PATH`` - config var if it's set, and falls back to ``APPLICATION_ROOT`` or - uses ``/`` if it's ``None``. - """ - return app.config['SESSION_COOKIE_PATH'] \ - or app.config['APPLICATION_ROOT'] - - def get_cookie_httponly(self, app): - """Returns True if the session cookie should be httponly. This - currently just returns the value of the ``SESSION_COOKIE_HTTPONLY`` - config var. - """ - return app.config['SESSION_COOKIE_HTTPONLY'] - - def get_cookie_secure(self, app): - """Returns True if the cookie should be secure. This currently - just returns the value of the ``SESSION_COOKIE_SECURE`` setting. - """ - return app.config['SESSION_COOKIE_SECURE'] - - def get_cookie_samesite(self, app): - """Return ``'Strict'`` or ``'Lax'`` if the cookie should use the - ``SameSite`` attribute. This currently just returns the value of - the :data:`SESSION_COOKIE_SAMESITE` setting. - """ - return app.config['SESSION_COOKIE_SAMESITE'] - - def get_expiration_time(self, app, session): - """A helper method that returns an expiration date for the session - or ``None`` if the session is linked to the browser session. The - default implementation returns now + the permanent session - lifetime configured on the application. - """ - if session.permanent: - return datetime.utcnow() + app.permanent_session_lifetime - - def should_set_cookie(self, app, session): - """Used by session backends to determine if a ``Set-Cookie`` header - should be set for this session cookie for this response. If the session - has been modified, the cookie is set. If the session is permanent and - the ``SESSION_REFRESH_EACH_REQUEST`` config is true, the cookie is - always set. - - This check is usually skipped if the session was deleted. - - .. versionadded:: 0.11 - """ - - return session.modified or ( - session.permanent and app.config['SESSION_REFRESH_EACH_REQUEST'] - ) - - def open_session(self, app, request): - """This method has to be implemented and must either return ``None`` - in case the loading failed because of a configuration error or an - instance of a session object which implements a dictionary like - interface + the methods and attributes on :class:`SessionMixin`. - """ - raise NotImplementedError() - - def save_session(self, app, session, response): - """This is called for actual sessions returned by :meth:`open_session` - at the end of the request. This is still called during a request - context so if you absolutely need access to the request you can do - that. - """ - raise NotImplementedError() - - -session_json_serializer = TaggedJSONSerializer() - - -class SecureCookieSessionInterface(SessionInterface): - """The default session interface that stores sessions in signed cookies - through the :mod:`itsdangerous` module. - """ - #: the salt that should be applied on top of the secret key for the - #: signing of cookie based sessions. - salt = 'cookie-session' - #: the hash function to use for the signature. The default is sha1 - digest_method = staticmethod(hashlib.sha1) - #: the name of the itsdangerous supported key derivation. The default - #: is hmac. - key_derivation = 'hmac' - #: A python serializer for the payload. The default is a compact - #: JSON derived serializer with support for some extra Python types - #: such as datetime objects or tuples. - serializer = session_json_serializer - session_class = SecureCookieSession - - def get_signing_serializer(self, app): - if not app.secret_key: - return None - signer_kwargs = dict( - key_derivation=self.key_derivation, - digest_method=self.digest_method - ) - return URLSafeTimedSerializer(app.secret_key, salt=self.salt, - serializer=self.serializer, - signer_kwargs=signer_kwargs) - - def open_session(self, app, request): - s = self.get_signing_serializer(app) - if s is None: - return None - val = request.cookies.get(app.session_cookie_name) - if not val: - return self.session_class() - max_age = total_seconds(app.permanent_session_lifetime) - try: - data = s.loads(val, max_age=max_age) - return self.session_class(data) - except BadSignature: - return self.session_class() - - def save_session(self, app, session, response): - domain = self.get_cookie_domain(app) - path = self.get_cookie_path(app) - - # If the session is modified to be empty, remove the cookie. - # If the session is empty, return without setting the cookie. - if not session: - if session.modified: - response.delete_cookie( - app.session_cookie_name, - domain=domain, - path=path - ) - - return - - # Add a "Vary: Cookie" header if the session was accessed at all. - if session.accessed: - response.vary.add('Cookie') - - if not self.should_set_cookie(app, session): - return - - httponly = self.get_cookie_httponly(app) - secure = self.get_cookie_secure(app) - samesite = self.get_cookie_samesite(app) - expires = self.get_expiration_time(app, session) - val = self.get_signing_serializer(app).dumps(dict(session)) - response.set_cookie( - app.session_cookie_name, - val, - expires=expires, - httponly=httponly, - domain=domain, - path=path, - secure=secure, - samesite=samesite - ) |