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
83a3adb9
Commit
83a3adb9
authored
Feb 17, 2015
by
Nimisha Asthagiri
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MA-291 Allow API access without email activation
parent
18a916ba
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
108 additions
and
10 deletions
+108
-10
common/djangoapps/enrollment/tests/test_views.py
+1
-1
common/djangoapps/enrollment/views.py
+3
-4
common/djangoapps/util/authentication.py
+35
-1
common/djangoapps/util/tests/test_authentication.py
+63
-0
lms/djangoapps/mobile_api/utils.py
+5
-3
requirements/edx/github.txt
+1
-1
No files found.
common/djangoapps/enrollment/tests/test_views.py
View file @
83a3adb9
...
...
@@ -147,7 +147,7 @@ class EnrollmentTest(ModuleStoreTestCase, APITestCase):
self
.
client
.
logout
()
# Try to enroll, this should fail.
self
.
_create_enrollment
(
expected_status
=
status
.
HTTP_40
3_FORBIDDEN
)
self
.
_create_enrollment
(
expected_status
=
status
.
HTTP_40
1_UNAUTHORIZED
)
def
test_user_not_activated
(
self
):
# Log out the default user, Bob.
...
...
common/djangoapps/enrollment/views.py
View file @
83a3adb9
...
...
@@ -9,7 +9,6 @@ from opaque_keys import InvalidKeyError
from
opaque_keys.edx.locator
import
CourseLocator
from
openedx.core.djangoapps.user_api
import
api
as
user_api
from
rest_framework
import
status
from
rest_framework.authentication
import
OAuth2Authentication
from
rest_framework
import
permissions
from
rest_framework.response
import
Response
from
rest_framework.throttling
import
UserRateThrottle
...
...
@@ -19,7 +18,7 @@ from opaque_keys import InvalidKeyError
from
enrollment
import
api
from
enrollment.errors
import
CourseNotFoundError
,
CourseEnrollmentError
,
CourseModeNotFoundError
from
embargo
import
api
as
embargo_api
from
util.authentication
import
SessionAuthenticationAllowInactiveUser
from
util.authentication
import
SessionAuthenticationAllowInactiveUser
,
OAuth2AuthenticationAllowInactiveUser
from
util.disable_rate_limit
import
can_disable_rate_limit
...
...
@@ -71,7 +70,7 @@ class EnrollmentView(APIView):
* user: The ID of the user.
"""
authentication_classes
=
OAuth2Authentication
,
SessionAuthenticationAllowInactiveUser
authentication_classes
=
OAuth2Authentication
AllowInactiveUser
,
SessionAuthenticationAllowInactiveUser
permission_classes
=
permissions
.
IsAuthenticated
,
throttle_classes
=
EnrollmentUserThrottle
,
...
...
@@ -243,7 +242,7 @@ class EnrollmentListView(APIView):
* user: The ID of the user.
"""
authentication_classes
=
OAuth2Authentication
,
SessionAuthenticationAllowInactiveUser
authentication_classes
=
OAuth2Authentication
AllowInactiveUser
,
SessionAuthenticationAllowInactiveUser
permission_classes
=
permissions
.
IsAuthenticated
,
throttle_classes
=
EnrollmentUserThrottle
,
...
...
common/djangoapps/util/authentication.py
View file @
83a3adb9
""" Common Authentication Handlers used across projects. """
from
rest_framework
import
authentication
from
rest_framework.exceptions
import
AuthenticationFailed
from
rest_framework.compat
import
oauth2_provider
,
provider_now
class
SessionAuthenticationAllowInactiveUser
(
authentication
.
SessionAuthentication
):
...
...
@@ -39,10 +41,42 @@ class SessionAuthenticationAllowInactiveUser(authentication.SessionAuthenticatio
# Unauthenticated, CSRF validation not required
# This is where regular `SessionAuthentication` checks that the user is active.
# We have removed that check in this implementation.
if
not
user
:
# But we added a check to prevent anonymous users since we require a logged-in account.
if
not
user
or
user
.
is_anonymous
():
return
None
self
.
enforce_csrf
(
request
)
# CSRF passed with authenticated user
return
(
user
,
None
)
class
OAuth2AuthenticationAllowInactiveUser
(
authentication
.
OAuth2Authentication
):
"""
This is a temporary workaround while the is_active field on the user is coupled
with whether or not the user has verified ownership of their claimed email address.
Once is_active is decoupled from verified_email, we will no longer need this
class override.
But until then, this authentication class ensures that the user is logged in,
but does not require that their account "is_active".
This class can be used for an OAuth2-accessible endpoint that allows users to access
that endpoint without having their email verified. For example, this is used
for mobile endpoints.
"""
def
authenticate_credentials
(
self
,
request
,
access_token
):
"""
Authenticate the request, given the access token.
Override base class implementation to discard failure if user is inactive.
"""
try
:
token
=
oauth2_provider
.
oauth2
.
models
.
AccessToken
.
objects
.
select_related
(
'user'
)
# provider_now switches to timezone aware datetime when
# the oauth2_provider version supports to it.
token
=
token
.
get
(
token
=
access_token
,
expires__gt
=
provider_now
())
except
oauth2_provider
.
oauth2
.
models
.
AccessToken
.
DoesNotExist
:
raise
AuthenticationFailed
(
'Invalid token'
)
return
token
.
user
,
token
common/djangoapps/util/tests/test_authentication.py
0 → 100644
View file @
83a3adb9
"""Tests for util.authentication module."""
from
mock
import
patch
from
django.conf
import
settings
from
rest_framework
import
permissions
from
rest_framework.compat
import
patterns
,
url
from
rest_framework.tests
import
test_authentication
from
provider
import
scope
,
constants
from
unittest
import
skipUnless
from
..authentication
import
OAuth2AuthenticationAllowInactiveUser
class
OAuth2AuthAllowInactiveUserDebug
(
OAuth2AuthenticationAllowInactiveUser
):
"""
A debug class analogous to the OAuth2AuthenticationDebug class that tests
the OAuth2 flow with the access token sent in a query param."""
allow_query_params_token
=
True
# The following patch overrides the URL patterns for the MockView class used in
# rest_framework.tests.test_authentication so that the corresponding AllowInactiveUser
# classes are tested instead.
@skipUnless
(
settings
.
FEATURES
.
get
(
'ENABLE_OAUTH2_PROVIDER'
),
'OAuth2 not enabled'
)
@patch.object
(
test_authentication
,
'urlpatterns'
,
patterns
(
''
,
url
(
r'^oauth2-test/$'
,
test_authentication
.
MockView
.
as_view
(
authentication_classes
=
[
OAuth2AuthenticationAllowInactiveUser
])
),
url
(
r'^oauth2-test-debug/$'
,
test_authentication
.
MockView
.
as_view
(
authentication_classes
=
[
OAuth2AuthAllowInactiveUserDebug
])
),
url
(
r'^oauth2-with-scope-test/$'
,
test_authentication
.
MockView
.
as_view
(
authentication_classes
=
[
OAuth2AuthenticationAllowInactiveUser
],
permission_classes
=
[
permissions
.
TokenHasReadWriteScope
]
)
)
)
)
class
OAuth2AuthenticationAllowInactiveUserTestCase
(
test_authentication
.
OAuth2Tests
):
"""
Tests the OAuth2AuthenticationAllowInactiveUser class by running all the existing tests in
OAuth2Tests but with the is_active flag on the user set to False.
"""
def
setUp
(
self
):
super
(
OAuth2AuthenticationAllowInactiveUserTestCase
,
self
)
.
setUp
()
# set the user's is_active flag to False.
self
.
user
.
is_active
=
False
self
.
user
.
save
()
# Override the SCOPE_NAME_DICT setting for tests for oauth2-with-scope-test. This is
# needed to support READ and WRITE scopes as they currently aren't supported by the
# edx-auth2-provider, and their scope values collide with other scopes defined in the
# edx-auth2-provider.
scope
.
SCOPE_NAME_DICT
=
{
'read'
:
constants
.
READ
,
'write'
:
constants
.
WRITE
}
lms/djangoapps/mobile_api/utils.py
View file @
83a3adb9
...
...
@@ -4,10 +4,9 @@ Common utility methods and decorators for Mobile APIs.
import
functools
from
rest_framework
import
permissions
from
rest_framework.authentication
import
OAuth2Authentication
,
SessionAuthentication
from
util.authentication
import
SessionAuthenticationAllowInactiveUser
,
OAuth2AuthenticationAllowInactiveUser
from
opaque_keys.edx.keys
import
CourseKey
from
xmodule.modulestore.django
import
modulestore
from
courseware.courses
import
get_course_with_access
...
...
@@ -55,7 +54,10 @@ def mobile_view(is_user=False):
Requires either OAuth2 or Session-based authentication.
If is_user is True, also requires username in URL matches the request user.
"""
func_or_class
.
authentication_classes
=
(
OAuth2Authentication
,
SessionAuthentication
)
func_or_class
.
authentication_classes
=
(
OAuth2AuthenticationAllowInactiveUser
,
SessionAuthenticationAllowInactiveUser
)
func_or_class
.
permission_classes
=
(
permissions
.
IsAuthenticated
,)
if
is_user
:
func_or_class
.
permission_classes
+=
(
IsUser
,)
...
...
requirements/edx/github.txt
View file @
83a3adb9
...
...
@@ -33,7 +33,7 @@ git+https://github.com/mitocw/django-cas.git@60a5b8e5a62e63e0d5d224a87f0b489201a
-e git+https://github.com/edx/opaque-keys.git@1254ed4d615a428591850656f39f26509b86d30a#egg=opaque-keys
-e git+https://github.com/edx/ease.git@97de68448e5495385ba043d3091f570a699d5b5f#egg=ease
-e git+https://github.com/edx/i18n-tools.git@193cebd9aa784f8899ef496f2aa050b08eff402b#egg=i18n-tools
-e git+https://github.com/edx/edx-oauth2-provider.git@0.4.
0
#egg=oauth2-provider
-e git+https://github.com/edx/edx-oauth2-provider.git@0.4.
1
#egg=oauth2-provider
-e git+https://github.com/edx/edx-val.git@9ceddb4944d0a1264b345947bf486340c5774a00#egg=edx-val
-e git+https://github.com/pmitros/RecommenderXBlock.git@9b07e807c89ba5761827d0387177f71aa57ef056#egg=recommender-xblock
-e git+https://github.com/edx/edx-milestones.git@547f2250ee49e73ce8d7ff4e78ecf1b049892510#egg=edx-milestones
...
...
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