-
Notifications
You must be signed in to change notification settings - Fork 211
[backend] feat(multi-tenancy): add default tenant migration and foreign keys (#3505) #4979
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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", | ||
| "asset_groups", | ||
| "assets", | ||
| "attack_patterns", | ||
| "challenges", | ||
|
damgouj marked this conversation as resolved.
|
||
| "channels", | ||
| "collectors", | ||
| "connector_instances", | ||
| "custom_dashboards", | ||
| "datapacks", | ||
|
damgouj marked this conversation as resolved.
|
||
| "documents", | ||
| "executors", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 ?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pending Denise's answer |
||
| "exercises", | ||
| "findings", | ||
| "groups", | ||
|
damgouj marked this conversation as resolved.
|
||
| "import_mappers", | ||
| "injectors", | ||
| "injects", | ||
| "kill_chain_phases", | ||
| "lessons_templates", | ||
| "mitigations", | ||
| "organizations", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. question: Mitigation ? Seams to be used by OpenCTI
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add tenant id and create issue to delete the code
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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;"); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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);"); | ||
| } | ||
| } | ||
| } | ||
| 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); | ||
| } | ||
| } |
There was a problem hiding this comment.
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 ?
There was a problem hiding this comment.
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 :)