Django

Code

Ticket #2548: session_middleware.14.diff

File session_middleware.14.diff, 10.0 kB (added by SmileyChris, 1 year ago)

Patch supporting both custom idle-time expiration and fixed date expiration.

  • AUTHORS

    old new  
    260260    tstromberg@google.com 
    261261    Makoto Tsuyuki <mtsuyuki@gmail.com> 
    262262    tt@gurgle.no 
    263     Amit Upadhyay 
     263    Amit Upadhyay <http://www.amitu.com/blog/> 
    264264    Geert Vanderkelen 
    265265    viestards.lists@gmail.com 
    266266    Vlado <vlado@labath.org> 
  • django/contrib/sessions/middleware.py

    old new  
    5151    def delete_test_cookie(self): 
    5252        del self[TEST_COOKIE_NAME] 
    5353 
     54    def get_max_age(self): 
     55        expiry = self.get('_session_expiry') 
     56        if not expiry:   # Checks both None and 0 cases 
     57            return settings.SESSION_COOKIE_AGE 
     58        if not isinstance(expiry, datetime.datetime): 
     59            return expiry 
     60        delta = expiry - datetime.datetime.now() 
     61        return delta.days * 86400 + delta.seconds 
     62 
     63    def get_expiry_date(self): 
     64        expiry = self.get('_session_expiry', settings.SESSION_COOKIE_AGE) 
     65        if isinstance(expiry, datetime.datetime): 
     66            return expiry 
     67        return datetime.datetime.now() + datetime.timedelta(seconds=expiry) 
     68 
     69    def set_expiry(self, value): 
     70        """ 
     71        Sets a custom expiration for the session. ``value`` can be an integer, a 
     72        Python ``datetime`` or ``timedelta`` object or ``None``. 
     73 
     74        If ``value`` is an integer, the session will expire after that many 
     75        seconds of inactivity. If set to ``0`` then the session will expire on 
     76        browser close. 
     77 
     78        If ``value`` is a ``datetime`` or ``timedelta`` object, the session 
     79        will expire at that specific future time. 
     80 
     81        If ``value`` is ``None``, the session uses the global session expiry 
     82        policy. 
     83        """ 
     84        if value is None: 
     85            # Remove any custom expiration for this session. 
     86            try: 
     87                del self['_session_expiry'] 
     88            except KeyError: 
     89                pass 
     90            return 
     91        if isinstance(value, datetime.timedelta): 
     92            value = datetime.datetime.now() + value 
     93        self['_session_expiry'] = value 
     94 
     95    def get_expire_at_browser_close(self): 
     96        if self.get('_session_expiry') is None: 
     97            return settings.SESSION_EXPIRE_AT_BROWSER_CLOSE 
     98        return self.get('_session_expiry') == 0 
     99 
    54100    def _get_session(self): 
    55101        # Lazily loads session from storage. 
    56102        self.accessed = True 
     
    95141                    obj = Session.objects.get_new_session_object() 
    96142                    session_key = obj.session_key 
    97143 
    98                 if settings.SESSION_EXPIRE_AT_BROWSER_CLOSE
    99                     max_age = None 
    100                     expires = None 
    101                 else: 
    102                     max_age = settings.SESSION_COOKIE_AGE 
    103                     rfcdate = formatdate(time.time() + settings.SESSION_COOKIE_AGE
     144                if request.session.get_expire_at_browser_close()
     145                    max_age = None  
     146                    expires = None  
     147                else:  
     148                    max_age = request.session.get_max_age() 
     149                    rfcdate = formatdate(time.time() + max_age
    104150                    # Fixed length date must have '-' separation in the format 
    105151                    # DD-MMM-YYYY for compliance with Netscape cookie standard 
    106152                    expires = (rfcdate[:7] + "-" + rfcdate[8:11] 
    107153                               + "-" + rfcdate[12:26] + "GMT") 
    108                 new_session = Session.objects.save(session_key, request.session._session, 
    109                     datetime.datetime.now() + datetime.timedelta(seconds=settings.SESSION_COOKIE_AGE)) 
     154                Session.objects.save(session_key, request.session._session, 
     155                                     request.session.get_expiry_date()) 
    110156                response.set_cookie(settings.SESSION_COOKIE_NAME, session_key, 
    111                     max_age=max_age, expires=expires, domain=settings.SESSION_COOKIE_DOMAIN, 
     157                    max_age=max_age, expires=expires, 
     158                    domain=settings.SESSION_COOKIE_DOMAIN, 
    112159                    secure=settings.SESSION_COOKIE_SECURE or None) 
    113160        return response 
  • django/contrib/sessions/tests.py

    old new  
    2626 
    2727>>> s.pop('some key', 'does not exist') 
    2828'does not exist' 
     29 
     30######################### 
     31# Custom session expiry # 
     32######################### 
     33 
     34>>> from django.conf import settings 
     35>>> from datetime import datetime, timedelta 
     36 
     37>>> td9 = timedelta(seconds=9) 
     38>>> td10 = timedelta(seconds=10) 
     39>>> td11 = timedelta(seconds=11) 
     40 
     41# A normal session has a max age equal to settings  
     42>>> s.get_max_age() == settings.SESSION_COOKIE_AGE 
     43True 
     44 
     45# So does a custom session with an idle expiration time of 0 (but it'll expire 
     46# at browser close) 
     47>>> s.set_expiry(0) 
     48>>> s.get_max_age() == settings.SESSION_COOKIE_AGE 
     49True 
     50 
     51# Custom session idle expiration time 
     52>>> s.set_expiry(10) 
     53>>> s.get_expiry_date() == datetime.now() + td10 
     54True 
     55>>> s.get_max_age() 
     5610 
     57 
     58# Custom session fixed expiry date (timedelta) 
     59>>> s.set_expiry(td10) 
     60>>> s.get_expiry_date() == datetime.now() + td10 
     61True 
     62>>> s.get_max_age() 
     6310 
     64 
     65# Custom session fixed expiry date (fixed datetime) 
     66>>> s.set_expiry(datetime.now() + td10) 
     67>>> s.get_expiry_date() == datetime.now() + td10 
     68True 
     69>>> s.get_max_age() 
     7010 
     71 
     72# Set back to default session age 
     73>>> s.set_expiry(None) 
     74>>> s.get_max_age() == settings.SESSION_COOKIE_AGE 
     75True 
     76 
     77# Allow to set back to default session age even if no alternate has been set 
     78>>> s.set_expiry(None) 
     79 
     80 
     81# We're changing the setting then reverting back to the original setting at the 
     82# end of these tests. 
     83>>> original_expire_at_browser_close = settings.SESSION_EXPIRE_AT_BROWSER_CLOSE 
     84>>> settings.SESSION_EXPIRE_AT_BROWSER_CLOSE = False 
     85 
     86# Custom session age 
     87>>> s.set_expiry(10) 
     88>>> s.get_expire_at_browser_close() 
     89False 
     90 
     91# Custom expire-at-browser-close 
     92>>> s.set_expiry(0) 
     93>>> s.get_expire_at_browser_close() 
     94True 
     95 
     96# Default session age 
     97>>> s.set_expiry(None) 
     98>>> s.get_expire_at_browser_close() 
     99False 
     100 
     101>>> settings.SESSION_EXPIRE_AT_BROWSER_CLOSE = True 
     102 
     103# Custom session age 
     104>>> s.set_expiry(10) 
     105>>> s.get_expire_at_browser_close() 
     106False 
     107 
     108# Custom expire-at-browser-close 
     109>>> s.set_expiry(0) 
     110>>> s.get_expire_at_browser_close() 
     111True 
     112 
     113# Default session age 
     114>>> s.set_expiry(None) 
     115>>> s.get_expire_at_browser_close() 
     116True 
     117 
     118>>> settings.SESSION_EXPIRE_AT_BROWSER_CLOSE = original_expire_at_browser_close 
    29119""" 
    30120 
    31121from django.contrib.sessions.middleware import SessionWrapper 
  • docs/sessions.txt

    old new  
    3939It implements the following standard dictionary methods: 
    4040 
    4141    * ``__getitem__(key)`` 
     42 
    4243      Example: ``fav_color = request.session['fav_color']`` 
    4344 
    4445    * ``__setitem__(key, value)`` 
     46 
    4547      Example: ``request.session['fav_color'] = 'blue'`` 
    4648 
    4749    * ``__delitem__(key)`` 
     50 
    4851      Example: ``del request.session['fav_color']``. This raises ``KeyError`` 
    4952      if the given ``key`` isn't already in the session. 
    5053 
    5154    * ``__contains__(key)`` 
     55 
    5256      Example: ``'fav_color' in request.session`` 
    5357 
    5458    * ``get(key, default=None)`` 
     59 
    5560      Example: ``fav_color = request.session.get('fav_color', 'red')`` 
    5661 
    5762    * ``keys()`` 
    5863 
    5964    * ``items()`` 
    6065 
    61 It also has these three methods: 
     66It also has these methods: 
    6267 
    6368    * ``set_test_cookie()`` 
     69 
    6470      Sets a test cookie to determine whether the user's browser supports 
    6571      cookies. Due to the way cookies work, you won't be able to test this 
    6672      until the user's next page request. See "Setting test cookies" below for 
    6773      more information. 
    6874 
    6975    * ``test_cookie_worked()`` 
     76 
    7077      Returns either ``True`` or ``False``, depending on whether the user's 
    7178      browser accepted the test cookie. Due to the way cookies work, you'll 
    7279      have to call ``set_test_cookie()`` on a previous, separate page request. 
    7380      See "Setting test cookies" below for more information. 
    7481 
    7582    * ``delete_test_cookie()`` 
     83 
    7684      Deletes the test cookie. Use this to clean up after yourself. 
    7785 
     86    * ``set_expiry(value)`` 
     87 
     88      Sets a custom expiration for the session. 
     89 
     90      If ``value`` is an integer, the session will expire after that many 
     91      seconds of inactivity. If set to ``0`` then the session will expire when 
     92      the user's browser is closed. 
     93 
     94      If ``value`` is a ``datetime`` or ``timedelta`` object, the session will 
     95      expire at that specific time. 
     96 
     97      If ``value`` is ``None``, the session reverts to using the global session 
     98      expiry policy. 
     99 
     100    * ``get_max_age()`` 
     101 
     102      Returns the number of seconds until this session expires. For sessions 
     103      with no custom expiration (or those set to expire at browser close), this 
     104      will equal ``settings.SESSION_COOKIE_AGE``. 
     105 
     106    * ``get_expiry_date()`` 
     107 
     108      Returns the date this session will expire. For sessions with no custom 
     109      expiration (or those set to expire at browser close), this will equal the 
     110      date ``settings.SESSION_COOKIE_AGE`` seconds from now. 
     111 
     112    * ``get_expire_at_browser_close()`` 
     113 
     114      Returns either ``True`` or ``False``, depending on whether this session 
     115      will expire when the user's browser is closed. 
     116 
    78117You can edit ``request.session`` at any point in your view. You can edit it 
    79118multiple times. 
    80119 
     
    217256her browser. Use this if you want people to have to log in every time they open 
    218257a browser. 
    219258 
     259This setting is a global default and can be overwritten by explicitly calling 
     260``request.session.set_expiry()`` as described above in 
     261`using sessions in views`_. 
     262 
    220263Clearing the session table 
    221264========================== 
    222265