diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/c77_secure_db.iml b/.idea/c77_secure_db.iml
new file mode 100644
index 0000000..c956989
--- /dev/null
+++ b/.idea/c77_secure_db.iml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..8ca82bd
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/php.xml b/.idea/php.xml
new file mode 100644
index 0000000..f324872
--- /dev/null
+++ b/.idea/php.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/c77_secure_db--1.0.sql b/c77_secure_db--1.0.sql
index 61035a2..0d46683 100644
--- a/c77_secure_db--1.0.sql
+++ b/c77_secure_db--1.0.sql
@@ -1468,29 +1468,266 @@ v_test_results := v_test_results || jsonb_build_object(
END;
-- TEST 5: Test token expiration (simulate expired token)
+-- Comprehensive security test suite
+CREATE OR REPLACE FUNCTION c77_secure_db_test_security()
+ RETURNS JSONB
+ LANGUAGE plpgsql AS $$
+DECLARE
+ v_test_results JSONB := '{}';
+ v_tests_passed INTEGER := 0;
+ v_tests_failed INTEGER := 0;
+ v_test_schema TEXT := 'c77_test_' || extract(epoch from now())::bigint;
+ v_operation_result JSONB;
BEGIN
--- This test verifies that expired tokens don't work
-PERFORM set_config('c77_secure_db.auth_token', gen_random_uuid()::text, true);
-EXECUTE format('INSERT INTO %I.test_secure_table (name) VALUES (''token_test'')', v_test_schema);
+ -- Create test environment
+ EXECUTE format('CREATE SCHEMA %I', v_test_schema);
-v_tests_failed := v_tests_failed + 1;
-v_test_results := v_test_results || jsonb_build_object(
- 'token_expiration', jsonb_build_object(
- 'status', 'FAILED',
- 'message', 'Invalid token was accepted - SECURITY FLAW!'
- )
- );
-EXCEPTION WHEN insufficient_privilege THEN
+ -- Create test table
+ EXECUTE format('
+ CREATE TABLE %I.test_secure_table (
+ id BIGSERIAL PRIMARY KEY,
+ name TEXT NOT NULL,
+ description TEXT,
+ content_hash TEXT,
+ hash_version INTEGER DEFAULT 1,
+ created_at TIMESTAMPTZ DEFAULT NOW(),
+ updated_at TIMESTAMPTZ DEFAULT NOW(),
+ deleted_at TIMESTAMPTZ
+ )', v_test_schema);
+
+ -- Register schema as secure
+ PERFORM c77_secure_db_manage_secure_schemas('add', v_test_schema);
+
+ -- TEST 1: Verify direct INSERT is blocked
+ BEGIN
+ EXECUTE format('INSERT INTO %I.test_secure_table (name) VALUES (''bypass_test'')', v_test_schema);
+
+ v_tests_failed := v_tests_failed + 1;
+ v_test_results := v_test_results || jsonb_build_object(
+ 'direct_insert_blocked', jsonb_build_object(
+ 'status', 'FAILED',
+ 'message', 'Direct INSERT was allowed - CRITICAL SECURITY FLAW!'
+ )
+ );
+ EXCEPTION WHEN insufficient_privilege THEN
v_tests_passed := v_tests_passed + 1;
-v_test_results := v_test_results || jsonb_build_object(
- 'token_expiration', jsonb_build_object(
- 'status', 'PASSED',
- 'message', 'Invalid token correctly rejected'
- )
- );
-FINALLY
-PERFORM set_config('c77_secure_db.auth_token', '', true);
+ v_test_results := v_test_results || jsonb_build_object(
+ 'direct_insert_blocked', jsonb_build_object(
+ 'status', 'PASSED',
+ 'message', 'Direct INSERT correctly blocked'
+ )
+ );
+ END;
+
+ -- TEST 2: Verify direct UPDATE is blocked
+ BEGIN
+ EXECUTE format('UPDATE %I.test_secure_table SET name = ''hacked'' WHERE id = 1', v_test_schema);
+
+ v_tests_failed := v_tests_failed + 1;
+ v_test_results := v_test_results || jsonb_build_object(
+ 'direct_update_blocked', jsonb_build_object(
+ 'status', 'FAILED',
+ 'message', 'Direct UPDATE was allowed - CRITICAL SECURITY FLAW!'
+ )
+ );
+ EXCEPTION WHEN insufficient_privilege THEN
+ v_tests_passed := v_tests_passed + 1;
+ v_test_results := v_test_results || jsonb_build_object(
+ 'direct_update_blocked', jsonb_build_object(
+ 'status', 'PASSED',
+ 'message', 'Direct UPDATE correctly blocked'
+ )
+ );
+ END;
+
+ -- TEST 3: Verify direct DELETE is blocked
+ BEGIN
+ EXECUTE format('DELETE FROM %I.test_secure_table WHERE id = 1', v_test_schema);
+
+ v_tests_failed := v_tests_failed + 1;
+ v_test_results := v_test_results || jsonb_build_object(
+ 'direct_delete_blocked', jsonb_build_object(
+ 'status', 'FAILED',
+ 'message', 'Direct DELETE was allowed - CRITICAL SECURITY FLAW!'
+ )
+ );
+ EXCEPTION WHEN insufficient_privilege THEN
+ v_tests_passed := v_tests_passed + 1;
+ v_test_results := v_test_results || jsonb_build_object(
+ 'direct_delete_blocked', jsonb_build_object(
+ 'status', 'PASSED',
+ 'message', 'Direct DELETE correctly blocked'
+ )
+ );
+ END;
+
+ -- TEST 4: Verify legitimate secure operation works
+ BEGIN
+ SELECT c77_secure_db_operation(jsonb_build_object(
+ 'schema_name', v_test_schema,
+ 'table_name', 'test_secure_table',
+ 'operation', 'insert',
+ 'data', jsonb_build_object('name', 'legitimate_test', 'description', 'This should work')
+ )) INTO v_operation_result;
+
+ IF (v_operation_result->>'success')::boolean THEN
+ v_tests_passed := v_tests_passed + 1;
+ v_test_results := v_test_results || jsonb_build_object(
+ 'legitimate_operation', jsonb_build_object(
+ 'status', 'PASSED',
+ 'message', 'Secure operation succeeded',
+ 'operation_id', v_operation_result->>'operation_id'
+ )
+ );
+ ELSE
+ v_tests_failed := v_tests_failed + 1;
+ v_test_results := v_test_results || jsonb_build_object(
+ 'legitimate_operation', jsonb_build_object(
+ 'status', 'FAILED',
+ 'message', 'Secure operation failed: ' || (v_operation_result->>'error')
+ )
+ );
+ END IF;
+ EXCEPTION WHEN OTHERS THEN
+ v_tests_failed := v_tests_failed + 1;
+ v_test_results := v_test_results || jsonb_build_object(
+ 'legitimate_operation', jsonb_build_object(
+ 'status', 'ERROR',
+ 'message', SQLERRM
+ )
+ );
+ END;
+
+ -- TEST 5: Test token expiration (simulate expired token)
+ BEGIN
+ -- This test verifies that expired tokens don't work
+ PERFORM set_config('c77_secure_db.auth_token', gen_random_uuid()::text, true);
+ EXECUTE format('INSERT INTO %I.test_secure_table (name) VALUES (''token_test'')', v_test_schema);
+
+ v_tests_failed := v_tests_failed + 1;
+ v_test_results := v_test_results || jsonb_build_object(
+ 'token_expiration', jsonb_build_object(
+ 'status', 'FAILED',
+ 'message', 'Invalid token was accepted - SECURITY FLAW!'
+ )
+ );
+ EXCEPTION WHEN insufficient_privilege THEN
+ v_tests_passed := v_tests_passed + 1;
+ v_test_results := v_test_results || jsonb_build_object(
+ 'token_expiration', jsonb_build_object(
+ 'status', 'PASSED',
+ 'message', 'Invalid token correctly rejected'
+ )
+ );
+ WHEN OTHERS THEN
+ v_tests_failed := v_tests_failed + 1;
+ v_test_results := v_test_results || jsonb_build_object(
+ 'token_expiration', jsonb_build_object(
+ 'status', 'ERROR',
+ 'message', SQLERRM
+ )
+ );
+ END;
+
+ -- Clean up token after TEST 5
+ PERFORM set_config('c77_secure_db.auth_token', '', true);
+
+ -- TEST 6: Test hash calculation and verification
+ BEGIN
+ -- Insert a record and verify its hash
+ SELECT c77_secure_db_operation(jsonb_build_object(
+ 'schema_name', v_test_schema,
+ 'table_name', 'test_secure_table',
+ 'operation', 'insert',
+ 'data', jsonb_build_object('name', 'hash_test', 'description', 'Test hash calculation')
+ )) INTO v_operation_result;
+
+ IF (v_operation_result->>'success')::boolean AND (v_operation_result->>'content_hash') IS NOT NULL THEN
+ -- Now verify the hash
+ DECLARE
+ v_freshness_result JSONB;
+ v_record_data JSONB;
+ BEGIN
+ -- Get the inserted record data (simulated)
+ v_record_data := jsonb_build_object(
+ 'id', 1, -- Assuming first record
+ 'name', 'hash_test',
+ 'description', 'Test hash calculation'
+ );
+
+ v_freshness_result := c77_secure_db_check_freshness(v_test_schema, 'test_secure_table', v_record_data);
+
+ IF (v_freshness_result->>'success')::boolean AND (v_freshness_result->>'fresh')::boolean THEN
+ v_tests_passed := v_tests_passed + 1;
+ v_test_results := v_test_results || jsonb_build_object(
+ 'hash_verification', jsonb_build_object(
+ 'status', 'PASSED',
+ 'message', 'Hash calculation and verification working correctly'
+ )
+ );
+ ELSE
+ v_tests_failed := v_tests_failed + 1;
+ v_test_results := v_test_results || jsonb_build_object(
+ 'hash_verification', jsonb_build_object(
+ 'status', 'FAILED',
+ 'message', 'Hash verification failed: ' || (v_freshness_result->>'error')
+ )
+ );
+ END IF;
+ END;
+ ELSE
+ v_tests_failed := v_tests_failed + 1;
+ v_test_results := v_test_results || jsonb_build_object(
+ 'hash_verification', jsonb_build_object(
+ 'status', 'FAILED',
+ 'message', 'Hash was not calculated during insert'
+ )
+ );
+ END IF;
+ EXCEPTION WHEN OTHERS THEN
+ v_tests_failed := v_tests_failed + 1;
+ v_test_results := v_test_results || jsonb_build_object(
+ 'hash_verification', jsonb_build_object(
+ 'status', 'ERROR',
+ 'message', SQLERRM
+ )
+ );
+ END;
+
+ -- Cleanup test environment
+ BEGIN
+ PERFORM c77_secure_db_manage_secure_schemas('remove', v_test_schema);
+ EXECUTE format('DROP SCHEMA %I CASCADE', v_test_schema);
+ EXCEPTION WHEN OTHERS THEN
+ -- Log cleanup failure but don't fail the test
+ v_test_results := v_test_results || jsonb_build_object(
+ 'cleanup_warning', 'Failed to cleanup test schema: ' || SQLERRM
+ );
+ END;
+
+ RETURN jsonb_build_object(
+ 'test_suite', 'c77_secure_db_security',
+ 'version', '2.0',
+ 'summary', jsonb_build_object(
+ 'tests_passed', v_tests_passed,
+ 'tests_failed', v_tests_failed,
+ 'total_tests', v_tests_passed + v_tests_failed,
+ 'success_rate', CASE
+ WHEN (v_tests_passed + v_tests_failed) > 0 THEN
+ round((v_tests_passed::numeric / (v_tests_passed + v_tests_failed) * 100), 2)
+ ELSE 0
+ END
+ ),
+ 'overall_status', CASE
+ WHEN v_tests_failed = 0 THEN 'ALL_TESTS_PASSED'
+ ELSE 'SECURITY_ISSUES_DETECTED'
+ END,
+ 'test_results', v_test_results,
+ 'test_schema_used', v_test_schema,
+ 'timestamp', now()
+ );
END;
+$$;
-- TEST 6: Test hash calculation and verification
BEGIN
@@ -1589,6 +1826,9 @@ RETURN jsonb_build_object(
END;
$$;
+
+
+
-- Test RBAC integration
CREATE OR REPLACE FUNCTION c77_secure_db_test_rbac_integration()
RETURNS JSONB