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
59 changes: 46 additions & 13 deletions backend/src/graphql/resolvers/threatActorResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,42 +5,75 @@
* repository-laget og sender resultatet tilbake til klienten.
*
* Database-logikk skal ikke ligge direkte i resolverne.
* Den håndteres av repositories.
* Den håndteres av repositories. Hovedoppgave er håndtering av
* GraphQl spørringene og validering.
*
*
* GraphQL Defs -> Resolver -> Repository -> Drizzle -> MySQL
*/
import {getAllThreatActorsGrid, getThreatActorByMitreId, getThreatActorFilterOptions, getThreatActorSoftwares, getThreatActorTechniques} from "../../repositories/threatActorRepository.js";
import { validateAssociatedArgs, validateMitreId, validateThreatActorGridArgs, type ThreatActorGridArgs } from "../validation/threatActorValidation.js";



export const threatActorResolvers = {
Query: {
/** Henter ut alle filterOptions */

/**
* Henter tilgjengelige filteralternativer fra databasen.
* Krever ingen argumenter eller inputvalidering.
*/
threatActorFilterOptions: async (_parent: unknown) => {
return getThreatActorFilterOptions();
},

/**
* Henter alle ThreatActors for Grid i front end.
* Henter en paginert liste med Threat Actors.
*
* Validerer søk, filtrering, sortering og pagination
* før argumentene sendes videre til repositoryet.
*/
allThreatActorsGrid: async (_parent: unknown, args: {limit: number; offset: number}) => {
return getAllThreatActorsGrid(args.limit, args.offset);
allThreatActorsGrid: async (_parent: unknown, args: ThreatActorGridArgs) => {

const validatedArgs = validateThreatActorGridArgs(args)

return getAllThreatActorsGrid(validatedArgs);
},

/**
* Henter én Threat Actor med tilhørende detaljer,
* aliaser, sektorer, teknikker og programvare.
* Henter detaljert informasjon om én Threat Actor.
*
* Validerer MITRE-ID før oppslag i databasen.
*/
getThreatActorByMitreId: async (_parent: unknown, args: {mitreId: string}) => {
return getThreatActorByMitreId(args.mitreId);

const mitreId = validateMitreId(args.mitreId)

return getThreatActorByMitreId(mitreId);
},

/**
* Henter paginerte Techniques tilknyttet en Threat Actor.
*
* Validerer MITRE-ID, limit og offset.
*/
getThreatActorTechniques: async (_parent: unknown, args: {mitreId: string; limit: number; offset: number}) => {
return getThreatActorTechniques(args.mitreId, args.limit, args.offset);
},

const validatedArgs = validateAssociatedArgs(args);

getThreatActorSoftwares: async (_parent: unknown, args: {mitreId: string; limit: number; offset: number}) => {
return getThreatActorSoftwares(args.mitreId, args.limit, args.offset);
return getThreatActorTechniques(validatedArgs.mitreId, validatedArgs.limit, validatedArgs.offset
);
},
/**
* Henter paginert Software tilknyttet en Threat Actor.
*
* Gjenbruker samme argumentvalidering som Techniques.
*/
getThreatActorSoftwares: async (_parent: unknown, args: {mitreId: string; limit: number; offset: number}) => {

const validatedArgs = validateAssociatedArgs(args);


return getThreatActorSoftwares(validatedArgs.mitreId, validatedArgs.limit, validatedArgs.offset);
},
},
};
201 changes: 163 additions & 38 deletions backend/src/graphql/typeDefs.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,52 @@

/**
* GraphQL schema: defines the types and operations available to the frontend.
* GraphQL Schema (SDL)
*
* Definerer API-kontrakten mellom frontend og backend:
* - Hvilke datatyper som finnes
* - Hvilke argumenter klienten kan sende
* - Hvilke data hver query returnerer
*
* GraphQL bruker:
* - String, Int og Boolean som grunnleggende datatyper
* - ! for å markere en verdi som ikke kan være null
* - [Type!]! for en ikke-null liste med ikke-null elementer
*
* Inputvalidering håndteres i validation-laget.
* Databaseoperasjoner håndteres i repository-laget.
*/

export const typeDefs = `#graphql
# ==================================================
# SHARED TYPES
# ==================================================
"""Representerer en tilknyttet entitet med MITRE-ID og navn."""
type AssociatedItem {
mitreId: String!
name: String!
}
"""Paginert resultat for tilknyttede entiteter."""
type AssociatedItemsPage {
items: [AssociatedItem!]!
totalCount: Int!
}
# ==================================================
# THREAT ACTORS
# ==================================================
"""Ett tilgjengelig filteralternativ med antall treff."""
type ThreatActorFilterOption {
value: String!
label: String!
count: Int!
}
"""Tilgjengelige filterverdier hentet fra databasen."""
type ThreatActorFilterOptions {
countries: [ThreatActorFilterOption!]!
regions: [ThreatActorFilterOption!]!
Expand All @@ -15,6 +55,18 @@ export const typeDefs = `#graphql
statuses: [ThreatActorFilterOption!]!
danger_levels: [ThreatActorFilterOption!]!
}
"""Valgfrie filtre for Threat Actor-katalogen."""
input ThreatActorFilterInput {
country: String
region: String
motivation: String
sector: String
status: String
dangerLevel: String
}
"""Data som trengs for å vise ett Threat Actor-kort."""
type ThreatActorGrid {
name: String!
mitreId: String!
Expand All @@ -24,21 +76,13 @@ export const typeDefs = `#graphql
motivation: String!
}
"""Paginert resultat fra Threat Actor-katalogen."""
type ThreatActorGridInfo {
items: [ThreatActorGrid!]!
totalCount: Int!
}
type AssociatedItem {
mitreId: String!
name: String!
}
type AssociatedItemsPage {
items: [AssociatedItem!]!
totalCount: Int!
}
"""Detaljert informasjon om én Threat Actor."""
type ThreatActorDetailed {
threatId: String!
mitreId: String!
Expand All @@ -57,39 +101,78 @@ export const typeDefs = `#graphql
sectors: [String!]!
}
# ==================================================
# TECHNIQUES
# ==================================================
"""Detaljert informasjon om en angrepsteknikk."""
type Technique {
mitreId: String!
name: String!
description: String!
tactics: [String!]!
platforms: [String!]!
}
"""Data som trengs for å vise ett Technique-kort."""
type TechniqueGrid {
mitreId: String!
name: String!
tactic: String!
platform: String!
}
"""Paginert resultat fra Technique-katalogen."""
type TechniqueGridResult {
items: [TechniqueGrid!]!
totalCount: Int!
}
"""En Threat Actor representert ved navn."""
type ThreatActorItem {
name: String!
}
# ==================================================
# SOFTWARE
# ==================================================
"""En entitet tilknyttet programvare."""
type RelatedSoftwareEntity {
id: String!
mitreId: String!
name: String!
}
"""Programvare med tilhørende relasjoner."""
type Software {
id: String!
mitreId: String!
name: String!
description: String!
type: String!
aliases: [String!]!
platforms: [String!]!
associatedTechniques: [RelatedSoftwareEntity!]!
usedByThreatActors: [RelatedSoftwareEntity!]!
}
# ==================================================
# TACTICS
# ==================================================
"""Data som trengs for å vise ett Tactic-kort."""
type TacticGrid {
mitreId: String!
name: String!
description: String!
techniqueCount: Int!
}
"""Detaljert informasjon om én Tactic."""
type TacticDetailed {
tacticId: String!
mitreId: String!
Expand All @@ -99,37 +182,57 @@ export const typeDefs = `#graphql
xMitreDeprecated: Boolean!
}
"""Paginert liste med Techniques."""
type TechniquePage {
items: [Technique!]!
totalCount: Int!
}
type RelatedSoftwareEntity {
id: String!
mitreId: String!
name: String!
}
type Software {
id: String!
mitreId: String!
name: String!
description: String!
type: String!
aliases: [String!]!
platforms: [String!]!
associatedTechniques: [RelatedSoftwareEntity!]!
usedByThreatActors: [RelatedSoftwareEntity!]!
}
# ==================================================
# QUERIES
# ==================================================
type Query {
allThreatActorsGrid(limit: Int!, offset: Int!): ThreatActorGridInfo!
getThreatActorByMitreId(mitreId: String!): ThreatActorDetailed
getThreatActorTechniques(mitreId: String!, limit: Int!, offset: Int!): AssociatedItemsPage!
getThreatActorSoftwares(mitreId: String!, limit: Int!, offset: Int!): AssociatedItemsPage!
# ---------------- THREAT ACTORS ----------------
"""
Henter en paginert liste med Threat Actors.
Støtter søk, filtrering og sortering.
"""
allThreatActorsGrid(
limit: Int!
offset: Int!
search: String
filters: ThreatActorFilterInput
sortBy: String
): ThreatActorGridInfo!
"""Henter detaljert informasjon om én Threat Actor."""
getThreatActorByMitreId(
mitreId: String!
): ThreatActorDetailed
"""Henter paginerte Techniques tilknyttet en Threat Actor."""
getThreatActorTechniques(
mitreId: String!
limit: Int!
offset: Int!
): AssociatedItemsPage!
"""Henter paginert Software tilknyttet en Threat Actor."""
getThreatActorSoftwares(
mitreId: String!
limit: Int!
offset: Int!
): AssociatedItemsPage!
"""Henter tilgjengelige filteralternativer."""
threatActorFilterOptions: ThreatActorFilterOptions!
######################################## Techinques vvvv
# ---------------- TECHNIQUES ----------------
# Henter alle Techniques
allTechniques(
Expand All @@ -152,11 +255,33 @@ export const typeDefs = `#graphql
mitreId: String!
): [Technique!]!
# ---------------- SOFTWARE ----------------
"""Henter all Software."""
software: [Software!]!
softwareByMitreId(mitreId: String!): Software
"""Henter én Software basert på MITRE-ID."""
softwareByMitreId(
mitreId: String!
): Software
# ---------------- TACTICS ----------------
"""Henter alle Tactics."""
allTactics: [TacticGrid!]!
getTacticByMitreId(mitreId: String!): TacticDetailed
getTacticTechniques(mitreId: String!, limit: Int!, offset: Int!): TechniquePage!
"""Henter én Tactic basert på MITRE-ID."""
getTacticByMitreId(
mitreId: String!
): TacticDetailed
"""Henter paginerte Techniques tilknyttet en Tactic."""
getTacticTechniques(
mitreId: String!
limit: Int!
offset: Int!
): TechniquePage!
}
`;
Loading