Skip to content
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
4 changes: 4 additions & 0 deletions api_app/analyzables_manager/models.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import logging
from typing import Type, Union

from django.core.exceptions import ValidationError
Expand All @@ -13,6 +14,8 @@
from api_app.helpers import calculate_md5, calculate_sha1, calculate_sha256
from certego_saas.models import User

logger = logging.getLogger(__name__)


class Analyzable(models.Model):
name = models.CharField(max_length=255)
Expand Down Expand Up @@ -77,6 +80,7 @@ def get_all_user_events_data_model(
).values_list("data_model__pk", flat=True)
)
query |= query2
logger.debug(f"{query=}")
return self.get_data_model_class().objects.filter(query)

def get_data_model_class(self) -> Type[BaseDataModel]:
Expand Down
5 changes: 5 additions & 0 deletions api_app/analyzables_manager/serializers.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import logging

from rest_framework import serializers as rfs

from api_app.analyzables_manager.models import Analyzable
from api_app.choices import Classification
from api_app.models import Job
from api_app.serializers.job import JobRelatedField

logger = logging.getLogger(__name__)


class AnalyzableSerializer(rfs.ModelSerializer):
jobs = JobRelatedField(many=True, read_only=True)
Expand All @@ -23,6 +27,7 @@ class Meta:
]

def to_representation(self, instance):
logger.debug(f"{instance=}")
analyzable = super().to_representation(instance)
job = (
Job.objects.filter(id__in=analyzable["jobs"])
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Generated by Django 4.2.17 on 2025-10-17 14:56

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("data_model_manager", "0010_domaindatamodel_killchain_phase_and_more"),
]

operations = [
migrations.AddIndex(
model_name="domaindatamodel",
index=models.Index(fields=["date"], name="data_model__date_42dc17_idx"),
),
migrations.AddIndex(
model_name="filedatamodel",
index=models.Index(fields=["date"], name="data_model__date_b1234c_idx"),
),
migrations.AddIndex(
model_name="ipdatamodel",
index=models.Index(fields=["date"], name="data_model__date_48d248_idx"),
),
]
3 changes: 3 additions & 0 deletions api_app/data_model_manager/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ class BaseDataModel(models.Model):

class Meta:
abstract = True
indexes = [
models.Index(fields=["date"]),
]

@property
def owner(self) -> User:
Expand Down
11 changes: 9 additions & 2 deletions api_app/ingestors_manager/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import logging

from rest_framework import status
from rest_framework.decorators import action
from rest_framework.response import Response

from api_app.ingestors_manager.models import IngestorConfig
Expand All @@ -16,10 +17,16 @@
class IngestorConfigViewSet(PythonConfigViewSet):
serializer_class = IngestorConfigSerializer

def disable_in_org(self, request, pk=None):
@action(
methods=["post"],
detail=True,
url_path="organization",
)
def disable_in_org(self, request, name=None):
return Response(status=status.HTTP_404_NOT_FOUND)

def enable_in_org(self, request, pk=None):
@disable_in_org.mapping.delete
def enable_in_org(self, request, name=None):
return Response(status=status.HTTP_404_NOT_FOUND)


Expand Down
8 changes: 6 additions & 2 deletions api_app/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from abc import ABCMeta, abstractmethod

from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Count, Q
from django.db.models.functions import Trunc
from django.http import FileResponse
Expand Down Expand Up @@ -1454,7 +1455,10 @@ def get_permissions(self):
)
def plugin_config(self, request, name=None):
logger.info(f"get plugin_config from user {request.user}, name {name}")
obj: PythonConfig = self.get_queryset().get(name=name)
try:
obj: PythonConfig = self.get_queryset().get(name=name)
except ObjectDoesNotExist:
raise NotFound("Requested plugin does not exist.")
try:
plugin_configs: PluginConfig = PluginConfig.objects.filter(
**{obj.snake_case_name: obj.pk}
Expand Down Expand Up @@ -1494,7 +1498,7 @@ def plugin_config(self, request, name=None):
param_obj["exist"] = True
org_config.append(copy.deepcopy(param_obj))
# override default config with user config (if any)
print(pc.data)
logger.debug(pc.data)
for config in [
config
for config in pc.data
Expand Down
14 changes: 7 additions & 7 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"private": true,
"proxy": "http://localhost:80/",
"dependencies": {
"@certego/certego-ui": "^0.1.18",
"@certego/certego-ui": "^0.1.19",
"@dagrejs/dagre": "^1.1.4",
"ace-builds": "^1.38.0",
"axios": "^1.8.3",
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/components/Routes.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import React, { Suspense } from "react";
import { FallBackLoading } from "@certego/certego-ui";
import { Navigate, useParams } from "react-router-dom";

import { format } from "date-fns";
import { fromZonedTime } from "date-fns-tz";
import AuthGuard from "../wrappers/AuthGuard";
import IfAuthRedirectGuard from "../wrappers/IfAuthRedirectGuard";
import { datetimeFormatStr, JobResultSections } from "../constants/miscConst";
import { JobResultSections, localTimezone } from "../constants/miscConst";

const Home = React.lazy(() => import("./home/Home"));
const Login = React.lazy(() => import("./auth/Login"));
Expand Down Expand Up @@ -50,9 +50,9 @@ function CustomRedirect() {
return (
<Navigate
to={`/history/jobs?received_request_time__gte=${encodeURIComponent(
format(startDatetime, datetimeFormatStr),
fromZonedTime(startDatetime, localTimezone).toISOString(),
)}&received_request_time__lte=${encodeURIComponent(
format(endDatetime, datetimeFormatStr),
fromZonedTime(endDatetime, localTimezone).toISOString(),
)}&ordering=-received_request_time`}
replace
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { VerticalListVisualizer } from "../../common/visualizer/elements/vertica
import { BooleanVisualizer } from "../../common/visualizer/elements/bool";

import { LastEvaluationComponent } from "../../common/engineBadges";
import { TagsIcons } from "../../../constants/dataModelConst";
import { DataModelTagsIcons } from "../../../constants/dataModelConst";
import { TagsColors } from "../../../constants/colorConst";
import { getIcon } from "../../common/icon/icons";
import { AnalyzableHistoryTypes } from "../../../constants/miscConst";
Expand Down Expand Up @@ -167,14 +167,14 @@ export function AnalyzableOverview({ analyzable }) {
value={tag}
id={`tags-${index}`}
icon={
Object.keys(TagsIcons).includes(tag) ? (
getIcon(TagsIcons?.[tag])
Object.keys(DataModelTagsIcons).includes(tag) ? (
getIcon(DataModelTagsIcons?.[tag])
) : (
<FaTag />
)
}
activeColor={
Object.keys(TagsIcons).includes(tag)
Object.keys(DataModelTagsIcons).includes(tag)
? TagsColors?.[tag]
: "secondary"
}
Expand All @@ -195,7 +195,7 @@ export function AnalyzableOverview({ analyzable }) {
),
],
[
"Comments",
"Reasons",
analyzable.last_data_model.related_threats.map(
(value, index) => (
<BaseVisualizer
Expand Down
19 changes: 12 additions & 7 deletions frontend/src/components/common/engineBadges.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,31 @@ import { VscFile } from "react-icons/vsc";
import { TbWorld } from "react-icons/tb";
import classnames from "classnames";
import { EvaluationColors, TagsColors } from "../../constants/colorConst";
import { EvaluationIcons, TagsIcons } from "../../constants/dataModelConst";
import {
DataModelEvaluationIcons,
DataModelTagsIcons,
} from "../../constants/dataModelConst";
import { getIcon } from "./icon/icons";

export function EvaluationBadge(props) {
const { id, evaluation, className } = props;
const { id, evaluation, label, className } = props;

const color = EvaluationColors?.[evaluation];
const divClass = classnames(`bg-${color}`, className);
const icon = EvaluationIcons?.[evaluation];
const icon = DataModelEvaluationIcons?.[evaluation];

return (
<Badge
id={`evaluation__job${id}_${evaluation}`}
className={`d-flex-center ${divClass}`}
>
{getIcon(icon)}
{getIcon(icon)}&nbsp;{label}
<UncontrolledTooltip
target={`evaluation__job${id}_${evaluation}`}
placement="top"
fade={false}
>
{evaluation.toUpperCase()}
{label || evaluation.toUpperCase()}
</UncontrolledTooltip>
</Badge>
);
Expand All @@ -36,10 +39,12 @@ export function EvaluationBadge(props) {
EvaluationBadge.propTypes = {
id: PropTypes.string.isRequired,
evaluation: PropTypes.string.isRequired,
label: PropTypes.string,
className: PropTypes.string,
};

EvaluationBadge.defaultProps = {
label: "",
className: null,
};

Expand Down Expand Up @@ -95,9 +100,9 @@ export function TagsBadge(props) {
const { id, tag, className } = props;
let color = "";
let icon = "";
if (Object.keys(TagsIcons).includes(tag)) {
if (Object.keys(DataModelTagsIcons).includes(tag)) {
color = TagsColors?.[tag];
icon = getIcon(TagsIcons?.[tag]);
icon = getIcon(DataModelTagsIcons?.[tag]);
} else if (tag === "not_found") {
color = "accent";
icon = "Not Found";
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/investigations/flow/utils.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { getLayoutedElements } from "../../common/flows/getLayoutedElements";
import { JobFinalStatuses } from "../../../constants/jobConst";
import { TagsIcons } from "../../../constants/dataModelConst";
import { DataModelTagsIcons } from "../../../constants/dataModelConst";

/* eslint-disable id-length */
function addJobNode(
Expand All @@ -21,7 +21,7 @@ function addJobNode(
const customTags = [];
const tags = [];
engineFields.tags.forEach((tag) => {
if (Object.keys(TagsIcons).includes(tag)) {
if (Object.keys(DataModelTagsIcons).includes(tag)) {
tags.push(tag);
} else {
customTags.push(tag);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ import {

import useTitle from "react-use/lib/useTitle";

import { format } from "date-fns-tz";
import { format, fromZonedTime } from "date-fns-tz";
import { INVESTIGATION_BASE_URI } from "../../../constants/apiURLs";
import { investigationTableColumns } from "./investigationTableColumns";
import { datetimeFormatStr } from "../../../constants/miscConst";
import { datetimeFormatStr, localTimezone } from "../../../constants/miscConst";
import { TimePicker } from "../../common/TimePicker";

// constants
Expand Down Expand Up @@ -90,12 +90,18 @@ export function InvestigationTable({

// this update the value after some times, this give user time to pick the datetime
useDebounceInput(
{ name: "start_time__gte", value: fromDateType },
{
name: "start_time__gte",
value: fromZonedTime(fromDateType, localTimezone).toISOString(),
},
1000,
onChangeFilter,
);
useDebounceInput(
{ name: "start_time__lte", value: toDateType },
{
name: "start_time__lte",
value: fromZonedTime(toDateType, localTimezone).toISOString(),
},
1000,
onChangeFilter,
);
Expand Down
13 changes: 10 additions & 3 deletions frontend/src/components/jobs/table/JobsTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React from "react";
import { Container, Row, Col, UncontrolledTooltip } from "reactstrap";
import { MdInfoOutline } from "react-icons/md";

import { fromZonedTime } from "date-fns-tz";
import {
Loader,
SyncButton,
Expand All @@ -16,7 +17,7 @@ import { format } from "date-fns";
import { jobTableColumns } from "./jobTableColumns";
import { JOB_BASE_URI } from "../../../constants/apiURLs";
import { usePluginConfigurationStore } from "../../../stores/usePluginConfigurationStore";
import { datetimeFormatStr } from "../../../constants/miscConst";
import { datetimeFormatStr, localTimezone } from "../../../constants/miscConst";
import { TimePicker } from "../../common/TimePicker";

// constants
Expand Down Expand Up @@ -75,12 +76,18 @@ export function JobsTable({ searchFromDateValue, searchToDateValue }) {

// this update the value after some times, this give user time to pick the datetime
useDebounceInput(
{ name: "received_request_time__gte", value: fromDateType },
{
name: "received_request_time__gte",
value: fromZonedTime(fromDateType, localTimezone).toISOString(),
},
1000,
onChangeFilter,
);
useDebounceInput(
{ name: "received_request_time__lte", value: toDateType },
{
name: "received_request_time__lte",
value: fromZonedTime(toDateType, localTimezone).toISOString(),
},
1000,
onChangeFilter,
);
Expand Down
Loading
Loading