mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-08-29 10:21:34 +00:00
feat: share credentials with users and roles, inherit data on account deletion (#1342)
* feat: share credentials with users and roles, inherit data on account deletion Credentials can be shared at "use" or "manage" level. Recipients get a copy re-encrypted under their own data key (shared_credential_secrets), kept in step with the owner's row through the same lifecycle hooks as shared host secrets. One gate, findUsableCredential(), replaces the private-namespace lookups so a shared credential works wherever a private one does. Deleting a user now hands their hosts and credentials to a successor (the deleting admin by default) instead of revoking everything they shared. * fix: harden credential ownership transfer
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
CREATE TABLE `credential_access` (
|
||||
`id` int AUTO_INCREMENT NOT NULL,
|
||||
`credential_id` int NOT NULL,
|
||||
`user_id` varchar(255),
|
||||
`role_id` int,
|
||||
`granted_by` varchar(255) NOT NULL,
|
||||
`permission_level` text NOT NULL DEFAULT ('use'),
|
||||
`expires_at` varchar(255),
|
||||
`created_at` varchar(255) NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
CONSTRAINT `credential_access_id` PRIMARY KEY(`id`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE `shared_credential_secrets` (
|
||||
`id` int AUTO_INCREMENT NOT NULL,
|
||||
`credential_access_id` int NOT NULL,
|
||||
`target_user_id` varchar(255) NOT NULL,
|
||||
`credential_id` int NOT NULL,
|
||||
`encrypted_username` text,
|
||||
`auth_type` text NOT NULL DEFAULT ('password'),
|
||||
`encrypted_password` text,
|
||||
`encrypted_key` text,
|
||||
`encrypted_key_password` text,
|
||||
`key_type` text,
|
||||
`public_key` text,
|
||||
`cert_public_key` text,
|
||||
`created_at` varchar(255) NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
`updated_at` varchar(255) NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
CONSTRAINT `shared_credential_secrets_id` PRIMARY KEY(`id`),
|
||||
CONSTRAINT `idx_shared_credential_secrets_scope` UNIQUE(`credential_access_id`,`target_user_id`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE `credential_access` ADD CONSTRAINT `credential_access_credential_id_ssh_credentials_id_fk` FOREIGN KEY (`credential_id`) REFERENCES `ssh_credentials`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `credential_access` ADD CONSTRAINT `credential_access_user_id_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `credential_access` ADD CONSTRAINT `credential_access_role_id_roles_id_fk` FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `credential_access` ADD CONSTRAINT `credential_access_granted_by_users_id_fk` FOREIGN KEY (`granted_by`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `shared_credential_secrets` ADD CONSTRAINT `shared_cred_secrets_access_id_fk` FOREIGN KEY (`credential_access_id`) REFERENCES `credential_access`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `shared_credential_secrets` ADD CONSTRAINT `shared_credential_secrets_target_user_id_users_id_fk` FOREIGN KEY (`target_user_id`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `shared_credential_secrets` ADD CONSTRAINT `shared_credential_secrets_credential_id_ssh_credentials_id_fk` FOREIGN KEY (`credential_id`) REFERENCES `ssh_credentials`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX `idx_credential_access_user_id` ON `credential_access` (`user_id`);--> statement-breakpoint
|
||||
CREATE INDEX `idx_credential_access_role_id` ON `credential_access` (`role_id`);--> statement-breakpoint
|
||||
CREATE INDEX `idx_credential_access_credential_id` ON `credential_access` (`credential_id`);--> statement-breakpoint
|
||||
CREATE INDEX `idx_shared_credential_secrets_target` ON `shared_credential_secrets` (`target_user_id`,`credential_id`);
|
||||
File diff suppressed because it is too large
Load Diff
@@ -127,6 +127,13 @@
|
||||
"when": 1787596414390,
|
||||
"tag": "0017_spicy_proteus",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 18,
|
||||
"version": "5",
|
||||
"when": 1787600445146,
|
||||
"tag": "0018_fancy_barracuda",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
CREATE TABLE "credential_access" (
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"credential_id" integer NOT NULL,
|
||||
"user_id" varchar(255),
|
||||
"role_id" integer,
|
||||
"granted_by" varchar(255) NOT NULL,
|
||||
"permission_level" text DEFAULT 'use' NOT NULL,
|
||||
"expires_at" varchar(255),
|
||||
"created_at" varchar(255) DEFAULT CURRENT_TIMESTAMP NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "shared_credential_secrets" (
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"credential_access_id" integer NOT NULL,
|
||||
"target_user_id" varchar(255) NOT NULL,
|
||||
"credential_id" integer NOT NULL,
|
||||
"encrypted_username" text,
|
||||
"auth_type" text DEFAULT 'password' NOT NULL,
|
||||
"encrypted_password" text,
|
||||
"encrypted_key" text,
|
||||
"encrypted_key_password" text,
|
||||
"key_type" text,
|
||||
"public_key" text,
|
||||
"cert_public_key" text,
|
||||
"created_at" varchar(255) DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
"updated_at" varchar(255) DEFAULT CURRENT_TIMESTAMP NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "credential_access" ADD CONSTRAINT "credential_access_credential_id_ssh_credentials_id_fk" FOREIGN KEY ("credential_id") REFERENCES "public"."ssh_credentials"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "credential_access" ADD CONSTRAINT "credential_access_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "credential_access" ADD CONSTRAINT "credential_access_role_id_roles_id_fk" FOREIGN KEY ("role_id") REFERENCES "public"."roles"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "credential_access" ADD CONSTRAINT "credential_access_granted_by_users_id_fk" FOREIGN KEY ("granted_by") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "shared_credential_secrets" ADD CONSTRAINT "shared_credential_secrets_credential_access_id_credential_access_id_fk" FOREIGN KEY ("credential_access_id") REFERENCES "public"."credential_access"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "shared_credential_secrets" ADD CONSTRAINT "shared_credential_secrets_target_user_id_users_id_fk" FOREIGN KEY ("target_user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "shared_credential_secrets" ADD CONSTRAINT "shared_credential_secrets_credential_id_ssh_credentials_id_fk" FOREIGN KEY ("credential_id") REFERENCES "public"."ssh_credentials"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX "idx_credential_access_user_id" ON "credential_access" USING btree ("user_id");--> statement-breakpoint
|
||||
CREATE INDEX "idx_credential_access_role_id" ON "credential_access" USING btree ("role_id");--> statement-breakpoint
|
||||
CREATE INDEX "idx_credential_access_credential_id" ON "credential_access" USING btree ("credential_id");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "idx_shared_credential_secrets_scope" ON "shared_credential_secrets" USING btree ("credential_access_id","target_user_id");--> statement-breakpoint
|
||||
CREATE INDEX "idx_shared_credential_secrets_target" ON "shared_credential_secrets" USING btree ("target_user_id","credential_id");
|
||||
File diff suppressed because it is too large
Load Diff
@@ -127,6 +127,13 @@
|
||||
"when": 1787596411353,
|
||||
"tag": "0017_curved_pet_avengers",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 18,
|
||||
"version": "7",
|
||||
"when": 1787600442827,
|
||||
"tag": "0018_puzzling_night_nurse",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
CREATE TABLE `credential_access` (
|
||||
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
`credential_id` integer NOT NULL,
|
||||
`user_id` text,
|
||||
`role_id` integer,
|
||||
`granted_by` text NOT NULL,
|
||||
`permission_level` text DEFAULT 'use' NOT NULL,
|
||||
`expires_at` text,
|
||||
`created_at` text DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
FOREIGN KEY (`credential_id`) REFERENCES `ssh_credentials`(`id`) ON UPDATE no action ON DELETE cascade,
|
||||
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE cascade,
|
||||
FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`) ON UPDATE no action ON DELETE cascade,
|
||||
FOREIGN KEY (`granted_by`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE cascade
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE INDEX `idx_credential_access_user_id` ON `credential_access` (`user_id`);--> statement-breakpoint
|
||||
CREATE INDEX `idx_credential_access_role_id` ON `credential_access` (`role_id`);--> statement-breakpoint
|
||||
CREATE INDEX `idx_credential_access_credential_id` ON `credential_access` (`credential_id`);--> statement-breakpoint
|
||||
CREATE TABLE `shared_credential_secrets` (
|
||||
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
`credential_access_id` integer NOT NULL,
|
||||
`target_user_id` text NOT NULL,
|
||||
`credential_id` integer NOT NULL,
|
||||
`encrypted_username` text,
|
||||
`auth_type` text DEFAULT 'password' NOT NULL,
|
||||
`encrypted_password` text,
|
||||
`encrypted_key` text(16384),
|
||||
`encrypted_key_password` text,
|
||||
`key_type` text,
|
||||
`public_key` text(4096),
|
||||
`cert_public_key` text(8192),
|
||||
`created_at` text DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
`updated_at` text DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
FOREIGN KEY (`credential_access_id`) REFERENCES `credential_access`(`id`) ON UPDATE no action ON DELETE cascade,
|
||||
FOREIGN KEY (`target_user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE cascade,
|
||||
FOREIGN KEY (`credential_id`) REFERENCES `ssh_credentials`(`id`) ON UPDATE no action ON DELETE cascade
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX `idx_shared_credential_secrets_scope` ON `shared_credential_secrets` (`credential_access_id`,`target_user_id`);--> statement-breakpoint
|
||||
CREATE INDEX `idx_shared_credential_secrets_target` ON `shared_credential_secrets` (`target_user_id`,`credential_id`);
|
||||
File diff suppressed because it is too large
Load Diff
@@ -99,6 +99,13 @@
|
||||
"when": 1787596405780,
|
||||
"tag": "0013_tranquil_master_mold",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 14,
|
||||
"version": "6",
|
||||
"when": 1787600440707,
|
||||
"tag": "0014_lean_doctor_octopus",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user