django-pfx 1.4.dev48__tar.gz → 1.4.dev50__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/PKG-INFO +1 -1
  2. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/django_pfx.egg-info/PKG-INFO +1 -1
  3. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/doc/source/authentication.md +4 -0
  4. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/default_settings.py +1 -0
  5. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/models/otp_user_mixin.py +12 -3
  6. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/tests/test_auth_api.py +4 -1
  7. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/.gitignore +0 -0
  8. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/.gitlab-ci.yml +0 -0
  9. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/.pre-commit-config.yaml +0 -0
  10. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/LICENSE +0 -0
  11. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/MANIFEST.in +0 -0
  12. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/README.md +0 -0
  13. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/django_pfx.egg-info/SOURCES.txt +0 -0
  14. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/django_pfx.egg-info/dependency_links.txt +0 -0
  15. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/django_pfx.egg-info/requires.txt +0 -0
  16. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/django_pfx.egg-info/top_level.txt +0 -0
  17. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/doc/Makefile +0 -0
  18. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/doc/conf.py +0 -0
  19. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/doc/index.rst +0 -0
  20. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/doc/source/api.views.rst +0 -0
  21. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/doc/source/decorator.md +0 -0
  22. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/doc/source/generate_openapi.md +0 -0
  23. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/doc/source/getting_started.md +0 -0
  24. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/doc/source/internationalisation.md +0 -0
  25. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/doc/source/model.md +0 -0
  26. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/doc/source/pfx_views.md +0 -0
  27. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/doc/source/profiling.md +0 -0
  28. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/doc/source/settings.md +0 -0
  29. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/doc/source/testing.md +0 -0
  30. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/img/pfx.png +0 -0
  31. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/img/pfx.svg +0 -0
  32. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/make_messages +0 -0
  33. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/manage.py +0 -0
  34. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/__init__.py +0 -0
  35. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/__init__.py +0 -0
  36. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/apidoc/__init__.py +0 -0
  37. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/apidoc/parameters.py +0 -0
  38. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/apidoc/schema.py +0 -0
  39. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/apidoc/tags.py +0 -0
  40. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/apps.py +0 -0
  41. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/decorator/__init__.py +0 -0
  42. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/decorator/rest.py +0 -0
  43. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/exceptions.py +0 -0
  44. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/fields.py +0 -0
  45. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/http/__init__.py +0 -0
  46. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/http/json_response.py +0 -0
  47. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/locale/fr/LC_MESSAGES/django.mo +0 -0
  48. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/locale/fr/LC_MESSAGES/django.po +0 -0
  49. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/management/__init__.py +0 -0
  50. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/management/commands/__init__.py +0 -0
  51. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/management/commands/makeapidoc.py +0 -0
  52. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/management/commands/profile.py +0 -0
  53. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/middleware/__init__.py +0 -0
  54. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/middleware/authentication.py +0 -0
  55. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/middleware/locale.py +0 -0
  56. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/middleware/profiling.py +0 -0
  57. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/migrations/0001_initial.py +0 -0
  58. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/migrations/__init__.py +0 -0
  59. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/models/__init__.py +0 -0
  60. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/models/abstract_pfx_base_user.py +0 -0
  61. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/models/cache_mixins.py +0 -0
  62. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/models/login_ban.py +0 -0
  63. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/models/not_null_fields.py +0 -0
  64. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/models/pfx_models.py +0 -0
  65. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/models/pfx_user.py +0 -0
  66. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/models/user_filtered_queryset_mixin.py +0 -0
  67. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/serializers/__init__.py +0 -0
  68. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/serializers/json.py +0 -0
  69. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/settings.py +0 -0
  70. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/shortcuts.py +0 -0
  71. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/storage/__init__.py +0 -0
  72. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/storage/s3_storage.py +0 -0
  73. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/templates/registration/otp_code_email.txt +0 -0
  74. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/templates/registration/otp_code_subject.txt +0 -0
  75. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/templates/registration/password_reset_email.txt +0 -0
  76. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/templates/registration/password_reset_subject.txt +0 -0
  77. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/templates/registration/welcome_email.txt +0 -0
  78. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/templates/registration/welcome_subject.txt +0 -0
  79. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/test.py +0 -0
  80. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/urls.py +0 -0
  81. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/views/__init__.py +0 -0
  82. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/views/authentication_views.py +0 -0
  83. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/views/fields.py +0 -0
  84. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/views/filters_views.py +0 -0
  85. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/views/locale_views.py +0 -0
  86. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/views/parameters/__init__.py +0 -0
  87. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/views/parameters/date_format.py +0 -0
  88. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/views/parameters/groups.py +0 -0
  89. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/views/parameters/list_count.py +0 -0
  90. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/views/parameters/list_items.py +0 -0
  91. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/views/parameters/list_mode.py +0 -0
  92. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/views/parameters/list_order.py +0 -0
  93. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/views/parameters/list_search.py +0 -0
  94. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/views/parameters/media_redirect.py +0 -0
  95. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/views/parameters/meta_fields.py +0 -0
  96. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/views/parameters/meta_filters.py +0 -0
  97. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/views/parameters/meta_orders.py +0 -0
  98. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/views/parameters/subset.py +0 -0
  99. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/views/parameters/subset_limit.py +0 -0
  100. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/views/parameters/subset_offset.py +0 -0
  101. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/views/parameters/subset_page.py +0 -0
  102. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/views/parameters/subset_page_size.py +0 -0
  103. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/views/parameters/subset_page_subset.py +0 -0
  104. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/pfxcore/views/rest_views.py +0 -0
  105. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/settings/__init__.py +0 -0
  106. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pfx/settings/dev.py +0 -0
  107. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/pyproject.toml +0 -0
  108. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/requirements.txt +0 -0
  109. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/serve-doc +0 -0
  110. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/setup.cfg +0 -0
  111. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/setup.py +0 -0
  112. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/__init__.py +0 -0
  113. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/locale/fr/LC_MESSAGES/django.po +0 -0
  114. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/models.py +0 -0
  115. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/settings/__init__.py +0 -0
  116. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/settings/ci.py +0 -0
  117. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/settings/common.py +0 -0
  118. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/settings/dev.py +0 -0
  119. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/settings/dev_custom_example.py +0 -0
  120. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/settings/dev_default.py +0 -0
  121. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/tests/__init__.py +0 -0
  122. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/tests/basic_api_errors.py +0 -0
  123. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/tests/basic_api_test.py +0 -0
  124. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/tests/test_api_doc.py +0 -0
  125. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/tests/test_body_mixin.py +0 -0
  126. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/tests/test_cache.py +0 -0
  127. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/tests/test_client.py +0 -0
  128. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/tests/test_fields.py +0 -0
  129. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/tests/test_filters.py +0 -0
  130. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/tests/test_locale_api.py +0 -0
  131. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/tests/test_perm_tests.py +0 -0
  132. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/tests/test_perms_api.py +0 -0
  133. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/tests/test_profiling_middleware.py +0 -0
  134. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/tests/test_settings.py +0 -0
  135. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/tests/test_shortcuts.py +0 -0
  136. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/tests/test_timezone_middleware.py +0 -0
  137. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/tests/test_tools.py +0 -0
  138. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/tests/test_user_queryset.py +0 -0
  139. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/tests/test_view_decorators.py +0 -0
  140. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/tests/test_view_fields.py +0 -0
  141. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/urls.py +0 -0
  142. {django_pfx-1.4.dev48 → django_pfx-1.4.dev50}/tests/views.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: django-pfx
3
- Version: 1.4.dev48
3
+ Version: 1.4.dev50
4
4
  Summary: Django PFX is a toolkit designed to streamline the development of RESTful APIs using the Django framework.
5
5
  Author: Hervé Martinet
6
6
  Author-email: herve.martinet@gmail.com
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: django-pfx
3
- Version: 1.4.dev48
3
+ Version: 1.4.dev50
4
4
  Summary: Django PFX is a toolkit designed to streamline the development of RESTful APIs using the Django framework.
5
5
  Author: Hervé Martinet
6
6
  Author-email: herve.martinet@gmail.com
@@ -97,6 +97,10 @@ class MyUser(OtpUserMixin, AbstractPFXBaseUser):
97
97
  * `PFX_TOKEN_OTP_VALIDITY`: Validity for OTP tokens (corresponds to the maximum time to enter
98
98
  an OTP code after logging in with a password) (optional, default `{'minutes': 15}`)
99
99
  * `PFX_HOTP_CODE_VALIDITY`: Validity of HOTP codes in minutes (used to send code by email) (optional, default `15`).
100
+ * `PFX_OTP_VALID_WINDOW`: TOTP valid window (optional, default `1`).
101
+ According to [RFC 6238 section 5.2](https://www.ietf.org/rfc/rfc6238.html#section-5.2).
102
+ * `PFX_OTP_IMAGE`: An image https URL used by FreeOTP. See [FreeOTP URI](https://github.com/npmccallum/freeotp-android/blob/master/URI.md).
103
+ * `PFX_OTP_COLOR`: A brand color (in RRGGBB format) for used by FreeOTP. See [FreeOTP URI](https://github.com/npmccallum/freeotp-android/blob/master/URI.md).
100
104
 
101
105
  The user can then enable or disable the OTP auth using the [services documented below](#enable-mfa-otp).
102
106
 
@@ -4,6 +4,7 @@ PFX_TOKEN_OTP_VALIDITY = {'minutes': 15}
4
4
  PFX_HOTP_CODE_VALIDITY = 15
5
5
  PFX_OTP_VALID_WINDOW = 1
6
6
  PFX_OTP_IMAGE = None
7
+ PFX_OTP_COLOR = None
7
8
 
8
9
  PFX_COOKIE_DOMAIN = None
9
10
  PFX_COOKIE_SECURE = True
@@ -65,7 +65,7 @@ class OtpUserMixin(models.Model):
65
65
  self.otp_secret_token = None
66
66
  self.save(update_fields=['otp_secret_token'])
67
67
 
68
- def get_otp_setup_uri(self, tmp=False):
68
+ def get_otp_setup_uri(self, tmp=False, with_color=True):
69
69
  """Return the setup URL for OTP activation.
70
70
  """
71
71
  import pyotp
@@ -73,9 +73,14 @@ class OtpUserMixin(models.Model):
73
73
  name=self.get_username(), issuer_name=settings.PFX_SITE_NAME)
74
74
  if settings.PFX_OTP_IMAGE:
75
75
  args['image'] = settings.PFX_OTP_IMAGE
76
- return pyotp.totp.TOTP(
76
+ uri = pyotp.totp.TOTP(
77
77
  tmp and self.otp_secret_token_tmp or
78
78
  self.otp_secret_token).provisioning_uri(**args)
79
+ if with_color and settings.PFX_OTP_COLOR:
80
+ # TODO: Can be put in provisioning_uri args if
81
+ # https://github.com/pyauth/pyotp/pull/164 is merge and published.
82
+ uri = f"{uri}&color={settings.PFX_OTP_COLOR}"
83
+ return uri
79
84
 
80
85
  def is_otp_valid(self, otp_code, tmp=False):
81
86
  """Verify an OTP code.
@@ -86,7 +91,11 @@ class OtpUserMixin(models.Model):
86
91
  :returns: `True` if the code is valid, `False` otherwise.
87
92
  """
88
93
  import pyotp
89
- totp = pyotp.parse_uri(self.get_otp_setup_uri(tmp=tmp))
94
+
95
+ # TODO : The with_color paramter can be removed if
96
+ # https://github.com/pyauth/pyotp/pull/164 is merge and published.
97
+ totp = pyotp.parse_uri(
98
+ self.get_otp_setup_uri(tmp=tmp, with_color=False))
90
99
  valid = totp.verify(
91
100
  otp_code, valid_window=settings.PFX_OTP_VALID_WINDOW)
92
101
  if not valid and timezone.now() <= self.hotp_expiry:
@@ -895,7 +895,9 @@ class AuthAPITest(TestAssertMixin, TransactionTestCase):
895
895
  self.assertRC(response, 200)
896
896
  self.client.token = self.get_val(response, 'token')
897
897
 
898
- @override_settings(PFX_OTP_IMAGE="https://example.org/fake.png")
898
+ @override_settings(
899
+ PFX_OTP_IMAGE="https://example.org/fake.png",
900
+ PFX_OTP_COLOR="FF0000")
899
901
  def test_otp_enable(self):
900
902
  self.client.login(username='jrr.tolkien', password='RIGHT PASSWORD')
901
903
 
@@ -905,6 +907,7 @@ class AuthAPITest(TestAssertMixin, TransactionTestCase):
905
907
  self.assertJIn(response, 'setup_uri', "otpauth://totp/")
906
908
  self.assertJIn(response, 'setup_uri', "Books%20Demo:jrr.tolkien")
907
909
  self.assertJIn(response, 'setup_uri', "issuer=Books%20Demo")
910
+ self.assertJIn(response, 'setup_uri', "color=FF0000")
908
911
  self.assertJIn(
909
912
  response, 'setup_uri',
910
913
  "image=https%3A%2F%2Fexample.org%2Ffake.png")
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes