Skip to content

Commit f344b06

Browse files
authored
Disable 255 chars length limit for redirect uri (#902) (#903)
* Disable 255 chars length limit for redirect uri (#902) RFC 7230 recommends to design system to be capable to work with URI at least to 8000 chars long. This commit allows handle redirect_uri that is over 255 chars.
1 parent 86e78b9 commit f344b06

File tree

5 files changed

+64
-13
lines changed

5 files changed

+64
-13
lines changed

‎AUTHORS‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ Jens Timmerman
2626
Jerome Leclanche
2727
Jim Graham
2828
Paul Oswald
29+
Pavel Tvrdík
2930
pySilver
3031
Rodney Richardson
3132
Silvano Cerza

‎CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1717
## [unreleased]
1818

1919
*#898 Added the ability to customize classes for django admin
20+
*#903 Disable `redirect_uri` field length limit for `AbstractGrant`
2021

2122
### Added
2223
*#884 Added support for Python 3.9
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 3.1.4 on 2020-12-11 13:14
2+
3+
fromdjango.dbimportmigrations, models
4+
5+
6+
classMigration(migrations.Migration):
7+
8+
dependencies= [
9+
('oauth2_provider', '0002_auto_20190406_1805'),
10+
]
11+
12+
operations= [
13+
migrations.AlterField(
14+
model_name='grant',
15+
name='redirect_uri',
16+
field=models.TextField(),
17+
),
18+
]

‎oauth2_provider/models.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ class AbstractGrant(models.Model):
220220
code=models.CharField(max_length=255, unique=True) # code comes from oauthlib
221221
application=models.ForeignKey(oauth2_settings.APPLICATION_MODEL, on_delete=models.CASCADE)
222222
expires=models.DateTimeField()
223-
redirect_uri=models.CharField(max_length=255)
223+
redirect_uri=models.TextField()
224224
scope=models.TextField(blank=True)
225225

226226
created=models.DateTimeField(auto_now_add=True)

‎tests/test_models.py‎

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,15 @@
2222
UserModel=get_user_model()
2323

2424

25-
classTestModels(TestCase):
25+
classBaseTestModels(TestCase):
2626
defsetUp(self):
2727
self.user=UserModel.objects.create_user("test_user", "[email protected]", "123456")
2828

29+
deftearDown(self):
30+
self.user.delete()
31+
32+
33+
classTestModels(BaseTestModels):
2934
deftest_allow_scopes(self):
3035
self.client.login(username="test_user", password="123456")
3136
app=Application.objects.create(
@@ -103,10 +108,7 @@ def test_scopes_property(self):
103108
OAUTH2_PROVIDER_REFRESH_TOKEN_MODEL="tests.SampleRefreshToken",
104109
OAUTH2_PROVIDER_GRANT_MODEL="tests.SampleGrant",
105110
)
106-
classTestCustomModels(TestCase):
107-
defsetUp(self):
108-
self.user=UserModel.objects.create_user("test_user", "[email protected]", "123456")
109-
111+
classTestCustomModels(BaseTestModels):
110112
deftest_custom_application_model(self):
111113
"""
112114
If a custom application model is installed, it should be present in
@@ -237,7 +239,21 @@ def test_custom_grant_model_not_installed(self):
237239
oauth2_settings.GRANT_MODEL="oauth2_provider.Grant"
238240

239241

240-
classTestGrantModel(TestCase):
242+
classTestGrantModel(BaseTestModels):
243+
defsetUp(self):
244+
super().setUp()
245+
self.application=Application.objects.create(
246+
name="Test Application",
247+
redirect_uris="",
248+
user=self.user,
249+
client_type=Application.CLIENT_CONFIDENTIAL,
250+
authorization_grant_type=Application.GRANT_AUTHORIZATION_CODE,
251+
)
252+
253+
deftearDown(self):
254+
self.application.delete()
255+
super().tearDown()
256+
241257
deftest_str(self):
242258
grant=Grant(code="test_code")
243259
self.assertEqual("%s"%grant, grant.code)
@@ -247,11 +263,26 @@ def test_expires_can_be_none(self):
247263
self.assertIsNone(grant.expires)
248264
self.assertTrue(grant.is_expired())
249265

266+
deftest_redirect_uri_can_be_longer_than_255_chars(self):
267+
long_redirect_uri="http://example.com/{}".format("authorized/"*25)
268+
self.assertTrue(len(long_redirect_uri) >255)
269+
grant=Grant.objects.create(
270+
user=self.user,
271+
code="test_code",
272+
application=self.application,
273+
expires=timezone.now(),
274+
redirect_uri=long_redirect_uri,
275+
scope="",
276+
)
277+
grant.refresh_from_db()
278+
279+
# It would be necessary to run test using another DB engine than sqlite
280+
# that transform varchar(255) into text data type.
281+
# https://sqlite.org/datatype3.html#affinity_name_examples
282+
self.assertEqual(grant.redirect_uri, long_redirect_uri)
250283

251-
classTestAccessTokenModel(TestCase):
252-
defsetUp(self):
253-
self.user=UserModel.objects.create_user("test_user", "[email protected]", "123456")
254284

285+
classTestAccessTokenModel(BaseTestModels):
255286
deftest_str(self):
256287
access_token=AccessToken(token="test_token")
257288
self.assertEqual("%s"%access_token, access_token.token)
@@ -273,15 +304,15 @@ def test_expires_can_be_none(self):
273304
self.assertTrue(access_token.is_expired())
274305

275306

276-
classTestRefreshTokenModel(TestCase):
307+
classTestRefreshTokenModel(BaseTestModels):
277308
deftest_str(self):
278309
refresh_token=RefreshToken(token="test_token")
279310
self.assertEqual("%s"%refresh_token, refresh_token.token)
280311

281312

282-
classTestClearExpired(TestCase):
313+
classTestClearExpired(BaseTestModels):
283314
defsetUp(self):
284-
self.user=UserModel.objects.create_user("test_user", "[email protected]", "123456")
315+
super().setUp()
285316
# Insert two tokens on database.
286317
app=Application.objects.create(
287318
name="test_app",

0 commit comments

Comments
(0)