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
0248f8af
Commit
0248f8af
authored
Sep 18, 2015
by
Diana Huang
Committed by
Adam Palay
Oct 07, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add new clickjacking decorator that whitelists LTI consumers.
parent
c76e2492
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
116 additions
and
0 deletions
+116
-0
cms/djangoapps/contentstore/views/public.py
+3
-0
common/djangoapps/third_party_auth/decorators.py
+32
-0
common/djangoapps/third_party_auth/migrations/0005_auto__add_field_ltiproviderconfig_lti_hostname.py
+0
-0
common/djangoapps/third_party_auth/models.py
+9
-0
common/djangoapps/third_party_auth/tests/test_decorators.py
+52
-0
lms/djangoapps/student_account/test/test_views.py
+18
-0
lms/djangoapps/student_account/views.py
+2
-0
No files found.
cms/djangoapps/contentstore/views/public.py
View file @
0248f8af
...
...
@@ -2,6 +2,7 @@
Public views
"""
from
django.views.decorators.csrf
import
ensure_csrf_cookie
from
django.views.decorators.clickjacking
import
xframe_options_deny
from
django.core.context_processors
import
csrf
from
django.core.urlresolvers
import
reverse
from
django.shortcuts
import
redirect
...
...
@@ -17,6 +18,7 @@ __all__ = ['signup', 'login_page', 'howitworks']
@ensure_csrf_cookie
@xframe_options_deny
def
signup
(
request
):
"""
Display the signup form.
...
...
@@ -34,6 +36,7 @@ def signup(request):
@ssl_login_shortcut
@ensure_csrf_cookie
@xframe_options_deny
def
login_page
(
request
):
"""
Display the login form.
...
...
common/djangoapps/third_party_auth/decorators.py
0 → 100644
View file @
0248f8af
"""
Decorators that can be used to interact with third_party_auth.
"""
from
functools
import
wraps
from
urlparse
import
urlparse
from
django.conf
import
settings
from
django.utils.decorators
import
available_attrs
from
third_party_auth.models
import
LTIProviderConfig
def
xframe_allow_whitelisted
(
view_func
):
"""
Modifies a view function so that its response has the X-Frame-Options HTTP header
set to 'DENY' if the request HTTP referrer is not from a whitelisted hostname.
"""
def
wrapped_view
(
request
,
*
args
,
**
kwargs
):
""" Modify the response with the correct X-Frame-Options. """
resp
=
view_func
(
request
,
*
args
,
**
kwargs
)
x_frame_option
=
'DENY'
if
settings
.
FEATURES
[
'ENABLE_THIRD_PARTY_AUTH'
]:
referer
=
request
.
META
.
get
(
'HTTP_REFERER'
)
if
referer
is
not
None
:
parsed_url
=
urlparse
(
referer
)
hostname
=
parsed_url
.
hostname
if
LTIProviderConfig
.
objects
.
current_set
()
.
filter
(
lti_hostname
=
hostname
,
enabled
=
True
)
.
exists
():
x_frame_option
=
'ALLOW'
resp
[
'X-Frame-Options'
]
=
x_frame_option
return
resp
return
wraps
(
view_func
,
assigned
=
available_attrs
(
view_func
))(
wrapped_view
)
common/djangoapps/third_party_auth/migrations/0005_auto__add_field_ltiproviderconfig_lti_hostname.py
0 → 100644
View file @
0248f8af
This diff is collapsed.
Click to expand it.
common/djangoapps/third_party_auth/models.py
View file @
0248f8af
...
...
@@ -493,6 +493,15 @@ class LTIProviderConfig(ProviderConfig):
'The name that the LTI Tool Consumer will use to identify itself'
)
)
lti_hostname
=
models
.
CharField
(
max_length
=
255
,
help_text
=
(
'The domain that will be acting as the LTI consumer.'
),
db_index
=
True
)
lti_consumer_secret
=
models
.
CharField
(
default
=
long_token
,
max_length
=
255
,
...
...
common/djangoapps/third_party_auth/tests/test_decorators.py
0 → 100644
View file @
0248f8af
"""
Tests for third_party_auth decorators.
"""
import
ddt
from
django.http
import
HttpResponse
from
django.test
import
RequestFactory
from
third_party_auth.decorators
import
xframe_allow_whitelisted
from
third_party_auth.tests.testutil
import
TestCase
@xframe_allow_whitelisted
def
mock_view
(
_request
):
""" A test view for testing purposes. """
return
HttpResponse
()
@ddt.ddt
class
TestXFrameWhitelistDecorator
(
TestCase
):
""" Test the xframe_allow_whitelisted decorator. """
def
setUp
(
self
):
super
(
TestXFrameWhitelistDecorator
,
self
)
.
setUp
()
self
.
configure_lti_provider
(
name
=
'Test'
,
lti_hostname
=
'localhost'
,
lti_consumer_key
=
'test_key'
,
enabled
=
True
)
self
.
factory
=
RequestFactory
()
def
construct_request
(
self
,
referer
):
""" Add the given referer to a request and then return it. """
request
=
self
.
factory
.
get
(
'/login'
)
request
.
META
[
'HTTP_REFERER'
]
=
referer
return
request
@ddt.unpack
@ddt.data
(
(
'http://localhost:8000/login'
,
'ALLOW'
),
(
'http://not-a-real-domain.com/login'
,
'DENY'
),
(
None
,
'DENY'
)
)
def
test_x_frame_options
(
self
,
url
,
expected_result
):
request
=
self
.
construct_request
(
url
)
response
=
mock_view
(
request
)
self
.
assertEqual
(
response
[
'X-Frame-Options'
],
expected_result
)
@ddt.data
(
'http://localhost/login'
,
'http://not-a-real-domain.com'
,
None
)
def
test_feature_flag_off
(
self
,
url
):
with
self
.
settings
(
FEATURES
=
{
'ENABLE_THIRD_PARTY_AUTH'
:
False
}):
request
=
self
.
construct_request
(
url
)
response
=
mock_view
(
request
)
self
.
assertEqual
(
response
[
'X-Frame-Options'
],
'DENY'
)
lms/djangoapps/student_account/test/test_views.py
View file @
0248f8af
...
...
@@ -354,6 +354,24 @@ class StudentAccountLoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMi
self
.
assertContains
(
resp
,
"Register for Test Microsite"
)
self
.
assertContains
(
resp
,
"register-form"
)
def
test_login_registration_xframe_protected
(
self
):
resp
=
self
.
client
.
get
(
reverse
(
"register_user"
),
{},
HTTP_REFERER
=
"http://localhost/iframe"
)
self
.
assertEqual
(
resp
[
'X-Frame-Options'
],
'DENY'
)
self
.
configure_lti_provider
(
name
=
'Test'
,
lti_hostname
=
'localhost'
,
lti_consumer_key
=
'test_key'
,
enabled
=
True
)
resp
=
self
.
client
.
get
(
reverse
(
"register_user"
),
HTTP_REFERER
=
"http://localhost/iframe"
)
self
.
assertEqual
(
resp
[
'X-Frame-Options'
],
'ALLOW'
)
def
_assert_third_party_auth_data
(
self
,
response
,
current_backend
,
current_provider
,
providers
):
"""Verify that third party auth info is rendered correctly in a DOM data attribute. """
finish_auth_url
=
None
...
...
lms/djangoapps/student_account/views.py
View file @
0248f8af
...
...
@@ -34,6 +34,7 @@ from student.views import (
from
student.helpers
import
get_next_url_for_login_page
import
third_party_auth
from
third_party_auth
import
pipeline
from
third_party_auth.decorators
import
xframe_allow_whitelisted
from
util.bad_request_rate_limiter
import
BadRequestRateLimiter
from
openedx.core.djangoapps.user_api.accounts.api
import
request_password_change
...
...
@@ -45,6 +46,7 @@ AUDIT_LOG = logging.getLogger("audit")
@require_http_methods
([
'GET'
])
@ensure_csrf_cookie
@xframe_allow_whitelisted
def
login_and_registration_form
(
request
,
initial_mode
=
"login"
):
"""Render the combined login/registration form, defaulting to login
...
...
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