Files
dsp/db/migrations/20241103_oauth_tables.sql
2026-01-29 14:31:48 +07:00

84 lines
3.3 KiB
SQL

--
-- DSP OAuth schema for JupyterHub integration
--
-- Run inside the MySQL container, e.g.:
-- docker-compose exec db mysql -u root -p niph_dsps < db/migrations/20241103_oauth_tables.sql
--
START TRANSACTION;
CREATE TABLE IF NOT EXISTS `dsp_oauth_clients` (
`client_id` varchar(128) NOT NULL,
`client_name` varchar(255) NOT NULL,
`client_secret_hash` varchar(255) DEFAULT NULL,
`redirect_uris` text NOT NULL,
`allowed_scopes` varchar(255) DEFAULT NULL,
`is_confidential` tinyint(1) NOT NULL DEFAULT 1,
`is_revoked` tinyint(1) NOT NULL DEFAULT 0,
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`client_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `dsp_oauth_auth_codes` (
`code_hash` char(64) NOT NULL,
`client_id` varchar(128) NOT NULL,
`person_id` int(11) NOT NULL,
`scope` varchar(255) DEFAULT NULL,
`redirect_uri` varchar(2000) NOT NULL,
`expires_at` datetime NOT NULL,
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`code_hash`),
KEY `idx_oauth_auth_client` (`client_id`),
KEY `idx_oauth_auth_expires` (`expires_at`),
CONSTRAINT `dsp_oauth_auth_codes_ibfk_1` FOREIGN KEY (`client_id`) REFERENCES `dsp_oauth_clients` (`client_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `dsp_oauth_auth_codes_ibfk_2` FOREIGN KEY (`person_id`) REFERENCES `ist_tbl_people` (`pkisp_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `dsp_oauth_access_tokens` (
`token_hash` char(64) NOT NULL,
`client_id` varchar(128) NOT NULL,
`person_id` int(11) NOT NULL,
`scope` varchar(255) DEFAULT NULL,
`expires_at` datetime NOT NULL,
`refresh_token_hash` char(64) DEFAULT NULL,
`refresh_expires_at` datetime DEFAULT NULL,
`is_revoked` tinyint(1) NOT NULL DEFAULT 0,
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`last_used_at` datetime DEFAULT NULL,
`revoked_at` datetime DEFAULT NULL,
PRIMARY KEY (`token_hash`),
KEY `idx_oauth_access_client` (`client_id`),
KEY `idx_oauth_access_person` (`person_id`),
KEY `idx_oauth_access_refresh` (`refresh_token_hash`),
KEY `idx_oauth_access_expires` (`expires_at`),
CONSTRAINT `dsp_oauth_access_tokens_ibfk_1` FOREIGN KEY (`client_id`) REFERENCES `dsp_oauth_clients` (`client_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `dsp_oauth_access_tokens_ibfk_2` FOREIGN KEY (`person_id`) REFERENCES `ist_tbl_people` (`pkisp_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
COMMIT;
--
-- Optional helper to register the JupyterHub client.
-- Replace the placeholder secret/redirects before running.
--
-- INSERT INTO dsp_oauth_clients (
-- client_id,
-- client_name,
-- client_secret_hash,
-- redirect_uris,
-- allowed_scopes
-- ) VALUES (
-- 'hub-client',
-- 'DSP JupyterHub',
-- '$2y$10$replace_this_with_password_hash',
-- 'https://hub.example.com/hub/oauth_callback',
-- 'profile'
-- )
-- ON DUPLICATE KEY UPDATE
-- client_name = VALUES(client_name),
-- client_secret_hash = VALUES(client_secret_hash),
-- redirect_uris = VALUES(redirect_uris),
-- allowed_scopes = VALUES(allowed_scopes),
-- updated_at = NOW();