Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
d1fe560
WIP change CharFields to TextFields, note missing specs
annamontare-nava Apr 20, 2026
3342d45
WIP adding specs
annamontare-nava Apr 20, 2026
c3eff5f
align phone number validation between accounts and dot_ext
annamontare-nava Apr 20, 2026
2aca369
change AuthFlowUuid.state to TextField
annamontare-nava Apr 20, 2026
c7e1ed2
add spec for FHIR IDs
annamontare-nava Apr 20, 2026
a323841
change fhir_id_v2 and fhir_id_v3 fields to max_length=64
annamontare-nava Apr 20, 2026
de00e02
add spec for pkce code challenge, change field length
annamontare-nava Apr 20, 2026
5b4ddd3
change length of challenge field to match spec
annamontare-nava Apr 20, 2026
a925d50
add note
annamontare-nava Apr 20, 2026
afb2a04
add note
annamontare-nava Apr 20, 2026
707b624
mark places where validators might be helpful
annamontare-nava Apr 20, 2026
22b2226
add validators for urls, change jwks_uri to TextField
annamontare-nava Apr 20, 2026
a2e9f8e
set max_length=512 for next_uri to be consistent
annamontare-nava Apr 20, 2026
fe8b198
fix choices argument
annamontare-nava Apr 20, 2026
25790f6
add migrations for this branch so far
annamontare-nava Apr 20, 2026
acc8c5b
set URLs max_length to be 2048
annamontare-nava Apr 21, 2026
0967b23
change the last few fields that needed 2048 max length
annamontare-nava Apr 21, 2026
0e5929e
Update dot_ext/forms.py to reflect new model fields
annamontare-nava Apr 21, 2026
5529106
change client_secret_plain max_length to 128
annamontare-nava Apr 21, 2026
8a37eb2
remove todos that will be handled in PR review
annamontare-nava Apr 21, 2026
7ba240d
remove todos that can be handled in future work
annamontare-nava Apr 21, 2026
0679f1f
resolve some todo comments
annamontare-nava Apr 21, 2026
67453dc
change client_id max length to 40
annamontare-nava Apr 21, 2026
f60a212
remove todo comment
annamontare-nava Apr 21, 2026
dd69cd6
align auth_pkce_method with spec, transfer changes to AuthFlowUuidCopy
annamontare-nava Apr 22, 2026
4de3ff0
add note confirming why username has max_length=150
annamontare-nava Apr 22, 2026
a7104ec
remove comment that will be handled in review
annamontare-nava Apr 22, 2026
e102d58
remove unused import
annamontare-nava Apr 22, 2026
676674b
add ruff formatting changes for only lines I already changed
annamontare-nava Apr 22, 2026
e8a333a
Merge branch 'master' into anna/bb2-4543-django-charfield-conversion
annamontare-nava Apr 22, 2026
b330138
fix doc comment
annamontare-nava Apr 22, 2026
4c4ad92
make AuthFlowUuidCopy just inherit from AuthFlowUuid
annamontare-nava Apr 22, 2026
909cf2b
make abstract base class that AuthFlowUuid and AuthFlowUuidCopy inher…
annamontare-nava Apr 30, 2026
2dd914e
Merge branch 'master' into anna/bb2-4543-django-charfield-conversion
annamontare-nava Apr 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 6.0.2 on 2026-04-20 18:07

import django.core.validators
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('accounts', '0005_alter_userprofile_user_type'),
]

operations = [
migrations.AlterField(
model_name='userprofile',
name='mobile_phone_number',
field=models.CharField(blank=True, help_text='US numbers only.', max_length=16, validators=[django.core.validators.RegexValidator(message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed.", regex='^\\+?\\d{9,15}$')]),
),
]
4 changes: 3 additions & 1 deletion apps/accounts/models.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from apps.constants import USER_CHOICES, USER_TYPE_DEV
from apps.validators import phone_regex
from apps.accounts.constants import (
AAL_CHOICES,
ADDITION,
Expand Down Expand Up @@ -100,7 +101,8 @@ class UserProfile(models.Model):
)

mobile_phone_number = models.CharField(
max_length=12,
validators=[phone_regex],
max_length=16,
blank=True,
help_text=_('US numbers only.'),
)
Expand Down
7 changes: 0 additions & 7 deletions apps/dot_ext/constants.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import re

from apps.constants import LAUNCH_SCOPE, OPENID_SCOPE

# REGEX of paths that should be updated with auth flow info in hhs_oauth_server.request_logging.py
Expand Down Expand Up @@ -49,11 +47,6 @@
TOKEN_ENDPOINT_V2_KEY = 'token-v2'
TOKEN_ENDPOINT_V3_KEY = 'token-v3'

URL_REGEX = re.compile(
r'^(https:\/\/)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.'
r'[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)$'
)

"""
Test Cases for demographic scopes related testing
Dictionaries included:
Expand Down
27 changes: 14 additions & 13 deletions apps/dot_ext/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from django import forms
from django.conf import settings
from django.core.validators import URLValidator
from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _
from oauth2_provider.forms import AllowForm as DotAllowForm
Expand All @@ -12,7 +13,7 @@
from apps.dot_ext.constants import PRINTABLE_SPECIAL_ASCII
from apps.dot_ext.scopes import CapabilitiesScopes
from apps.dot_ext.models import Application, InternalApplicationLabels
from apps.dot_ext.validators import validate_logo_image, validate_notags, validate_url
from apps.dot_ext.validators import validate_logo_image, validate_notags
from django.contrib.auth.models import Group, User
from django.forms.widgets import URLInput

Expand Down Expand Up @@ -50,22 +51,22 @@ class CustomRegisterApplicationForm(forms.ModelForm):

policy_uri = forms.CharField(
required=False,
max_length=512,
validators=[validate_url],
max_length=2048,
validators=[URLValidator()],
widget=URLInput,
)

tos_uri = forms.CharField(
required=False,
max_length=512,
validators=[validate_url],
max_length=2048,
validators=[URLValidator()],
widget=URLInput,
)

website_uri = forms.CharField(
required=False,
max_length=512,
validators=[validate_url],
max_length=2048,
validators=[URLValidator()],
widget=URLInput,
)

Expand Down Expand Up @@ -219,22 +220,22 @@ class CreateNewApplicationForm(forms.ModelForm):

policy_uri = forms.CharField(
required=False,
max_length=512,
validators=[validate_url],
max_length=2048,
validators=[URLValidator()],
widget=URLInput,
)

tos_uri = forms.CharField(
required=False,
max_length=512,
validators=[validate_url],
max_length=2048,
validators=[URLValidator()],
widget=URLInput,
)

website_uri = forms.CharField(
required=False,
max_length=512,
validators=[validate_url],
max_length=2048,
validators=[URLValidator()],
widget=URLInput,
)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Generated by Django 6.0.2 on 2026-04-20 18:07

import django.core.validators
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('dot_ext', '0011_remove_application_allow_client_credentials_and_more'),
]

operations = [
migrations.AlterField(
model_name='application',
name='client_uri',
field=models.TextField(blank=True, default='', help_text='This is typically a home/download website for the application. For example, https://www.example.org or http://www.example.org .', max_length=512, null=True, validators=[django.core.validators.URLValidator()], verbose_name='Client URI'),
),
migrations.AlterField(
model_name='application',
name='contacts',
field=models.TextField(blank=True, default='', help_text='This is typically an email', verbose_name="Client's Contacts"),
),
migrations.AlterField(
model_name='application',
name='jwks_uri',
field=models.TextField(blank=True, default=None, max_length=512, null=True, validators=[django.core.validators.URLValidator()], verbose_name='JSON Web Key Set URI'),
),
migrations.AlterField(
model_name='application',
name='logo_uri',
field=models.TextField(blank=True, default='', max_length=512, validators=[django.core.validators.URLValidator()], verbose_name='Logo URI'),
),
migrations.AlterField(
model_name='application',
name='op_policy_uri',
field=models.TextField(blank=True, default='', max_length=512, validators=[django.core.validators.URLValidator()]),
),
migrations.AlterField(
model_name='application',
name='op_tos_uri',
field=models.TextField(blank=True, default='https://bluebutton.cms.gov/terms', max_length=512, validators=[django.core.validators.URLValidator()]),
),
migrations.AlterField(
model_name='application',
name='policy_uri',
field=models.TextField(blank=True, default='', help_text='This can be a model privacy notice or other policy document.', max_length=512, validators=[django.core.validators.URLValidator()], verbose_name="Client's Policy URI"),
),
migrations.AlterField(
model_name='application',
name='software_id',
field=models.TextField(blank=True, default='', help_text='A unique identifier for an application defined by its creator.', max_length=128),
),
migrations.AlterField(
model_name='application',
name='support_email',
field=models.TextField(blank=True, null=True),
),
migrations.AlterField(
model_name='application',
name='support_phone_number',
field=models.CharField(blank=True, max_length=16, null=True, validators=[django.core.validators.RegexValidator(message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed.", regex='^\\+?\\d{9,15}$')]),
),
migrations.AlterField(
model_name='application',
name='tos_uri',
field=models.TextField(blank=True, default='', max_length=512, validators=[django.core.validators.URLValidator()], verbose_name="Client's Terms of Service URI"),
),
migrations.AlterField(
model_name='application',
name='website_uri',
field=models.TextField(blank=True, default='', help_text='This is typically a home/download website for the application. For example, https://www.example.org or http://www.example.org .', max_length=512, null=True, validators=[django.core.validators.URLValidator()], verbose_name='Website URI'),
),
migrations.AlterField(
model_name='applicationlabel',
name='name',
field=models.TextField(max_length=255, unique=True),
),
migrations.AlterField(
model_name='authflowuuid',
name='state',
field=models.TextField(db_index=True, max_length=64, null=True, unique=True),
),
migrations.AlterField(
model_name='internalapplicationlabels',
name='description',
field=models.TextField(blank=True, default=''),
),
migrations.AlterField(
model_name='internalapplicationlabels',
name='label',
field=models.TextField(default='', max_length=255, unique=True),
),
migrations.AlterField(
model_name='internalapplicationlabels',
name='slug',
field=models.TextField(default='', max_length=1024, unique=True),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Generated by Django 6.0.2 on 2026-04-21 19:17

import django.core.validators
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('dot_ext', '0012_alter_application_client_uri_and_more'),
]

operations = [
migrations.AlterField(
model_name='application',
name='client_uri',
field=models.TextField(blank=True, default='', help_text='This is typically a home/download website for the application. For example, https://www.example.org or http://www.example.org .', max_length=2048, null=True, validators=[django.core.validators.URLValidator()], verbose_name='Client URI'),
),
migrations.AlterField(
model_name='application',
name='jwks_uri',
field=models.TextField(blank=True, default=None, max_length=2048, null=True, validators=[django.core.validators.URLValidator()], verbose_name='JSON Web Key Set URI'),
),
migrations.AlterField(
model_name='application',
name='logo_uri',
field=models.TextField(blank=True, default='', max_length=2048, validators=[django.core.validators.URLValidator()], verbose_name='Logo URI'),
),
migrations.AlterField(
model_name='application',
name='policy_uri',
field=models.TextField(blank=True, default='', help_text='This can be a model privacy notice or other policy document.', max_length=2048, validators=[django.core.validators.URLValidator()], verbose_name="Client's Policy URI"),
),
migrations.AlterField(
model_name='application',
name='tos_uri',
field=models.TextField(blank=True, default='', max_length=2048, validators=[django.core.validators.URLValidator()], verbose_name="Client's Terms of Service URI"),
),
migrations.AlterField(
model_name='application',
name='website_uri',
field=models.TextField(blank=True, default='', help_text='This is typically a home/download website for the application. For example, https://www.example.org or http://www.example.org .', max_length=2048, null=True, validators=[django.core.validators.URLValidator()], verbose_name='Website URI'),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generated by Django 6.0.2 on 2026-04-21 19:27

import django.core.validators
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('dot_ext', '0013_alter_application_client_uri_and_more'),
]

operations = [
migrations.AlterField(
model_name='application',
name='op_policy_uri',
field=models.TextField(blank=True, default='', max_length=2048, validators=[django.core.validators.URLValidator()]),
),
migrations.AlterField(
model_name='application',
name='op_tos_uri',
field=models.TextField(blank=True, default='https://bluebutton.cms.gov/terms', max_length=2048, validators=[django.core.validators.URLValidator()]),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 6.0.2 on 2026-04-21 20:27

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('dot_ext', '0014_alter_application_op_policy_uri_and_more'),
]

operations = [
migrations.AlterField(
model_name='application',
name='client_secret_plain',
field=models.CharField(blank=True, default='', max_length=128),
),
]
18 changes: 18 additions & 0 deletions apps/dot_ext/migrations/0016_alter_authflowuuid_client_id.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 6.0.2 on 2026-04-21 22:05

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('dot_ext', '0015_alter_application_client_secret_plain'),
]

operations = [
migrations.AlterField(
model_name='authflowuuid',
name='client_id',
field=models.CharField(max_length=40, null=True),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Generated by Django 6.0.2 on 2026-04-22 11:25

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('dot_ext', '0016_alter_authflowuuid_client_id'),
]

operations = [
migrations.AlterField(
model_name='authflowuuid',
name='auth_pkce_method',
field=models.CharField(choices=[('S256', 'S256'), ('plain', 'plain')], max_length=16, null=True),
),
migrations.AlterField(
model_name='authflowuuidcopy',
name='auth_pkce_method',
field=models.CharField(choices=[('S256', 'S256'), ('plain', 'plain')], max_length=16, null=True),
),
migrations.AlterField(
model_name='authflowuuidcopy',
name='client_id',
field=models.CharField(max_length=40, null=True),
),
migrations.AlterField(
model_name='authflowuuidcopy',
name='created',
field=models.DateTimeField(auto_now_add=True, null=True),
),
migrations.AlterField(
model_name='authflowuuidcopy',
name='state',
field=models.TextField(db_index=True, max_length=64, null=True, unique=True),
),
]
Loading
Loading