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

feat: task runner enabler with huey #1422

Merged
merged 17 commits into from
Jan 27, 2025
Merged
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ Check out the online documentation on <https://intuitem.gitbook.io/ciso-assistan
62. Mindeststandard-des-BSI-zur-Nutzung-externer-Cloud-Dienste (Version 2.1) 🇩🇪
63. Formulaire d'évaluation de la maturité - niveau fondamental (DGA) 🇫🇷
64. NIS2 technical and methodological requirements 2024/2690 🇪🇺
65. Saudi Arabian Monetary Authority (SAMA) Cybersecurity Framework 🇸🇦
65. Saudi Arabian Monetary Authority (SAMA) Cybersecurity Framework 🇸🇦
66. Guide de sécurité des données (CNIL) 🇫🇷
67. International Traffic in Arms Regulations (ITAR) 🇺🇸
68. Federal Trade Commission (FTC) Standards for Safeguarding Customer Information 🇺🇸
Expand Down Expand Up @@ -407,6 +407,12 @@ ln -fs ../../git_hooks/post-commit .
ln -fs ../../git_hooks/post-merge .
```

11. for Huey (tasks runner)

- prepare a mailer for testing.
- run `python manage.py run_huey -w 2 -k process` or equivalent in a separate shell.
- you can use `MAIL_DEBUG` to have mail on the console for easier debug

### Running the frontend

1. cd into the frontend directory
Expand Down Expand Up @@ -551,6 +557,6 @@ See [LICENSE.md](./LICENSE.md) for details. For more details about the commercia

Unless otherwise noted, all files are © intuitem.

## Activity
## Activity

![Alt](https://repobeats.axiom.co/api/embed/83162c6044da29efd7efa28f746b6bee5a3c6a8a.svg "Repobeats analytics image")
26 changes: 15 additions & 11 deletions backend/ciso_assistant/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ def set_ciso_assistant_url(_, __, event_dict):

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = os.environ.get("DJANGO_DEBUG", "False") == "True"
MAIL_DEBUG = os.environ.get("MAIL_DEBUG", "False") == "True"

logger.info("DEBUG mode: %s", DEBUG)
logger.info("CISO_ASSISTANT_URL: %s", CISO_ASSISTANT_URL)
Expand Down Expand Up @@ -156,7 +157,7 @@ def set_ciso_assistant_url(_, __, event_dict):
"allauth.socialaccount",
"allauth.socialaccount.providers.saml",
"allauth.mfa",
# "huey.contrib.djhuey",
"huey.contrib.djhuey",
]

MIDDLEWARE = [
Expand Down Expand Up @@ -378,16 +379,6 @@ 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 Expand Up @@ -421,3 +412,16 @@ def set_ciso_assistant_url(_, __, event_dict):
"VERIFIED_EMAIL": True,
},
}

if MAIL_DEBUG:
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
DEFAULT_FROM_EMAIL = "[email protected]"

## Huey settings
HUEY = {
"huey_class": "huey.SqliteHuey",
"name": "ciso_assistant",
"filename": BASE_DIR / "db" / "huey.db",
"results": True, # would be interesting for debug
"immediate": False, # set to False to run in "live" mode regardless of DEBUG, otherwise it will follow
}
75 changes: 75 additions & 0 deletions backend/core/tasks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
from datetime import date
from huey import crontab
from huey.contrib.djhuey import periodic_task, task, db_periodic_task, db_task
from core.models import AppliedControl
from django.db.models import Q
from django.core.mail import send_mail
from django.conf import settings
import logging
import random

import logging.config
import structlog

logging.config.dictConfig(settings.LOGGING)
logger = structlog.getLogger(__name__)


# @db_periodic_task(crontab(minute='*/1')) for testing
@db_periodic_task(crontab(hour="6"))
def check_controls_with_expired_eta():
expired_controls = (
AppliedControl.objects.exclude(status="active")
.filter(eta__lt=date.today(), eta__isnull=False)
.prefetch_related("owner")
)
# Group by individual owner
owner_controls = {}
for control in expired_controls:
for owner in control.owner.all():
if owner.email not in owner_controls:
owner_controls[owner.email] = []
owner_controls[owner.email].append(control)
# Send personalized email to each owner
for owner_email, controls in owner_controls.items():
send_notification_email(owner_email, controls)


@task()
def send_notification_email(owner_email, controls):
# Check required email settings
required_settings = ["EMAIL_HOST", "EMAIL_PORT", "DEFAULT_FROM_EMAIL"]
missing_settings = [
setting
for setting in required_settings
if not hasattr(settings, setting) or not getattr(settings, setting)
]

if missing_settings:
error_msg = f"Cannot send email notification: Missing email settings: {', '.join(missing_settings)}"
logger.error(error_msg)
return

if not owner_email:
logger.error("Cannot send email notification: No recipient email provided")
return

subject = f"CISO Assistant: You have {len(controls)} expired control(s)"
message = "Hello,\n\nThe following controls have expired:\n\n"
for control in controls:
message += f"- {control.name} (ETA: {control.eta})\n"
message += "\nThis reminder will stop once the control is marked as active or you update the ETA.\n"
message += "Log in to your CISO Assistant portal and check 'my assignments' section to get to your controls directly.\n\n"
message += "Thank you."

try:
send_mail(
subject=subject,
message=message,
from_email=settings.DEFAULT_FROM_EMAIL,
recipient_list=[owner_email],
fail_silently=False,
)
logger.info(f"Successfully sent notification email to {owner_email}")
except Exception as e:
logger.error(f"Failed to send notification email to {owner_email}: {str(e)}")
ab-smith marked this conversation as resolved.
Show resolved Hide resolved
35 changes: 19 additions & 16 deletions docker-compose-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,25 @@ services:
volumes:
- ./db:/code/db

# huey:
# container_name: huey
# build:
# context: ./backend
# dockerfile: Dockerfile
# restart: always
# environment:
# - ALLOWED_HOSTS=backend,localhost
# - DJANGO_DEBUG=False
# volumes:
# - ./db:/code/db
# entrypoint:
# - /bin/sh
# - -c
# - |
# poetry run python manage.py run_huey
huey:
container_name: huey
build:
context: ./backend
dockerfile: Dockerfile
depends_on:
- backend
restart: always
environment:
- ALLOWED_HOSTS=backend,localhost
- CISO_ASSISTANT_URL=https://localhost:8443
- DJANGO_DEBUG=False
volumes:
- ./db:/code/db
entrypoint:
- /bin/sh
- -c
- |
poetry run python manage.py run_huey -w 2 --scheduler-interval 60

frontend:
container_name: frontend
Expand Down
83 changes: 83 additions & 0 deletions docker-compose-pg-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
services:
backend:
container_name: backend
build:
context: ./backend
dockerfile: Dockerfile
restart: always
depends_on:
- postgres
environment:
- ALLOWED_HOSTS=backend,localhost
- CISO_ASSISTANT_URL=https://localhost:8443
- DJANGO_DEBUG=True
- POSTGRES_NAME=ciso_assistant
- POSTGRES_USER=ciso_assistant
- POSTGRES_PASSWORD=ciso_assistant
- DB_HOST=postgres
volumes:
- ./db:/code/db

huey:
container_name: huey
build:
context: ./backend
dockerfile: Dockerfile
depends_on:
- backend
restart: always
environment:
- ALLOWED_HOSTS=backend,localhost
- CISO_ASSISTANT_URL=https://localhost:8443
- DJANGO_DEBUG=False
- POSTGRES_NAME=ciso_assistant
- POSTGRES_USER=ciso_assistant
- POSTGRES_PASSWORD=ciso_assistant
- DB_HOST=postgres
volumes:
- ./db:/code/db
entrypoint:
- /bin/sh
- -c
- |
poetry run python manage.py run_huey -w 2 --scheduler-interval 60

frontend:
container_name: frontend
environment:
- PUBLIC_BACKEND_API_URL=http://backend:8000/api
- PROTOCOL_HEADER=x-forwarded-proto
- HOST_HEADER=x-forwarded-host

build:
context: ./frontend
dockerfile: Dockerfile
depends_on:
- backend

postgres:
container_name: postgres
image: postgres:16
restart: always
environment:
POSTGRES_DB: ciso_assistant
POSTGRES_USER: ciso_assistant
POSTGRES_PASSWORD: ciso_assistant
volumes:
- ./db/pg:/var/lib/postgresql/data

caddy:
container_name: caddy
image: caddy:2.8.4
restart: unless-stopped
ports:
- 8443:8443
command:
- caddy
- reverse-proxy
- --from
- https://localhost:8443
- --to
- frontend:3000
volumes:
- ./db:/data
39 changes: 23 additions & 16 deletions docker-compose-pg.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,37 @@ services:
depends_on:
- postgres
environment:
- ALLOWED_HOSTS=backend
- ALLOWED_HOSTS=backend,localhost
- CISO_ASSISTANT_URL=https://localhost:8443
- DJANGO_DEBUG=True
- DJANGO_DEBUG=False
- POSTGRES_NAME=ciso_assistant
- POSTGRES_USER=ciso_assistant
- POSTGRES_PASSWORD=ciso_assistant
- DB_HOST=postgres
volumes:
- ./db:/code/db

# huey:
# container_name: huey
# image: ghcr.io/intuitem/ciso-assistant-community/backend:latest
# restart: always
# environment:
# - ALLOWED_HOSTS=backend,localhost
# - DJANGO_DEBUG=False
# volumes:
# - ./db:/code/db
# entrypoint:
# - /bin/sh
# - -c
# - |
# poetry run python manage.py run_huey
huey:
container_name: huey
image: ghcr.io/intuitem/ciso-assistant-community/backend:latest
depends_on:
- backend
restart: always
environment:
- ALLOWED_HOSTS=backend,localhost
- CISO_ASSISTANT_URL=https://localhost:8443
- DJANGO_DEBUG=False
- POSTGRES_NAME=ciso_assistant
- POSTGRES_USER=ciso_assistant
- POSTGRES_PASSWORD=ciso_assistant
- DB_HOST=postgres
ab-smith marked this conversation as resolved.
Show resolved Hide resolved
volumes:
- ./db:/code/db
entrypoint:
- /bin/sh
- -c
- |
poetry run python manage.py run_huey -w 2 --scheduler-interval 60

frontend:
container_name: frontend
Expand Down
19 changes: 19 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,25 @@ services:
volumes:
- ./db:/code/db

huey:
container_name: huey
image: ghcr.io/intuitem/ciso-assistant-community/backend:latest
depends_on:
- backend
restart: always
environment:
- ALLOWED_HOSTS=backend,localhost
- CISO_ASSISTANT_URL=https://localhost:8443
- DJANGO_DEBUG=False
- AUTH_TOKEN_TTL=7200
volumes:
- ./db:/code/db
entrypoint:
- /bin/sh
- -c
- |
poetry run python manage.py run_huey -w 2 --scheduler-interval 60
frontend:
container_name: frontend
environment:
Expand Down
Loading