Revert "Merge remote-tracking branch 'origin/main' into nl/1798-update-email-signature"

This reverts commit ef5358e7e2, reversing
changes made to 5746dbe0a1.
This commit is contained in:
CocoByte 2024-03-12 12:37:49 -06:00
parent ef5358e7e2
commit 1e44b20690
No known key found for this signature in database
GPG key ID: BBFAA2526384C97F
88 changed files with 1834 additions and 2597 deletions

View file

@ -1,4 +1,4 @@
# 15. Use Django-FSM library for domain request state
# 15. Use Django-FSM library for domain application state
Date: 2022-11-03
@ -10,12 +10,12 @@ Accepted
The applications that registrants submit for domains move through a variety of
different states or stages as they are processed by CISA staff. Traditionally,
there would be a “domain request” data model with a “status” field. The
there would be a “domain application” data model with a “status” field. The
rules in the application code that control what changes are permitted to the
statuses are called “domain logic”.
In a large piece of software, domain logic often spreads around the code base
because while handling a single request like “mark this domain request as
because while handling a single request like “mark this application as
approved”, requirements can be enforced at many different points during the
process.
@ -28,7 +28,7 @@ states and can change states (or “transition”) according to fixed rules.
We will use the django-fsm library to represent the status of our domain
registration applications as a finite state machine. The library allows us to
list what statuses are possible and describe which state transitions are
possible (e.g. Can an approved domain request ever be marked as “in-process”?).
possible (e.g. Can an approved application ever be marked as “in-process”?).
## Consequences

View file

@ -8,17 +8,17 @@ Accepted
## Context
The domain request form by which registrants apply for a .gov domain is presented over many pages.
The application form by which registrants apply for a .gov domain is presented over many pages.
Because we use server-side rendering, each page of the domain request is a unique HTML page with form fields surrounded by a form tag.
Because we use server-side rendering, each page of the application is a unique HTML page with form fields surrounded by a form tag.
Needing a way to coordinate state between the pages as a user fills in their domain request, we initially used the Form wizard from [django-formtools](https://django-formtools.readthedocs.io/en/latest/wizard.html). This eventually proved unworkable due to the lack of native ability to have more than one Django form object displayed on a single HTML page.
Needing a way to coordinate state between the pages as a user fills in their application, we initially used the Form wizard from [django-formtools](https://django-formtools.readthedocs.io/en/latest/wizard.html). This eventually proved unworkable due to the lack of native ability to have more than one Django form object displayed on a single HTML page.
However, a significant portion of the user workflow had already been coded, so it seemed prudent to port some of the formtools logic into our codebase.
## Decision
To maintain each page of the domain request as its own Django view class, inheriting common code from a parent class.
To maintain each page of the domain application as its own Django view class, inheriting common code from a parent class.
To maintain Django form and formset class in accordance with the Django models whose data they collect, independently of the pages on which they appear.

View file

@ -9,7 +9,7 @@ Approved
## Context
Our application needs to be able to send email to applicants for various
purposes including notifying them that their domain request has been submitted.
purposes including notifying them that their application has been submitted.
We need infrastructure for programmatically sending email. Amazon Web Services
(AWS) provides the Simple Email Service (SES) that can do that. CISA can
provide access to AWS SES for our application.

View file

@ -8,7 +8,8 @@ Accepted
## Context
CISA needs a way to perform administrative actions to manage the new get.gov application as well as the .gov domain requests submitted. Analysts need to be able to view, review, and approve domain requests. Other
CISA needs a way to perform administrative actions to manage the new get.gov application as well as the .gov domain
application requests submitted. Analysts need to be able to view, review, and approve domain applications. Other
dashboard views, reports, searches (with filters and sorting) are also highly desired.
## Decision

View file

@ -8,13 +8,13 @@ Accepted
## Context
Historically, the .gov vendor managed initial identity verification and organizational affiliation for users that request a .gov domain. With the new registrar, _any user with a valid Login.gov account_ will be able to make a request. As a primary layer of abuse prevention (i.e., DDoSing the registry program with illegitimate requests), we need a way to stop new users from submitting multiple domain requests before they are known to the .gov registry. In this case, "known" means they have at least one approved domain request or existing domain.
Historically, the .gov vendor managed initial identity verification and organizational affiliation for users that request a .gov domain. With the new registrar, _any user with a valid Login.gov account_ will be able to make a request. As a primary layer of abuse prevention (i.e., DDoSing the registry program with illegitimate requests), we need a way to stop new users from submitting multiple domain requests before they are known to the .gov registry. In this case, "known" means they have at least one approved domain application or existing domain.
## Considered Options
**Option 1:** Users will not be able to submit any new applications if they have 0 prior approved applications OR prior registered .gov domains. We would add a page alert informing the user that they cannot submit their application because they have a domain request in one of these "3" statuses (Submitted, In Review or Action Needed). They would still be able to create and edit new applications, just not submit them. The benefits of this option are that it would allow users to have multiple applications essentially in "draft mode" that are queued up and ready for submission after they are permitted to submit.
**Option 1:** Users will not be able to submit any new applications if they have 0 prior approved applications OR prior registered .gov domains. We would add a page alert informing the user that they cannot submit their application because they have an application in one of these "3" statuses (Submitted, In Review or Action Needed). They would still be able to create and edit new applications, just not submit them. The benefits of this option are that it would allow users to have multiple applications essentially in "draft mode" that are queued up and ready for submission after they are permitted to submit.
**Option 2:** Users will not be able to submit any new applications if they have 0 prior approved applications OR prior registered .gov domains. Additionally, we would remove the ability to edit any application with the started/withdrawn/rejected status, or start a new application. The benefit of this option is that a user would not be able to begin an action (submitting a domain request) that they are not allowed to complete.
**Option 2:** Users will not be able to submit any new applications if they have 0 prior approved applications OR prior registered .gov domains. Additionally, we would remove the ability to edit any application with the started/withdrawn/rejected status, or start a new application. The benefit of this option is that a user would not be able to begin an action (submitting an application) that they are not allowed to complete.
## Decision

View file

@ -18,13 +18,13 @@ Deployment_Node(aws, "AWS GovCloud", "Amazon Web Services Region") {
Deployment_Node(organization, "get.gov organization") {
Deployment_Node(sandbox, "sandbox space") {
System_Boundary(dashboard_sandbox, "get.gov registrar") {
Container(getgov_app_sandbox, "Registrar Domain Request", "Python, Django", "Delivers static HTML/CSS and forms")
Container(getgov_app_sandbox, "Registrar Application", "Python, Django", "Delivers static HTML/CSS and forms")
ContainerDb(dashboard_db_sandbox, "sandbox PostgreSQL Database", "AWS RDS", "Stores agency information and reports")
}
}
Deployment_Node(stable, "stable space") {
System_Boundary(dashboard_stable, "get.gov registrar") {
Container(getgov_app_stable, "Registrar Domain Request", "Python, Django", "Delivers static HTML/CSS and forms")
Container(getgov_app_stable, "Registrar Application", "Python, Django", "Delivers static HTML/CSS and forms")
ContainerDb(dashboard_db_stable, "stable PostgreSQL Database", "AWS RDS", "Stores agency information and reports")
}
}

View file

@ -3,9 +3,9 @@
This diagram connects the data models along with various workflow stages.
1. The applicant starts the process at `/request` interacting with the
`DomainRequest` object.
`DomainApplication` object.
2. The analyst approves the domain request using the `DomainRequest`'s
2. The analyst approves the application using the `DomainApplication`'s
`approve()` method which creates many related objects: `UserDomainRole`,
`Domain`, and `DomainInformation`.
@ -36,8 +36,8 @@ $ docker run -v $(pwd):$(pwd) -w $(pwd) -it plantuml/plantuml -tsvg model_timeli
allowmixing
left to right direction
class DomainRequest {
Request for a domain
class DomainApplication {
Application for a domain
--
creator (User)
investigator (User)
@ -66,7 +66,7 @@ note left of User
<b>username</b> is the Login UUID
end note
DomainRequest -l- User : creator, investigator
DomainApplication -l- User : creator, investigator
class Contact {
Contact info for a person
@ -80,7 +80,7 @@ class Contact {
--
}
DomainRequest *-r-* Contact : authorizing_official, submitter, other_contacts
DomainApplication *-r-* Contact : authorizing_official, submitter, other_contacts
class DraftDomain {
Requested domain
@ -89,7 +89,7 @@ class DraftDomain {
--
}
DomainRequest -l- DraftDomain : requested_domain
DomainApplication -l- DraftDomain : requested_domain
class Domain {
Approved domain
@ -99,21 +99,21 @@ class Domain {
<b>EPP methods</b>
}
DomainRequest .right[#blue].> Domain : approve()
DomainApplication .right[#blue].> Domain : approve()
class DomainInformation {
Registrar information on a domain
--
domain (Domain)
domain_request (DomainRequest)
domain_application (DomainApplication)
security_email
--
Request information...
}
DomainInformation -- Domain
DomainInformation -- DomainRequest
DomainRequest .[#blue].> DomainInformation : approve()
DomainInformation -- DomainApplication
DomainApplication .[#blue].> DomainInformation : approve()
class UserDomainRole {
Permissions
@ -125,7 +125,7 @@ class UserDomainRole {
}
UserDomainRole -- User
UserDomainRole -- Domain
DomainRequest .[#blue].> UserDomainRole : approve()
DomainApplication .[#blue].> UserDomainRole : approve()
class DomainInvitation {
Email invitations sent
@ -139,10 +139,10 @@ DomainInvitation -- Domain
DomainInvitation .[#green].> UserDomainRole : User.on_each_login()
actor applicant #Red
applicant -d-> DomainRequest : **/request**
applicant -d-> DomainApplication : **/request**
actor analyst #Blue
analyst -[#blue]-> DomainRequest : **approve()**
analyst -[#blue]-> DomainApplication : **approve()**
actor user1 #Green
user1 -[#green]-> Domain : **/domain/<id>/nameservers**

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Before After
Before After

View file

@ -39,8 +39,8 @@ class "registrar.Contact <Registrar>" as registrar.Contact #d6f4e9 {
registrar.Contact -- registrar.User
class "registrar.DomainRequest <Registrar>" as registrar.DomainRequest #d6f4e9 {
domain request
class "registrar.DomainApplication <Registrar>" as registrar.DomainApplication #d6f4e9 {
domain application
--
+ id (BigAutoField)
+ created_at (DateTimeField)
@ -77,15 +77,15 @@ class "registrar.DomainRequest <Registrar>" as registrar.DomainRequest #d6f4e9 {
# other_contacts (ManyToManyField)
--
}
registrar.DomainRequest -- registrar.User
registrar.DomainRequest -- registrar.User
registrar.DomainRequest -- registrar.Contact
registrar.DomainRequest -- registrar.DraftDomain
registrar.DomainRequest -- registrar.Domain
registrar.DomainRequest -- registrar.Contact
registrar.DomainRequest *--* registrar.Website
registrar.DomainRequest *--* registrar.Website
registrar.DomainRequest *--* registrar.Contact
registrar.DomainApplication -- registrar.User
registrar.DomainApplication -- registrar.User
registrar.DomainApplication -- registrar.Contact
registrar.DomainApplication -- registrar.DraftDomain
registrar.DomainApplication -- registrar.Domain
registrar.DomainApplication -- registrar.Contact
registrar.DomainApplication *--* registrar.Website
registrar.DomainApplication *--* registrar.Website
registrar.DomainApplication *--* registrar.Contact
class "registrar.DomainInformation <Registrar>" as registrar.DomainInformation #d6f4e9 {
@ -95,7 +95,7 @@ class "registrar.DomainInformation <Registrar>" as registrar.DomainInformation #
+ created_at (DateTimeField)
+ updated_at (DateTimeField)
~ creator (ForeignKey)
~ domain_request (OneToOneField)
~ domain_application (OneToOneField)
+ organization_type (CharField)
+ federally_recognized_tribe (BooleanField)
+ state_recognized_tribe (BooleanField)
@ -124,7 +124,7 @@ class "registrar.DomainInformation <Registrar>" as registrar.DomainInformation #
--
}
registrar.DomainInformation -- registrar.User
registrar.DomainInformation -- registrar.DomainRequest
registrar.DomainInformation -- registrar.DomainApplication
registrar.DomainInformation -- registrar.Contact
registrar.DomainInformation -- registrar.Domain
registrar.DomainInformation -- registrar.Contact

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 72 KiB

Before After
Before After