Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2024-08-07 | MAIN --> PROD | DEV (5f89fd8) --> STAGING #4155

Merged
merged 2 commits into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 13 additions & 1 deletion backend/audit/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,23 @@ def save_model(self, request, obj, form, change):
logger.info(
f"SAC {sac.report_id} updated successfully with waiver by user: {request.user.email}."
)
elif (
SingleAuditChecklist.STATUS.IN_PROGRESS
and SacValidationWaiver.TYPES.FINDING_REFERENCE_NUMBER
in obj.waiver_types
):
logger.info(
f"User {request.user.email} is applying waiver for SAC with status: {sac.submission_status}"
)
super().save_model(request, obj, form, change)
logger.info(
f"Duplicate finding reference number waiver applied to SAC {sac.report_id} by user: {request.user.email}."
)
else:
messages.set_level(request, messages.WARNING)
messages.warning(
request,
f"Cannot apply waiver to SAC with status {sac.submission_status}. Expected status to be one of {SingleAuditChecklist.STATUS.READY_FOR_CERTIFICATION}, {SingleAuditChecklist.STATUS.AUDITOR_CERTIFIED}",
f"Cannot apply waiver to SAC with status {sac.submission_status}. Expected status to be one of {SingleAuditChecklist.STATUS.READY_FOR_CERTIFICATION}, {SingleAuditChecklist.STATUS.AUDITOR_CERTIFIED}, or {SingleAuditChecklist.STATUS.IN_PROGRESS}.",
)
logger.warning(
f"User {request.user.email} attempted to apply waiver to SAC with invalid status: {sac.submission_status}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ def check_finding_reference_uniqueness(sac_dict, *_args, **_kwargs):

all_sections = sac_dict.get("sf_sac_sections", {})
data_source = sac_dict.get("sf_sac_meta", {}).get("data_source", "")
waiver_types = sac_dict.get("waiver_types", [])
findings_uniform_guidance_section = (
all_sections.get("findings_uniform_guidance") or {}
)
Expand All @@ -32,6 +33,11 @@ def check_finding_reference_uniqueness(sac_dict, *_args, **_kwargs):
# Skip this validation if it is an historical audit report with duplicate reference numbers
return errors

from audit.models import SacValidationWaiver

if SacValidationWaiver.TYPES.FINDING_REFERENCE_NUMBER in waiver_types:
return errors

for finding in findings_uniform_guidance:
award_ref = finding["program"]["award_reference"]
ref_number = finding["findings"]["reference_number"]
Expand Down
13 changes: 12 additions & 1 deletion backend/audit/cross_validation/sac_validation_shape.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,11 @@ def sac_validation_shape(sac):
...
},
"sf_sac_meta": { ... },
"waiver_types": [ ... ],
}

"""
from audit.models import Access
from audit.models import Access, SacValidationWaiver

shape = {
"sf_sac_sections": {k: get_shaped_section(sac, k) for k in SECTION_NAMES},
Expand All @@ -81,6 +82,16 @@ def sac_validation_shape(sac):
},
}

# Querying the SacValidationWaiver table for waivers
waivers = SacValidationWaiver.objects.filter(report_id=sac.report_id)

# Extracting waiver types from waivers
waiver_types = [
waiver_type for waiver in waivers for waiver_type in waiver.waiver_types
]

shape["waiver_types"] = waiver_types

certifying_auditee = Access.objects.filter(
sac=sac, role="certifying_auditee_contact"
).first()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from django.conf import settings
from django.test import TestCase
from audit.models import SingleAuditChecklist
from audit.models import SingleAuditChecklist, SacValidationWaiver
from census_historical_migration.invalid_record import InvalidRecord
from .check_finding_reference_uniqueness import check_finding_reference_uniqueness
from .sac_validation_shape import sac_validation_shape
Expand Down Expand Up @@ -108,3 +108,28 @@ def test_duplicate_references_for_historical_award(self):

errors = check_finding_reference_uniqueness(sac_validation_shape(sac))
self.assertEqual(errors, [])

def test_duplicate_finding_reference_numbers_with_waivers(self):
"""
Check that errors are not returned for report with duplicate reference numbers when the validation is waived.
"""
range_size = generate_random_integer(2, 4)
sac = baker.make(SingleAuditChecklist)
baker.make(
SacValidationWaiver,
report_id=sac,
waiver_types=[SacValidationWaiver.TYPES.FINDING_REFERENCE_NUMBER],
)
sac.findings_uniform_guidance = self._make_findings_uniform_guidance(
[self._award_reference() for _ in range(range_size)],
[
[
self._reference_number(self.REF_MIN),
self._reference_number(self.REF_MIN),
self._reference_number(self.REF_MAX),
]
],
)
sac.waiver_types = [SacValidationWaiver.TYPES.FINDING_REFERENCE_NUMBER]
errors = check_finding_reference_uniqueness(sac_validation_shape(sac))
self.assertEqual(errors, [])
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Generated by Django 5.0.4 on 2024-08-05 17:26

import django.contrib.postgres.fields
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("audit", "0011_ueivalidationwaiver_expiration_and_more"),
]

operations = [
migrations.AlterField(
model_name="sacvalidationwaiver",
name="waiver_types",
field=django.contrib.postgres.fields.ArrayField(
base_field=models.CharField(
choices=[
(
"auditee_certifying_official",
"No auditee certifying official is available",
),
(
"auditor_certifying_official",
"No auditor certifying official is available",
),
(
"finding_reference_number",
"Report has duplicate finding reference numbers",
),
],
max_length=50,
),
default=list,
size=None,
verbose_name="The waiver type",
),
),
]
5 changes: 5 additions & 0 deletions backend/audit/models/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,7 @@ class SacValidationWaiver(models.Model):
class TYPES:
AUDITEE_CERTIFYING_OFFICIAL = "auditee_certifying_official"
AUDITOR_CERTIFYING_OFFICIAL = "auditor_certifying_official"
FINDING_REFERENCE_NUMBER = "finding_reference_number"

WAIVER_CHOICES = [
(
Expand All @@ -749,6 +750,10 @@ class TYPES:
TYPES.AUDITOR_CERTIFYING_OFFICIAL,
"No auditor certifying official is available",
),
(
TYPES.FINDING_REFERENCE_NUMBER,
"Report has duplicate finding reference numbers",
),
]
report_id = models.ForeignKey(
"SingleAuditChecklist",
Expand Down
79 changes: 78 additions & 1 deletion docs/branching.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ graph TD
```

### Steps:
1. Start a branch from `main` for new work commit changes. When your work is ready, rebase to `main` and clean your commit history. When acceptance criteria is met and tests pass, create a pull request that targets the `main` branch. The terraform plan for the dev environmnet will be created as part of the PR. Tag one or more relevant people for review.
1. Start a branch from `main` for new work commit changes. When your work is ready, rebase to `main` and clean your commit history. When acceptance criteria is met and tests pass, create a pull request that targets the `main` branch. Make sure that the commits in your pull request are **signed** ([follow these steps](#signed-commits)). The terraform plan for the dev environment will be created as part of the PR. Tag one or more relevant people for review.
2. Branch is ready for review. The reviewer will test locally for acceptance criteria, readability, security considerations, and good testing practices. Don't review your own PR. Once the PR is merged into the `main` branch, after tests pass, any changes to the management or dev spaces via terraform will be applied, and the code will deployed to the dev environment.
3. When its time to create a release for review, we will add those changes to `prod` via PR. Merging to the `prod` branch will deploy the code to staging after tests pass.
4. The release is reviewed by stakeholders. When it is ready for production, an OROS approver will add a version tag starting with "v". The tag will trigger an automated deploy to production. There is a GitHub rule to enforce that only "maintainer" role are allowed to add tags starting with "v."
Expand Down Expand Up @@ -81,3 +81,80 @@ graph TD
2. When the branch is ready for review. Test locally for acceptance criteria, look for readability, security considerations, and good testing practices. Don't review your own PR. Once merged into `prod` This will auto deploy to the staging environment after tests pass.
3. The hotfix is reviewed by stakeholders in the staging environment. When it is ready for production, a GitHub maintainer will add a version tag starting with "v". The tag will trigger an automated deploy to production. There is a GitHub rule to enforce that only `maintainer` role are allowed to add tags starting with "v."
4. Changes need to be merged back into the `main` branch.

## Signed Commits

Commits are required to be signed prior to being formed into a PR and merged into `main`. We use GPG keys to verify these commits. You can complete the following steps to ensure your commits are verified.

### Setup

You can install GnuPG [here](https://gnupg.org/download/index.html) to gain access to the CLI commands below.

### CLI Instructions

```
1. Generate a new GPG Key
gpg --full-generate-key
Press Enter for Default key
Press Enter for default keysize
Enter Expiration (0)
Enter your name
Enter your github @noreply email to keep your account email private (https://github.com/settings/emails)

2. Get your GPG key
gpg --list-secret-keys --keyid-format=long
gpg --armor --export <keyid>

3. Copy your Key and add it to git gpg keys (https://github.com/settings/keys)
-----BEGIN PGP PUBLIC KEY BLOCK-----
....
-----END PGP PUBLIC KEY BLOCK-----

4. Tell git about your key
git config --global --unset gpg.format
gpg --list-secret-keys --keyid-format=long
Get your keyid (should be the same as step 2)
git config --global user.signingkey <keyid>
git config --global commit.gpgsign true

# For windows users only:
git config --global gpg.program "C:\Program Files (x86)\GnuPG\bin\gpg.exe"

NOTE: You will now have to enter your gpg passcode in order to do a commit (Yes, even git fork prompts for a pass now). Keep it handy or easy for you to remember while still being complex
```

---
**NOTE**

Before doing anything with git, use gpg --sign on some file to make sure that the signing machinery is currently working for you. This should only apply if you have already created some commits without completing the above steps to configure your GPG key.
```
gpg --sign <some file>
git checkout <your branch>
git log --reverse --show-signature
git rebase -i HEAD~<numeral indicating number of commits you need to sign>
```
This is sample output:
```
pick d3381defc Change backend so that it converts user-submitted UEIs to uppercase.
pick 679acdde6 Really unsubtle approach to uppercasing the UEI on the frontend.
pick 45eeb61bb Prettier linting.
pick 5d676ca90 Prettier linting.
```
Add `exec git commit --amend --no-edit -s` after every pick line, changing it to something like this:
```
pick d3381defc Change backend so that it converts user-submitted UEIs to uppercase.
exec git commit --amend --no-edit -s
pick 679acdde6 Really unsubtle approach to uppercasing the UEI on the frontend.
exec git commit --amend --no-edit -s
pick 45eeb61bb Prettier linting.
exec git commit --amend --no-edit -s
pick 5d676ca90 Prettier linting.
exec git commit --amend --no-edit -s
```
This will rebase your branch; if there are errors you’ll end up in an intermediate state and will need to do git rebase --continue after fixing them.
Once that’s done, push the branch again:
```
git push --force origin <your branch>
```

Your existing commits should now be signed as well as your new commits moving forward.
Loading
Loading