-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
21 changed files
with
511 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -97,6 +97,7 @@ While on production (the sandbox referred to as `stable`), an existing analyst o | |
"username": "<UUID here>", | ||
"first_name": "", | ||
"last_name": "", | ||
"email": "", | ||
}, | ||
... | ||
] | ||
|
@@ -121,6 +122,7 @@ Analysts are a variant of the admin role with limited permissions. The process f | |
"username": "<UUID here>", | ||
"first_name": "", | ||
"last_name": "", | ||
"email": "", | ||
}, | ||
... | ||
] | ||
|
@@ -131,6 +133,20 @@ Analysts are a variant of the admin role with limited permissions. The process f | |
|
||
Do note that if you wish to have both an analyst and admin account, append `-Analyst` to your first and last name, or use a completely different first/last name to avoid confusion. Example: `Bob-Analyst` | ||
|
||
## Adding an email address to the email whitelist (sandboxes only) | ||
On all non-production environments, we use an email whitelist table (called `Allowed emails`). This whitelist is not case sensitive, and it provides an inclusion for +1 emails (like [email protected]). The content after the `+` can be any _digit_. The whitelist checks for the "base" email (example.person) so even if you only have the +1 email defined, an email will still be sent assuming that it follows those conventions. | ||
|
||
To add yourself to this, you can go about it in three ways. | ||
|
||
Permanent (all sandboxes): | ||
1. In src/registrar/fixtures_users.py, add the "email" field to your user in either the ADMIN or STAFF table. | ||
2. In src/registrar/fixtures_users.py, add the desired email address to the `ADDITIONAL_ALLOWED_EMAILS` list. This route is suggested for product. | ||
|
||
Sandbox specific (wiped when the db is reset): | ||
3. Create a new record on the `Allowed emails` table with your email address. This can be done through django admin. | ||
|
||
More detailed instructions regarding #3 can be found [here](https://docs.google.com/document/d/1ebIz4PcUuoiT7LlVy83EAyHAk_nWPEc99neMp4QjzDs). | ||
|
||
## Adding to CODEOWNERS (optional) | ||
|
||
The CODEOWNERS file sets the tagged individuals as default reviewers on any Pull Request that changes files that they are marked as owners of. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ | |
User, | ||
UserGroup, | ||
) | ||
from registrar.models.allowed_email import AllowedEmail | ||
|
||
|
||
fake = Faker() | ||
|
@@ -32,6 +33,7 @@ class UserFixture: | |
"username": "aad084c3-66cc-4632-80eb-41cdf5c5bcbf", | ||
"first_name": "Aditi", | ||
"last_name": "Green", | ||
"email": "[email protected]", | ||
}, | ||
{ | ||
"username": "be17c826-e200-4999-9389-2ded48c43691", | ||
|
@@ -42,11 +44,13 @@ class UserFixture: | |
"username": "5f283494-31bd-49b5-b024-a7e7cae00848", | ||
"first_name": "Rachid", | ||
"last_name": "Mrad", | ||
"email": "[email protected]", | ||
}, | ||
{ | ||
"username": "eb2214cd-fc0c-48c0-9dbd-bc4cd6820c74", | ||
"first_name": "Alysia", | ||
"last_name": "Broddrick", | ||
"email": "[email protected]", | ||
}, | ||
{ | ||
"username": "8f8e7293-17f7-4716-889b-1990241cbd39", | ||
|
@@ -63,6 +67,7 @@ class UserFixture: | |
"username": "83c2b6dd-20a2-4cac-bb40-e22a72d2955c", | ||
"first_name": "Cameron", | ||
"last_name": "Dixon", | ||
"email": "[email protected]", | ||
}, | ||
{ | ||
"username": "0353607a-cbba-47d2-98d7-e83dcd5b90ea", | ||
|
@@ -83,16 +88,19 @@ class UserFixture: | |
"username": "2a88a97b-be96-4aad-b99e-0b605b492c78", | ||
"first_name": "Rebecca", | ||
"last_name": "Hsieh", | ||
"email": "[email protected]", | ||
}, | ||
{ | ||
"username": "fa69c8e8-da83-4798-a4f2-263c9ce93f52", | ||
"first_name": "David", | ||
"last_name": "Kennedy", | ||
"email": "[email protected]", | ||
}, | ||
{ | ||
"username": "f14433d8-f0e9-41bf-9c72-b99b110e665d", | ||
"first_name": "Nicolle", | ||
"last_name": "LeClair", | ||
"email": "[email protected]", | ||
}, | ||
{ | ||
"username": "24840450-bf47-4d89-8aa9-c612fe68f9da", | ||
|
@@ -141,6 +149,7 @@ class UserFixture: | |
"username": "ffec5987-aa84-411b-a05a-a7ee5cbcde54", | ||
"first_name": "Aditi-Analyst", | ||
"last_name": "Green-Analyst", | ||
"email": "[email protected]", | ||
}, | ||
{ | ||
"username": "d6bf296b-fac5-47ff-9c12-f88ccc5c1b99", | ||
|
@@ -183,6 +192,7 @@ class UserFixture: | |
"username": "5dc6c9a6-61d9-42b4-ba54-4beff28bac3c", | ||
"first_name": "David-Analyst", | ||
"last_name": "Kennedy-Analyst", | ||
"email": "[email protected]", | ||
}, | ||
{ | ||
"username": "0eb6f326-a3d4-410f-a521-aa4c1fad4e47", | ||
|
@@ -194,7 +204,7 @@ class UserFixture: | |
"username": "cfe7c2fc-e24a-480e-8b78-28645a1459b3", | ||
"first_name": "Nicolle-Analyst", | ||
"last_name": "LeClair-Analyst", | ||
"email": "nicolle.leclair@ecstech.com", | ||
"email": "nicolle.leclair@gmail.com", | ||
}, | ||
{ | ||
"username": "378d0bc4-d5a7-461b-bd84-3ae6f6864af9", | ||
|
@@ -240,6 +250,9 @@ class UserFixture: | |
}, | ||
] | ||
|
||
# Additional emails to add to the AllowedEmail whitelist. | ||
ADDITIONAL_ALLOWED_EMAILS: list[str] = ["[email protected]", "[email protected]"] | ||
|
||
def load_users(cls, users, group_name, are_superusers=False): | ||
logger.info(f"Going to load {len(users)} users in group {group_name}") | ||
for user_data in users: | ||
|
@@ -264,6 +277,32 @@ def load_users(cls, users, group_name, are_superusers=False): | |
logger.warning(e) | ||
logger.info(f"All users in group {group_name} loaded.") | ||
|
||
def load_allowed_emails(cls, users, additional_emails): | ||
"""Populates a whitelist of allowed emails (as defined in this list)""" | ||
logger.info(f"Going to load allowed emails for {len(users)} users") | ||
if additional_emails: | ||
logger.info(f"Going to load {len(additional_emails)} additional allowed emails") | ||
|
||
# Load user emails | ||
allowed_emails = [] | ||
for user_data in users: | ||
user_email = user_data.get("email") | ||
if user_email and user_email not in allowed_emails: | ||
allowed_emails.append(AllowedEmail(email=user_email)) | ||
else: | ||
first_name = user_data.get("first_name") | ||
last_name = user_data.get("last_name") | ||
logger.warning(f"Could not add email to whitelist for {first_name} {last_name}.") | ||
|
||
# Load additional emails | ||
allowed_emails.extend([AllowedEmail(email=email) for email in additional_emails]) | ||
|
||
if allowed_emails: | ||
AllowedEmail.objects.bulk_create(allowed_emails) | ||
logger.info(f"Loaded {len(allowed_emails)} allowed emails") | ||
else: | ||
logger.info("No allowed emails to load") | ||
|
||
@classmethod | ||
def load(cls): | ||
# Lumped under .atomic to ensure we don't make redundant DB calls. | ||
|
@@ -275,3 +314,7 @@ def load(cls): | |
with transaction.atomic(): | ||
cls.load_users(cls, cls.ADMINS, "full_access_group", are_superusers=True) | ||
cls.load_users(cls, cls.STAFF, "cisa_analysts_group") | ||
|
||
# Combine ADMINS and STAFF lists | ||
all_users = cls.ADMINS + cls.STAFF | ||
cls.load_allowed_emails(cls, all_users, additional_emails=cls.ADDITIONAL_ALLOWED_EMAILS) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# Generated by Django 4.2.10 on 2024-08-29 18:16 | ||
|
||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
("registrar", "0120_add_domainrequest_submission_dates"), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name="AllowedEmail", | ||
fields=[ | ||
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), | ||
("created_at", models.DateTimeField(auto_now_add=True)), | ||
("updated_at", models.DateTimeField(auto_now=True)), | ||
("email", models.EmailField(max_length=320, unique=True)), | ||
], | ||
options={ | ||
"abstract": False, | ||
}, | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# This migration creates the create_full_access_group and create_cisa_analyst_group groups | ||
# It is dependent on 0079 (which populates federal agencies) | ||
# If permissions on the groups need changing, edit CISA_ANALYST_GROUP_PERMISSIONS | ||
# in the user_group model then: | ||
# [NOT RECOMMENDED] | ||
# step 1: docker-compose exec app ./manage.py migrate --fake registrar 0035_contenttypes_permissions | ||
# step 2: docker-compose exec app ./manage.py migrate registrar 0036_create_groups | ||
# step 3: fake run the latest migration in the migrations list | ||
# [RECOMMENDED] | ||
# Alternatively: | ||
# step 1: duplicate the migration that loads data | ||
# step 2: docker-compose exec app ./manage.py migrate | ||
|
||
from django.db import migrations | ||
from registrar.models import UserGroup | ||
from typing import Any | ||
|
||
|
||
# For linting: RunPython expects a function reference, | ||
# so let's give it one | ||
def create_groups(apps, schema_editor) -> Any: | ||
UserGroup.create_cisa_analyst_group(apps, schema_editor) | ||
UserGroup.create_full_access_group(apps, schema_editor) | ||
|
||
|
||
class Migration(migrations.Migration): | ||
dependencies = [ | ||
("registrar", "0121_allowedemail"), | ||
] | ||
|
||
operations = [ | ||
migrations.RunPython( | ||
create_groups, | ||
reverse_code=migrations.RunPython.noop, | ||
atomic=True, | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.