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
e76e05fa
Commit
e76e05fa
authored
Dec 09, 2015
by
Nimisha Asthagiri
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Specially handle login redirect for mobile apps
parent
f3cb6924
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
122 additions
and
12 deletions
+122
-12
lms/envs/common.py
+5
-0
openedx/core/djangoapps/safe_sessions/middleware.py
+8
-0
openedx/core/djangoapps/safe_sessions/tests/test_middleware.py
+49
-12
openedx/core/lib/mobile_utils.py
+60
-0
No files found.
lms/envs/common.py
View file @
e76e05fa
...
...
@@ -2706,3 +2706,8 @@ MAX_BOOKMARKS_PER_COURSE = 100
# lms.env.json file.
REGISTRATION_EXTENSION_FORM
=
None
# Identifier included in the User Agent from open edX mobile apps.
MOBILE_APP_USER_AGENT_REGEXES
=
[
r'edX/org.edx.mobile'
,
]
openedx/core/djangoapps/safe_sessions/middleware.py
View file @
e76e05fa
...
...
@@ -61,10 +61,12 @@ from django.contrib.auth import SESSION_KEY
from
django.contrib.auth.views
import
redirect_to_login
from
django.contrib.sessions.middleware
import
SessionMiddleware
from
django.core
import
signing
from
django.http
import
HttpResponse
from
django.utils.crypto
import
get_random_string
from
hashlib
import
sha256
from
logging
import
getLogger
from
openedx.core.lib.mobile_utils
import
is_request_from_mobile_app
log
=
getLogger
(
__name__
)
...
...
@@ -339,6 +341,12 @@ class SafeSessionMiddleware(SessionMiddleware):
cookie and redirects the user to the login page.
"""
_mark_cookie_for_deletion
(
request
)
# Mobile apps have custom handling of authentication failures. They
# should *not* be redirected to the website's login page.
if
is_request_from_mobile_app
(
request
):
return
HttpResponse
(
status
=
401
)
return
redirect_to_login
(
request
.
path
)
@staticmethod
...
...
openedx/core/djangoapps/safe_sessions/tests/test_middleware.py
View file @
e76e05fa
...
...
@@ -10,6 +10,7 @@ from django.contrib.auth.models import AnonymousUser
from
django.http
import
HttpResponse
,
HttpResponseRedirect
,
SimpleCookie
from
django.test
import
TestCase
from
django.test.client
import
RequestFactory
from
django.test.utils
import
override_settings
from
mock
import
patch
from
student.tests.factories
import
UserFactory
...
...
@@ -18,6 +19,17 @@ from ..middleware import SafeSessionMiddleware, SafeCookieData
from
.test_utils
import
TestSafeSessionsLogMixin
def
create_mock_request
():
"""
Creates and returns a mock request object for testing.
"""
request
=
RequestFactory
()
request
.
COOKIES
=
{}
request
.
META
=
{}
request
.
path
=
'/'
return
request
class
TestSafeSessionProcessRequest
(
TestSafeSessionsLogMixin
,
TestCase
):
"""
Test class for SafeSessionMiddleware.process_request
...
...
@@ -25,9 +37,7 @@ class TestSafeSessionProcessRequest(TestSafeSessionsLogMixin, TestCase):
def
setUp
(
self
):
super
(
TestSafeSessionProcessRequest
,
self
)
.
setUp
()
self
.
user
=
UserFactory
.
create
()
self
.
request
=
RequestFactory
()
self
.
request
.
COOKIES
=
{}
self
.
request
.
path
=
'/'
self
.
request
=
create_mock_request
()
def
assert_response
(
self
,
safe_cookie_data
=
None
,
success
=
True
):
"""
...
...
@@ -128,9 +138,7 @@ class TestSafeSessionProcessResponse(TestSafeSessionsLogMixin, TestCase):
def
setUp
(
self
):
super
(
TestSafeSessionProcessResponse
,
self
)
.
setUp
()
self
.
user
=
UserFactory
.
create
()
self
.
request
=
RequestFactory
()
self
.
request
.
COOKIES
=
{}
self
.
request
.
path
=
'/'
self
.
request
=
create_mock_request
()
self
.
request
.
session
=
{}
self
.
client
.
response
=
HttpResponse
()
self
.
client
.
response
.
cookies
=
SimpleCookie
()
...
...
@@ -230,9 +238,7 @@ class TestSafeSessionMiddleware(TestSafeSessionsLogMixin, TestCase):
def
setUp
(
self
):
super
(
TestSafeSessionMiddleware
,
self
)
.
setUp
()
self
.
user
=
UserFactory
.
create
()
self
.
request
=
RequestFactory
()
self
.
request
.
COOKIES
=
{}
self
.
request
.
path
=
'/'
self
.
request
=
create_mock_request
()
self
.
client
.
response
=
HttpResponse
()
self
.
client
.
response
.
cookies
=
SimpleCookie
()
...
...
@@ -246,7 +252,10 @@ class TestSafeSessionMiddleware(TestSafeSessionsLogMixin, TestCase):
settings
.
SESSION_COOKIE_NAME
]
def
test_success
(
self
):
def
verify_success
(
self
):
"""
Verifies success path.
"""
self
.
client
.
login
(
username
=
self
.
user
.
username
,
password
=
'test'
)
self
.
request
.
user
=
self
.
user
...
...
@@ -265,11 +274,27 @@ class TestSafeSessionMiddleware(TestSafeSessionsLogMixin, TestCase):
response
=
SafeSessionMiddleware
()
.
process_response
(
self
.
request
,
self
.
client
.
response
)
self
.
assertEquals
(
response
.
status_code
,
200
)
def
test_error
(
self
):
def
test_success
(
self
):
self
.
verify_success
()
def
test_success_from_mobile_web_view
(
self
):
self
.
request
.
path
=
'/xblock/block-v1:org+course+run+type@html+block@block_id'
self
.
verify_success
()
@override_settings
(
MOBILE_APP_USER_AGENT_REGEXES
=
[
r'open edX Mobile App'
])
def
test_success_from_mobile_app
(
self
):
self
.
request
.
META
=
{
'HTTP_USER_AGENT'
:
'open edX Mobile App Version 2.1'
}
self
.
verify_success
()
def
verify_error
(
self
,
expected_response_status
):
"""
Verifies error path.
"""
self
.
request
.
COOKIES
[
settings
.
SESSION_COOKIE_NAME
]
=
'not-a-safe-cookie'
with
self
.
assert_parse_error
():
SafeSessionMiddleware
()
.
process_request
(
self
.
request
)
request_response
=
SafeSessionMiddleware
()
.
process_request
(
self
.
request
)
self
.
assertEquals
(
request_response
.
status_code
,
expected_response_status
)
self
.
assertTrue
(
self
.
request
.
need_to_delete_cookie
)
self
.
cookies_from_request_to_response
()
...
...
@@ -277,3 +302,15 @@ class TestSafeSessionMiddleware(TestSafeSessionsLogMixin, TestCase):
with
patch
(
'django.http.HttpResponse.set_cookie'
)
as
mock_delete_cookie
:
SafeSessionMiddleware
()
.
process_response
(
self
.
request
,
self
.
client
.
response
)
self
.
assertTrue
(
mock_delete_cookie
.
called
)
def
test_error
(
self
):
self
.
verify_error
(
302
)
def
test_error_from_mobile_web_view
(
self
):
self
.
request
.
path
=
'/xblock/block-v1:org+course+run+type@html+block@block_id'
self
.
verify_error
(
401
)
@override_settings
(
MOBILE_APP_USER_AGENT_REGEXES
=
[
r'open edX Mobile App'
])
def
test_error_from_mobile_app
(
self
):
self
.
request
.
META
=
{
'HTTP_USER_AGENT'
:
'open edX Mobile App Version 2.1'
}
self
.
verify_error
(
401
)
openedx/core/lib/mobile_utils.py
0 → 100644
View file @
e76e05fa
"""
Common utilities related to the mobile apps.
"""
import
re
from
django.conf
import
settings
def
is_request_from_mobile_app
(
request
):
"""
Returns whether the given request was made by an open edX mobile app,
either natively or through the mobile web view.
Note: The check for the user agent works only for mobile apps version 2.1
and higher. Previous apps did not update their user agents to include the
distinguishing string.
The check for the web view is a temporary check that works for mobile apps
version 2.0 and higher. See is_request_from_mobile_web_view for more
information.
Args:
request (HttpRequest)
"""
if
is_request_from_mobile_web_view
(
request
):
return
True
if
getattr
(
settings
,
'MOBILE_APP_USER_AGENT_REGEXES'
,
None
):
user_agent
=
request
.
META
.
get
(
'HTTP_USER_AGENT'
)
if
user_agent
:
for
user_agent_regex
in
settings
.
MOBILE_APP_USER_AGENT_REGEXES
:
if
re
.
match
(
user_agent_regex
,
user_agent
):
return
True
return
False
PATHS_ACCESSED_BY_MOBILE_WITH_SESSION_COOKIES
=
[
r'^/xblock/{usage_key_string}$'
.
format
(
usage_key_string
=
settings
.
USAGE_KEY_PATTERN
),
]
def
is_request_from_mobile_web_view
(
request
):
"""
Returns whether the given request was made by an open edX mobile web
view using a session cookie.
Args:
request (HttpRequest)
"""
# TODO (MA-1825): This is a TEMPORARY HACK until all of the version 2.0
# iOS mobile apps have updated. The earlier versions didn't update their
# user agents so we are checking for the specific URLs that are
# accessed through the mobile web view.
for
mobile_path
in
PATHS_ACCESSED_BY_MOBILE_WITH_SESSION_COOKIES
:
if
re
.
match
(
mobile_path
,
request
.
path
):
return
True
return
False
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