Skip to content

Commit

Permalink
Merge branch 'main' into make_fontawesome_work_offline
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-intuitem committed Feb 25, 2024
2 parents 1716e93 + b60b0b8 commit 07cfc09
Show file tree
Hide file tree
Showing 94 changed files with 21,475 additions and 10,191 deletions.
2 changes: 0 additions & 2 deletions .github/workflows/functional-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ on:
pull_request:
branches: [main, develop]
types: [opened, synchronize]
paths:
- 'frontend/tests/**'
workflow_dispatch:

env:
Expand Down
19 changes: 10 additions & 9 deletions .github/workflows/startup-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,13 @@ jobs:
docker compose exec backend /bin/bash -c "[email protected] DJANGO_SUPERUSER_PASSWORD=1234 python manage.py createsuperuser --noinput && exit 0"
- name: Run tests
working-directory: ${{ env.working-directory }}
run: npx playwright test tests/functional/startup.test.ts
- uses: actions/upload-artifact@v4
if: always()
with:
name: startup-docker-test-report
path: |
${{ env.working-directory }}/tests/reports/
${{ env.working-directory }}/tests/results/
retention-days: 5
run: |
response=$(curl -d "[email protected]&password=1234" -H "Origin: https://localhost:8443" https://localhost:8443/login -k)
server_reponse='{"type":"redirect","status":302,"location":"/analytics"}'
if [[ "$response" == "$server_reponse" ]]; then
echo "Success"
exit 0
else
echo "Failure"
exit 1
fi
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
**/node_modules/
.vscode
*.sqlite3
django_secret_key
temp/
db/
56 changes: 22 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ CISO Assistant brings a different take on Cyber Security Posture Management:
![](posture.png)

This decoupling allows you to save considerable amount of time:

- reuse previous assessments,
- assess a scope against multiple frameworks at the same time,
- assess a scope against multiple frameworks at the same time,
- leave the reporting formatting and sanity check to CISO assistant and focus on your remediations

Read the [full article](https://intuitem.com/blog/we-are-going-open-source/) about the community editions on our blog.
Expand All @@ -30,6 +31,7 @@ Read the [full article](https://intuitem.com/blog/we-are-going-open-source/) abo
- PSPF

Checkout the [library](/library/libraries/) for the Domain Specific Language used and how you can define your own.

### Coming soon

- GDPR checklist
Expand Down Expand Up @@ -69,7 +71,7 @@ cd ciso-assistant-community

When asked for, enter your email and password for your superuser.

You can then reach CISO Assistant using your web brower at [http://localhost:3000/](http://localhost:3000/)
You can then reach CISO Assistant using your web brower at [https://localhost:8443/](https://localhost:8443/)

For the following executions, use "docker-compose up" directly.

Expand Down Expand Up @@ -133,11 +135,15 @@ export EMAIL_USE_TLS_RESCUE=True
# You can define the email of the first superuser, useful for automation
export CISO_SUPERUSER_EMAIL=<XXX>

# By default, Django secret key is generated randomly at each start of CISO Assistant. This is convenient for quick test,
# but not recommended for production, as it can break the sessions (see
# this [topic](https://stackoverflow.com/questions/15170637/effects-of-changing-djangos-secret-key) for more information).
# By default, Django secret key is generated randomly at each start of CISO Assistant. This is convenient for quick test,
# but not recommended for production, as it can break the sessions (see
# this [topic](https://stackoverflow.com/questions/15170637/effects-of-changing-djangos-secret-key) for more information).
# To set a fixed secret key, use the environment variable DJANGO_SECRET_KEY.
export DJANGO_SECRET_KEY=...

# Logging configuration
export LOG_LEVEL=INFO # optional, default value is INFO. Available options: DEBUG, INFO, WARNING, ERROR, CRITICAL
export LOG_FORMAT=plain # optional, default value is plain. Available options: json, plain
```

3. Choose the tool of your choice, either python-venv or virtualenv. For example:
Expand All @@ -162,14 +168,14 @@ pip install -r requirements.txt
5. If you want to setup Postgres:

- Launch one of these commands to enter in Postgres:
- ```psql as superadmin```
- ```sudo su postgres```
- ```psql```
- `psql as superadmin`
- `sudo su postgres`
- `psql`
- Create the database "ciso-assistant"
- ```create database ciso-assistant;```
- `create database ciso-assistant;`
- Create user "ciso-assistantuser" and grant it access
- ```create user ciso-assistantuser with password '<POSTGRES_PASSWORD>';```
- ```grant all privileges on database ciso-assistant to ciso-assistantuser;```
- `create user ciso-assistantuser with password '<POSTGRES_PASSWORD>';`
- `grant all privileges on database ciso-assistant to ciso-assistantuser;`

6. Apply migrations.

Expand All @@ -185,17 +191,16 @@ python manage.py migrate
python manage.py createsuperuser
```


8. Run development server.

```sh
python manage.py runserver
```

9. Configure the git hooks for generating the build name.
9. Configure the git hooks for generating the build name.

```sh
cd .git/hooks
cd .git/hooks
ln -fs ../../git_hooks/post-commit .
ln -fs ../../git_hooks/post-merge .
```
Expand All @@ -221,8 +226,8 @@ OR
```bash
export PUBLIC_BACKEND_API_URL=http://localhost:8000/api
```
Note: for docker compose, or if you use a proxy like caddy, the ORIGIN variable has to be declared too (see https://kit.svelte.dev/docs/configuration#csrf).

Note: for docker compose, or if you use a proxy like caddy, the ORIGIN variable has to be declared too (see https://kit.svelte.dev/docs/configuration#csrf).

3. Install dependencies

Expand All @@ -236,26 +241,9 @@ npm install
npm run dev
```

5. If you want to setup Postgres:

- Launch one of these commands to enter in Postgres:
- ```psql as superadmin```
- ```sudo su postgres```
- ```psql```
- Create the database "mira"
- ```create database mira;```
- Create user "mirauser" and grant it access
- ```create user mirauser with password '<POSTGRES_PASSWORD>';```
- ```grant all privileges on database mira to mirauser;```

6. Prepare and apply migrations.

```sh
(venv)$ cd backend
(venv)$ pytest
```
5. Reach the frontend on http://localhost:5173

Coming soon.
Note: Safari will not properly work in this setup, as it requires https for secure cookies. The simplest solution is to use Chrome or Firefox. An alternative is to use a caddy proxy. This is the solution used in docker-compose, so you can use it as an example.

## Managing migrations

Expand Down
1 change: 1 addition & 0 deletions backend/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ __pycache__
*.DS_Store
*~$*
staticfiles/*
static/
*.mo
.env
.vscode
Expand Down
7 changes: 7 additions & 0 deletions backend/app_tests/api/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,13 @@ def create_object(
# Uses the API endpoint to create an object with authentication
response = authenticated_client.post(url, build_params, format=query_format)

if fails:
# Asserts that the object was not created
assert (
response.status_code == expected_status
), f"{verbose_name} can not be created with authentication"
return

# Asserts that the object was created successfully
assert (
response.status_code == expected_status
Expand Down
27 changes: 22 additions & 5 deletions backend/app_tests/api/test_api_requirement_assessments.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import pytest
from rest_framework.status import HTTP_400_BAD_REQUEST
from rest_framework.test import APIClient
from core.models import (
ComplianceAssessment,
Expand Down Expand Up @@ -41,7 +42,9 @@ def test_get_requirement_assessments(self, authenticated_client):
project=Project.objects.create(name="test", folder=folder),
framework=Framework.objects.all()[0],
),
"requirement": RequirementNode.objects.create(name="test", folder=folder, assessable=False),
"requirement": RequirementNode.objects.create(
name="test", folder=folder, assessable=False
),
},
)

Expand Down Expand Up @@ -76,7 +79,9 @@ def test_update_requirement_assessments(self, authenticated_client):
project=Project.objects.create(name="test", folder=folder),
framework=Framework.objects.all()[0],
),
"requirement": RequirementNode.objects.create(name="test", folder=folder, assessable=False),
"requirement": RequirementNode.objects.create(
name="test", folder=folder, assessable=False
),
},
{
"status": REQUIREMENT_ASSESSMENT_STATUS2,
Expand Down Expand Up @@ -113,14 +118,18 @@ def test_get_requirement_assessments(self, authenticated_client):
},
{
"folder": str(folder.id),
"compliance_assessment": {"id": str(compliance_assessment.id), "str": compliance_assessment.name},
"compliance_assessment": {
"id": str(compliance_assessment.id),
"str": compliance_assessment.name,
},
"requirement": str(RequirementNode.objects.all()[0].id),
},
-1,
)

def test_create_requirement_assessments(self, authenticated_client):
"""test to create requirement assessments with the API with authentication"""
"""nobody has permission to do that, so it will fail"""

EndpointTestsQueries.Auth.import_object(authenticated_client, "Framework")
folder = Folder.objects.create(name="test")
Expand All @@ -144,9 +153,14 @@ def test_create_requirement_assessments(self, authenticated_client):
"security_measures": [str(security_measure.id)],
},
{
"compliance_assessment": {"id": str(compliance_assessment.id), "str": compliance_assessment.name}
"compliance_assessment": {
"id": str(compliance_assessment.id),
"str": compliance_assessment.name,
}
},
base_count=-1,
fails=True,
expected_status=HTTP_400_BAD_REQUEST
)

def test_update_requirement_assessments(self, authenticated_client):
Expand Down Expand Up @@ -189,7 +203,10 @@ def test_update_requirement_assessments(self, authenticated_client):
},
{
"folder": str(Folder.get_root_folder().id),
"compliance_assessment": {"id": str(compliance_assessment.id), "str": compliance_assessment.name},
"compliance_assessment": {
"id": str(compliance_assessment.id),
"str": compliance_assessment.name,
},
"requirement": str(RequirementNode.objects.all()[0].id),
},
)
Expand Down
2 changes: 1 addition & 1 deletion backend/cal/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Generated by Django 5.0.2 on 2024-02-10 02:00
# Generated by Django 5.0.2 on 2024-02-23 00:51

from django.db import migrations, models

Expand Down
8 changes: 0 additions & 8 deletions backend/ciso_assistant/asgi.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
"""
<<<<<<<< HEAD:backend/ciso_assistant/asgi.py
ASGI config for ciso_assistant project.
========
ASGI config for mira project.
>>>>>>>> main:mira/asgi.py
It exposes the ASGI callable as a module-level variable named ``application``.
Expand All @@ -15,10 +11,6 @@

from django.core.asgi import get_asgi_application

<<<<<<<< HEAD:backend/ciso_assistant/asgi.py
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ciso_assistant.settings")
========
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mira.settings')
>>>>>>>> main:mira/asgi.py

application = get_asgi_application()
Loading

0 comments on commit 07cfc09

Please sign in to comment.