Skip to content

Commit 07889c1

Browse files
Fixed #1 -- Added anonymous session support via middleware and request.session. Removed the former request.session, which wasn't being used anyway. Removed auth.Session model. See the BackwardsIncompatibleChanges wiki page for IMPORTANT notes on code you'll have to change and a DB table you'll have to create.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@518 bcc190cf-cafb-0310-a4f2-bffc1f526a37
1 parent f21ff30 commit 07889c1

File tree

13 files changed

+179
-152
lines changed

13 files changed

+179
-152
lines changed

django/bin/daily_cleanup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
def clean_up():
88
# Clean up old database records
99
cursor = db.cursor()
10-
cursor.execute("DELETE FROM auth_sessions WHERE start_time < NOW() - INTERVAL '2 weeks'")
10+
cursor.execute("DELETE FROM core_sessions WHERE expire_date < NOW()")
1111
cursor.execute("DELETE FROM registration_challenges WHERE request_date < NOW() - INTERVAL '1 week'")
1212
db.commit()
1313

django/conf/global_settings.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,6 @@
4848
# Host for sending e-mail.
4949
EMAIL_HOST = 'localhost'
5050

51-
# Name of the session cookie. This can be whatever you want.
52-
AUTH_SESSION_COOKIE = 'rizzo'
53-
5451
# List of locations of the template source files, in search order.
5552
TEMPLATE_DIRS = ()
5653

@@ -113,6 +110,14 @@
113110
"django.middleware.doc.XViewMiddleware",
114111
)
115112

113+
############
114+
# SESSIONS #
115+
############
116+
117+
SESSION_COOKIE_NAME = 'hotclub' # Cookie name. This can be whatever you want.
118+
SESSION_COOKIE_AGE = 60 * 60 * 24 * 7 * 2 # Age of cookie, in seconds (default: 2 weeks).
119+
SESSION_COOKIE_DOMAIN = None # A string like ".lawrence.com", or None for standard domain cookie.
120+
116121
#########
117122
# CACHE #
118123
#########
@@ -121,9 +126,6 @@
121126
# possible values.
122127
CACHE_BACKEND = 'simple://'
123128

124-
# Set to a string like ".lawrence.com", or None for a standard domain cookie.
125-
REGISTRATION_COOKIE_DOMAIN = None
126-
127129
####################
128130
# COMMENTS #
129131
####################

django/contrib/comments/views/comments.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from django.core.mail import mail_admins, mail_managers
33
from django.core.exceptions import Http404, ObjectDoesNotExist
44
from django.core.extensions import DjangoContext as Context
5-
from django.models.auth import sessions
5+
from django.models.auth import users
66
from django.models.comments import comments, freecomments
77
from django.models.core import contenttypes
88
from django.parts.auth.formfields import AuthenticationForm
@@ -215,7 +215,7 @@ def post_comment(request):
215215
# If user gave correct username/password and wasn't already logged in, log them in
216216
# so they don't have to enter a username/password again.
217217
if manipulator.get_user() and new_data.has_key('password') and manipulator.get_user().check_password(new_data['password']):
218-
sessions.start_web_session(manipulator.get_user_id(), request, response)
218+
request.session[users.SESSION_KEY] = manipulator.get_user_id()
219219
if errors or request.POST.has_key('preview'):
220220
class CommentFormWrapper(formfields.FormWrapper):
221221
def __init__(self, manipulator, new_data, errors, rating_choices):

django/core/handlers/modpython.py

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -95,29 +95,17 @@ def _get_raw_post_data(self):
9595
self._raw_post_data = self._req.read()
9696
return self._raw_post_data
9797

98-
def _load_session_and_user(self):
99-
from django.models.auth import sessions
100-
from django.conf.settings import AUTH_SESSION_COOKIE
101-
session_cookie = self.COOKIES.get(AUTH_SESSION_COOKIE, '')
102-
try:
103-
self._session = sessions.get_session_from_cookie(session_cookie)
104-
self._user = self._session.get_user()
105-
except sessions.SessionDoesNotExist:
106-
from django.parts.auth import anonymoususers
107-
self._session = None
108-
self._user = anonymoususers.AnonymousUser()
109-
110-
def _get_session(self):
111-
if not hasattr(self, '_session'):
112-
self._load_session_and_user()
113-
return self._session
114-
115-
def _set_session(self, session):
116-
self._session = session
117-
11898
def _get_user(self):
11999
if not hasattr(self, '_user'):
120-
self._load_session_and_user()
100+
from django.models.auth import users
101+
try:
102+
user_id = self.session[users.SESSION_KEY]
103+
if not user_id:
104+
raise ValueError
105+
self._user = users.get_object(pk=user_id)
106+
except (AttributeError, KeyError, ValueError, users.UserDoesNotExist):
107+
from django.parts.auth import anonymoususers
108+
self._user = anonymoususers.AnonymousUser()
121109
return self._user
122110

123111
def _set_user(self, user):
@@ -130,7 +118,6 @@ def _set_user(self, user):
130118
META = property(_get_meta)
131119
REQUEST = property(_get_request)
132120
raw_post_data = property(_get_raw_post_data)
133-
session = property(_get_session, _set_session)
134121
user = property(_get_user, _set_user)
135122

136123
class ModPythonHandler(BaseHandler):

django/core/handlers/wsgi.py

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -76,29 +76,17 @@ def _get_raw_post_data(self):
7676
self._raw_post_data = self.environ['wsgi.input'].read(int(self.environ["CONTENT_LENGTH"]))
7777
return self._raw_post_data
7878

79-
def _load_session_and_user(self):
80-
from django.models.auth import sessions
81-
from django.conf.settings import AUTH_SESSION_COOKIE
82-
session_cookie = self.COOKIES.get(AUTH_SESSION_COOKIE, '')
83-
try:
84-
self._session = sessions.get_session_from_cookie(session_cookie)
85-
self._user = self._session.get_user()
86-
except sessions.SessionDoesNotExist:
87-
from django.parts.auth import anonymoususers
88-
self._session = None
89-
self._user = anonymoususers.AnonymousUser()
90-
91-
def _get_session(self):
92-
if not hasattr(self, '_session'):
93-
self._load_session_and_user()
94-
return self._session
95-
96-
def _set_session(self, session):
97-
self._session = session
98-
9979
def _get_user(self):
10080
if not hasattr(self, '_user'):
101-
self._load_session_and_user()
81+
from django.models.auth import users
82+
try:
83+
user_id = self.session[users.SESSION_KEY]
84+
if not user_id:
85+
raise ValueError
86+
self._user = users.get_object(pk=user_id)
87+
except (AttributeError, KeyError, ValueError, users.UserDoesNotExist):
88+
from django.parts.auth import anonymoususers
89+
self._user = anonymoususers.AnonymousUser()
10290
return self._user
10391

10492
def _set_user(self, user):
@@ -110,7 +98,6 @@ def _set_user(self, user):
11098
FILES = property(_get_files)
11199
REQUEST = property(_get_request)
112100
raw_post_data = property(_get_raw_post_data)
113-
session = property(_get_session, _set_session)
114101
user = property(_get_user, _set_user)
115102

116103
class WSGIHandler(BaseHandler):

django/middleware/admin.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from django.utils import httpwrappers
22
from django.core import template_loader
33
from django.core.extensions import DjangoContext as Context
4-
from django.models.auth import sessions, users
4+
from django.models.auth import users
55
from django.views.registration import passwords
66
from django.views.auth.login import logout
77
import base64, md5
@@ -29,14 +29,17 @@ def process_view(self, request, view_func, param_dict):
2929
# Otherwise the password reset would need its own entry in the httpd
3030
# conf, which is a little uglier than this. Same goes for the logout
3131
# view.
32+
3233
if view_func in (passwords.password_reset, passwords.password_reset_done, logout):
3334
return
3435

36+
assert hasattr(request, 'session'), "The admin requires session middleware to be installed. Edit your MIDDLEWARE_CLASSES setting to insert 'django.middleware.sessions.SessionMiddleware' before %r." % self.__class__.__name__
37+
3538
# Check for a logged in, valid user
3639
if self.user_is_valid(request.user):
3740
return
3841

39-
# If this isn't alreay the login page, display it
42+
# If this isn't already the login page, display it
4043
if not request.POST.has_key('this_is_the_login_form'):
4144
if request.POST:
4245
message = "Please log in again, because your session has expired. "\
@@ -64,18 +67,16 @@ def process_view(self, request, view_func, param_dict):
6467
# The user data is correct; log in the user in and continue
6568
else:
6669
if self.authenticate_user(user, request.POST.get('password', '')):
70+
request.session[users.SESSION_KEY] = user.id
6771
if request.POST.has_key('post_data'):
6872
post_data = decode_post_data(request.POST['post_data'])
6973
if post_data and not post_data.has_key('this_is_the_login_form'):
7074
# overwrite request.POST with the saved post_data, and continue
7175
request.POST = post_data
7276
request.user = user
73-
request.session = sessions.create_session(user.id)
7477
return
7578
else:
76-
response = httpwrappers.HttpResponseRedirect(request.path)
77-
sessions.start_web_session(user.id, request, response)
78-
return response
79+
return httpwrappers.HttpResponseRedirect(request.path)
7980
else:
8081
return self.display_login_form(request, ERROR_MESSAGE)
8182

django/middleware/sessions.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
from django.conf.settings import SESSION_COOKIE_NAME, SESSION_COOKIE_AGE, SESSION_COOKIE_DOMAIN
2+
from django.models.core import sessions
3+
import datetime
4+
5+
TEST_COOKIE_NAME = 'testcookie'
6+
TEST_COOKIE_VALUE = 'worked'
7+
8+
class SessionWrapper(object):
9+
def __init__(self, session_key):
10+
self.session_key = session_key
11+
self.modified = False
12+
13+
def __getitem__(self, key):
14+
return self._session[key]
15+
16+
def __setitem__(self, key, value):
17+
self._session[key] = value
18+
self.modified = True
19+
20+
def __delitem__(self, key):
21+
del self._session[key]
22+
self.modified = True
23+
24+
def get(self, key, default=None):
25+
return self._session.get(key, default)
26+
27+
def set_test_cookie(self):
28+
self[TEST_COOKIE_NAME] = TEST_COOKIE_VALUE
29+
30+
def test_cookie_worked(self):
31+
return self.get(TEST_COOKIE_NAME) == TEST_COOKIE_VALUE
32+
33+
def _get_session(self):
34+
# Lazily loads session from storage.
35+
try:
36+
return self._session_cache
37+
except AttributeError:
38+
if self.session_key is None:
39+
self._session_cache = {}
40+
else:
41+
try:
42+
s = sessions.get_object(session_key__exact=self.session_key,
43+
expire_date__gt=datetime.datetime.now())
44+
self._session_cache = s.get_decoded()
45+
except sessions.SessionDoesNotExist:
46+
self._session_cache = {}
47+
return self._session_cache
48+
49+
_session = property(_get_session)
50+
51+
class SessionMiddleware:
52+
def process_view(self, request, view_func, param_dict):
53+
request.session = SessionWrapper(request.COOKIES.get(SESSION_COOKIE_NAME, None))
54+
55+
def process_response(self, request, response):
56+
# If request.session was modified, or if response.session was set, save
57+
# those changes and set a session cookie.
58+
try:
59+
modified = request.session.modified
60+
except AttributeError:
61+
modified = False
62+
if modified:
63+
session_key = request.session.session_key or sessions.get_new_session_key()
64+
new_session = sessions.save(session_key, request.session._session,
65+
datetime.datetime.now() + datetime.timedelta(seconds=SESSION_COOKIE_AGE))
66+
# TODO: Accept variable session length and domain.
67+
response.set_cookie(SESSION_COOKIE_NAME, session_key,
68+
max_age=SESSION_COOKIE_AGE, domain=SESSION_COOKIE_DOMAIN)
69+
return response

django/models/auth.py

Lines changed: 3 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ class User(meta.Model):
4444
help_text="In addition to the permissions manually assigned, this user will also get all permissions granted to each group he/she is in."),
4545
meta.ManyToManyField(Permission, name='user_permissions', blank=True, filter_interface=meta.HORIZONTAL),
4646
)
47+
module_constants = {
48+
'SESSION_KEY': '_auth_user_id',
49+
}
4750
ordering = ('username',)
4851
exceptions = ('SiteProfileNotAvailable',)
4952
admin = meta.Admin(
@@ -172,64 +175,6 @@ def _module_make_random_password(length=10, allowed_chars='abcdefghjkmnpqrstuvwx
172175
from random import choice
173176
return ''.join([choice(allowed_chars) for i in range(length)])
174177

175-
class Session(meta.Model):
176-
fields = (
177-
meta.ForeignKey(User),
178-
meta.CharField('session_md5', maxlength=32),
179-
meta.DateTimeField('start_time', auto_now=True),
180-
)
181-
module_constants = {
182-
'TEST_COOKIE_NAME': 'testcookie',
183-
'TEST_COOKIE_VALUE': 'worked',
184-
}
185-
186-
def __repr__(self):
187-
return "session started at %s" % self.start_time
188-
189-
def get_cookie(self):
190-
"Returns a tuple of the cookie name and value for this session."
191-
from django.conf.settings import AUTH_SESSION_COOKIE, SECRET_KEY
192-
import md5
193-
return AUTH_SESSION_COOKIE, self.session_md5 + md5.new(self.session_md5 + SECRET_KEY + 'auth').hexdigest()
194-
195-
def _module_create_session(user_id):
196-
"Registers a session and returns the session_md5."
197-
from django.conf.settings import SECRET_KEY
198-
import md5, random, sys
199-
# The random module is seeded when this Apache child is created.
200-
# Use person_id and SECRET_KEY as added salt.
201-
session_md5 = md5.new(str(random.randint(user_id, sys.maxint - 1)) + SECRET_KEY).hexdigest()
202-
s = Session(None, user_id, session_md5, None)
203-
s.save()
204-
return s
205-
206-
def _module_get_session_from_cookie(session_cookie_string):
207-
from django.conf.settings import SECRET_KEY
208-
import md5
209-
if not session_cookie_string:
210-
raise SessionDoesNotExist
211-
session_md5, tamper_check = session_cookie_string[:32], session_cookie_string[32:]
212-
if md5.new(session_md5 + SECRET_KEY + 'auth').hexdigest() != tamper_check:
213-
raise SessionDoesNotExist
214-
return get_object(session_md5__exact=session_md5, select_related=True)
215-
216-
def _module_destroy_all_sessions(user_id):
217-
"Destroys all sessions for a user, logging out all computers."
218-
for session in get_list(user_id__exact=user_id):
219-
session.delete()
220-
221-
def _module_start_web_session(user_id, request, response):
222-
"Sets the necessary cookie in the given HttpResponse object, also updates last login time for user."
223-
from django.models.auth import users
224-
from django.conf.settings import REGISTRATION_COOKIE_DOMAIN
225-
user = users.get_object(pk=user_id)
226-
user.last_login = datetime.datetime.now()
227-
user.save()
228-
session = create_session(user_id)
229-
key, value = session.get_cookie()
230-
cookie_domain = REGISTRATION_COOKIE_DOMAIN or None
231-
response.set_cookie(key, value, domain=cookie_domain)
232-
233178
class Message(meta.Model):
234179
fields = (
235180
meta.ForeignKey(User),

0 commit comments

Comments
 (0)