Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
0501775d
Commit
0501775d
authored
Mar 03, 2014
by
Dave St.Germain
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add an option to prevent multiple logins of the same user.
parent
6517b067
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
63 additions
and
2 deletions
+63
-2
cms/envs/common.py
+3
-0
common/djangoapps/student/models.py
+31
-2
common/djangoapps/student/tests/test_login.py
+26
-0
lms/envs/common.py
+3
-0
No files found.
cms/envs/common.py
View file @
0501775d
...
...
@@ -91,6 +91,9 @@ FEATURES = {
# Allow creating courses with non-ascii characters in the course id
'ALLOW_UNICODE_COURSE_ID'
:
False
,
# Prevent concurrent logins per user
'PREVENT_CONCURRENT_LOGINS'
:
False
,
}
ENABLE_JASMINE
=
False
...
...
common/djangoapps/student/models.py
View file @
0501775d
...
...
@@ -34,6 +34,7 @@ from django_countries import CountryField
from
track
import
contexts
from
track.views
import
server_track
from
eventtracking
import
tracker
from
importlib
import
import_module
from
course_modes.models
import
CourseMode
import
lms.lib.comment_client
as
cc
...
...
@@ -42,6 +43,7 @@ from util.query import use_read_replica_if_available
unenroll_done
=
Signal
(
providing_args
=
[
"course_enrollment"
])
log
=
logging
.
getLogger
(
__name__
)
AUDIT_LOG
=
logging
.
getLogger
(
"audit"
)
SessionStore
=
import_module
(
settings
.
SESSION_ENGINE
)
.
SessionStore
class
AnonymousUserId
(
models
.
Model
):
...
...
@@ -239,6 +241,20 @@ class UserProfile(models.Model):
def
set_meta
(
self
,
js
):
self
.
meta
=
json
.
dumps
(
js
)
def
set_login_session
(
self
,
session_id
=
None
):
"""
Sets the current session id for the logged-in user.
If session_id doesn't match the existing session,
deletes the old session object.
"""
meta
=
self
.
get_meta
()
old_login
=
meta
.
get
(
'session_id'
,
None
)
if
old_login
:
SessionStore
(
session_key
=
old_login
)
.
delete
()
meta
[
'session_id'
]
=
session_id
self
.
set_meta
(
meta
)
self
.
save
()
def
unique_id_for_user
(
user
):
"""
...
...
@@ -292,7 +308,6 @@ class PendingEmailChange(models.Model):
activation_key
=
models
.
CharField
((
'activation key'
),
max_length
=
32
,
unique
=
True
,
db_index
=
True
)
EVENT_NAME_ENROLLMENT_ACTIVATED
=
'edx.course.enrollment.activated'
EVENT_NAME_ENROLLMENT_DEACTIVATED
=
'edx.course.enrollment.deactivated'
...
...
@@ -383,7 +398,6 @@ class CourseEnrollment(models.Model):
# list of possible values.
mode
=
models
.
CharField
(
default
=
"honor"
,
max_length
=
100
)
class
Meta
:
unique_together
=
((
'user'
,
'course_id'
),)
ordering
=
(
'user'
,
'course_id'
)
...
...
@@ -866,3 +880,18 @@ def log_successful_logout(sender, request, user, **kwargs):
AUDIT_LOG
.
info
(
u"Logout - user.id: {0}"
.
format
(
request
.
user
.
id
))
else
:
AUDIT_LOG
.
info
(
u"Logout - {0}"
.
format
(
request
.
user
))
@receiver
(
user_logged_in
)
@receiver
(
user_logged_out
)
def
enforce_single_login
(
sender
,
request
,
user
,
signal
,
**
kwargs
):
"""
Sets the current session id in the user profile,
to prevent concurrent logins.
"""
if
settings
.
FEATURES
.
get
(
'PREVENT_CONCURRENT_LOGINS'
,
False
):
if
signal
==
user_logged_in
:
key
=
request
.
session
.
session_key
else
:
key
=
None
user
.
profile
.
set_login_session
(
key
)
common/djangoapps/student/tests/test_login.py
View file @
0501775d
...
...
@@ -179,6 +179,32 @@ class LoginTest(TestCase):
response
,
_audit_log
=
self
.
_login_response
(
'test@edx.org'
,
'wrong_password'
)
self
.
_assert_response
(
response
,
success
=
False
,
value
=
'Too many failed login attempts'
)
@patch.dict
(
"django.conf.settings.FEATURES"
,
{
'PREVENT_CONCURRENT_LOGINS'
:
True
})
def
test_single_session
(
self
):
creds
=
{
'email'
:
'test@edx.org'
,
'password'
:
'test_password'
}
client1
=
Client
()
client2
=
Client
()
response
=
client1
.
post
(
self
.
url
,
creds
)
self
.
_assert_response
(
response
,
success
=
True
)
self
.
assertEqual
(
self
.
user
.
profile
.
get_meta
()[
'session_id'
],
self
.
client
.
session
.
session_key
)
# second login should log out the first
response
=
client2
.
post
(
self
.
url
,
creds
)
self
.
_assert_response
(
response
,
success
=
True
)
try
:
# this test can be run with either lms or studio settings
# since studio does not have a dashboard url, we should
# look for another url that is login_required, in that case
url
=
reverse
(
'dashboard'
)
except
NoReverseMatch
:
url
=
reverse
(
'upload_transcripts'
)
response
=
client1
.
get
(
url
)
# client1 will be logged out
self
.
assertEqual
(
response
.
status_code
,
302
)
def
_login_response
(
self
,
email
,
password
,
patched_audit_log
=
'student.views.AUDIT_LOG'
):
''' Post the login info '''
post_params
=
{
'email'
:
email
,
'password'
:
password
}
...
...
lms/envs/common.py
View file @
0501775d
...
...
@@ -239,6 +239,9 @@ FEATURES = {
# Toggle to enable alternate urls for marketing links
'ENABLE_MKTG_SITE'
:
False
,
# Prevent concurrent logins per user
'PREVENT_CONCURRENT_LOGINS'
:
False
,
}
# Used for A/B testing
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment