Replacing OAuth2Auth (#23067)
- Removing deprecated auth classes - Replacing OAuth2AuthenticationAllowInactiveUserDeprecated with OAuth2AuthenticationAllowInactiveUser - the old class was a child class of a deprecated class that we are removing and replacing.
This commit is contained in:
@@ -16,7 +16,7 @@ from rest_framework.response import Response
|
||||
|
||||
from course_modes.api.serializers import CourseModeSerializer
|
||||
from course_modes.models import CourseMode
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUserDeprecated
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUser
|
||||
from openedx.core.lib.api.parsers import MergePatchParser
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@@ -29,7 +29,7 @@ class CourseModesMixin(object):
|
||||
"""
|
||||
authentication_classes = (
|
||||
JwtAuthentication,
|
||||
OAuth2AuthenticationAllowInactiveUserDeprecated,
|
||||
OAuth2AuthenticationAllowInactiveUser,
|
||||
SessionAuthenticationAllowInactiveUser,
|
||||
)
|
||||
# When not considering JWT conditions, this permission class grants access
|
||||
|
||||
@@ -19,8 +19,8 @@ from rest_framework.views import APIView
|
||||
from social_django.models import UserSocialAuth
|
||||
|
||||
from openedx.core.lib.api.authentication import (
|
||||
OAuth2AuthenticationDeprecated,
|
||||
OAuth2AuthenticationAllowInactiveUserDeprecated
|
||||
OAuth2Authentication,
|
||||
OAuth2AuthenticationAllowInactiveUser
|
||||
)
|
||||
from openedx.core.lib.api.permissions import ApiKeyHeaderPermission
|
||||
from third_party_auth import pipeline
|
||||
@@ -67,7 +67,7 @@ class BaseUserView(APIView):
|
||||
authentication_classes = (
|
||||
# Users may want to view/edit the providers used for authentication before they've
|
||||
# activated their account, so we allow inactive users.
|
||||
OAuth2AuthenticationAllowInactiveUserDeprecated,
|
||||
OAuth2AuthenticationAllowInactiveUser,
|
||||
SessionAuthenticationAllowInactiveUser,
|
||||
)
|
||||
throttle_classes = [ProviderSustainedThrottle, ProviderBurstThrottle]
|
||||
@@ -335,7 +335,7 @@ class UserMappingView(ListAPIView):
|
||||
* remote_id: The Id from third party auth provider
|
||||
"""
|
||||
authentication_classes = (
|
||||
JwtAuthentication, OAuth2AuthenticationDeprecated,
|
||||
JwtAuthentication, OAuth2Authentication,
|
||||
)
|
||||
|
||||
serializer_class = serializers.UserMappingSerializer
|
||||
@@ -402,7 +402,7 @@ class ThirdPartyAuthUserStatusView(APIView):
|
||||
user with respect to the third party auth providers configured in the system.
|
||||
"""
|
||||
authentication_classes = (
|
||||
JwtAuthentication, OAuth2AuthenticationAllowInactiveUserDeprecated, SessionAuthenticationAllowInactiveUser
|
||||
JwtAuthentication, OAuth2AuthenticationAllowInactiveUser, SessionAuthenticationAllowInactiveUser
|
||||
)
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ from rest_framework.exceptions import APIException
|
||||
|
||||
from badges.models import BadgeAssertion
|
||||
from openedx.core.djangoapps.user_api.permissions import is_field_shared_factory
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUserDeprecated
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUser
|
||||
|
||||
from .serializers import BadgeAssertionSerializer
|
||||
|
||||
@@ -94,7 +94,7 @@ class UserBadgeAssertions(generics.ListAPIView):
|
||||
"""
|
||||
serializer_class = BadgeAssertionSerializer
|
||||
authentication_classes = (
|
||||
OAuth2AuthenticationAllowInactiveUserDeprecated,
|
||||
OAuth2AuthenticationAllowInactiveUser,
|
||||
SessionAuthenticationAllowInactiveUser
|
||||
)
|
||||
permission_classes = (is_field_shared_factory("accomplishments_shared"),)
|
||||
|
||||
@@ -18,7 +18,7 @@ from lms.djangoapps.instructor.views.api import students_update_enrollment
|
||||
from openedx.core.djangoapps.course_groups.cohorts import add_user_to_cohort, get_cohort_by_name
|
||||
from openedx.core.djangoapps.course_groups.models import CourseUserGroup
|
||||
from openedx.core.djangoapps.enrollments.views import EnrollmentUserThrottle
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationDeprecated
|
||||
from openedx.core.lib.api.authentication import OAuth2Authentication
|
||||
from openedx.core.lib.api.permissions import IsStaff
|
||||
from util.disable_rate_limit import can_disable_rate_limit
|
||||
|
||||
@@ -68,7 +68,7 @@ class BulkEnrollView(APIView):
|
||||
to the 'before' and 'after' states.
|
||||
"""
|
||||
|
||||
authentication_classes = (JwtAuthentication, OAuth2AuthenticationDeprecated,)
|
||||
authentication_classes = (JwtAuthentication, OAuth2Authentication,)
|
||||
permission_classes = (IsStaff,)
|
||||
throttle_classes = (EnrollmentUserThrottle,)
|
||||
|
||||
|
||||
@@ -353,7 +353,7 @@ class CCXListView(GenericAPIView):
|
||||
"""
|
||||
authentication_classes = (
|
||||
JwtAuthentication,
|
||||
authentication.OAuth2AuthenticationAllowInactiveUserDeprecated,
|
||||
authentication.OAuth2AuthenticationAllowInactiveUser,
|
||||
SessionAuthenticationAllowInactiveUser,
|
||||
)
|
||||
permission_classes = (IsAuthenticated, permissions.IsMasterCourseStaffInstructor)
|
||||
@@ -612,7 +612,7 @@ class CCXDetailView(GenericAPIView):
|
||||
|
||||
authentication_classes = (
|
||||
JwtAuthentication,
|
||||
authentication.OAuth2AuthenticationAllowInactiveUserDeprecated,
|
||||
authentication.OAuth2AuthenticationAllowInactiveUser,
|
||||
SessionAuthenticationAllowInactiveUser,
|
||||
)
|
||||
permission_classes = (IsAuthenticated, permissions.IsCourseStaffInstructor)
|
||||
|
||||
@@ -21,7 +21,7 @@ from lms.djangoapps.certificates.api import get_certificate_for_user, get_certif
|
||||
from openedx.core.djangoapps.certificates.api import certificates_viewable_for_course
|
||||
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
|
||||
from openedx.core.djangoapps.user_api.accounts.api import visible_fields
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUserDeprecated
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUser
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@@ -85,7 +85,7 @@ class CertificatesDetailView(APIView):
|
||||
|
||||
authentication_classes = (
|
||||
JwtAuthentication,
|
||||
OAuth2AuthenticationAllowInactiveUserDeprecated,
|
||||
OAuth2AuthenticationAllowInactiveUser,
|
||||
SessionAuthenticationAllowInactiveUser,
|
||||
)
|
||||
|
||||
@@ -147,7 +147,7 @@ class CertificatesListView(APIView):
|
||||
"""REST API endpoints for listing certificates."""
|
||||
authentication_classes = (
|
||||
JwtAuthentication,
|
||||
OAuth2AuthenticationAllowInactiveUserDeprecated,
|
||||
OAuth2AuthenticationAllowInactiveUser,
|
||||
SessionAuthenticationAllowInactiveUser,
|
||||
)
|
||||
permission_classes = (
|
||||
|
||||
@@ -23,7 +23,7 @@ from openedx.core.djangoapps.embargo import api as embargo_api
|
||||
from openedx.core.djangoapps.enrollments.api import add_enrollment
|
||||
from openedx.core.djangoapps.enrollments.views import EnrollmentCrossDomainSessionAuth
|
||||
from openedx.core.djangoapps.user_api.preferences.api import update_email_opt_in
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUserDeprecated
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUser
|
||||
from student.models import CourseEnrollment
|
||||
from student.signals import SAILTHRU_AUDIT_PURCHASE
|
||||
from util.json_request import JsonResponse
|
||||
@@ -40,7 +40,7 @@ class BasketsView(APIView):
|
||||
|
||||
# LMS utilizes User.user_is_active to indicate email verification, not whether an account is active. Sigh!
|
||||
authentication_classes = (JwtAuthentication,
|
||||
OAuth2AuthenticationAllowInactiveUserDeprecated,
|
||||
OAuth2AuthenticationAllowInactiveUser,
|
||||
EnrollmentCrossDomainSessionAuth)
|
||||
permission_classes = (IsAuthenticated,)
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ from rest_framework.authentication import SessionAuthentication
|
||||
from rest_framework.generics import ListAPIView, RetrieveUpdateAPIView
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.views import APIView
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationDeprecated
|
||||
from openedx.core.lib.api.authentication import OAuth2Authentication
|
||||
|
||||
from course_modes.models import CourseMode
|
||||
from openedx.core.djangoapps.commerce.utils import ecommerce_api_client
|
||||
@@ -30,7 +30,7 @@ log = logging.getLogger(__name__)
|
||||
|
||||
class CourseListView(ListAPIView):
|
||||
""" List courses and modes. """
|
||||
authentication_classes = (JwtAuthentication, OAuth2AuthenticationDeprecated, SessionAuthentication,)
|
||||
authentication_classes = (JwtAuthentication, OAuth2Authentication, SessionAuthentication,)
|
||||
permission_classes = (IsAuthenticated,)
|
||||
serializer_class = CourseSerializer
|
||||
pagination_class = None
|
||||
@@ -44,7 +44,7 @@ class CourseRetrieveUpdateView(PutAsCreateMixin, RetrieveUpdateAPIView):
|
||||
lookup_field = 'id'
|
||||
lookup_url_kwarg = 'course_id'
|
||||
model = CourseMode
|
||||
authentication_classes = (JwtAuthentication, OAuth2AuthenticationDeprecated, SessionAuthentication,)
|
||||
authentication_classes = (JwtAuthentication, OAuth2Authentication, SessionAuthentication,)
|
||||
permission_classes = (ApiKeyOrModelPermission,)
|
||||
serializer_class = CourseSerializer
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ from openedx.core.djangoapps.crawlers.models import CrawlersConfig
|
||||
from openedx.core.djangoapps.credit.services import CreditService
|
||||
from openedx.core.djangoapps.util.user_utils import SystemUser
|
||||
from openedx.core.djangolib.markup import HTML
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUserDeprecated
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUser
|
||||
from openedx.core.lib.api.view_utils import view_auth_classes
|
||||
from openedx.core.lib.gating.services import GatingService
|
||||
from openedx.core.lib.license import wrap_with_license
|
||||
@@ -1033,7 +1033,7 @@ def handle_xblock_callback(request, course_id, usage_id, handler, suffix=None):
|
||||
# to avoid introducing backwards-incompatible changes.
|
||||
# You can see https://github.com/edx/XBlock/pull/383 for more details.
|
||||
else:
|
||||
authentication_classes = (JwtAuthentication, OAuth2AuthenticationAllowInactiveUserDeprecated)
|
||||
authentication_classes = (JwtAuthentication, OAuth2AuthenticationAllowInactiveUser)
|
||||
authenticators = [auth() for auth in authentication_classes]
|
||||
|
||||
for authenticator in authenticators:
|
||||
|
||||
@@ -56,10 +56,8 @@ from openedx.core.djangoapps.django_comment_common.utils import (
|
||||
)
|
||||
from openedx.core.djangoapps.user_api.accounts.permissions import CanReplaceUsername, CanRetireUser
|
||||
from openedx.core.djangoapps.user_api.models import UserRetirementStatus
|
||||
from openedx.core.lib.api.authentication import (
|
||||
OAuth2AuthenticationAllowInactiveUserDeprecated,
|
||||
OAuth2AuthenticationAllowInactiveUser
|
||||
)
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUser
|
||||
|
||||
from openedx.core.lib.api.parsers import MergePatchParser
|
||||
from openedx.core.lib.api.view_utils import DeveloperErrorViewMixin, view_auth_classes
|
||||
from util.json_request import JsonResponse
|
||||
@@ -67,30 +65,6 @@ from xmodule.modulestore.django import modulestore
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
# .. toggle_name: DISCUSSION_USE_NEW_OAUTH2_CLASS
|
||||
# .. toggle_implementation: DjangoSetting
|
||||
# .. toggle_default: False
|
||||
# .. toggle_description: Toggle for replacing a deprecated class with its replacement
|
||||
# .. toggle_category: n/a
|
||||
# .. toggle_use_cases: Monitored Rollout
|
||||
# .. toggle_creation_date: 2020-01-31
|
||||
# .. toggle_expiration_date: 2020-02-28
|
||||
# .. toggle_warnings: None
|
||||
# .. toggle_tickets: BOM-1037
|
||||
# .. toggle_status: supported
|
||||
if getattr(settings, "DISCUSSION_USE_NEW_OAUTH2_CLASS", False):
|
||||
_discussion_configured_authentication_classes = (
|
||||
JwtAuthentication,
|
||||
OAuth2AuthenticationAllowInactiveUser,
|
||||
SessionAuthenticationAllowInactiveUser,
|
||||
)
|
||||
else:
|
||||
_discussion_configured_authentication_classes = (
|
||||
JwtAuthentication,
|
||||
OAuth2AuthenticationAllowInactiveUserDeprecated,
|
||||
SessionAuthenticationAllowInactiveUser,
|
||||
)
|
||||
|
||||
|
||||
@view_auth_classes()
|
||||
class CourseView(DeveloperErrorViewMixin, APIView):
|
||||
@@ -777,7 +751,11 @@ class CourseDiscussionSettingsAPIView(DeveloperErrorViewMixin, APIView):
|
||||
* available_division_schemes: A list of available division schemes for the course.
|
||||
|
||||
"""
|
||||
authentication_classes = _discussion_configured_authentication_classes
|
||||
authentication_classes = (
|
||||
JwtAuthentication,
|
||||
OAuth2AuthenticationAllowInactiveUser,
|
||||
SessionAuthenticationAllowInactiveUser,
|
||||
)
|
||||
parser_classes = (JSONParser, MergePatchParser,)
|
||||
permission_classes = (permissions.IsAuthenticated, permissions.IsAdminUser)
|
||||
|
||||
@@ -908,7 +886,11 @@ class CourseDiscussionRolesAPIView(DeveloperErrorViewMixin, APIView):
|
||||
|
||||
* division_scheme: The division scheme used by the course.
|
||||
"""
|
||||
authentication_classes = _discussion_configured_authentication_classes
|
||||
authentication_classes = (
|
||||
JwtAuthentication,
|
||||
OAuth2AuthenticationAllowInactiveUser,
|
||||
SessionAuthenticationAllowInactiveUser,
|
||||
)
|
||||
permission_classes = (permissions.IsAuthenticated, permissions.IsAdminUser)
|
||||
|
||||
def _get_request_kwargs(self, course_id, rolename):
|
||||
|
||||
@@ -19,7 +19,7 @@ from rest_framework.views import APIView
|
||||
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
|
||||
from openedx.core.djangoapps.cors_csrf.decorators import ensure_csrf_cookie_cross_domain
|
||||
from openedx.core.djangoapps.waffle_utils import WaffleFlag, WaffleFlagNamespace
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUserDeprecated
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUser
|
||||
from openedx.core.lib.api.permissions import ApiKeyHeaderPermissionIsAuthenticated
|
||||
from openedx.core.lib.api.view_utils import DeveloperErrorViewMixin
|
||||
|
||||
@@ -100,7 +100,7 @@ class Rev934(DeveloperErrorViewMixin, APIView):
|
||||
|
||||
authentication_classes = (
|
||||
JwtAuthentication,
|
||||
OAuth2AuthenticationAllowInactiveUserDeprecated,
|
||||
OAuth2AuthenticationAllowInactiveUser,
|
||||
SessionAuthenticationAllowInactiveUser,
|
||||
)
|
||||
permission_classes = (ApiKeyHeaderPermissionIsAuthenticated,)
|
||||
|
||||
@@ -16,7 +16,7 @@ from lms.djangoapps.courseware.access import has_access
|
||||
from lms.djangoapps.grades.api import CourseGradeFactory, clear_prefetched_course_grades, prefetch_course_grades
|
||||
from lms.djangoapps.grades.rest_api.serializers import GradingPolicySerializer
|
||||
from lms.djangoapps.grades.rest_api.v1.utils import CourseEnrollmentPagination, GradeViewMixin
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUserDeprecated
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUser
|
||||
from openedx.core.lib.api.view_utils import PaginatedAPIView, get_course_key, verify_course_exists
|
||||
from xmodule.modulestore.django import modulestore
|
||||
|
||||
@@ -91,7 +91,7 @@ class CourseGradesView(GradeViewMixin, PaginatedAPIView):
|
||||
"""
|
||||
authentication_classes = (
|
||||
JwtAuthentication,
|
||||
OAuth2AuthenticationAllowInactiveUserDeprecated,
|
||||
OAuth2AuthenticationAllowInactiveUser,
|
||||
SessionAuthenticationAllowInactiveUser,
|
||||
)
|
||||
|
||||
@@ -171,7 +171,7 @@ class CourseGradingPolicy(GradeViewMixin, ListAPIView):
|
||||
|
||||
authentication_classes = (
|
||||
JwtAuthentication,
|
||||
OAuth2AuthenticationAllowInactiveUserDeprecated,
|
||||
OAuth2AuthenticationAllowInactiveUser,
|
||||
SessionAuthenticationAllowInactiveUser,
|
||||
)
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ from openedx.core.djangoapps.django_comment_common.models import (
|
||||
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
|
||||
from openedx.core.djangoapps.user_api.preferences.api import get_user_preference, set_user_preference
|
||||
from openedx.core.djangolib.markup import HTML, Text
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUserDeprecated
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUser
|
||||
from openedx.core.lib.api.view_utils import DeveloperErrorViewMixin
|
||||
from shoppingcart.models import (
|
||||
Coupon,
|
||||
@@ -1474,7 +1474,7 @@ class CohortCSV(DeveloperErrorViewMixin, APIView):
|
||||
"""
|
||||
authentication_classes = (
|
||||
JwtAuthentication,
|
||||
OAuth2AuthenticationAllowInactiveUserDeprecated,
|
||||
OAuth2AuthenticationAllowInactiveUser,
|
||||
SessionAuthenticationAllowInactiveUser,
|
||||
)
|
||||
permission_classes = (permissions.IsAuthenticated, permissions.IsAdminUser)
|
||||
|
||||
@@ -47,7 +47,7 @@ from openedx.core.djangoapps.catalog.utils import (
|
||||
normalize_program_type
|
||||
)
|
||||
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUserDeprecated
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUser
|
||||
from openedx.core.lib.api.view_utils import DeveloperErrorViewMixin, PaginatedAPIView
|
||||
from student.helpers import get_resume_urls_for_enrollments
|
||||
from student.models import CourseEnrollment
|
||||
@@ -328,7 +328,7 @@ class ProgramEnrollmentsView(
|
||||
"""
|
||||
authentication_classes = (
|
||||
JwtAuthentication,
|
||||
OAuth2AuthenticationAllowInactiveUserDeprecated,
|
||||
OAuth2AuthenticationAllowInactiveUser,
|
||||
SessionAuthenticationAllowInactiveUser,
|
||||
)
|
||||
permission_classes = (permissions.JWT_RESTRICTED_APPLICATION_OR_USER_ACCESS,)
|
||||
@@ -472,7 +472,7 @@ class ProgramCourseEnrollmentsView(
|
||||
"""
|
||||
authentication_classes = (
|
||||
JwtAuthentication,
|
||||
OAuth2AuthenticationAllowInactiveUserDeprecated,
|
||||
OAuth2AuthenticationAllowInactiveUser,
|
||||
SessionAuthenticationAllowInactiveUser,
|
||||
)
|
||||
permission_classes = (permissions.JWT_RESTRICTED_APPLICATION_OR_USER_ACCESS,)
|
||||
@@ -614,7 +614,7 @@ class ProgramCourseGradesView(
|
||||
"""
|
||||
authentication_classes = (
|
||||
JwtAuthentication,
|
||||
OAuth2AuthenticationAllowInactiveUserDeprecated,
|
||||
OAuth2AuthenticationAllowInactiveUser,
|
||||
SessionAuthenticationAllowInactiveUser,
|
||||
)
|
||||
permission_classes = (permissions.JWT_RESTRICTED_APPLICATION_OR_USER_ACCESS,)
|
||||
@@ -695,7 +695,7 @@ class UserProgramReadOnlyAccessView(DeveloperErrorViewMixin, PaginatedAPIView):
|
||||
"""
|
||||
authentication_classes = (
|
||||
JwtAuthentication,
|
||||
OAuth2AuthenticationAllowInactiveUserDeprecated,
|
||||
OAuth2AuthenticationAllowInactiveUser,
|
||||
SessionAuthenticationAllowInactiveUser,
|
||||
)
|
||||
permission_classes = (IsAuthenticated,)
|
||||
@@ -874,7 +874,7 @@ class ProgramCourseEnrollmentOverviewView(
|
||||
"""
|
||||
authentication_classes = (
|
||||
JwtAuthentication,
|
||||
OAuth2AuthenticationAllowInactiveUserDeprecated,
|
||||
OAuth2AuthenticationAllowInactiveUser,
|
||||
SessionAuthenticationAllowInactiveUser,
|
||||
)
|
||||
permission_classes = (IsAuthenticated,)
|
||||
@@ -983,7 +983,7 @@ class EnrollmentDataResetView(APIView):
|
||||
"""
|
||||
authentication_classes = (
|
||||
JwtAuthentication,
|
||||
OAuth2AuthenticationAllowInactiveUserDeprecated,
|
||||
OAuth2AuthenticationAllowInactiveUser,
|
||||
SessionAuthenticationAllowInactiveUser,
|
||||
)
|
||||
permission_classes = (permissions.JWT_RESTRICTED_APPLICATION_OR_USER_ACCESS,)
|
||||
|
||||
@@ -27,7 +27,7 @@ from rest_framework.generics import GenericAPIView
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.reverse import reverse
|
||||
from rest_framework.views import APIView
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationDeprecated
|
||||
from openedx.core.lib.api.authentication import OAuth2Authentication
|
||||
|
||||
from lms.djangoapps.courseware.courses import get_course_with_access, has_access
|
||||
from lms.djangoapps.discussion.django_comment_client.utils import has_discussion_privileges
|
||||
@@ -369,7 +369,7 @@ class TeamsListView(ExpandableFieldViewMixin, GenericAPIView):
|
||||
"""
|
||||
|
||||
# OAuth2Authentication must come first to return a 401 for unauthenticated users
|
||||
authentication_classes = (OAuth2AuthenticationDeprecated, SessionAuthentication)
|
||||
authentication_classes = (OAuth2Authentication, SessionAuthentication)
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
serializer_class = CourseTeamSerializer
|
||||
|
||||
@@ -697,7 +697,7 @@ class TeamsDetailView(ExpandableFieldViewMixin, RetrievePatchAPIView):
|
||||
If the user is logged in and the team does not exist, a 404 is returned.
|
||||
|
||||
"""
|
||||
authentication_classes = (OAuth2AuthenticationDeprecated, SessionAuthentication)
|
||||
authentication_classes = (OAuth2Authentication, SessionAuthentication)
|
||||
permission_classes = (permissions.IsAuthenticated, IsStaffOrPrivilegedOrReadOnly, IsEnrolledOrIsStaff,)
|
||||
lookup_field = 'team_id'
|
||||
serializer_class = CourseTeamSerializer
|
||||
@@ -792,7 +792,7 @@ class TopicListView(GenericAPIView):
|
||||
those teams whose members are outside of institutions affliation.
|
||||
"""
|
||||
|
||||
authentication_classes = (OAuth2AuthenticationDeprecated, SessionAuthentication)
|
||||
authentication_classes = (OAuth2Authentication, SessionAuthentication)
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
pagination_class = TopicsPagination
|
||||
|
||||
@@ -923,7 +923,7 @@ class TopicDetailView(APIView):
|
||||
those teams whose members are outside of institutions affliation.
|
||||
"""
|
||||
|
||||
authentication_classes = (OAuth2AuthenticationDeprecated, SessionAuthentication)
|
||||
authentication_classes = (OAuth2Authentication, SessionAuthentication)
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
|
||||
def get(self, request, topic_id, course_id):
|
||||
@@ -1083,7 +1083,7 @@ class MembershipListView(ExpandableFieldViewMixin, GenericAPIView):
|
||||
another user to a team.
|
||||
"""
|
||||
|
||||
authentication_classes = (OAuth2AuthenticationDeprecated, SessionAuthentication)
|
||||
authentication_classes = (OAuth2Authentication, SessionAuthentication)
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
serializer_class = MembershipSerializer
|
||||
|
||||
@@ -1296,7 +1296,7 @@ class MembershipDetailView(ExpandableFieldViewMixin, GenericAPIView):
|
||||
If the membership does not exist, a 404 error is returned.
|
||||
"""
|
||||
|
||||
authentication_classes = (OAuth2AuthenticationDeprecated, SessionAuthentication)
|
||||
authentication_classes = (OAuth2Authentication, SessionAuthentication)
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
|
||||
serializer_class = MembershipSerializer
|
||||
@@ -1366,7 +1366,7 @@ class MembershipBulkManagementView(GenericAPIView):
|
||||
View for uploading and downloading team membership CSVs.
|
||||
"""
|
||||
|
||||
authentication_classes = (OAuth2AuthenticationDeprecated, SessionAuthentication)
|
||||
authentication_classes = (OAuth2Authentication, SessionAuthentication)
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
|
||||
def get(self, request, **_kwargs):
|
||||
|
||||
@@ -8,7 +8,7 @@ from edx_rest_framework_extensions.auth.jwt.authentication import JwtAuthenticat
|
||||
from rest_framework.authentication import SessionAuthentication
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.generics import ListAPIView
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationDeprecated
|
||||
from openedx.core.lib.api.authentication import OAuth2Authentication
|
||||
|
||||
from openedx.core.djangoapps.api_admin.api.v1 import serializers as api_access_serializers
|
||||
from openedx.core.djangoapps.api_admin.models import ApiAccessRequest
|
||||
@@ -50,7 +50,7 @@ class ApiAccessRequestView(ListAPIView):
|
||||
"previous": null
|
||||
}
|
||||
"""
|
||||
authentication_classes = (JwtAuthentication, OAuth2AuthenticationDeprecated, SessionAuthentication,)
|
||||
authentication_classes = (JwtAuthentication, OAuth2Authentication, SessionAuthentication,)
|
||||
permission_classes = (IsAuthenticated, )
|
||||
serializer_class = api_access_serializers.ApiAccessRequestSerializer
|
||||
filter_backends = (IsOwnerOrStaffFilterBackend, DjangoFilterBackend)
|
||||
|
||||
@@ -30,7 +30,7 @@ from rest_framework.views import APIView
|
||||
from openedx.core.djangoapps.auth_exchange.forms import AccessTokenExchangeForm
|
||||
from openedx.core.djangoapps.oauth_dispatch import adapters
|
||||
from openedx.core.djangoapps.oauth_dispatch.api import create_dot_access_token
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUserDeprecated
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUser
|
||||
|
||||
|
||||
class AccessTokenExchangeBase(APIView):
|
||||
@@ -131,7 +131,7 @@ class LoginWithAccessTokenView(APIView):
|
||||
"""
|
||||
View for exchanging an access token for session cookies
|
||||
"""
|
||||
authentication_classes = (OAuth2AuthenticationAllowInactiveUserDeprecated,)
|
||||
authentication_classes = (OAuth2AuthenticationAllowInactiveUser,)
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
|
||||
@staticmethod
|
||||
|
||||
@@ -23,7 +23,7 @@ from rest_framework.generics import ListCreateAPIView
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationDeprecated, OAuth2Authentication
|
||||
from openedx.core.lib.api.authentication import OAuth2Authentication
|
||||
from openedx.core.djangoapps.bookmarks.api import BookmarksLimitReachedError
|
||||
from openedx.core.lib.api.permissions import IsUserInUrl
|
||||
from openedx.core.lib.url_utils import unquote_slashes
|
||||
@@ -34,21 +34,6 @@ from .serializers import BookmarkSerializer
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
# .. toggle_name: BOOKMARKS_USE_NEW_OAUTH2_CLASS
|
||||
# .. toggle_implementation: DjangoSetting
|
||||
# .. toggle_default: False
|
||||
# .. toggle_description: Toggle for replacing OAuth2AuthenticationDeprecated with OAuth2Authentication for bookmarks.
|
||||
# .. toggle_category: n/a
|
||||
# .. toggle_use_cases: Monitored Rollout
|
||||
# .. toggle_creation_date: 2020-01-31
|
||||
# .. toggle_expiration_date: 2020-02-28
|
||||
# .. toggle_warnings: None
|
||||
# .. toggle_tickets: BOM-1037
|
||||
# .. toggle_status: supported
|
||||
if getattr(settings, "BOOKMARKS_USE_NEW_OAUTH2_CLASS", False):
|
||||
_bookmarks_configured_authentication_classes = (OAuth2Authentication, SessionAuthentication)
|
||||
else:
|
||||
_bookmarks_configured_authentication_classes = (OAuth2AuthenticationDeprecated, SessionAuthentication)
|
||||
|
||||
# Default error message for user
|
||||
DEFAULT_USER_MESSAGE = ugettext_noop(u'An error has occurred. Please try again.')
|
||||
@@ -115,7 +100,7 @@ class BookmarksViewMixin(object):
|
||||
class BookmarksListView(ListCreateAPIView, BookmarksViewMixin):
|
||||
"""REST endpoints for lists of bookmarks."""
|
||||
|
||||
authentication_classes = _bookmarks_configured_authentication_classes
|
||||
authentication_classes = (OAuth2Authentication, SessionAuthentication,)
|
||||
pagination_class = BookmarksPagination
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
serializer_class = BookmarkSerializer
|
||||
@@ -307,7 +292,7 @@ class BookmarksDetailView(APIView, BookmarksViewMixin):
|
||||
if the bookmark does not exist.
|
||||
"""
|
||||
|
||||
authentication_classes = _bookmarks_configured_authentication_classes
|
||||
authentication_classes = (OAuth2Authentication, SessionAuthentication)
|
||||
permission_classes = (permissions.IsAuthenticated, IsUserInUrl)
|
||||
|
||||
serializer_class = BookmarkSerializer
|
||||
|
||||
@@ -28,7 +28,7 @@ from rest_framework.serializers import Serializer
|
||||
from lms.djangoapps.courseware.courses import get_course, get_course_with_access
|
||||
from edxmako.shortcuts import render_to_response
|
||||
from openedx.core.djangoapps.course_groups.models import CohortMembership
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUserDeprecated
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUser
|
||||
from openedx.core.lib.api.view_utils import DeveloperErrorViewMixin
|
||||
from student.auth import has_course_author_access
|
||||
from util.json_request import JsonResponse, expect_json
|
||||
@@ -429,7 +429,7 @@ class APIPermissions(GenericAPIView):
|
||||
"""
|
||||
authentication_classes = (
|
||||
JwtAuthentication,
|
||||
OAuth2AuthenticationAllowInactiveUserDeprecated,
|
||||
OAuth2AuthenticationAllowInactiveUser,
|
||||
SessionAuthenticationAllowInactiveUser,
|
||||
)
|
||||
permission_classes = (permissions.IsAuthenticated, permissions.IsAdminUser)
|
||||
|
||||
@@ -18,7 +18,7 @@ from rest_framework import generics, mixins, permissions, views, viewsets
|
||||
from rest_framework.authentication import SessionAuthentication
|
||||
from rest_framework.exceptions import ValidationError
|
||||
from rest_framework.response import Response
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationDeprecated
|
||||
from openedx.core.lib.api.authentication import OAuth2Authentication
|
||||
from six import text_type
|
||||
|
||||
from openedx.core.djangoapps.credit.api import create_credit_request
|
||||
@@ -45,7 +45,7 @@ from openedx.core.lib.api.mixins import PutAsCreateMixin
|
||||
from openedx.core.lib.api.permissions import IsStaffOrOwner
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
AUTHENTICATION_CLASSES = (JwtAuthentication, OAuth2AuthenticationDeprecated, SessionAuthentication,)
|
||||
AUTHENTICATION_CLASSES = (JwtAuthentication, OAuth2Authentication, SessionAuthentication,)
|
||||
|
||||
|
||||
class CreditProviderViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
|
||||
@@ -30,7 +30,7 @@ from openedx.core.djangoapps.enrollments.serializers import CourseEnrollmentsApi
|
||||
from openedx.core.djangoapps.user_api.accounts.permissions import CanRetireUser
|
||||
from openedx.core.djangoapps.user_api.models import UserRetirementStatus
|
||||
from openedx.core.djangoapps.user_api.preferences.api import update_email_opt_in
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUserDeprecated
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUser
|
||||
from openedx.core.lib.api.permissions import ApiKeyHeaderPermission, ApiKeyHeaderPermissionIsAuthenticated
|
||||
from openedx.core.lib.api.view_utils import DeveloperErrorViewMixin
|
||||
from openedx.core.lib.exceptions import CourseNotFoundError
|
||||
@@ -168,7 +168,7 @@ class EnrollmentView(APIView, ApiKeyPermissionMixIn):
|
||||
|
||||
authentication_classes = (
|
||||
JwtAuthentication,
|
||||
OAuth2AuthenticationAllowInactiveUserDeprecated,
|
||||
OAuth2AuthenticationAllowInactiveUser,
|
||||
SessionAuthenticationAllowInactiveUser,
|
||||
)
|
||||
permission_classes = (ApiKeyHeaderPermissionIsAuthenticated,)
|
||||
@@ -243,7 +243,7 @@ class EnrollmentUserRolesView(APIView):
|
||||
"""
|
||||
authentication_classes = (
|
||||
JwtAuthentication,
|
||||
OAuth2AuthenticationAllowInactiveUserDeprecated,
|
||||
OAuth2AuthenticationAllowInactiveUser,
|
||||
EnrollmentCrossDomainSessionAuth,
|
||||
)
|
||||
permission_classes = (ApiKeyHeaderPermissionIsAuthenticated,)
|
||||
@@ -612,7 +612,7 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn):
|
||||
"""
|
||||
authentication_classes = (
|
||||
JwtAuthentication,
|
||||
OAuth2AuthenticationAllowInactiveUserDeprecated,
|
||||
OAuth2AuthenticationAllowInactiveUser,
|
||||
EnrollmentCrossDomainSessionAuth,
|
||||
)
|
||||
permission_classes = (ApiKeyHeaderPermissionIsAuthenticated,)
|
||||
@@ -940,7 +940,7 @@ class CourseEnrollmentsApiListView(DeveloperErrorViewMixin, ListAPIView):
|
||||
"""
|
||||
authentication_classes = (
|
||||
JwtAuthentication,
|
||||
OAuth2AuthenticationAllowInactiveUserDeprecated,
|
||||
OAuth2AuthenticationAllowInactiveUser,
|
||||
SessionAuthenticationAllowInactiveUser,
|
||||
)
|
||||
permission_classes = (permissions.IsAdminUser,)
|
||||
|
||||
@@ -20,7 +20,7 @@ from six import text_type
|
||||
|
||||
from openedx.core.djangoapps.user_api.accounts.image_helpers import get_profile_image_names, set_has_profile_image
|
||||
from openedx.core.djangoapps.user_api.errors import UserNotFound
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUserDeprecated
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUser
|
||||
from openedx.core.lib.api.parsers import TypedFileUploadParser
|
||||
from openedx.core.lib.api.permissions import IsUserInUrl
|
||||
from openedx.core.lib.api.view_utils import DeveloperErrorViewMixin
|
||||
@@ -115,7 +115,7 @@ class ProfileImageView(DeveloperErrorViewMixin, APIView):
|
||||
parser_classes = (MultiPartParser, FormParser, TypedFileUploadParser)
|
||||
authentication_classes = (
|
||||
JwtAuthentication,
|
||||
OAuth2AuthenticationAllowInactiveUserDeprecated,
|
||||
OAuth2AuthenticationAllowInactiveUser,
|
||||
SessionAuthenticationAllowInactiveUser,
|
||||
)
|
||||
permission_classes = (permissions.IsAuthenticated, IsUserInUrl)
|
||||
|
||||
@@ -49,7 +49,7 @@ from openedx.core.djangoapps.profile_images.images import remove_profile_images
|
||||
from openedx.core.djangoapps.user_api.accounts.image_helpers import get_profile_image_names, set_has_profile_image
|
||||
from openedx.core.djangoapps.user_authn.exceptions import AuthFailedError
|
||||
from openedx.core.djangolib.oauth2_retirement_utils import retire_dop_oauth2_models, retire_dot_oauth2_models
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUserDeprecated
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUser
|
||||
from openedx.core.lib.api.parsers import MergePatchParser
|
||||
from student.models import (
|
||||
AccountRecovery,
|
||||
@@ -267,7 +267,7 @@ class AccountViewSet(ViewSet):
|
||||
If the update is successful, updated user account data is returned.
|
||||
"""
|
||||
authentication_classes = (
|
||||
JwtAuthentication, OAuth2AuthenticationAllowInactiveUserDeprecated, SessionAuthenticationAllowInactiveUser
|
||||
JwtAuthentication, OAuth2AuthenticationAllowInactiveUser, SessionAuthenticationAllowInactiveUser
|
||||
)
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
parser_classes = (MergePatchParser,)
|
||||
|
||||
@@ -14,7 +14,7 @@ from rest_framework import permissions, status
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUserDeprecated
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUser
|
||||
from openedx.core.lib.api.parsers import MergePatchParser
|
||||
from openedx.core.lib.api.permissions import IsUserInUrlOrStaff
|
||||
|
||||
@@ -91,7 +91,7 @@ class PreferencesView(APIView):
|
||||
"""
|
||||
authentication_classes = (
|
||||
JwtAuthentication,
|
||||
OAuth2AuthenticationAllowInactiveUserDeprecated,
|
||||
OAuth2AuthenticationAllowInactiveUser,
|
||||
SessionAuthenticationAllowInactiveUser,
|
||||
)
|
||||
permission_classes = (permissions.IsAuthenticated, IsUserInUrlOrStaff)
|
||||
@@ -202,7 +202,7 @@ class PreferencesDetailView(APIView):
|
||||
If the update is successful, an HTTP 204 "No Content" response is
|
||||
returned with no additional content.
|
||||
"""
|
||||
authentication_classes = (OAuth2AuthenticationAllowInactiveUserDeprecated, SessionAuthenticationAllowInactiveUser)
|
||||
authentication_classes = (OAuth2AuthenticationAllowInactiveUser, SessionAuthenticationAllowInactiveUser)
|
||||
permission_classes = (permissions.IsAuthenticated, IsUserInUrlOrStaff)
|
||||
|
||||
def get(self, request, username, preference_key):
|
||||
|
||||
@@ -5,7 +5,7 @@ from django.http import Http404
|
||||
from edx_rest_framework_extensions.auth.jwt.authentication import JwtAuthentication
|
||||
from rest_framework.authentication import SessionAuthentication
|
||||
from rest_framework.generics import RetrieveAPIView
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationDeprecated
|
||||
from openedx.core.lib.api.authentication import OAuth2Authentication
|
||||
|
||||
from lms.djangoapps.verify_student.models import ManualVerification, SoftwareSecurePhotoVerification, SSOVerification
|
||||
from lms.djangoapps.verify_student.utils import most_recent_verification
|
||||
@@ -19,7 +19,7 @@ from openedx.core.lib.api.permissions import IsStaffOrOwner
|
||||
|
||||
class IDVerificationStatusView(RetrieveAPIView):
|
||||
""" IDVerificationStatus detail endpoint. """
|
||||
authentication_classes = (JwtAuthentication, OAuth2AuthenticationDeprecated, SessionAuthentication,)
|
||||
authentication_classes = (JwtAuthentication, OAuth2Authentication, SessionAuthentication,)
|
||||
permission_classes = (IsStaffOrOwner,)
|
||||
|
||||
def get_serializer(self, *args, **kwargs):
|
||||
|
||||
@@ -6,7 +6,6 @@ import django.utils.timezone
|
||||
from oauth2_provider import models as dot_models
|
||||
from provider.oauth2 import models as dop_models
|
||||
from rest_framework.exceptions import AuthenticationFailed
|
||||
from rest_framework_oauth.authentication import OAuth2Authentication as OAuth2AuthenticationDeprecatedBase
|
||||
from rest_framework.authentication import BaseAuthentication, get_authorization_header
|
||||
from edx_django_utils.monitoring import set_custom_metric
|
||||
|
||||
@@ -21,121 +20,6 @@ OAUTH2_USER_NOT_ACTIVE_ERROR = 'user_not_active'
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class OAuth2AuthenticationDeprecated(OAuth2AuthenticationDeprecatedBase):
|
||||
"""
|
||||
This child class was added to add new_relic metrics to OAuth2Authentication. This should be very temporary.
|
||||
"""
|
||||
|
||||
def authenticate(self, request):
|
||||
"""
|
||||
Returns two-tuple of (user, token) if access token authentication
|
||||
succeeds, None if the user did not try to authenticate using an access
|
||||
token, or raises an AuthenticationFailed (HTTP 401) if authentication
|
||||
fails.
|
||||
"""
|
||||
set_custom_metric("OAuth2AuthenticationDeprecated", "Failed")
|
||||
try:
|
||||
auth = get_authorization_header(request).split()
|
||||
set_custom_metric('OAuth2Authentication_token_location', 'unknown')
|
||||
|
||||
if auth and len(auth) == 2 and auth[0].lower() == b'bearer':
|
||||
set_custom_metric('OAuth2Authentication_token_location', 'bearer-in-header')
|
||||
except Exception: # pylint: disable=broad-except
|
||||
pass
|
||||
|
||||
output = super(OAuth2AuthenticationDeprecated, self).authenticate(request)
|
||||
if output is None:
|
||||
set_custom_metric("OAuth2AuthenticationDeprecated", "None")
|
||||
else:
|
||||
set_custom_metric("OAuth2AuthenticationDeprecated", "Success")
|
||||
return output
|
||||
|
||||
|
||||
class OAuth2AuthenticationAllowInactiveUserDeprecated(OAuth2AuthenticationDeprecated):
|
||||
"""
|
||||
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(self, request):
|
||||
"""
|
||||
Returns two-tuple of (user, token) if access token authentication
|
||||
succeeds, raises an AuthenticationFailed (HTTP 401) if authentication
|
||||
fails or None if the user did not try to authenticate using an access
|
||||
token.
|
||||
"""
|
||||
|
||||
try:
|
||||
return super(OAuth2AuthenticationAllowInactiveUserDeprecated, self).authenticate(request)
|
||||
except AuthenticationFailed as exc:
|
||||
if isinstance(exc.detail, dict):
|
||||
developer_message = exc.detail['developer_message']
|
||||
error_code = exc.detail['error_code']
|
||||
else:
|
||||
developer_message = exc.detail
|
||||
if 'No credentials provided' in developer_message:
|
||||
error_code = OAUTH2_TOKEN_ERROR_NOT_PROVIDED
|
||||
elif 'Token string should not contain spaces' in developer_message:
|
||||
error_code = OAUTH2_TOKEN_ERROR_MALFORMED
|
||||
else:
|
||||
error_code = OAUTH2_TOKEN_ERROR
|
||||
raise AuthenticationFailed({
|
||||
u'error_code': error_code,
|
||||
u'developer_message': developer_message
|
||||
})
|
||||
|
||||
def authenticate_credentials(self, request, access_token):
|
||||
"""
|
||||
Authenticate the request, given the access token.
|
||||
Overrides base class implementation to discard failure if user is
|
||||
inactive.
|
||||
"""
|
||||
|
||||
token = self.get_access_token(access_token)
|
||||
if not token:
|
||||
raise AuthenticationFailed({
|
||||
u'error_code': OAUTH2_TOKEN_ERROR_NONEXISTENT,
|
||||
u'developer_message': u'The provided access token does not match any valid tokens.'
|
||||
})
|
||||
elif token.expires < django.utils.timezone.now():
|
||||
raise AuthenticationFailed({
|
||||
u'error_code': OAUTH2_TOKEN_ERROR_EXPIRED,
|
||||
u'developer_message': u'The provided access token has expired and is no longer valid.',
|
||||
})
|
||||
else:
|
||||
return token.user, token
|
||||
|
||||
def get_access_token(self, access_token):
|
||||
"""
|
||||
Return a valid access token that exists in one of our OAuth2 libraries,
|
||||
or None if no matching token is found.
|
||||
"""
|
||||
return self._get_dot_token(access_token) or self._get_dop_token(access_token)
|
||||
|
||||
def _get_dop_token(self, access_token):
|
||||
"""
|
||||
Return a valid access token stored by django-oauth2-provider (DOP), or
|
||||
None if no matching token is found.
|
||||
"""
|
||||
token_query = dop_models.AccessToken.objects.select_related('user')
|
||||
return token_query.filter(token=access_token).first()
|
||||
|
||||
def _get_dot_token(self, access_token):
|
||||
"""
|
||||
Return a valid access token stored by django-oauth-toolkit (DOT), or
|
||||
None if no matching token is found.
|
||||
"""
|
||||
token_query = dot_models.AccessToken.objects.select_related('user')
|
||||
return token_query.filter(token=access_token).first()
|
||||
|
||||
|
||||
class OAuth2Authentication(BaseAuthentication):
|
||||
"""
|
||||
OAuth 2 authentication backend using either `django-oauth2-provider` or 'django-oauth-toolkit'
|
||||
|
||||
@@ -24,8 +24,7 @@ from rest_framework import status
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.test import APIClient, APIRequestFactory
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework_oauth import permissions
|
||||
from rest_framework_oauth.compat import oauth2_provider, oauth2_provider_scope
|
||||
import provider as oauth2_provider
|
||||
|
||||
from openedx.core.djangoapps.oauth_dispatch import adapters
|
||||
from openedx.core.lib.api import authentication
|
||||
@@ -47,19 +46,8 @@ class MockView(APIView): # pylint: disable=missing-docstring
|
||||
return HttpResponse({'a': 1, 'b': 2, 'c': 3})
|
||||
|
||||
|
||||
# This is the a change we've made from the django-rest-framework-oauth version
|
||||
# of these tests. We're subclassing our custom OAuth2AuthenticationAllowInactiveUser
|
||||
# instead of OAuth2Authentication.
|
||||
class OAuth2AuthenticationDebug(authentication.OAuth2AuthenticationAllowInactiveUserDeprecated):
|
||||
allow_query_params_token = True
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^oauth2/', include(('provider.oauth2.urls', 'oauth2'), namespace='oauth2')),
|
||||
url(
|
||||
r'^oauth2-inactive-deprecated-test/$',
|
||||
MockView.as_view(authentication_classes=[authentication.OAuth2AuthenticationAllowInactiveUserDeprecated])
|
||||
),
|
||||
url(
|
||||
r'^oauth2-inactive-test/$',
|
||||
MockView.as_view(authentication_classes=[authentication.OAuth2AuthenticationAllowInactiveUser])
|
||||
@@ -67,28 +55,19 @@ urlpatterns = [
|
||||
url(
|
||||
r'^oauth2-test/$',
|
||||
MockView.as_view(authentication_classes=[authentication.OAuth2Authentication])
|
||||
),
|
||||
# TODO(jinder): remove url when OAuth2AuthenticationDeprecated is fully removed
|
||||
url(r'^oauth2-test-debug/$', MockView.as_view(authentication_classes=[OAuth2AuthenticationDebug])),
|
||||
url(
|
||||
r'^oauth2-with-scope-test/$',
|
||||
MockView.as_view(
|
||||
authentication_classes=[authentication.OAuth2AuthenticationAllowInactiveUserDeprecated],
|
||||
permission_classes=[permissions.TokenHasReadWriteScope]
|
||||
)
|
||||
),
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
@ddt.ddt # pylint: disable=missing-docstring
|
||||
@unittest.skipUnless(settings.FEATURES.get("ENABLE_OAUTH2_PROVIDER"), "OAuth2 not enabled")
|
||||
@override_settings(ROOT_URLCONF=__name__)
|
||||
class OAuth2AllowInActiveUsersDeprecatedTests(TestCase):
|
||||
class OAuth2AllowInActiveUsersTests(TestCase):
|
||||
|
||||
OAUTH2_BASE_TESTING_URL = '/oauth2-inactive-deprecated-test/'
|
||||
OAUTH2_BASE_TESTING_URL = '/oauth2-inactive-test/'
|
||||
|
||||
def setUp(self):
|
||||
super(OAuth2AllowInActiveUsersDeprecatedTests, self).setUp()
|
||||
super(OAuth2AllowInActiveUsersTests, self).setUp()
|
||||
self.dop_adapter = adapters.DOPAdapter()
|
||||
self.dot_adapter = adapters.DOTAdapter()
|
||||
self.csrf_client = APIClient(enforce_csrf_checks=True)
|
||||
@@ -194,7 +173,6 @@ class OAuth2AllowInActiveUsersDeprecatedTests(TestCase):
|
||||
# provided (yet).
|
||||
self.assertNotIn('error_code', json.loads(response.content.decode('utf-8')))
|
||||
|
||||
@unittest.skipUnless(oauth2_provider, 'django-oauth2-provider not installed')
|
||||
def test_get_form_passing_auth(self):
|
||||
"""Ensure GETing form over OAuth with correct client credentials succeed"""
|
||||
response = self.get_with_bearer_token(self.OAUTH2_BASE_TESTING_URL)
|
||||
@@ -204,7 +182,6 @@ class OAuth2AllowInActiveUsersDeprecatedTests(TestCase):
|
||||
response = self.get_with_bearer_token(self.OAUTH2_BASE_TESTING_URL, token=self.dot_access_token.token)
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
|
||||
@unittest.skipUnless(oauth2_provider, 'django-oauth2-provider not installed')
|
||||
def test_post_form_passing_auth_url_transport(self):
|
||||
"""Ensure GETing form over OAuth with correct client credentials in form data succeed"""
|
||||
response = self.csrf_client.post(
|
||||
@@ -213,15 +190,6 @@ class OAuth2AllowInActiveUsersDeprecatedTests(TestCase):
|
||||
)
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
|
||||
# TODO(jinder): remove test when OAuth2AuthenticationDeprecated is fully removed
|
||||
@unittest.skipUnless(oauth2_provider, 'django-oauth2-provider not installed')
|
||||
def test_get_form_passing_auth_url_transport(self):
|
||||
"""Ensure GETing form over OAuth with correct client credentials in query succeed when DEBUG is True"""
|
||||
query = urlencode({'access_token': self.access_token.token})
|
||||
response = self.csrf_client.get('/oauth2-test-debug/?%s' % query)
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
|
||||
@unittest.skipUnless(oauth2_provider, 'django-oauth2-provider not installed')
|
||||
def test_get_form_failing_auth_url_transport(self):
|
||||
"""Ensure GETing form over OAuth with correct client credentials in query fails when DEBUG is False"""
|
||||
query = urlencode({'access_token': self.access_token.token})
|
||||
@@ -231,13 +199,11 @@ class OAuth2AllowInActiveUsersDeprecatedTests(TestCase):
|
||||
# This case is handled directly by DRF so no error_code is provided (yet).
|
||||
self.assertNotIn('error_code', json.loads(response.content.decode('utf-8')))
|
||||
|
||||
@unittest.skipUnless(oauth2_provider, 'django-oauth2-provider not installed')
|
||||
def test_post_form_passing_auth(self):
|
||||
"""Ensure POSTing form over OAuth with correct credentials passes and does not require CSRF"""
|
||||
response = self.post_with_bearer_token(self.OAUTH2_BASE_TESTING_URL)
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
|
||||
@unittest.skipUnless(oauth2_provider, 'django-oauth2-provider not installed')
|
||||
def test_post_form_token_removed_failing_auth(self):
|
||||
"""Ensure POSTing when there is no OAuth access token in db fails"""
|
||||
self.access_token.delete()
|
||||
@@ -248,7 +214,6 @@ class OAuth2AllowInActiveUsersDeprecatedTests(TestCase):
|
||||
error_code=authentication.OAUTH2_TOKEN_ERROR_NONEXISTENT
|
||||
)
|
||||
|
||||
@unittest.skipUnless(oauth2_provider, 'django-oauth2-provider not installed')
|
||||
def test_post_form_with_refresh_token_failing_auth(self):
|
||||
"""Ensure POSTing with refresh token instead of access token fails"""
|
||||
response = self.post_with_bearer_token(self.OAUTH2_BASE_TESTING_URL, token=self.refresh_token.token)
|
||||
@@ -258,7 +223,6 @@ class OAuth2AllowInActiveUsersDeprecatedTests(TestCase):
|
||||
error_code=authentication.OAUTH2_TOKEN_ERROR_NONEXISTENT
|
||||
)
|
||||
|
||||
@unittest.skipUnless(oauth2_provider, 'django-oauth2-provider not installed')
|
||||
def test_post_form_with_expired_access_token_failing_auth(self):
|
||||
"""Ensure POSTing with expired access token fails with a 'token_expired' error"""
|
||||
self.access_token.expires = now() - timedelta(seconds=10) # 10 seconds late
|
||||
@@ -283,7 +247,6 @@ class OAuth2AllowInActiveUsersDeprecatedTests(TestCase):
|
||||
)
|
||||
)
|
||||
@ddt.unpack
|
||||
@unittest.skipUnless(oauth2_provider, 'django-oauth2-provider not installed')
|
||||
def test_response_for_get_request_with_bad_auth_token(self, http_params, token_error):
|
||||
response = self.get_with_bearer_token(self.OAUTH2_BASE_TESTING_URL, http_params, token=token_error.token)
|
||||
self.check_error_codes(
|
||||
@@ -301,23 +264,8 @@ class OAuth2AllowInActiveUsersDeprecatedTests(TestCase):
|
||||
response = self.post_with_bearer_token(self.OAUTH2_BASE_TESTING_URL, token=token_error.token)
|
||||
self.check_error_codes(response, status_code=status.HTTP_401_UNAUTHORIZED, error_code=token_error.error_code)
|
||||
|
||||
ScopeStatusDDT = namedtuple('ScopeStatusDDT', ['scope', 'read_status', 'write_status'])
|
||||
|
||||
@ddt.data(
|
||||
ScopeStatusDDT('read', read_status=status.HTTP_200_OK, write_status=status.HTTP_403_FORBIDDEN),
|
||||
ScopeStatusDDT('write', status.HTTP_403_FORBIDDEN, status.HTTP_200_OK),
|
||||
)
|
||||
@unittest.skipUnless(oauth2_provider, 'django-oauth2-provider not installed')
|
||||
def test_responses_to_scoped_requests(self, scope_statuses):
|
||||
self.access_token.scope = oauth2_provider_scope.SCOPE_NAME_DICT[scope_statuses.scope]
|
||||
self.access_token.save()
|
||||
response = self.get_with_bearer_token('/oauth2-with-scope-test/', token=self.access_token.token)
|
||||
self.assertEqual(response.status_code, scope_statuses.read_status)
|
||||
response = self.post_with_bearer_token('/oauth2-with-scope-test/', token=self.access_token.token)
|
||||
self.assertEqual(response.status_code, scope_statuses.write_status)
|
||||
|
||||
|
||||
class OAuth2AuthenticationTests(OAuth2AllowInActiveUsersDeprecatedTests): # pylint: disable=test-inherits-tests
|
||||
class OAuth2AuthenticationTests(OAuth2AllowInActiveUsersTests): # pylint: disable=test-inherits-tests
|
||||
|
||||
OAUTH2_BASE_TESTING_URL = '/oauth2-test/'
|
||||
|
||||
@@ -326,8 +274,3 @@ class OAuth2AuthenticationTests(OAuth2AllowInActiveUsersDeprecatedTests): # pyl
|
||||
# Since this is testing back to previous version, user should be set to true
|
||||
self.user.is_active = True
|
||||
self.user.save()
|
||||
|
||||
|
||||
class OAuth2AllowInActiveUsersTests(OAuth2AllowInActiveUsersDeprecatedTests): # pylint: disable=test-inherits-tests
|
||||
|
||||
OAUTH2_BASE_TESTING_URL = '/oauth2-inactive-test/'
|
||||
|
||||
@@ -23,7 +23,7 @@ from rest_framework.views import APIView
|
||||
from six import text_type, iteritems
|
||||
|
||||
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUserDeprecated
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUser
|
||||
from openedx.core.lib.api.permissions import IsUserInUrl
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@ def view_auth_classes(is_user=False, is_authenticated=True):
|
||||
"""
|
||||
func_or_class.authentication_classes = (
|
||||
JwtAuthentication,
|
||||
OAuth2AuthenticationAllowInactiveUserDeprecated,
|
||||
OAuth2AuthenticationAllowInactiveUser,
|
||||
SessionAuthenticationAllowInactiveUser
|
||||
)
|
||||
func_or_class.permission_classes = ()
|
||||
|
||||
@@ -18,7 +18,7 @@ from experiments.models import ExperimentData
|
||||
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
|
||||
from openedx.core.djangoapps.cors_csrf.decorators import ensure_csrf_cookie_cross_domain
|
||||
from openedx.core.djangoapps.oauth_dispatch.jwt import create_jwt_for_user
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUserDeprecated
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUser
|
||||
from openedx.core.lib.api.permissions import ApiKeyHeaderPermissionIsAuthenticated
|
||||
from openedx.core.lib.api.view_utils import DeveloperErrorViewMixin
|
||||
|
||||
@@ -59,7 +59,7 @@ class CourseUserDiscount(DeveloperErrorViewMixin, APIView):
|
||||
"jwt": xxxxxxxx.xxxxxxxx.xxxxxxx
|
||||
}
|
||||
"""
|
||||
authentication_classes = (JwtAuthentication, OAuth2AuthenticationAllowInactiveUserDeprecated,
|
||||
authentication_classes = (JwtAuthentication, OAuth2AuthenticationAllowInactiveUser,
|
||||
SessionAuthenticationAllowInactiveUser,)
|
||||
permission_classes = (ApiKeyHeaderPermissionIsAuthenticated,)
|
||||
|
||||
@@ -130,7 +130,7 @@ class CourseUserDiscountWithUserParam(DeveloperErrorViewMixin, APIView):
|
||||
"jwt": xxxxxxxx.xxxxxxxx.xxxxxxx
|
||||
}
|
||||
"""
|
||||
authentication_classes = (JwtAuthentication, OAuth2AuthenticationAllowInactiveUserDeprecated,
|
||||
authentication_classes = (JwtAuthentication, OAuth2AuthenticationAllowInactiveUser,
|
||||
SessionAuthenticationAllowInactiveUser,)
|
||||
permission_classes = (ApiKeyHeaderPermissionIsAuthenticated, IsAdminUser)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user