Skip to content

Commit

Permalink
Fix conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
monsieurswag committed Dec 3, 2024
2 parents 3e72c9e + 4b803b3 commit 0756134
Show file tree
Hide file tree
Showing 111 changed files with 5,068 additions and 793 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/startup-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ jobs:
export $(grep -v '^#' .env | xargs)
- name: Config the Docker app
run: |
sleep 60 # give the migrations time to finish (included in the up on the previous step)
sleep 120 # give the migrations time to finish (included in the up on the previous step)
docker compose -f docker-compose-build.yml exec backend /bin/bash -c "[email protected] DJANGO_SUPERUSER_PASSWORD=1234 poetry run python manage.py createsuperuser --noinput && exit 0"
- name: Run tests
working-directory: ${{ env.frontend-directory }}
Expand All @@ -142,6 +142,7 @@ jobs:
exit 0
else
echo "Failure"
echo "Check if migrations are not too long"
exit 1
fi
Expand Down Expand Up @@ -258,7 +259,7 @@ jobs:
export $(grep -v '^#' .env | xargs)
- name: Config the Docker app
run: |
sleep 60 # give the migrations time to finish (included in the up on the previous step)
sleep 120 # give the migrations time to finish (included in the up on the previous step)
docker compose -f enterprise/docker-compose-build.yml exec backend /bin/bash -c "[email protected] DJANGO_SUPERUSER_PASSWORD=1234 poetry run python manage.py createsuperuser --noinput --settings=${{ env.enterprise-backend-settings-module }} && exit 0"
- name: Run tests
working-directory: ${{ env.frontend-directory }}
Expand All @@ -270,5 +271,6 @@ jobs:
exit 0
else
echo "Failure"
echo "Check if migrations are not too long"
exit 1
fi
4 changes: 2 additions & 2 deletions LICENSE.txt → LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
Source code in this repository is variously licensed under the GNU Affero General Public License (AGPL), or the intuitem Commercial License (https://intuitem.com/license/commercial/).
Source code in this repository is variously licensed under the GNU Affero General Public License (AGPL), or the [intuitem Commercial License](enterprise/LICENSE.md).

- All the files within the top-level "enterprise" directory are released under the intuitem Commercial Software License.

- All the files outside the top-level "enterprise" directory are released under the [AGPLv3](https://choosealicense.com/licenses/agpl-3.0/).

Binary files are generated for each edition for CISO Assistant:
- Binaries located at ghcr.io/intuitem/ciso-assistant-community/ are released under the AGPL.
- Binaries located at ghcr.io/intuitem/ciso-assistant-community/ are released under the AGPLv3.
- Binaries located directly under the ghcr.io/intuitem/ namespace are released under the intuitem Commercial Software License.

intuitem Commercial Software License requires a valid contract between the licensee and intuitem.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@ Our vision is to provide a one stop shop for cyber security posture management a

CyberSecurity teams need to use GRC as a foundation to structure their program and implement the right tools and processes to mitigate the risks, and leave the rest to CISO Assistant 🐙

The vision of the tool is based on this model:
The vision of the tool is based on these fundamental objects:

![](posture.png)
![](core_objects.png)

The full details are available in the [data model](documentation/architecture/data-model.md).
There are other concepts and models to provide other features. The full details are available in the [data model](documentation/architecture/data-model.md).

The decoupling allows you to save a considerable amount of time:
The decoupling concept is a pillar of the app and allows you to save a considerable amount of time:

- reuse previous assessments,
- assess a scope against multiple frameworks at the same time,
Expand Down Expand Up @@ -534,6 +534,6 @@ All the files within the top-level "enterprise" directory are released under the

All the files outside the top-level "enterprise" directory are released under the [AGPLv3](https://choosealicense.com/licenses/agpl-3.0/).

See [LICENSE.txt](./LICENSE.txt) for details. For more details about the commercial editions, you can reach us on <[email protected]>.
See [LICENSE.md](./LICENSE.md) for details. For more details about the commercial editions, you can reach us on <[email protected]>.

Unless otherwise noted, all files are © intuitem.
8 changes: 4 additions & 4 deletions backend/app_tests/api/test_api_projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def test_get_projects(self, test):
"name": PROJECT_NAME,
"description": PROJECT_DESCRIPTION,
"folder": test.folder,
"internal_reference": PROJECT_REFERENCE,
"ref_id": PROJECT_REFERENCE,
"lc_status": PROJECT_STATUS[0],
},
{
Expand All @@ -112,7 +112,7 @@ def test_create_projects(self, test):
"name": PROJECT_NAME,
"description": PROJECT_DESCRIPTION,
"folder": str(test.folder.id),
"internal_reference": PROJECT_REFERENCE,
"ref_id": PROJECT_REFERENCE,
"lc_status": PROJECT_STATUS[0],
},
{
Expand All @@ -137,14 +137,14 @@ def test_update_projects(self, test):
"name": PROJECT_NAME,
"description": PROJECT_DESCRIPTION,
"folder": test.folder,
"internal_reference": PROJECT_REFERENCE,
"ref_id": PROJECT_REFERENCE,
"lc_status": PROJECT_STATUS[0],
},
{
"name": "new " + PROJECT_NAME,
"description": "new " + PROJECT_DESCRIPTION,
"folder": str(folder.id),
"internal_reference": "new " + PROJECT_REFERENCE,
"ref_id": "new " + PROJECT_REFERENCE,
"lc_status": status[0],
},
{
Expand Down
86 changes: 84 additions & 2 deletions backend/app_tests/api/test_api_requirement_assessments.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,48 @@ def test_get_requirement_assessments(self, test):
"id": str(compliance_assessment.id),
"str": compliance_assessment.name,
},
"requirement": str(RequirementNode.objects.all()[0].id),
"requirement": {
"str": str(RequirementNode.objects.all()[0]),
"id": str(RequirementNode.objects.all()[0].id),
"urn": RequirementNode.objects.all()[0].urn,
"annotation": RequirementNode.objects.all()[0].annotation,
"name": RequirementNode.objects.all()[0].name,
"description": RequirementNode.objects.all()[0].description,
"typical_evidence": RequirementNode.objects.all()[
0
].typical_evidence,
"ref_id": RequirementNode.objects.all()[0].ref_id,
"associated_reference_controls": RequirementNode.objects.all()[
0
].associated_reference_controls,
"associated_threats": RequirementNode.objects.all()[
0
].associated_threats,
"parent_requirement": {
"str": RequirementNode.objects.all()[0].parent_requirement.get(
"str"
),
"urn": RequirementNode.objects.all()[0].parent_requirement.get(
"urn"
),
"id": str(
RequirementNode.objects.all()[0].parent_requirement.get(
"id"
)
),
"ref_id": RequirementNode.objects.all()[
0
].parent_requirement.get("ref_id"),
"name": RequirementNode.objects.all()[0].parent_requirement.get(
"name"
),
"description": RequirementNode.objects.all()[
0
].parent_requirement.get("description"),
}
if RequirementNode.objects.all()[0].parent_requirement
else None,
},
},
base_count=-1,
user_group=test.user_group,
Expand Down Expand Up @@ -210,7 +251,48 @@ def test_update_requirement_assessments(self, test):
"id": str(compliance_assessment.id),
"str": compliance_assessment.name,
},
"requirement": str(RequirementNode.objects.all()[0].id),
"requirement": {
"str": str(RequirementNode.objects.all()[0]),
"id": str(RequirementNode.objects.all()[0].id),
"urn": RequirementNode.objects.all()[0].urn,
"annotation": RequirementNode.objects.all()[0].annotation,
"name": RequirementNode.objects.all()[0].name,
"description": RequirementNode.objects.all()[0].description,
"typical_evidence": RequirementNode.objects.all()[
0
].typical_evidence,
"ref_id": RequirementNode.objects.all()[0].ref_id,
"associated_reference_controls": RequirementNode.objects.all()[
0
].associated_reference_controls,
"associated_threats": RequirementNode.objects.all()[
0
].associated_threats,
"parent_requirement": {
"str": RequirementNode.objects.all()[0].parent_requirement.get(
"str"
),
"urn": RequirementNode.objects.all()[0].parent_requirement.get(
"urn"
),
"id": str(
RequirementNode.objects.all()[0].parent_requirement.get(
"id"
)
),
"ref_id": RequirementNode.objects.all()[
0
].parent_requirement.get("ref_id"),
"name": RequirementNode.objects.all()[0].parent_requirement.get(
"name"
),
"description": RequirementNode.objects.all()[
0
].parent_requirement.get("description"),
}
if RequirementNode.objects.all()[0].parent_requirement
else None,
},
},
user_group=test.user_group,
)
Expand Down
12 changes: 12 additions & 0 deletions backend/ciso_assistant/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ def set_ciso_assistant_url(_, __, event_dict):
"allauth.socialaccount",
"allauth.socialaccount.providers.saml",
"allauth.mfa",
"huey.contrib.djhuey",
]

MIDDLEWARE = [
Expand Down Expand Up @@ -224,6 +225,7 @@ def set_ciso_assistant_url(_, __, event_dict):
"MIN_REFRESH_INTERVAL": 60,
}


# Empty outside of debug mode so that allauth middleware does not raise an error
STATIC_URL = ""

Expand Down Expand Up @@ -372,6 +374,16 @@ def set_ciso_assistant_url(_, __, event_dict):
# OTHER SETTINGS
}

HUEY = {
"huey_class": "huey.SqliteHuey", # Huey implementation to use.
"name": "huey-ciso-assistant", # Use db name for huey.
"results": True, # Store return values of tasks.
"store_none": False, # If a task returns None, do not save to results.
"immediate": DEBUG, # If DEBUG=True, run synchronously.
"utc": True, # Use UTC for all times internally.
"filename": "db/huey.sqlite3",
}

# SSO with allauth

ACCOUNT_USER_MODEL_USERNAME_FIELD = None
Expand Down
20 changes: 17 additions & 3 deletions backend/core/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
from iam.models import Folder, Permission, RoleAssignment, User
from library.helpers import get_referential_translation

from statistics import mean
import math

from .models import *
from .utils import camel_case

Expand Down Expand Up @@ -889,6 +892,13 @@ def viewable_items(model):

viewable_controls = viewable_items(AppliedControl)
controls_count = viewable_controls.count()
progress_avg = math.ceil(
mean([x.progress() for x in viewable_items(ComplianceAssessment)] or [0])
)
missed_eta_count = viewable_controls.filter(
eta__lt=date.today(),
).count()

data = {
"controls": {
"total": controls_count,
Expand All @@ -897,6 +907,8 @@ def viewable_items(model):
"on_hold": viewable_controls.filter(status="on_hold").count(),
"active": viewable_controls.filter(status="active").count(),
"deprecated": viewable_controls.filter(status="deprecated").count(),
"p1": viewable_controls.filter(priority=1).exclude(status="active").count(),
"eta_missed": missed_eta_count,
},
"risk": {
"assessments": viewable_items(RiskAssessment).count(),
Expand All @@ -908,17 +920,19 @@ def viewable_items(model):
"acceptances": viewable_items(RiskAcceptance).count(),
},
"compliance": {
"used_frameworks": viewable_items(ComplianceAssessment)
.values("framework_id")
.distinct()
.count(),
"audits": viewable_items(ComplianceAssessment).count(),
"active_audits": viewable_items(ComplianceAssessment)
.filter(status__in=["in_progress", "in_review", "done"])
.count(),
"evidences": viewable_items(Evidence).count(),
"compliant_items": viewable_items(RequirementAssessment)
.filter(result="compliant")
.count(),
"non_compliant_items": viewable_items(RequirementAssessment)
.filter(result="non_compliant")
.count(),
"progress_avg": progress_avg,
},
"audits_stats": build_audits_stats(user),
"csf_functions": csf_functions(user),
Expand Down
7 changes: 4 additions & 3 deletions backend/core/management/commands/status.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ def handle(self, *args, **kwargs):
nb_risk_assessments = RiskAssessment.objects.all().count()
nb_risk_scenarios = RiskScenario.objects.all().count()
nb_risk_acceptances = RiskAcceptance.objects.all().count()
nb_seats_available = getattr(settings, "LICENSE_SEATS", 0)
nb_expiry_date = getattr(settings, "LICENSE_EXPIRATION", "")
nb_seats = getattr(settings, "LICENSE_SEATS", 0)
nb_editors = len(User.get_editors())
expiration = getattr(settings, "LICENSE_EXPIRATION", "")

created_at = Folder.get_root_folder().created_at
last_login = max(
Expand All @@ -41,5 +42,5 @@ def handle(self, *args, **kwargs):
+ f"threats={nb_threats} functions={nb_functions} measures={nb_measures} "
+ f"evidences={nb_evidences} compliance={nb_compliance_assessments} risk={nb_risk_assessments} "
+ f"scenarios={nb_risk_scenarios} acceptances={nb_risk_acceptances} "
+ f"number_of_seats={nb_seats_available} expiry_date={nb_expiry_date}"
+ f"seats={nb_seats} editors={nb_editors} expiration={expiration}"
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Generated by Django 5.1.1 on 2024-11-19 10:15

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("core", "0040_riskscenario_ref_id"),
]

operations = [
migrations.RenameField(
model_name="project", old_name="internal_reference", new_name="ref_id"
),
migrations.AlterField(
model_name="project",
name="ref_id",
field=models.CharField(
blank=True, max_length=100, null=True, verbose_name="reference id"
),
),
migrations.AddField(
model_name="appliedcontrol",
name="ref_id",
field=models.CharField(
blank=True, max_length=100, null=True, verbose_name="reference id"
),
),
migrations.AddField(
model_name="complianceassessment",
name="ref_id",
field=models.CharField(
blank=True, max_length=100, null=True, verbose_name="reference id"
),
),
migrations.AddField(
model_name="riskassessment",
name="ref_id",
field=models.CharField(
blank=True, max_length=100, null=True, verbose_name="reference id"
),
),
]
19 changes: 19 additions & 0 deletions backend/core/migrations/0042_asset_filtering_labels.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 5.1.1 on 2024-11-28 10:13

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("core", "0041_add_ref_id_to_project_appliedcontrol_assessment"),
]

operations = [
migrations.AddField(
model_name="asset",
name="filtering_labels",
field=models.ManyToManyField(
blank=True, to="core.filteringlabel", verbose_name="Labels"
),
),
]
Loading

0 comments on commit 0756134

Please sign in to comment.