refactor: pyupgrade on ace_common, api_admin, auth_exchange (#26782)
This commit is contained in:
@@ -20,14 +20,14 @@ class AceCommonConfig(AppConfig):
|
||||
plugin_app = {
|
||||
PluginSettings.CONFIG: {
|
||||
ProjectType.LMS: {
|
||||
SettingsType.PRODUCTION: {PluginSettings.RELATIVE_PATH: u'settings.production'},
|
||||
SettingsType.COMMON: {PluginSettings.RELATIVE_PATH: u'settings.common'},
|
||||
SettingsType.DEVSTACK: {PluginSettings.RELATIVE_PATH: u'settings.devstack'},
|
||||
SettingsType.PRODUCTION: {PluginSettings.RELATIVE_PATH: 'settings.production'},
|
||||
SettingsType.COMMON: {PluginSettings.RELATIVE_PATH: 'settings.common'},
|
||||
SettingsType.DEVSTACK: {PluginSettings.RELATIVE_PATH: 'settings.devstack'},
|
||||
},
|
||||
ProjectType.CMS: {
|
||||
SettingsType.PRODUCTION: {PluginSettings.RELATIVE_PATH: u'settings.production'},
|
||||
SettingsType.COMMON: {PluginSettings.RELATIVE_PATH: u'settings.common'},
|
||||
SettingsType.DEVSTACK: {PluginSettings.RELATIVE_PATH: u'settings.devstack'},
|
||||
SettingsType.PRODUCTION: {PluginSettings.RELATIVE_PATH: 'settings.production'},
|
||||
SettingsType.COMMON: {PluginSettings.RELATIVE_PATH: 'settings.common'},
|
||||
SettingsType.DEVSTACK: {PluginSettings.RELATIVE_PATH: 'settings.devstack'},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ from openedx.core.djangoapps.site_configuration import helpers as configuration_
|
||||
|
||||
class BaseMessageType(MessageType): # lint-amnesty, pylint: disable=missing-class-docstring
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(BaseMessageType, self).__init__(*args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().__init__(*args, **kwargs)
|
||||
from_address = configuration_helpers.get_value('email_from_address')
|
||||
if from_address:
|
||||
self.options.update({'from_address': from_address}) # pylint: disable=no-member
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
# pylint: disable=missing-docstring
|
||||
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from crum import get_current_request
|
||||
from django import template
|
||||
from django.utils.safestring import mark_safe
|
||||
from six.moves.urllib.parse import urlparse # pylint: disable=import-error
|
||||
|
||||
from openedx.core.djangoapps.ace_common.tracking import CampaignTrackingInfo, GoogleAnalyticsTrackingPixel
|
||||
from openedx.core.djangolib.markup import HTML
|
||||
@@ -57,14 +56,14 @@ def _get_variables_from_context(context, tag_name):
|
||||
|
||||
if request is None:
|
||||
raise template.VariableDoesNotExist(
|
||||
u'The {0} template tag requires a "request" to be present in the template context. Consider using '
|
||||
u'"emulate_http_request" if you are rendering the template in a celery task.'.format(tag_name)
|
||||
'The {} template tag requires a "request" to be present in the template context. Consider using '
|
||||
'"emulate_http_request" if you are rendering the template in a celery task.'.format(tag_name)
|
||||
)
|
||||
|
||||
message = context.get('message')
|
||||
if message is None:
|
||||
raise template.VariableDoesNotExist(
|
||||
u'The {0} template tag requires a "message" to be present in the template context.'.format(tag_name)
|
||||
f'The {tag_name} template tag requires a "message" to be present in the template context.'
|
||||
)
|
||||
|
||||
return request.site, request.user, message
|
||||
@@ -88,7 +87,7 @@ def google_analytics_tracking_pixel(context):
|
||||
image_url = _get_google_analytics_tracking_url(context)
|
||||
if image_url is not None:
|
||||
return mark_safe(
|
||||
HTML(u'<img src="{0}" alt="" role="presentation" aria-hidden="true" />').format(HTML(image_url))
|
||||
HTML('<img src="{0}" alt="" role="presentation" aria-hidden="true" />').format(HTML(image_url))
|
||||
)
|
||||
else:
|
||||
return ''
|
||||
@@ -103,7 +102,7 @@ def _get_google_analytics_tracking_url(context):
|
||||
campaign_source=message.app_label,
|
||||
campaign_name=message.name,
|
||||
campaign_content=message.uuid,
|
||||
document_path='/email/{0}/{1}/{2}/{3}'.format(
|
||||
document_path='/email/{}/{}/{}/{}'.format(
|
||||
message.app_label,
|
||||
message.name,
|
||||
message.send_uuid,
|
||||
@@ -151,5 +150,5 @@ def ensure_url_is_absolute(site, relative_path):
|
||||
else:
|
||||
root = site.domain.rstrip('/')
|
||||
relative_path = relative_path.lstrip('/')
|
||||
url = u'https://{root}/{path}'.format(root=root, path=relative_path)
|
||||
url = f'https://{root}/{relative_path}'
|
||||
return url
|
||||
|
||||
@@ -2,17 +2,17 @@
|
||||
|
||||
|
||||
import uuid
|
||||
from unittest.mock import patch
|
||||
from urllib.parse import parse_qs, urlparse
|
||||
|
||||
from django.http import HttpRequest
|
||||
from edx_ace import Message, Recipient
|
||||
from mock import patch
|
||||
from six.moves.urllib.parse import parse_qs, urlparse # pylint: disable=import-error
|
||||
|
||||
from openedx.core.djangoapps.site_configuration.tests.factories import SiteFactory
|
||||
from common.djangoapps.student.tests.factories import UserFactory
|
||||
|
||||
|
||||
class QueryStringAssertionMixin(object):
|
||||
class QueryStringAssertionMixin:
|
||||
|
||||
def assert_query_string_equal(self, expected_qs, actual_qs):
|
||||
"""
|
||||
@@ -64,10 +64,10 @@ class QueryStringAssertionMixin(object):
|
||||
assert parsed_qs[expected_key] == [str(expected_value)]
|
||||
|
||||
|
||||
class EmailTemplateTagMixin(object):
|
||||
class EmailTemplateTagMixin:
|
||||
|
||||
def setUp(self):
|
||||
super(EmailTemplateTagMixin, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
patcher = patch('openedx.core.djangoapps.ace_common.templatetags.ace.get_current_request')
|
||||
self.mock_get_current_request = patcher.start()
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
"""
|
||||
Tests for ace message module
|
||||
"""
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
import ddt
|
||||
from django.test import TestCase
|
||||
from mock import patch
|
||||
|
||||
from openedx.core.djangoapps.ace_common.message import BaseMessageType
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ class TestAbsoluteUrl(CacheIsolationTestCase):
|
||||
def setUp(self):
|
||||
self.site = SiteFactory.create()
|
||||
self.site.domain = 'example.com'
|
||||
super(TestAbsoluteUrl, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
def test_absolute_url(self):
|
||||
absolute = ensure_url_is_absolute(self.site, '/foo/bar')
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
# pylint: disable=missing-docstring
|
||||
|
||||
from urllib.parse import parse_qs
|
||||
|
||||
import attr
|
||||
import six
|
||||
from django.utils.http import urlencode
|
||||
from six.moves.urllib.parse import parse_qs # pylint: disable=import-error, ungrouped-imports
|
||||
|
||||
from openedx.core.djangoapps.theming.helpers import get_config_value_from_site_or_settings
|
||||
|
||||
@@ -13,7 +12,7 @@ DEFAULT_CAMPAIGN_MEDIUM = 'email'
|
||||
|
||||
|
||||
@attr.s
|
||||
class CampaignTrackingInfo(object):
|
||||
class CampaignTrackingInfo:
|
||||
"""
|
||||
A struct for storing the set of UTM parameters that are recognized by tracking tools when included in URLs.
|
||||
"""
|
||||
@@ -40,14 +39,14 @@ class CampaignTrackingInfo(object):
|
||||
if existing_query_string is not None:
|
||||
parameters = parse_qs(existing_query_string)
|
||||
|
||||
for attribute, value in six.iteritems(attr.asdict(self)):
|
||||
for attribute, value in attr.asdict(self).items():
|
||||
if value is not None:
|
||||
parameters['utm_' + attribute] = [value]
|
||||
return urlencode(parameters, doseq=True)
|
||||
|
||||
|
||||
@attr.s
|
||||
class GoogleAnalyticsTrackingPixel(object):
|
||||
class GoogleAnalyticsTrackingPixel:
|
||||
"""
|
||||
Implementation of the Google Analytics measurement protocol for email tracking.
|
||||
|
||||
@@ -101,14 +100,14 @@ class GoogleAnalyticsTrackingPixel(object):
|
||||
site=self.site,
|
||||
)
|
||||
if user_id_dimension is not None and self.user_id is not None:
|
||||
parameter_name = 'cd{0}'.format(user_id_dimension)
|
||||
parameter_name = f'cd{user_id_dimension}'
|
||||
parameters[parameter_name] = self.user_id
|
||||
|
||||
if self.course_id is not None and self.event_label is None:
|
||||
param_name = fields.event_label.metadata['param_name']
|
||||
parameters[param_name] = six.text_type(self.course_id)
|
||||
parameters[param_name] = str(self.course_id)
|
||||
|
||||
return u"https://www.google-analytics.com/collect?{params}".format(params=urlencode(parameters))
|
||||
return "https://www.google-analytics.com/collect?{params}".format(params=urlencode(parameters))
|
||||
|
||||
def _get_tracking_id(self):
|
||||
tracking_id = get_config_value_from_site_or_settings("GOOGLE_ANALYTICS_ACCOUNT", site=self.site)
|
||||
|
||||
@@ -33,9 +33,9 @@ class ApiAccessRequestAdmin(admin.ModelAdmin):
|
||||
},),
|
||||
('Status', {
|
||||
'description': Text(_(
|
||||
u'Once you have approved this request, go to {catalog_admin_url} to set up a catalog for this user.'
|
||||
'Once you have approved this request, go to {catalog_admin_url} to set up a catalog for this user.'
|
||||
)).format(
|
||||
catalog_admin_url=HTML(u'<a href="{0}">{0}</a>').format(reverse('api_admin:catalog-search'))
|
||||
catalog_admin_url=HTML('<a href="{0}">{0}</a>').format(reverse('api_admin:catalog-search'))
|
||||
),
|
||||
'fields': ('status',),
|
||||
}),
|
||||
|
||||
@@ -11,7 +11,7 @@ class ApiAccessRequestSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
ApiAccessRequest serializer.
|
||||
"""
|
||||
class Meta(object):
|
||||
class Meta:
|
||||
model = ApiAccessRequest
|
||||
fields = (
|
||||
'id', 'created', 'modified', 'user', 'status', 'website',
|
||||
|
||||
@@ -83,7 +83,7 @@ class ApiAccessRequestViewTests(TestCase):
|
||||
"""
|
||||
self.update_user_and_re_login(is_staff=True)
|
||||
|
||||
response = self.client.get(self.url + '?user__username={}'.format(self.user.username))
|
||||
response = self.client.get(self.url + f'?user__username={self.user.username}')
|
||||
self._assert_api_access_request_response(api_response=response, expected_results_count=1)
|
||||
|
||||
def test_filtering_for_non_existing_user(self):
|
||||
|
||||
@@ -13,7 +13,7 @@ class ApiAccessRequestForm(forms.ModelForm):
|
||||
"""Form to request API access."""
|
||||
terms_of_service = forms.BooleanField(widget=TermsOfServiceCheckboxInput(), label='')
|
||||
|
||||
class Meta(object):
|
||||
class Meta:
|
||||
model = ApiAccessRequest
|
||||
fields = ('company_name', 'website', 'company_address', 'reason', 'terms_of_service')
|
||||
labels = {
|
||||
@@ -34,7 +34,7 @@ class ApiAccessRequestForm(forms.ModelForm):
|
||||
def __init__(self, *args, **kwargs):
|
||||
# Get rid of the colons at the end of the field labels.
|
||||
kwargs.setdefault('label_suffix', '')
|
||||
super(ApiAccessRequestForm, self).__init__(*args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
|
||||
class ViewersWidget(forms.widgets.TextInput):
|
||||
@@ -61,7 +61,7 @@ class ViewersField(forms.Field):
|
||||
return [username.strip() for username in value.split(',')]
|
||||
|
||||
def validate(self, value):
|
||||
super(ViewersField, self).validate(value) # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().validate(value)
|
||||
nonexistent_users = []
|
||||
for username in value:
|
||||
try:
|
||||
@@ -70,7 +70,7 @@ class ViewersField(forms.Field):
|
||||
nonexistent_users.append(username)
|
||||
if nonexistent_users:
|
||||
raise forms.ValidationError(
|
||||
_(u'The following users do not exist: {usernames}.').format(usernames=nonexistent_users)
|
||||
_('The following users do not exist: {usernames}.').format(usernames=nonexistent_users)
|
||||
)
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ class CatalogForm(forms.ModelForm):
|
||||
|
||||
viewers = ViewersField()
|
||||
|
||||
class Meta(object):
|
||||
class Meta:
|
||||
model = Catalog
|
||||
fields = ('name', 'query', 'viewers')
|
||||
help_texts = {
|
||||
|
||||
@@ -8,7 +8,6 @@ from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imp
|
||||
from django.contrib.sites.models import Site
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
from django.db.models.signals import post_save, pre_save
|
||||
from six import text_type
|
||||
|
||||
from openedx.core.djangoapps.api_admin.models import (
|
||||
ApiAccessConfig,
|
||||
@@ -106,7 +105,7 @@ class Command(BaseCommand):
|
||||
try:
|
||||
return User.objects.get(username=username)
|
||||
except User.DoesNotExist:
|
||||
raise CommandError('User {} not found'.format(username)) # lint-amnesty, pylint: disable=raise-missing-from
|
||||
raise CommandError(f'User {username} not found') # lint-amnesty, pylint: disable=raise-missing-from
|
||||
|
||||
def create_api_access_request(self, user, status, reason, website):
|
||||
"""
|
||||
@@ -123,9 +122,9 @@ class Command(BaseCommand):
|
||||
except OSError as e:
|
||||
# Ignore a specific error that occurs in the downstream `send_request_email` receiver.
|
||||
# see https://openedx.atlassian.net/browse/EDUCATOR-4478
|
||||
error_msg = text_type(e)
|
||||
error_msg = str(e)
|
||||
if 'Permission denied' in error_msg and 'mako_lms' in error_msg:
|
||||
logger.warning('Error sending email about access request: {}'.format(error_msg))
|
||||
logger.warning(f'Error sending email about access request: {error_msg}')
|
||||
else:
|
||||
raise CommandError(error_msg) # lint-amnesty, pylint: disable=raise-missing-from
|
||||
except Exception as e:
|
||||
@@ -136,7 +135,7 @@ class Command(BaseCommand):
|
||||
)
|
||||
raise CommandError(msg) # lint-amnesty, pylint: disable=raise-missing-from
|
||||
|
||||
logger.info('Created ApiAccessRequest for user {}'.format(user.username))
|
||||
logger.info(f'Created ApiAccessRequest for user {user.username}')
|
||||
|
||||
def create_api_access_config(self):
|
||||
"""
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
import ddt
|
||||
from django.conf import settings
|
||||
@@ -6,7 +7,6 @@ from django.contrib.sites.models import Site
|
||||
from django.core.management import call_command
|
||||
from django.core.management.base import CommandError
|
||||
from django.test import TestCase
|
||||
from mock import patch
|
||||
|
||||
from openedx.core.djangoapps.api_admin.management.commands import create_api_access_request
|
||||
from openedx.core.djangoapps.api_admin.models import ApiAccessConfig, ApiAccessRequest
|
||||
@@ -20,7 +20,7 @@ class TestCreateApiAccessRequest(TestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestCreateApiAccessRequest, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.command = 'create_api_access_request'
|
||||
cls.user = UserFactory()
|
||||
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
import model_utils.fields
|
||||
@@ -21,7 +18,7 @@ class Migration(migrations.Migration):
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)),
|
||||
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)),
|
||||
('status', models.CharField(default=u'pending', help_text='Status of this API access request', max_length=255, db_index=True, choices=[(u'pending', 'Pending'), (u'denied', 'Denied'), (u'approved', 'Approved')])),
|
||||
('status', models.CharField(default='pending', help_text='Status of this API access request', max_length=255, db_index=True, choices=[('pending', 'Pending'), ('denied', 'Denied'), ('approved', 'Approved')])),
|
||||
('website', models.URLField(help_text='The URL of the website associated with this API user.')),
|
||||
('reason', models.TextField(help_text='The reason this user wants to access the API.')),
|
||||
('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)),
|
||||
@@ -38,7 +35,7 @@ class Migration(migrations.Migration):
|
||||
('id', models.IntegerField(verbose_name='ID', db_index=True, auto_created=True, blank=True)),
|
||||
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)),
|
||||
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)),
|
||||
('status', models.CharField(default=u'pending', help_text='Status of this API access request', max_length=255, db_index=True, choices=[(u'pending', 'Pending'), (u'denied', 'Denied'), (u'approved', 'Approved')])),
|
||||
('status', models.CharField(default='pending', help_text='Status of this API access request', max_length=255, db_index=True, choices=[('pending', 'Pending'), ('denied', 'Denied'), ('approved', 'Approved')])),
|
||||
('website', models.URLField(help_text='The URL of the website associated with this API user.')),
|
||||
('reason', models.TextField(help_text='The reason this user wants to access the API.')),
|
||||
('history_id', models.AutoField(serialize=False, primary_key=True)),
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
API_GROUP_NAME = 'API Access Request Approvers'
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
@@ -30,22 +27,22 @@ class Migration(migrations.Migration):
|
||||
migrations.AddField(
|
||||
model_name='apiaccessrequest',
|
||||
name='company_address',
|
||||
field=models.CharField(default=u'', max_length=255),
|
||||
field=models.CharField(default='', max_length=255),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='apiaccessrequest',
|
||||
name='company_name',
|
||||
field=models.CharField(default=u'', max_length=255),
|
||||
field=models.CharField(default='', max_length=255),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='historicalapiaccessrequest',
|
||||
name='company_address',
|
||||
field=models.CharField(default=u'', max_length=255),
|
||||
field=models.CharField(default='', max_length=255),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='historicalapiaccessrequest',
|
||||
name='company_name',
|
||||
field=models.CharField(default=u'', max_length=255),
|
||||
field=models.CharField(default='', max_length=255),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='apiaccessrequest',
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
import logging
|
||||
from smtplib import SMTPException
|
||||
from urllib.parse import urlunsplit
|
||||
|
||||
from config_models.models import ConfigurationModel
|
||||
from django.conf import settings
|
||||
@@ -18,7 +19,6 @@ from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.encoding import python_2_unicode_compatible
|
||||
|
||||
from model_utils.models import TimeStampedModel
|
||||
from six.moves.urllib.parse import urlunsplit # pylint: disable=import-error
|
||||
|
||||
from common.djangoapps.edxmako.shortcuts import render_to_string
|
||||
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
|
||||
@@ -36,9 +36,9 @@ class ApiAccessRequest(TimeStampedModel):
|
||||
.. pii_retirement: local_api
|
||||
"""
|
||||
|
||||
PENDING = u'pending'
|
||||
DENIED = u'denied'
|
||||
APPROVED = u'approved'
|
||||
PENDING = 'pending'
|
||||
DENIED = 'denied'
|
||||
APPROVED = 'approved'
|
||||
STATUS_CHOICES = (
|
||||
(PENDING, _('Pending')),
|
||||
(DENIED, _('Denied')),
|
||||
@@ -54,8 +54,8 @@ class ApiAccessRequest(TimeStampedModel):
|
||||
)
|
||||
website = models.URLField(help_text=_('The URL of the website associated with this API user.'))
|
||||
reason = models.TextField(help_text=_('The reason this user wants to access the API.'))
|
||||
company_name = models.CharField(max_length=255, default=u'')
|
||||
company_address = models.CharField(max_length=255, default=u'')
|
||||
company_name = models.CharField(max_length=255, default='')
|
||||
company_address = models.CharField(max_length=255, default='')
|
||||
site = models.ForeignKey(Site, on_delete=models.CASCADE)
|
||||
contacted = models.BooleanField(default=False)
|
||||
|
||||
@@ -118,18 +118,18 @@ class ApiAccessRequest(TimeStampedModel):
|
||||
|
||||
def approve(self):
|
||||
"""Approve this request."""
|
||||
log.info(u'Approving API request from user [%s].', self.user.id)
|
||||
log.info('Approving API request from user [%s].', self.user.id)
|
||||
self.status = self.APPROVED
|
||||
self.save()
|
||||
|
||||
def deny(self):
|
||||
"""Deny this request."""
|
||||
log.info(u'Denying API request from user [%s].', self.user.id)
|
||||
log.info('Denying API request from user [%s].', self.user.id)
|
||||
self.status = self.DENIED
|
||||
self.save()
|
||||
|
||||
def __str__(self):
|
||||
return u'ApiAccessRequest {website} [{status}]'.format(website=self.website, status=self.status)
|
||||
return f'ApiAccessRequest {self.website} [{self.status}]'
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
@@ -141,7 +141,7 @@ class ApiAccessConfig(ConfigurationModel):
|
||||
"""
|
||||
|
||||
def __str__(self):
|
||||
return 'ApiAccessConfig [enabled={}]'.format(self.enabled)
|
||||
return f'ApiAccessConfig [enabled={self.enabled}]'
|
||||
|
||||
|
||||
@receiver(post_save, sender=ApiAccessRequest, dispatch_uid="api_access_request_post_save_email")
|
||||
@@ -178,14 +178,14 @@ def _send_new_pending_email(instance):
|
||||
message = render_to_string('api_admin/api_access_request_email_new_request.txt', context)
|
||||
try:
|
||||
send_mail(
|
||||
_u(u'API access request from {company}').format(company=instance.company_name),
|
||||
_u('API access request from {company}').format(company=instance.company_name),
|
||||
message,
|
||||
settings.API_ACCESS_FROM_EMAIL,
|
||||
[settings.API_ACCESS_MANAGER_EMAIL],
|
||||
fail_silently=False
|
||||
)
|
||||
except SMTPException:
|
||||
log.exception(u'Error sending API user notification email for request [%s].', instance.id)
|
||||
log.exception('Error sending API user notification email for request [%s].', instance.id)
|
||||
|
||||
|
||||
def _send_decision_email(instance):
|
||||
@@ -208,7 +208,7 @@ def _send_decision_email(instance):
|
||||
}
|
||||
|
||||
message = render_to_string(
|
||||
'api_admin/api_access_request_email_{status}.txt'.format(status=instance.status),
|
||||
f'api_admin/api_access_request_email_{instance.status}.txt',
|
||||
context
|
||||
)
|
||||
try:
|
||||
@@ -221,7 +221,7 @@ def _send_decision_email(instance):
|
||||
)
|
||||
instance.contacted = True
|
||||
except SMTPException:
|
||||
log.exception(u'Error sending API user notification email for request [%s].', instance.id)
|
||||
log.exception('Error sending API user notification email for request [%s].', instance.id)
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
@@ -237,7 +237,7 @@ class Catalog(models.Model):
|
||||
query = models.TextField(null=False, blank=False)
|
||||
viewers = models.TextField()
|
||||
|
||||
class Meta(object):
|
||||
class Meta:
|
||||
# Catalogs live in course discovery, so we do not create any
|
||||
# tables in LMS. Instead we override the save method to not
|
||||
# touch the database, and use our API client to communicate
|
||||
@@ -252,7 +252,7 @@ class Catalog(models.Model):
|
||||
self.query = attributes['query']
|
||||
self.viewers = attributes['viewers']
|
||||
else:
|
||||
super(Catalog, self).__init__(*args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def save(self, **kwargs): # lint-amnesty, pylint: disable=arguments-differ, unused-argument
|
||||
return None
|
||||
@@ -268,4 +268,4 @@ class Catalog(models.Model):
|
||||
}
|
||||
|
||||
def __str__(self):
|
||||
return u'Catalog {name} [{query}]'.format(name=self.name, query=self.query)
|
||||
return f'Catalog {self.name} [{self.query}]'
|
||||
|
||||
@@ -15,7 +15,7 @@ Application = get_application_model() # pylint: disable=invalid-name
|
||||
|
||||
class ApiAccessRequestFactory(DjangoModelFactory):
|
||||
"""Factory for ApiAccessRequest objects."""
|
||||
class Meta(object):
|
||||
class Meta:
|
||||
model = ApiAccessRequest
|
||||
|
||||
user = factory.SubFactory(UserFactory)
|
||||
@@ -24,7 +24,7 @@ class ApiAccessRequestFactory(DjangoModelFactory):
|
||||
|
||||
class ApplicationFactory(DjangoModelFactory):
|
||||
"""Factory for OAuth Application objects."""
|
||||
class Meta(object):
|
||||
class Meta:
|
||||
model = Application
|
||||
|
||||
authorization_grant_type = Application.GRANT_CLIENT_CREDENTIALS
|
||||
@@ -34,7 +34,7 @@ class ApplicationFactory(DjangoModelFactory):
|
||||
class CatalogFactory(DjangoModelFactory):
|
||||
"""Factory for Catalog objects."""
|
||||
|
||||
class Meta(object):
|
||||
class Meta:
|
||||
model = Catalog
|
||||
|
||||
id = FuzzyInteger(0, 999) # pylint: disable=invalid-name
|
||||
|
||||
@@ -2,11 +2,10 @@
|
||||
|
||||
|
||||
from smtplib import SMTPException
|
||||
from unittest import mock
|
||||
|
||||
import pytest
|
||||
import ddt
|
||||
import mock
|
||||
import six
|
||||
from django.db import IntegrityError
|
||||
from django.test import TestCase
|
||||
|
||||
@@ -23,7 +22,7 @@ from common.djangoapps.student.tests.factories import UserFactory
|
||||
class ApiAccessRequestTests(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(ApiAccessRequestTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.user = UserFactory()
|
||||
self.request = ApiAccessRequestFactory(user=self.user)
|
||||
|
||||
@@ -64,7 +63,7 @@ class ApiAccessRequestTests(TestCase):
|
||||
assert ApiAccessRequest.api_access_status(self.user) is None
|
||||
|
||||
def test_unicode(self):
|
||||
request_unicode = six.text_type(self.request)
|
||||
request_unicode = str(self.request)
|
||||
assert self.request.website in request_unicode
|
||||
assert self.request.status in request_unicode
|
||||
|
||||
@@ -85,14 +84,14 @@ class ApiAccessRequestTests(TestCase):
|
||||
class ApiAccessConfigTests(TestCase):
|
||||
|
||||
def test_unicode(self):
|
||||
assert six.text_type(ApiAccessConfig(enabled=True)) == u'ApiAccessConfig [enabled=True]'
|
||||
assert six.text_type(ApiAccessConfig(enabled=False)) == u'ApiAccessConfig [enabled=False]'
|
||||
assert str(ApiAccessConfig(enabled=True)) == 'ApiAccessConfig [enabled=True]'
|
||||
assert str(ApiAccessConfig(enabled=False)) == 'ApiAccessConfig [enabled=False]'
|
||||
|
||||
|
||||
@skip_unless_lms
|
||||
class ApiAccessRequestSignalTests(TestCase):
|
||||
def setUp(self):
|
||||
super(ApiAccessRequestSignalTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.user = UserFactory()
|
||||
self.api_access_request = ApiAccessRequest(user=self.user, site=SiteFactory())
|
||||
self.send_new_pending_email_function = 'openedx.core.djangoapps.api_admin.models._send_new_pending_email'
|
||||
@@ -141,7 +140,7 @@ class ApiAccessRequestSignalTests(TestCase):
|
||||
|
||||
# Verify that initial save logs email errors properly
|
||||
mock_model_log_exception.assert_called_once_with(
|
||||
u'Error sending API user notification email for request [%s].', self.api_access_request.id
|
||||
'Error sending API user notification email for request [%s].', self.api_access_request.id
|
||||
)
|
||||
# Verify object saved
|
||||
assert self.api_access_request.id is not None
|
||||
@@ -151,7 +150,7 @@ class ApiAccessRequestSignalTests(TestCase):
|
||||
self.api_access_request.approve()
|
||||
# Verify that updating request status logs email errors properly
|
||||
mock_model_log_exception.assert_called_once_with(
|
||||
u'Error sending API user notification email for request [%s].', self.api_access_request.id
|
||||
'Error sending API user notification email for request [%s].', self.api_access_request.id
|
||||
)
|
||||
# Verify object saved
|
||||
assert self.api_access_request.status == ApiAccessRequest.APPROVED
|
||||
|
||||
@@ -29,7 +29,7 @@ class ApiAdminTest(TestCase):
|
||||
Base class to allow API admin access to tests.
|
||||
"""
|
||||
def setUp(self):
|
||||
super(ApiAdminTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
ApiAccessConfig(enabled=True).save()
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ class ApiRequestViewTest(ApiAdminTest):
|
||||
Test the API Request View.
|
||||
"""
|
||||
def setUp(self):
|
||||
super(ApiRequestViewTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.url = reverse('api_admin:api-request')
|
||||
password = 'abc123'
|
||||
self.user = UserFactory(password=password)
|
||||
@@ -110,7 +110,7 @@ class ApiRequestStatusViewTest(ApiAdminTest):
|
||||
Tests of the API Status endpoint.
|
||||
"""
|
||||
def setUp(self):
|
||||
super(ApiRequestStatusViewTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
password = 'abc123'
|
||||
self.user = UserFactory(password=password)
|
||||
self.client.login(username=self.user.username, password=password)
|
||||
@@ -226,7 +226,7 @@ class CatalogTest(ApiAdminTest):
|
||||
Test the catalog API.
|
||||
"""
|
||||
def setUp(self):
|
||||
super(CatalogTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
password = 'abc123'
|
||||
self.user = UserFactory(password=password, is_staff=True)
|
||||
self.client.login(username=self.user.username, password=password)
|
||||
@@ -237,7 +237,7 @@ class CatalogTest(ApiAdminTest):
|
||||
|
||||
url = '{root}/catalogs/'.format(root=settings.COURSE_CATALOG_API_URL.rstrip('/'))
|
||||
if catalog_id:
|
||||
url += '{id}/'.format(id=catalog_id)
|
||||
url += f'{catalog_id}/'
|
||||
|
||||
httpretty.register_uri(
|
||||
method,
|
||||
@@ -254,7 +254,7 @@ class CatalogSearchViewTest(CatalogTest):
|
||||
Test the catalog search endpoint.
|
||||
"""
|
||||
def setUp(self):
|
||||
super(CatalogSearchViewTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.url = reverse('api_admin:catalog-search')
|
||||
|
||||
def test_get(self):
|
||||
@@ -279,7 +279,7 @@ class CatalogListViewTest(CatalogTest):
|
||||
Test the catalog list endpoint.
|
||||
"""
|
||||
def setUp(self):
|
||||
super(CatalogListViewTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.catalog_user = UserFactory()
|
||||
self.url = reverse('api_admin:catalog-list', kwargs={'username': self.catalog_user.username})
|
||||
|
||||
@@ -331,7 +331,7 @@ class CatalogEditViewTest(CatalogTest):
|
||||
Test edits to the catalog endpoint.
|
||||
"""
|
||||
def setUp(self):
|
||||
super(CatalogEditViewTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.catalog_user = UserFactory()
|
||||
self.catalog = CatalogFactory(viewers=[self.catalog_user.username])
|
||||
self.url = reverse('api_admin:catalog-edit', kwargs={'catalog_id': self.catalog.id})
|
||||
@@ -353,7 +353,7 @@ class CatalogEditViewTest(CatalogTest):
|
||||
self.assertRedirects(response, reverse('api_admin:catalog-search'))
|
||||
assert httpretty.last_request().method == 'DELETE' # lint-amnesty, pylint: disable=no-member
|
||||
assert httpretty.last_request().path == \
|
||||
'/api/v1/catalogs/{}/'.format(self.catalog.id) # lint-amnesty, pylint: disable=no-member
|
||||
f'/api/v1/catalogs/{self.catalog.id}/' # lint-amnesty, pylint: disable=no-member
|
||||
assert len(httpretty.httpretty.latest_requests) == 1
|
||||
|
||||
@httpretty.activate
|
||||
@@ -380,7 +380,7 @@ class CatalogPreviewViewTest(CatalogTest):
|
||||
Test the catalog preview endpoint.
|
||||
"""
|
||||
def setUp(self):
|
||||
super(CatalogPreviewViewTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.url = reverse('api_admin:catalog-preview')
|
||||
|
||||
@httpretty.activate
|
||||
|
||||
@@ -40,12 +40,12 @@ class ApiRequestView(CreateView):
|
||||
"""
|
||||
if ApiAccessRequest.api_access_status(request.user) is not None:
|
||||
return redirect(reverse('api_admin:api-status'))
|
||||
return super(ApiRequestView, self).get(request) # lint-amnesty, pylint: disable=super-with-arguments
|
||||
return super().get(request)
|
||||
|
||||
def form_valid(self, form):
|
||||
form.instance.user = self.request.user
|
||||
form.instance.site = get_current_site(self.request)
|
||||
return super(ApiRequestView, self).form_valid(form) # lint-amnesty, pylint: disable=super-with-arguments
|
||||
return super().form_valid(form)
|
||||
|
||||
|
||||
class ApiRequestStatusView(ApplicationRegistration):
|
||||
@@ -87,7 +87,7 @@ class ApiRequestStatusView(ApplicationRegistration):
|
||||
})
|
||||
|
||||
def get_form(self, form_class=None):
|
||||
form = super(ApiRequestStatusView, self).get_form(form_class) # lint-amnesty, pylint: disable=super-with-arguments
|
||||
form = super().get_form(form_class)
|
||||
# Copy the data, since it's an immutable QueryDict.
|
||||
copied_data = form.data.copy()
|
||||
# Now set the fields that were removed earlier. We give them
|
||||
@@ -105,14 +105,14 @@ class ApiRequestStatusView(ApplicationRegistration):
|
||||
def form_valid(self, form):
|
||||
# Delete any existing applications if the user has decided to regenerate their credentials
|
||||
Application.objects.filter(user=self.request.user).delete()
|
||||
return super(ApiRequestStatusView, self).form_valid(form) # lint-amnesty, pylint: disable=super-with-arguments
|
||||
return super().form_valid(form)
|
||||
|
||||
def form_invalid(self, form):
|
||||
return self.get(self.request, form)
|
||||
|
||||
@require_api_access
|
||||
def post(self, request): # lint-amnesty, pylint: disable=arguments-differ
|
||||
return super(ApiRequestStatusView, self).post(request) # lint-amnesty, pylint: disable=super-with-arguments
|
||||
return super().post(request)
|
||||
|
||||
|
||||
class ApiTosView(TemplateView):
|
||||
@@ -121,7 +121,7 @@ class ApiTosView(TemplateView):
|
||||
template_name = 'api_admin/terms_of_service.html'
|
||||
|
||||
|
||||
class CatalogApiMixin(object):
|
||||
class CatalogApiMixin:
|
||||
def get_catalog_api_client(self, user):
|
||||
return create_catalog_api_client(user)
|
||||
|
||||
|
||||
@@ -30,16 +30,16 @@ class TermsOfServiceCheckboxInput(CheckboxInput):
|
||||
# Translators: link_start and link_end are HTML tags for a link to the terms of service.
|
||||
# platform_name is the name of this Open edX installation.
|
||||
label = Text(_(
|
||||
u'I, and my organization, accept the {link_start}{platform_name} API Terms of Service{link_end}.'
|
||||
'I, and my organization, accept the {link_start}{platform_name} API Terms of Service{link_end}.'
|
||||
)).format(
|
||||
platform_name=configuration_helpers.get_value('PLATFORM_NAME', settings.PLATFORM_NAME),
|
||||
link_start=HTML(u'<a href="{url}" rel="noopener" target="_blank">').format(
|
||||
link_start=HTML('<a href="{url}" rel="noopener" target="_blank">').format(
|
||||
url=reverse('api_admin:api-tos')
|
||||
),
|
||||
link_end=HTML('</a>'),
|
||||
)
|
||||
|
||||
html = HTML(u'<input{{}} /> <label class="tos-checkbox-label" for="{id}">{label}</label>').format(
|
||||
html = HTML('<input{{}} /> <label class="tos-checkbox-label" for="{id}">{label}</label>').format(
|
||||
id=final_attrs['id'],
|
||||
label=label
|
||||
)
|
||||
|
||||
@@ -55,7 +55,7 @@ class ScopeChoiceField(forms.ChoiceField):
|
||||
value = value.split(' ')
|
||||
|
||||
# Split values into list
|
||||
return u' '.join([smart_text(val) for val in value]).split(u' ')
|
||||
return ' '.join([smart_text(val) for val in value]).split(' ')
|
||||
|
||||
def validate(self, value):
|
||||
"""
|
||||
@@ -86,7 +86,7 @@ class AccessTokenExchangeForm(forms.Form):
|
||||
client_id = CharField(required=False)
|
||||
|
||||
def __init__(self, request, oauth2_adapter, *args, **kwargs):
|
||||
super(AccessTokenExchangeForm, self).__init__(*args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().__init__(*args, **kwargs)
|
||||
self.request = request
|
||||
self.oauth2_adapter = oauth2_adapter
|
||||
|
||||
@@ -96,7 +96,7 @@ class AccessTokenExchangeForm(forms.Form):
|
||||
instead of validating each field.
|
||||
"""
|
||||
try:
|
||||
super(AccessTokenExchangeForm, self)._clean_fields() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super()._clean_fields()
|
||||
except OAuthValidationError as e:
|
||||
self._errors.update(e.args[0])
|
||||
|
||||
@@ -105,7 +105,7 @@ class AccessTokenExchangeForm(forms.Form):
|
||||
Overriding the default cleaning behaviour for a shallow error dict.
|
||||
"""
|
||||
try:
|
||||
super(AccessTokenExchangeForm, self)._clean_form() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super()._clean_form()
|
||||
except OAuthValidationError as e:
|
||||
self._errors.update(e.args[0])
|
||||
|
||||
@@ -118,7 +118,7 @@ class AccessTokenExchangeForm(forms.Form):
|
||||
raise OAuthValidationError(
|
||||
{
|
||||
"error": "invalid_request",
|
||||
"error_description": u"{} is required".format(field_name),
|
||||
"error_description": f"{field_name} is required",
|
||||
}
|
||||
)
|
||||
return field_val
|
||||
@@ -154,7 +154,7 @@ class AccessTokenExchangeForm(forms.Form):
|
||||
raise OAuthValidationError(
|
||||
{
|
||||
"error": "invalid_request",
|
||||
"error_description": u"{} is not a supported provider".format(backend.name),
|
||||
"error_description": f"{backend.name} is not a supported provider",
|
||||
}
|
||||
)
|
||||
|
||||
@@ -167,7 +167,7 @@ class AccessTokenExchangeForm(forms.Form):
|
||||
raise OAuthValidationError( # lint-amnesty, pylint: disable=raise-missing-from
|
||||
{
|
||||
"error": "invalid_client",
|
||||
"error_description": u"{} is not a valid client_id".format(client_id),
|
||||
"error_description": f"{client_id} is not a valid client_id",
|
||||
}
|
||||
)
|
||||
if client.client_type != Application.CLIENT_PUBLIC:
|
||||
@@ -176,7 +176,7 @@ class AccessTokenExchangeForm(forms.Form):
|
||||
# invalid_client isn't really the right code, but this mirrors
|
||||
# https://github.com/edx/django-oauth2-provider/blob/edx/provider/oauth2/forms.py#L331
|
||||
"error": "invalid_client",
|
||||
"error_description": u"{} is not a public client".format(client_id),
|
||||
"error_description": f"{client_id} is not a public client",
|
||||
}
|
||||
)
|
||||
self.cleaned_data["client"] = client
|
||||
|
||||
@@ -6,7 +6,7 @@ from openedx.core.djangoapps.oauth_dispatch import adapters
|
||||
from openedx.core.djangoapps.oauth_dispatch.tests.constants import DUMMY_REDIRECT_URL
|
||||
|
||||
|
||||
class DOTAdapterMixin(object):
|
||||
class DOTAdapterMixin:
|
||||
"""
|
||||
Mixin to rewire existing tests to use django-oauth-toolkit (DOT) backend
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ class AccessTokenExchangeFormTest(AccessTokenExchangeTestMixin):
|
||||
Mixin that defines test cases for AccessTokenExchangeForm
|
||||
"""
|
||||
def setUp(self):
|
||||
super(AccessTokenExchangeFormTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.request = RequestFactory().post("dummy_url")
|
||||
redirect_uri = 'dummy_redirect_url'
|
||||
SessionMiddleware().process_request(self.request)
|
||||
@@ -34,7 +34,7 @@ class AccessTokenExchangeFormTest(AccessTokenExchangeTestMixin):
|
||||
self.request.backend = social_utils.load_backend(self.request.social_strategy, self.BACKEND, redirect_uri)
|
||||
|
||||
def tearDown(self):
|
||||
super(AccessTokenExchangeFormTest, self).tearDown() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().tearDown()
|
||||
Partial.objects.all().delete()
|
||||
|
||||
def _assert_error(self, data, expected_error, expected_error_description): # lint-amnesty, pylint: disable=arguments-differ
|
||||
|
||||
@@ -40,19 +40,19 @@ class AccessTokenExchangeViewTest(AccessTokenExchangeTestMixin):
|
||||
in the future.
|
||||
"""
|
||||
def setUp(self):
|
||||
super(AccessTokenExchangeViewTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.url = reverse("exchange_access_token", kwargs={"backend": self.BACKEND})
|
||||
self.csrf_client = APIClient(enforce_csrf_checks=True)
|
||||
|
||||
def tearDown(self):
|
||||
super(AccessTokenExchangeViewTest, self).tearDown() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().tearDown()
|
||||
Partial.objects.all().delete()
|
||||
|
||||
def _assert_error(self, data, expected_error, expected_error_description, error_code=None):
|
||||
response = self.csrf_client.post(self.url, data)
|
||||
assert response.status_code == (error_code if error_code else 400)
|
||||
assert response['Content-Type'] == 'application/json'
|
||||
expected_data = {u"error": expected_error, u"error_description": expected_error_description}
|
||||
expected_data = {"error": expected_error, "error_description": expected_error_description}
|
||||
if error_code:
|
||||
expected_data['error_code'] = error_code
|
||||
assert json.loads(response.content.decode('utf-8')) == expected_data
|
||||
@@ -146,7 +146,7 @@ class TestLoginWithAccessTokenView(TestCase):
|
||||
Tests for LoginWithAccessTokenView
|
||||
"""
|
||||
def setUp(self):
|
||||
super(TestLoginWithAccessTokenView, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.user = UserFactory()
|
||||
self.oauth2_client = Application.objects.create(client_type=Application.CLIENT_CONFIDENTIAL)
|
||||
|
||||
@@ -155,7 +155,7 @@ class TestLoginWithAccessTokenView(TestCase):
|
||||
Calls the login_with_access_token endpoint and verifies the response given the expected values.
|
||||
"""
|
||||
url = reverse("login_with_access_token")
|
||||
response = self.client.post(url, HTTP_AUTHORIZATION=u"Bearer {0}".format(access_token).encode('utf-8'))
|
||||
response = self.client.post(url, HTTP_AUTHORIZATION=f"Bearer {access_token}".encode('utf-8'))
|
||||
assert response.status_code == expected_status_code
|
||||
if expected_cookie_name:
|
||||
assert expected_cookie_name in response.cookies
|
||||
|
||||
@@ -20,7 +20,7 @@ class AccessTokenExchangeTestMixin(ThirdPartyOAuthTestMixin):
|
||||
* _assert_success(data, expected_scopes)
|
||||
"""
|
||||
def setUp(self):
|
||||
super(AccessTokenExchangeTestMixin, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
# Initialize to minimal data
|
||||
self.data = {
|
||||
@@ -61,7 +61,7 @@ class AccessTokenExchangeTestMixin(ThirdPartyOAuthTestMixin):
|
||||
for field in ["access_token", "client_id"]:
|
||||
data = dict(self.data)
|
||||
del data[field]
|
||||
self._assert_error(data, "invalid_request", u"{} is required".format(field)) # lint-amnesty, pylint: disable=no-value-for-parameter
|
||||
self._assert_error(data, "invalid_request", f"{field} is required") # lint-amnesty, pylint: disable=no-value-for-parameter
|
||||
|
||||
def test_invalid_client(self):
|
||||
self.data["client_id"] = "nonexistent_client"
|
||||
@@ -77,7 +77,7 @@ class AccessTokenExchangeTestMixin(ThirdPartyOAuthTestMixin):
|
||||
self._assert_error( # lint-amnesty, pylint: disable=no-value-for-parameter
|
||||
self.data,
|
||||
"invalid_client",
|
||||
"{}_confidential is not a public client".format(self.client_id),
|
||||
f"{self.client_id}_confidential is not a public client",
|
||||
)
|
||||
|
||||
def test_inactive_user(self):
|
||||
|
||||
@@ -41,7 +41,7 @@ class AccessTokenExchangeBase(APIView):
|
||||
|
||||
@method_decorator(social_utils.psa("social:complete"))
|
||||
def dispatch(self, *args, **kwargs): # pylint: disable=arguments-differ
|
||||
return super(AccessTokenExchangeBase, self).dispatch(*args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
|
||||
return super().dispatch(*args, **kwargs)
|
||||
|
||||
def post(self, request, _backend):
|
||||
"""
|
||||
@@ -146,8 +146,8 @@ class LoginWithAccessTokenView(APIView):
|
||||
|
||||
if not self._is_grant_password(request.auth):
|
||||
raise AuthenticationFailed({
|
||||
u'error_code': u'non_supported_token',
|
||||
u'developer_message': u'Only support DOT type access token with grant type password. '
|
||||
'error_code': 'non_supported_token',
|
||||
'developer_message': 'Only support DOT type access token with grant type password. '
|
||||
})
|
||||
|
||||
login(request, request.user) # login generates and stores the user's cookies in the session
|
||||
|
||||
Reference in New Issue
Block a user