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
aad6dc43
Commit
aad6dc43
authored
11 years ago
by
ihoover
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #417 from edx/ihoover/feature_flag_auto_auth
Ihoover/feature flag auto auth
parents
c80a05f4
56883d65
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
199 additions
and
39 deletions
+199
-39
cms/envs/common.py
+8
-5
cms/urls.py
+6
-0
common/djangoapps/student/tests/test_auto_auth.py
+111
-0
common/djangoapps/student/views.py
+53
-31
lms/envs/aws.py
+4
-0
lms/envs/common.py
+11
-3
lms/urls.py
+6
-0
No files found.
cms/envs/common.py
View file @
aad6dc43
...
...
@@ -62,9 +62,6 @@ MITX_FEATURES = {
}
ENABLE_JASMINE
=
False
# needed to use lms student app
GENERATE_RANDOM_USER_CREDENTIALS
=
False
############################# SET PATH INFORMATION #############################
PROJECT_ROOT
=
path
(
__file__
)
.
abspath
()
.
dirname
()
.
dirname
()
# /mitx/cms
...
...
@@ -108,9 +105,12 @@ TEMPLATE_CONTEXT_PROCESSORS = (
'django.core.context_processors.static'
,
'django.contrib.messages.context_processors.messages'
,
'django.contrib.auth.context_processors.auth'
,
# this is required for admin
'django.core.context_processors.csrf'
,
# necessary for csrf protection
)
# add csrf support unless disabled for load testing
if
not
MITX_FEATURES
.
get
(
'AUTOMATIC_AUTH_FOR_LOAD_TESTING'
):
TEMPLATE_CONTEXT_PROCESSORS
+=
(
'django.core.context_processors.csrf'
,)
# necessary for csrf protection
LMS_BASE
=
None
#################### CAPA External Code Evaluation #############################
...
...
@@ -142,7 +142,6 @@ MIDDLEWARE_CLASSES = (
'django.middleware.cache.UpdateCacheMiddleware'
,
'django.middleware.common.CommonMiddleware'
,
'django.contrib.sessions.middleware.SessionMiddleware'
,
'django.middleware.csrf.CsrfViewMiddleware'
,
'method_override.middleware.MethodOverrideMiddleware'
,
# Instead of AuthenticationMiddleware, we use a cache-backed version
...
...
@@ -158,6 +157,10 @@ MIDDLEWARE_CLASSES = (
'django.middleware.transaction.TransactionMiddleware'
)
# add in csrf middleware unless disabled for load testing
if
not
MITX_FEATURES
.
get
(
'AUTOMATIC_AUTH_FOR_LOAD_TESTING'
):
MIDDLEWARE_CLASSES
=
MIDDLEWARE_CLASSES
+
(
'django.middleware.csrf.CsrfViewMiddleware'
,)
############################ SIGNAL HANDLERS ################################
# This is imported to register the exception signal handling that logs exceptions
import
monitoring.exceptions
# noqa
...
...
This diff is collapsed.
Click to expand it.
cms/urls.py
View file @
aad6dc43
...
...
@@ -149,6 +149,12 @@ if settings.MITX_FEATURES.get('ENABLE_SERVICE_STATUS'):
urlpatterns
+=
(
url
(
r'^admin/'
,
include
(
admin
.
site
.
urls
)),)
# enable automatic login
if
settings
.
MITX_FEATURES
.
get
(
'AUTOMATIC_AUTH_FOR_LOAD_TESTING'
):
urlpatterns
+=
(
url
(
r'^auto_auth$'
,
'student.views.auto_auth'
),
)
urlpatterns
=
patterns
(
*
urlpatterns
)
# Custom error pages
...
...
This diff is collapsed.
Click to expand it.
common/djangoapps/student/tests/test_auto_auth.py
0 → 100644
View file @
aad6dc43
from
django.test
import
TestCase
from
django.test.client
import
Client
from
django.contrib.auth.models
import
User
from
util.testing
import
UrlResetMixin
from
mock
import
patch
from
django.core.urlresolvers
import
reverse
,
NoReverseMatch
class
AutoAuthEnabledTestCase
(
UrlResetMixin
,
TestCase
):
"""
Tests for the Auto auth view that we have for load testing.
"""
@patch.dict
(
"django.conf.settings.MITX_FEATURES"
,
{
"AUTOMATIC_AUTH_FOR_LOAD_TESTING"
:
True
})
def
setUp
(
self
):
# Patching the settings.MITX_FEATURES['AUTOMATIC_AUTH_FOR_LOAD_TESTING']
# value affects the contents of urls.py,
# so we need to call super.setUp() which reloads urls.py (because
# of the UrlResetMixin)
super
(
AutoAuthEnabledTestCase
,
self
)
.
setUp
()
self
.
url
=
'/auto_auth'
self
.
cms_csrf_url
=
"signup"
self
.
lms_csrf_url
=
"signin_user"
self
.
client
=
Client
()
def
test_create_user
(
self
):
"""
Test that user gets created when visiting the page.
"""
self
.
client
.
get
(
self
.
url
)
qset
=
User
.
objects
.
all
()
# assert user was created and is active
self
.
assertEqual
(
qset
.
count
(),
1
)
user
=
qset
[
0
]
assert
user
.
is_active
@patch
(
'student.views.random.randint'
)
def
test_create_multiple_users
(
self
,
randint
):
"""
Test to make sure multiple users are created.
"""
randint
.
return_value
=
1
self
.
client
.
get
(
self
.
url
)
randint
.
return_value
=
2
self
.
client
.
get
(
self
.
url
)
qset
=
User
.
objects
.
all
()
# make sure that USER_1 and USER_2 were created
self
.
assertEqual
(
qset
.
count
(),
2
)
@patch.dict
(
"django.conf.settings.MITX_FEATURES"
,
{
"MAX_AUTO_AUTH_USERS"
:
1
})
def
test_login_already_created_user
(
self
):
"""
Test that when we have reached the limit for automatic users
a subsequent request results in an already existant one being
logged in.
"""
# auto-generate 1 user (the max)
url
=
'/auto_auth'
self
.
client
.
get
(
url
)
# go to the site again
self
.
client
.
get
(
url
)
qset
=
User
.
objects
.
all
()
# make sure it is the same user
self
.
assertEqual
(
qset
.
count
(),
1
)
class
AutoAuthDisabledTestCase
(
UrlResetMixin
,
TestCase
):
"""
Test that the page is inaccessible with default settings
"""
@patch.dict
(
"django.conf.settings.MITX_FEATURES"
,
{
"AUTOMATIC_AUTH_FOR_LOAD_TESTING"
:
False
})
def
setUp
(
self
):
# Patching the settings.MITX_FEATURES['AUTOMATIC_AUTH_FOR_LOAD_TESTING']
# value affects the contents of urls.py,
# so we need to call super.setUp() which reloads urls.py (because
# of the UrlResetMixin)
super
(
AutoAuthDisabledTestCase
,
self
)
.
setUp
()
self
.
url
=
'/auto_auth'
self
.
client
=
Client
()
def
test_auto_auth_disabled
(
self
):
"""
Make sure automatic authentication is disabled.
"""
response
=
self
.
client
.
get
(
self
.
url
)
self
.
assertEqual
(
response
.
status_code
,
404
)
def
test_csrf_enabled
(
self
):
"""
test that when not load testing, csrf protection is on
"""
cms_csrf_url
=
"signup"
lms_csrf_url
=
"signin_user"
self
.
client
=
Client
(
enforce_csrf_checks
=
True
)
try
:
csrf_protected_url
=
reverse
(
cms_csrf_url
)
response
=
self
.
client
.
post
(
csrf_protected_url
)
except
NoReverseMatch
:
csrf_protected_url
=
reverse
(
lms_csrf_url
)
response
=
self
.
client
.
post
(
csrf_protected_url
)
self
.
assertEqual
(
response
.
status_code
,
403
)
This diff is collapsed.
Click to expand it.
common/djangoapps/student/views.py
View file @
aad6dc43
...
...
@@ -19,6 +19,7 @@ from django.core.context_processors import csrf
from
django.core.mail
import
send_mail
from
django.core.urlresolvers
import
reverse
from
django.core.validators
import
validate_email
,
validate_slug
,
ValidationError
from
django.core.exceptions
import
ObjectDoesNotExist
from
django.db
import
IntegrityError
,
transaction
from
django.http
import
HttpResponse
,
HttpResponseBadRequest
,
HttpResponseForbidden
,
HttpResponseNotAllowed
,
Http404
from
django.shortcuts
import
redirect
...
...
@@ -674,18 +675,20 @@ def create_account(request, post_override=None):
subject
=
''
.
join
(
subject
.
splitlines
())
message
=
render_to_string
(
'emails/activation_email.txt'
,
d
)
try
:
if
settings
.
MITX_FEATURES
.
get
(
'REROUTE_ACTIVATION_EMAIL'
):
dest_addr
=
settings
.
MITX_FEATURES
[
'REROUTE_ACTIVATION_EMAIL'
]
message
=
(
"Activation for
%
s (
%
s):
%
s
\n
"
%
(
user
,
user
.
email
,
profile
.
name
)
+
'-'
*
80
+
'
\n\n
'
+
message
)
send_mail
(
subject
,
message
,
settings
.
DEFAULT_FROM_EMAIL
,
[
dest_addr
],
fail_silently
=
False
)
elif
not
settings
.
GENERATE_RANDOM_USER_CREDENTIALS
:
res
=
user
.
email_user
(
subject
,
message
,
settings
.
DEFAULT_FROM_EMAIL
)
except
:
log
.
warning
(
'Unable to send activation email to user'
,
exc_info
=
True
)
js
[
'value'
]
=
_
(
'Could not send activation e-mail.'
)
return
HttpResponse
(
json
.
dumps
(
js
))
# dont send email if we are doing load testing or random user generation for some reason
if
not
(
settings
.
MITX_FEATURES
.
get
(
'AUTOMATIC_AUTH_FOR_LOAD_TESTING'
)):
try
:
if
settings
.
MITX_FEATURES
.
get
(
'REROUTE_ACTIVATION_EMAIL'
):
dest_addr
=
settings
.
MITX_FEATURES
[
'REROUTE_ACTIVATION_EMAIL'
]
message
=
(
"Activation for
%
s (
%
s):
%
s
\n
"
%
(
user
,
user
.
email
,
profile
.
name
)
+
'-'
*
80
+
'
\n\n
'
+
message
)
send_mail
(
subject
,
message
,
settings
.
DEFAULT_FROM_EMAIL
,
[
dest_addr
],
fail_silently
=
False
)
else
:
res
=
user
.
email_user
(
subject
,
message
,
settings
.
DEFAULT_FROM_EMAIL
)
except
:
log
.
warning
(
'Unable to send activation email to user'
,
exc_info
=
True
)
js
[
'value'
]
=
_
(
'Could not send activation e-mail.'
)
return
HttpResponse
(
json
.
dumps
(
js
))
# Immediately after a user creates an account, we log them in. They are only
# logged in until they close the browser. They can't log in again until they click
...
...
@@ -902,32 +905,51 @@ def create_exam_registration(request, post_override=None):
return
HttpResponse
(
json
.
dumps
(
js
),
mimetype
=
"application/json"
)
def
get_random_post_override
(
):
def
auto_auth
(
request
):
"""
Return a dictionary suitable for passing to post_vars of _do_create_account or post_override
of create_account, with random user info.
Automatically logs the user in with a generated random credentials
This view is only accessible when
settings.MITX_SETTINGS['AUTOMATIC_AUTH_FOR_LOAD_TESTING'] is true.
"""
def
id_generator
(
size
=
6
,
chars
=
string
.
ascii_uppercase
+
string
.
ascii_lowercase
+
string
.
digits
):
return
''
.
join
(
random
.
choice
(
chars
)
for
x
in
range
(
size
))
return
{
'username'
:
"random_"
+
id_generator
(),
'email'
:
id_generator
(
size
=
10
,
chars
=
string
.
ascii_lowercase
)
+
"_dummy_test@mitx.mit.edu"
,
'password'
:
id_generator
(),
'name'
:
(
id_generator
(
size
=
5
,
chars
=
string
.
ascii_lowercase
)
+
" "
+
id_generator
(
size
=
7
,
chars
=
string
.
ascii_lowercase
)),
'honor_code'
:
u'true'
,
'terms_of_service'
:
u'true'
,
}
def
get_dummy_post_data
(
username
,
password
):
"""
Return a dictionary suitable for passing to post_vars of _do_create_account or post_override
of create_account, with specified username and password.
"""
return
{
'username'
:
username
,
'email'
:
username
+
"_dummy_test@mitx.mit.edu"
,
'password'
:
password
,
'name'
:
username
+
" "
+
username
,
'honor_code'
:
u'true'
,
'terms_of_service'
:
u'true'
,
}
def
create_random_account
(
create_account_function
):
def
inner_create_random_account
(
request
):
return
create_account_function
(
request
,
post_override
=
get_random_post_override
())
# generate random user ceredentials from a small name space (determined by settings)
name_base
=
'USER_'
pass_base
=
'PASS_'
return
inner_create_random_account
max_users
=
settings
.
MITX_FEATURES
.
get
(
'MAX_AUTO_AUTH_USERS'
,
200
)
number
=
random
.
randint
(
1
,
max_users
)
# TODO (vshnayder): do we need GENERATE_RANDOM_USER_CREDENTIALS for anything?
if
settings
.
GENERATE_RANDOM_USER_CREDENTIALS
:
create_account
=
create_random_account
(
create_account
)
username
=
name_base
+
str
(
number
)
password
=
pass_base
+
str
(
number
)
# if they already are a user, log in
try
:
user
=
User
.
objects
.
get
(
username
=
username
)
user
=
authenticate
(
username
=
username
,
password
=
password
)
login
(
request
,
user
)
# else create and activate account info
except
ObjectDoesNotExist
:
post_override
=
get_dummy_post_data
(
username
,
password
)
create_account
(
request
,
post_override
=
post_override
)
request
.
user
.
is_active
=
True
request
.
user
.
save
()
# return empty success
return
HttpResponse
(
''
)
@ensure_csrf_cookie
...
...
This diff is collapsed.
Click to expand it.
lms/envs/aws.py
View file @
aad6dc43
...
...
@@ -178,6 +178,10 @@ for name, value in ENV_TOKENS.get("CODE_JAIL", {}).items():
COURSES_WITH_UNSAFE_CODE
=
ENV_TOKENS
.
get
(
"COURSES_WITH_UNSAFE_CODE"
,
[])
# automatic log in for load testing
MITX_FEATURES
[
'AUTOMATIC_AUTH_FOR_LOAD_TESTING'
]
=
ENV_TOKENS
.
get
(
'AUTOMATIC_AUTH_FOR_LOAD_TESTING'
)
MITX_FEATURES
[
'MAX_AUTO_AUTH_USERS'
]
=
ENV_TOKENS
.
get
(
'MAX_AUTO_AUTH_USERS'
)
############################## SECURE AUTH ITEMS ###############
# Secret things: passwords, access keys, etc.
...
...
This diff is collapsed.
Click to expand it.
lms/envs/common.py
View file @
aad6dc43
...
...
@@ -37,7 +37,6 @@ PLATFORM_NAME = "edX"
COURSEWARE_ENABLED
=
True
ENABLE_JASMINE
=
False
GENERATE_RANDOM_USER_CREDENTIALS
=
False
PERFSTATS
=
False
DISCUSSION_SETTINGS
=
{
...
...
@@ -145,6 +144,9 @@ MITX_FEATURES = {
# Allow use of the hint managment instructor view.
'ENABLE_HINTER_INSTRUCTOR_VIEW'
:
False
,
# for load testing
'AUTOMATIC_AUTH_FOR_LOAD_TESTING'
:
False
,
# Toggle to enable chat availability (configured on a per-course
# basis in Studio)
'ENABLE_CHAT'
:
False
...
...
@@ -218,7 +220,6 @@ TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.messages.context_processors.messages'
,
#'django.core.context_processors.i18n',
'django.contrib.auth.context_processors.auth'
,
# this is required for admin
'django.core.context_processors.csrf'
,
# necessary for csrf protection
# Added for django-wiki
'django.core.context_processors.media'
,
...
...
@@ -231,6 +232,10 @@ TEMPLATE_CONTEXT_PROCESSORS = (
'mitxmako.shortcuts.marketing_link_context_processor'
,
)
# add csrf support unless disabled for load testing
if
not
MITX_FEATURES
.
get
(
'AUTOMATIC_AUTH_FOR_LOAD_TESTING'
):
TEMPLATE_CONTEXT_PROCESSORS
+=
(
'django.core.context_processors.csrf'
,)
# necessary for csrf protection
STUDENT_FILEUPLOAD_MAX_SIZE
=
4
*
1000
*
1000
# 4 MB
MAX_FILEUPLOADS_PER_INPUT
=
20
...
...
@@ -469,7 +474,6 @@ MIDDLEWARE_CLASSES = (
'django_comment_client.middleware.AjaxExceptionMiddleware'
,
'django.middleware.common.CommonMiddleware'
,
'django.contrib.sessions.middleware.SessionMiddleware'
,
'django.middleware.csrf.CsrfViewMiddleware'
,
# Instead of AuthenticationMiddleware, we use a cached backed version
#'django.contrib.auth.middleware.AuthenticationMiddleware',
...
...
@@ -488,6 +492,10 @@ MIDDLEWARE_CLASSES = (
'codejail.django_integration.ConfigureCodeJailMiddleware'
,
)
# add in csrf middleware unless disabled for load testing
if
not
MITX_FEATURES
.
get
(
'AUTOMATIC_AUTH_FOR_LOAD_TESTING'
):
MIDDLEWARE_CLASSES
=
MIDDLEWARE_CLASSES
+
(
'django.middleware.csrf.CsrfViewMiddleware'
,)
############################### Pipeline #######################################
STATICFILES_STORAGE
=
'pipeline.storage.PipelineCachedStorage'
...
...
This diff is collapsed.
Click to expand it.
lms/urls.py
View file @
aad6dc43
...
...
@@ -441,6 +441,12 @@ if settings.MITX_FEATURES.get('ENABLE_HINTER_INSTRUCTOR_VIEW'):
'instructor.hint_manager.hint_manager'
,
name
=
"hint_manager"
),
)
# enable automatic login
if
settings
.
MITX_FEATURES
.
get
(
'AUTOMATIC_AUTH_FOR_LOAD_TESTING'
):
urlpatterns
+=
(
url
(
r'^auto_auth$'
,
'student.views.auto_auth'
),
)
urlpatterns
=
patterns
(
*
urlpatterns
)
if
settings
.
DEBUG
:
...
...
This diff is collapsed.
Click to expand it.
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