22
22
# Provides services for checking logins and presenting the login page.
26
26
from mod_python import Session
29
from ivle import (util, db, caps, forumutil)
30
from ivle.auth import authenticate, autherror
29
from ivle import (util, caps, forumutil)
30
from ivle.auth import authenticate, AuthError
33
34
"""Determines whether the user is logged in or not (looking at sessions),
47
48
# Get the user details from the session, if already logged in
48
49
# (None means not logged in yet)
49
login_details = get_user_details(req)
50
user = get_user_details(req)
51
52
# Check the session to see if someone is logged in. If so, go with it.
52
53
# No security is required here. You must have already been authenticated
53
54
# in order to get a 'login_name' variable in the session.
54
if login_details is not None and login_details.state == "enabled":
55
if user is not None and user.state == "enabled":
55
56
# Only allow users to authenticate if their account is ENABLED
60
61
# Check if there is any postdata containing login information
61
if login_details is None and req.method == 'POST':
62
if user is None and req.method == 'POST':
62
63
fields = req.get_fieldstorage()
63
64
username = fields.getfirst('user')
64
65
password = fields.getfirst('pass')
70
71
badlogin = "No password supplied."
74
authenticate.authenticate(username.value, password.value)
75
# NOTE: Can't catch AuthError, since each module throws a
76
# different identity of AuthError.
77
except Exception, msg:
74
user = authenticate.authenticate(req.store,
75
username.value, password.value)
76
except AuthError, msg:
79
if login_details is None:
80
79
# Must have got an error. Do not authenticate.
82
elif login_details.pass_expired():
81
elif user.password_expired:
83
82
badlogin = "Your password has expired."
84
elif login_details.acct_expired():
83
elif user.account_expired:
85
84
badlogin = "Your account has expired."
87
86
# Success - Set the session and redirect to avoid POSTDATA
88
87
session = req.get_session()
89
session['user'] = login_details
88
session['login'] = user.login
91
db.DB().update_user(username.value,
92
last_login = time.localtime())
93
req.add_cookie(forumutil.make_forum_cookie(login_details))
90
user.last_login = datetime.datetime.now()
92
req.add_cookie(forumutil.make_forum_cookie(user))
94
93
req.throw_redirect(req.uri)
96
95
# Present the HTML login page
99
98
req.write_html_head_foot = True
101
100
# User is not logged in or their account is not enabled.
102
if login_details is not None:
103
102
# Only possible if no errors occured thus far
104
if login_details.state == "no_agreement":
103
if user.state == "no_agreement":
105
104
# User has authenticated but has not accepted the TOS.
106
105
# Present them with the TOS page.
107
106
# First set their username for display at the top, but make sure
108
107
# the apps tabs are not displayed
109
req.user = login_details
110
109
# IMPORTANT NOTE FOR HACKERS: You can't simply disable this check
111
110
# if you are not planning to display a TOS page - the TOS
112
111
# acceptance process actually calls usermgt to create the user
113
112
# jails and related stuff.
114
present_tos(req, login_details.fullname)
113
present_tos(req, user.fullname)
116
elif login_details.state == "disabled":
115
elif user.state == "disabled":
117
116
# User has authenticated but their account is disabled
118
117
badlogin = "Your account has been disabled."
119
elif login_details.state == "pending":
118
elif user.state == "pending":
120
119
# FIXME: this isn't quite the right answer, but it
121
120
# should be more robust in the short term.
122
121
session = req.get_session()
123
122
session.invalidate()
125
db.DB().update_user(login_details.login, state='no_agreement')
124
user.state = u'no_agreement'
126
126
req.throw_redirect(req.uri)
128
128
# Write the HTML for the login page
159
159
session = req.get_session()
161
161
# Check the session to see if someone is logged in. If so, go with it.
162
# No security is required here. You must have already been authenticated
163
# in order to get a 'login_name' variable in the session.
165
return session['user']
163
login = session['login']
167
# Get the full User object from the db associated with this login
168
return ivle.database.User.get_by_login(req.store, login)
169
170
def present_tos(req, fullname):
170
171
"""Present the Terms of Service screen to the user (who has just logged in
171
172
for the first time and needs to accept these before being admitted into