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
a820b3f7
Commit
a820b3f7
authored
Mar 27, 2014
by
Dave St.Germain
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2793 from edx/dcs/mat-17
Add an option to prevent multiple logins of the same user.
parents
6517b067
0501775d
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 @
a820b3f7
...
...
@@ -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 @
a820b3f7
...
...
@@ -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 @
a820b3f7
...
...
@@ -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 @
a820b3f7
...
...
@@ -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