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
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package io.openaev.migration;

import static io.openaev.database.model.Tenant.DEFAULT_TENANT_UUID;

import java.sql.Statement;
import java.util.List;
import org.flywaydb.core.api.migration.BaseJavaMigration;
import org.flywaydb.core.api.migration.Context;
import org.springframework.stereotype.Component;

@Component
public class V4_74__Create_default_tenant extends BaseJavaMigration {

// Strings to replace in the SQL statement
private static List<String> TABLES =
List.of(
"agents",
"asset_agent_jobs",
Comment on lines +17 to +18
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: Since an agent is linked to a asset, do we need to add the tenant link here ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seen together and with JB, yes we need :)

"asset_groups",
"assets",
"attack_patterns",
"challenges",
Comment thread
damgouj marked this conversation as resolved.
"channels",
"collectors",
"connector_instances",
"custom_dashboards",
"datapacks",
Comment thread
damgouj marked this conversation as resolved.
"documents",
"executors",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: Why not adding tenant on domains like attack pattern and kill chain phases ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pending Denise's answer

"exercises",
"findings",
"groups",
Comment thread
damgouj marked this conversation as resolved.
"import_mappers",
"injectors",
"injects",
"kill_chain_phases",
"lessons_templates",
"mitigations",
"organizations",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: Mitigation ? Seams to be used by OpenCTI

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add tenant id and create issue to delete the code

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: I have the feeling that notification_rules should include a tenant field so that we can list them in the future when we build the notification center. To be confirmed.

"notification_rules",
"payloads",
"roles",
"scenarios",
"tag_rules",
"tags",
"teams",
"vulnerabilities");

@Override
public void migrate(Context context) throws Exception {
try (Statement statement = context.getConnection().createStatement()) {
// Add default tenant
statement.execute(
String.format(
"""
INSERT INTO tenants(tenant_id, tenant_name, tenant_description)
VALUES ('%s', 'First default tenant auto created to rename', 'First default tenant auto created to rename');
""",
DEFAULT_TENANT_UUID));
// Add deleted_at in tenants for soft delete
statement.execute("ALTER TABLE tenants ADD tenant_deleted_at TIMESTAMP WITH TIME ZONE;");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: Should it be included in the bean ?

// Add foreign keys with index, auto set default tenant id with default value
for (String table : TABLES) {
statement.addBatch(
String.format(
"""
ALTER TABLE %s
ADD COLUMN tenant_id VARCHAR(255) NOT NULL DEFAULT '%s',
ADD CONSTRAINT fk_tenant_id FOREIGN KEY (tenant_id) REFERENCES tenants(tenant_id) ON DELETE CASCADE;
""",
table, DEFAULT_TENANT_UUID));
statement.addBatch(
String.format(
"""
CREATE INDEX IF NOT EXISTS idx_tenant_id ON %s(tenant_id);
""",
table));
}
statement.executeBatch();
// Add linked table for users and tenants
statement.execute(
"""
CREATE TABLE IF NOT EXISTS users_tenants (
user_id VARCHAR(255) NOT NULL,
tenant_id VARCHAR(255) NOT NULL,
PRIMARY KEY (user_id, tenant_id),
CONSTRAINT fk_user_id FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE,
CONSTRAINT fk_tenant_id FOREIGN KEY (tenant_id) REFERENCES tenants(tenant_id) ON DELETE CASCADE
);
""");
statement.execute("CREATE INDEX IF NOT EXISTS idx_user_id ON users_tenants(user_id);");
statement.execute("CREATE INDEX IF NOT EXISTS idx_tenant_id ON users_tenants(tenant_id);");
}
}
}
18 changes: 18 additions & 0 deletions openaev-model/src/main/java/io/openaev/context/TenantContext.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package io.openaev.context;

import io.openaev.database.model.Tenant;

public class TenantContext {

private static final ThreadLocal<String> CURRENT_TENANT = new ThreadLocal<>();

public static String getCurrentTenant() {
return Tenant.DEFAULT_TENANT_UUID;
// return CURRENT_TENANT.get();
}

// TODO multi-tenancy: set with Front URL instead of default UUID and update the return above
public static void setCurrentTenant(String tenant) {
CURRENT_TENANT.set(tenant);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.openaev.database.model;

import static io.openaev.database.model.Tenant.DEFAULT_TENANT_UUID;
import static java.time.Instant.now;

import com.fasterxml.jackson.annotation.JsonIgnore;
Expand Down Expand Up @@ -144,6 +145,13 @@ public boolean isActive() {
@Transient
private final ResourceType resourceType = ResourceType.AGENT;

// Ignore json and not null
@ManyToOne
@JoinColumn(name = "tenant_id")
@JsonIgnore
@NotNull
private Tenant tenant = new Tenant(DEFAULT_TENANT_UUID);

@Override
public int hashCode() {
return Objects.hash(id);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.openaev.database.model;

import static io.openaev.database.model.Tenant.DEFAULT_TENANT_UUID;
import static jakarta.persistence.DiscriminatorType.STRING;
import static java.time.Instant.now;
import static lombok.AccessLevel.NONE;
Expand Down Expand Up @@ -63,6 +64,12 @@ public class Asset implements Base {
@JsonProperty("asset_external_reference")
private String externalReference;

@ManyToOne
@JoinColumn(name = "tenant_id")
@JsonIgnore
@NotNull
private Tenant tenant = new Tenant(DEFAULT_TENANT_UUID);

// -- TAG --

@Schema(implementation = String[].class)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package io.openaev.database.model;

import static io.openaev.database.model.Tenant.DEFAULT_TENANT_UUID;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.openaev.database.audit.ModelBaseListener;
import io.openaev.helper.MonoIdSerializer;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.util.Objects;
import lombok.Data;
import lombok.Getter;
Expand Down Expand Up @@ -48,6 +52,12 @@ public class AssetAgentJob implements Base {
@NotBlank
private String command;

@ManyToOne
@JoinColumn(name = "tenant_id")
@JsonIgnore
@NotNull
private Tenant tenant = new Tenant(DEFAULT_TENANT_UUID);

@Override
public String toString() {
return id;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.openaev.database.model;

import static io.openaev.database.model.Tenant.DEFAULT_TENANT_UUID;
import static java.time.Instant.now;
import static lombok.AccessLevel.NONE;

Expand Down Expand Up @@ -57,6 +58,12 @@ public class AssetGroup implements Base {
@JsonProperty("asset_group_external_reference")
private String externalReference;

@ManyToOne
@JoinColumn(name = "tenant_id")
@JsonIgnore
@NotNull
private Tenant tenant = new Tenant(DEFAULT_TENANT_UUID);

// -- ASSET --

@Type(JsonType.class)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.openaev.database.model;

import static io.openaev.database.model.Tenant.DEFAULT_TENANT_UUID;
import static java.time.Instant.now;

import com.fasterxml.jackson.annotation.JsonIgnore;
Expand All @@ -14,6 +15,7 @@
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
Expand Down Expand Up @@ -101,6 +103,12 @@ public class AttackPattern implements Base {
@JsonProperty("attack_pattern_kill_chain_phases")
private List<KillChainPhase> killChainPhases = new ArrayList<>();

@ManyToOne
@JoinColumn(name = "tenant_id")
@JsonIgnore
@NotNull
private Tenant tenant = new Tenant(DEFAULT_TENANT_UUID);

@Getter(onMethod_ = @JsonIgnore)
@Transient
private final ResourceType resourceType = ResourceType.ATTACK_PATTERN;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.openaev.database.model;

import static io.openaev.database.model.Tenant.DEFAULT_TENANT_UUID;
import static java.time.Instant.now;

import com.fasterxml.jackson.annotation.JsonIgnore;
Expand Down Expand Up @@ -97,6 +98,12 @@ public class Challenge implements Base {
@JsonProperty("challenge_documents")
private List<Document> documents = new ArrayList<>();

@ManyToOne
@JoinColumn(name = "tenant_id")
@JsonIgnore
@NotNull
private Tenant tenant = new Tenant(DEFAULT_TENANT_UUID);

@Transient private List<String> exerciseIds = new ArrayList<>();

@Transient private List<String> scenarioIds = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.openaev.database.model;

import static io.openaev.database.model.Tenant.DEFAULT_TENANT_UUID;
import static java.time.Instant.now;

import com.fasterxml.jackson.annotation.JsonIgnore;
Expand Down Expand Up @@ -90,6 +91,12 @@ public class Channel implements Base {
@Schema(implementation = String.class)
private Document logoLight;

@ManyToOne
@JoinColumn(name = "tenant_id")
@JsonIgnore
@NotNull
private Tenant tenant = new Tenant(DEFAULT_TENANT_UUID);

@Getter(onMethod_ = @JsonIgnore)
@Transient
private final ResourceType resourceType = ResourceType.CHANNEL;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.openaev.database.model;

import static io.openaev.database.model.Tenant.DEFAULT_TENANT_UUID;
import static java.time.Instant.now;

import com.fasterxml.jackson.annotation.JsonIgnore;
Expand Down Expand Up @@ -71,6 +72,12 @@ public class Collector extends BaseConnectorEntity {
@Type(JsonType.class)
private ObjectNode state;

@ManyToOne
@JoinColumn(name = "tenant_id")
@JsonIgnore
@NotNull
private Tenant tenant = new Tenant(DEFAULT_TENANT_UUID);

@Getter(onMethod_ = @JsonIgnore)
@Transient
private final ResourceType resourceType = ResourceType.COLLECTOR;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package io.openaev.database.model;

import static io.openaev.database.model.Tenant.DEFAULT_TENANT_UUID;

import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.openaev.database.audit.ModelBaseListener;
import jakarta.persistence.*;
Expand Down Expand Up @@ -90,6 +93,12 @@ public class ConnectorInstancePersisted extends ConnectorInstance implements Bas
@NotNull
private Set<ConnectorInstanceConfiguration> configurations = new HashSet<>();

@ManyToOne
@JoinColumn(name = "tenant_id")
@JsonIgnore
@NotNull
private Tenant tenant = new Tenant(DEFAULT_TENANT_UUID);

@Override
public String getClassName() {
if (this.getCatalogConnector() != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.openaev.database.model;

import static io.openaev.database.model.Tenant.DEFAULT_TENANT_UUID;
import static jakarta.persistence.FetchType.LAZY;
import static java.time.Instant.now;
import static java.util.function.Function.identity;
Expand Down Expand Up @@ -68,6 +69,12 @@ public class CustomDashboard implements Base {
@OrderBy("id ASC")
private List<CustomDashboardParameters> parameters = new ArrayList<>();

@ManyToOne
@JoinColumn(name = "tenant_id")
@JsonIgnore
@NotNull
private Tenant tenant = new Tenant(DEFAULT_TENANT_UUID);

public CustomDashboard addParameter(
@NotBlank final String name, @NotBlank final CustomDashboardParameterType type) {
if (this.getParameters().stream().anyMatch(p -> p.getType().equals(type) && type.uniq)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package io.openaev.database.model;

import static io.openaev.database.model.Tenant.DEFAULT_TENANT_UUID;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;

Expand All @@ -16,4 +20,10 @@ public class DataPack {
@JsonProperty("datapack_id")
@NotBlank
private String id;

@ManyToOne
@JoinColumn(name = "tenant_id")
@JsonIgnore
@NotNull
private Tenant tenant = new Tenant(DEFAULT_TENANT_UUID);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.openaev.database.model;

import static io.openaev.database.model.Tenant.DEFAULT_TENANT_UUID;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
Expand All @@ -9,6 +11,7 @@
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
Expand Down Expand Up @@ -108,6 +111,12 @@ public class Document implements Base {
@JsonIgnore
private Set<Challenge> challenges = new HashSet<>();

@ManyToOne
@JoinColumn(name = "tenant_id")
@JsonIgnore
@NotNull
private Tenant tenant = new Tenant(DEFAULT_TENANT_UUID);

@OneToMany(mappedBy = "document", fetch = FetchType.LAZY)
@JsonIgnore
private Set<InjectDocument> injectDocuments = new HashSet<>();
Expand Down
Loading
Loading