Skip to content

Commit

Permalink
merged with main
Browse files Browse the repository at this point in the history
  • Loading branch information
abroddrick committed Dec 19, 2023
2 parents aa11af0 + 18e27ab commit 261f490
Show file tree
Hide file tree
Showing 22 changed files with 1,145 additions and 91 deletions.
31 changes: 31 additions & 0 deletions docs/operations/data_migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -493,3 +493,34 @@ The `load_organization_data` script has five optional parameters. These are as f
| 3 | **directory** | Specifies the directory containing the files that will be parsed. Defaults to "migrationdata" |
| 4 | **domain_additional_filename** | Specifies the filename of domain_additional. Used as an override for the JSON. Has no default. |
| 5 | **organization_adhoc_filename** | Specifies the filename of organization_adhoc. Used as an override for the JSON. Has no default. |


## Extend Domain Extension Dates
This section outlines how to extend the expiration date of all ready domains (or a select subset) by a defined period of time.

### Running on sandboxes

#### Step 1: Login to CloudFoundry
```cf login -a api.fr.cloud.gov --sso```

#### Step 2: SSH into your environment
```cf ssh getgov-{space}```

Example: `cf ssh getgov-za`

#### Step 3: Create a shell instance
```/tmp/lifecycle/shell```

#### Step 4: Extend domains
```./manage.py extend_expiration_dates```

### Running locally
```docker-compose exec app ./manage.py extend_expiration_dates```

##### Optional parameters
| | Parameter | Description |
|:-:|:-------------------------- |:----------------------------------------------------------------------------|
| 1 | **extensionAmount** | Determines the period of time to extend by, in years. Defaults to 1 year. |
| 2 | **debug** | Increases logging detail. Defaults to False. |
| 3 | **limitParse** | Determines how many domains to parse. Defaults to all. |
| 4 | **disableIdempotentCheck** | Boolean that determines if we should check for idempotence or not. Compares the proposed extension date to the value in TransitionDomains. Defaults to False. |
1 change: 0 additions & 1 deletion src/.pa11yci
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
"http://localhost:8080/register/other_contacts/",
"http://localhost:8080/register/anything_else/",
"http://localhost:8080/register/requirements/",
"http://localhost:8080/register/review/",
"http://localhost:8080/register/finished/"
]
}
10 changes: 6 additions & 4 deletions src/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,15 +91,17 @@ def available(request, domain=""):
# validate that the given domain could be a domain name and fail early if
# not.
if not (DraftDomain.string_could_be_domain(domain) or DraftDomain.string_could_be_domain(domain + ".gov")):
return JsonResponse({"available": False, "message": DOMAIN_API_MESSAGES["invalid"]})
return JsonResponse({"available": False, "code": "invalid", "message": DOMAIN_API_MESSAGES["invalid"]})
# a domain is available if it is NOT in the list of current domains
try:
if check_domain_available(domain):
return JsonResponse({"available": True, "message": DOMAIN_API_MESSAGES["success"]})
return JsonResponse({"available": True, "code": "success", "message": DOMAIN_API_MESSAGES["success"]})
else:
return JsonResponse({"available": False, "message": DOMAIN_API_MESSAGES["unavailable"]})
return JsonResponse(
{"available": False, "code": "unavailable", "message": DOMAIN_API_MESSAGES["unavailable"]}
)
except Exception:
return JsonResponse({"available": False, "message": DOMAIN_API_MESSAGES["error"]})
return JsonResponse({"available": False, "code": "error", "message": DOMAIN_API_MESSAGES["error"]})


@require_http_methods(["GET"])
Expand Down
20 changes: 18 additions & 2 deletions src/djangooidc/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,14 @@ def authenticate(self, request, **kwargs):
# defaults _will_ be updated, these are not fallbacks
"defaults": openid_data,
}
user, created = UserModel.objects.update_or_create(**args)
if created:

user, created = UserModel.objects.get_or_create(**args)

if not created:
# If user exists, update existing user
self.update_existing_user(user, args["defaults"])
else:
# If user is created, configure the user
user = self.configure_user(user, **kwargs)
else:
try:
Expand All @@ -58,6 +64,16 @@ def authenticate(self, request, **kwargs):
user.on_each_login()
return user

def update_existing_user(self, user, kwargs):
"""Update other fields without overwriting first_name and last_name.
Overwrite first_name and last_name if not empty string"""

for key, value in kwargs.items():
# Check if the key is not first_name or last_name or value is not empty string
if key not in ["first_name", "last_name"] or value:
setattr(user, key, value)
user.save()

def clean_username(self, username):
"""
Performs any cleaning on the "username" prior to using it to get or
Expand Down
99 changes: 99 additions & 0 deletions src/djangooidc/tests/test_backends.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
from django.test import TestCase
from registrar.models import User
from ..backends import OpenIdConnectBackend # Adjust the import path based on your project structure


class OpenIdConnectBackendTestCase(TestCase):
def setUp(self):
self.backend = OpenIdConnectBackend()
self.kwargs = {
"sub": "test_user",
"given_name": "John",
"family_name": "Doe",
"email": "[email protected]",
"phone": "123456789",
}

def tearDown(self) -> None:
User.objects.all().delete()

def test_authenticate_with_create_user(self):
"""Test that authenticate creates a new user if it does not find
existing user"""
# Ensure that the authenticate method creates a new user
user = self.backend.authenticate(request=None, **self.kwargs)
self.assertIsNotNone(user)
self.assertIsInstance(user, User)
self.assertEqual(user.username, "test_user")

# Verify that user fields are correctly set
self.assertEqual(user.first_name, "John")
self.assertEqual(user.last_name, "Doe")
self.assertEqual(user.email, "[email protected]")
self.assertEqual(user.phone, "123456789")

def test_authenticate_with_existing_user(self):
"""Test that authenticate updates an existing user if it finds one.
For this test, given_name and family_name are supplied"""
# Create an existing user with the same username
existing_user = User.objects.create_user(username="test_user")

# Ensure that the authenticate method updates the existing user
user = self.backend.authenticate(request=None, **self.kwargs)
self.assertIsNotNone(user)
self.assertIsInstance(user, User)
self.assertEqual(user, existing_user) # The same user instance should be returned

# Verify that user fields are correctly updated
self.assertEqual(user.first_name, "John")
self.assertEqual(user.last_name, "Doe")
self.assertEqual(user.email, "[email protected]")
self.assertEqual(user.phone, "123456789")

def test_authenticate_with_existing_user_no_name(self):
"""Test that authenticate updates an existing user if it finds one.
For this test, given_name and family_name are not supplied"""
# Create an existing user with the same username and with first and last names
existing_user = User.objects.create_user(username="test_user", first_name="John", last_name="Doe")

# Remove given_name and family_name from the input, self.kwargs
self.kwargs.pop("given_name", None)
self.kwargs.pop("family_name", None)

# Ensure that the authenticate method updates the existing user
# and preserves existing first and last names
user = self.backend.authenticate(request=None, **self.kwargs)
self.assertIsNotNone(user)
self.assertIsInstance(user, User)
self.assertEqual(user, existing_user) # The same user instance should be returned

# Verify that user fields are correctly updated
self.assertEqual(user.first_name, "John")
self.assertEqual(user.last_name, "Doe")
self.assertEqual(user.email, "[email protected]")
self.assertEqual(user.phone, "123456789")

def test_authenticate_with_existing_user_different_name(self):
"""Test that authenticate updates an existing user if it finds one.
For this test, given_name and family_name are supplied and overwrite"""
# Create an existing user with the same username and with first and last names
existing_user = User.objects.create_user(username="test_user", first_name="WillBe", last_name="Replaced")

# Ensure that the authenticate method updates the existing user
# and preserves existing first and last names
user = self.backend.authenticate(request=None, **self.kwargs)
self.assertIsNotNone(user)
self.assertIsInstance(user, User)
self.assertEqual(user, existing_user) # The same user instance should be returned

# Verify that user fields are correctly updated
self.assertEqual(user.first_name, "John")
self.assertEqual(user.last_name, "Doe")
self.assertEqual(user.email, "[email protected]")
self.assertEqual(user.phone, "123456789")

def test_authenticate_with_unknown_user(self):
"""Test that authenticate returns None when no kwargs are supplied"""
# Ensure that the authenticate method handles the case when the user is not found
user = self.backend.authenticate(request=None, **{})
self.assertIsNone(user)
11 changes: 11 additions & 0 deletions src/registrar/forms/domain.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ class DomainAddUserForm(forms.Form):

email = forms.EmailField(label="Email")

def clean(self):
"""clean form data by lowercasing email"""
cleaned_data = super().clean()

# Lowercase the value of the 'email' field
email_value = cleaned_data.get("email")
if email_value:
cleaned_data["email"] = email_value.lower()

return cleaned_data


class DomainNameserverForm(forms.Form):
"""Form for changing nameservers."""
Expand Down
Loading

0 comments on commit 261f490

Please sign in to comment.