mirror of
https://github.com/bitechdev/ResolveSpec.git
synced 2026-06-28 07:47:39 +00:00
feat(security): add program user ID and table to user context
Build , Vet Test, and Lint / Lint Code (push) Failing after 0s
Build , Vet Test, and Lint / Run Vet Tests (1.24.x) (push) Failing after 0s
Build , Vet Test, and Lint / Build (push) Failing after 1s
Tests / Unit Tests (push) Failing after 0s
Tests / Integration Tests (push) Failing after 1s
Build , Vet Test, and Lint / Run Vet Tests (1.23.x) (push) Failing after 14m57s
Build , Vet Test, and Lint / Lint Code (push) Failing after 0s
Build , Vet Test, and Lint / Run Vet Tests (1.24.x) (push) Failing after 0s
Build , Vet Test, and Lint / Build (push) Failing after 1s
Tests / Unit Tests (push) Failing after 0s
Tests / Integration Tests (push) Failing after 1s
Build , Vet Test, and Lint / Run Vet Tests (1.23.x) (push) Failing after 14m57s
This commit is contained in:
@@ -13,6 +13,9 @@ CREATE TABLE IF NOT EXISTS users (
|
|||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
last_login_at TIMESTAMP,
|
last_login_at TIMESTAMP,
|
||||||
|
-- Program-level user mapping
|
||||||
|
program_user_id INTEGER DEFAULT 0,
|
||||||
|
program_user_table VARCHAR(255) DEFAULT '',
|
||||||
-- OAuth2 fields
|
-- OAuth2 fields
|
||||||
remote_id VARCHAR(255), -- Provider's user ID (e.g., Google sub, GitHub id)
|
remote_id VARCHAR(255), -- Provider's user ID (e.g., Google sub, GitHub id)
|
||||||
auth_provider VARCHAR(50), -- 'local', 'google', 'github', 'microsoft', 'facebook', etc.
|
auth_provider VARCHAR(50), -- 'local', 'google', 'github', 'microsoft', 'facebook', etc.
|
||||||
@@ -99,6 +102,8 @@ DECLARE
|
|||||||
v_expires_at TIMESTAMP;
|
v_expires_at TIMESTAMP;
|
||||||
v_ip_address TEXT;
|
v_ip_address TEXT;
|
||||||
v_user_agent TEXT;
|
v_user_agent TEXT;
|
||||||
|
v_program_user_id INTEGER;
|
||||||
|
v_program_user_table TEXT;
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Extract login request fields
|
-- Extract login request fields
|
||||||
v_username := p_request->>'username';
|
v_username := p_request->>'username';
|
||||||
@@ -106,8 +111,8 @@ BEGIN
|
|||||||
v_user_agent := p_request->'claims'->>'user_agent';
|
v_user_agent := p_request->'claims'->>'user_agent';
|
||||||
|
|
||||||
-- Validate user credentials
|
-- Validate user credentials
|
||||||
SELECT id, username, email, password, user_level, roles
|
SELECT id, username, email, password, user_level, roles, program_user_id, program_user_table
|
||||||
INTO v_user_id, v_username, v_email, v_password_hash, v_user_level, v_roles
|
INTO v_user_id, v_username, v_email, v_password_hash, v_user_level, v_roles, v_program_user_id, v_program_user_table
|
||||||
FROM users
|
FROM users
|
||||||
WHERE username = v_username AND is_active = true;
|
WHERE username = v_username AND is_active = true;
|
||||||
|
|
||||||
@@ -146,7 +151,9 @@ BEGIN
|
|||||||
'email', v_email,
|
'email', v_email,
|
||||||
'user_level', v_user_level,
|
'user_level', v_user_level,
|
||||||
'roles', string_to_array(COALESCE(v_roles, ''), ','),
|
'roles', string_to_array(COALESCE(v_roles, ''), ','),
|
||||||
'session_id', v_session_token
|
'session_id', v_session_token,
|
||||||
|
'program_user_id', COALESCE(v_program_user_id, 0),
|
||||||
|
'program_user_table', COALESCE(v_program_user_table, '')
|
||||||
),
|
),
|
||||||
'expires_in', 86400 -- 24 hours in seconds
|
'expires_in', 86400 -- 24 hours in seconds
|
||||||
);
|
);
|
||||||
@@ -195,12 +202,16 @@ DECLARE
|
|||||||
v_user_level INTEGER;
|
v_user_level INTEGER;
|
||||||
v_roles TEXT;
|
v_roles TEXT;
|
||||||
v_session_id TEXT;
|
v_session_id TEXT;
|
||||||
|
v_program_user_id INTEGER;
|
||||||
|
v_program_user_table TEXT;
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Query session and user data
|
-- Query session and user data
|
||||||
SELECT
|
SELECT
|
||||||
s.user_id, u.username, u.email, u.user_level, u.roles, s.session_token
|
s.user_id, u.username, u.email, u.user_level, u.roles, s.session_token,
|
||||||
|
u.program_user_id, u.program_user_table
|
||||||
INTO
|
INTO
|
||||||
v_user_id, v_username, v_email, v_user_level, v_roles, v_session_id
|
v_user_id, v_username, v_email, v_user_level, v_roles, v_session_id,
|
||||||
|
v_program_user_id, v_program_user_table
|
||||||
FROM user_sessions s
|
FROM user_sessions s
|
||||||
JOIN users u ON s.user_id = u.id
|
JOIN users u ON s.user_id = u.id
|
||||||
WHERE s.session_token = p_session_token
|
WHERE s.session_token = p_session_token
|
||||||
@@ -222,7 +233,9 @@ BEGIN
|
|||||||
'email', v_email,
|
'email', v_email,
|
||||||
'user_level', v_user_level,
|
'user_level', v_user_level,
|
||||||
'session_id', v_session_id,
|
'session_id', v_session_id,
|
||||||
'roles', string_to_array(COALESCE(v_roles, ''), ',')
|
'roles', string_to_array(COALESCE(v_roles, ''), ','),
|
||||||
|
'program_user_id', COALESCE(v_program_user_id, 0),
|
||||||
|
'program_user_table', COALESCE(v_program_user_table, '')
|
||||||
);
|
);
|
||||||
END;
|
END;
|
||||||
$$ LANGUAGE plpgsql;
|
$$ LANGUAGE plpgsql;
|
||||||
@@ -266,10 +279,14 @@ DECLARE
|
|||||||
v_expires_at TIMESTAMP;
|
v_expires_at TIMESTAMP;
|
||||||
v_ip_address TEXT;
|
v_ip_address TEXT;
|
||||||
v_user_agent TEXT;
|
v_user_agent TEXT;
|
||||||
|
v_program_user_id INTEGER;
|
||||||
|
v_program_user_table TEXT;
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Verify old session exists and is valid
|
-- Verify old session exists and is valid
|
||||||
SELECT s.user_id, u.username, u.email, u.user_level, u.roles, s.ip_address, s.user_agent
|
SELECT s.user_id, u.username, u.email, u.user_level, u.roles, s.ip_address, s.user_agent,
|
||||||
INTO v_user_id, v_username, v_email, v_user_level, v_roles, v_ip_address, v_user_agent
|
u.program_user_id, u.program_user_table
|
||||||
|
INTO v_user_id, v_username, v_email, v_user_level, v_roles, v_ip_address, v_user_agent,
|
||||||
|
v_program_user_id, v_program_user_table
|
||||||
FROM user_sessions s
|
FROM user_sessions s
|
||||||
JOIN users u ON s.user_id = u.id
|
JOIN users u ON s.user_id = u.id
|
||||||
WHERE s.session_token = p_old_session_token
|
WHERE s.session_token = p_old_session_token
|
||||||
@@ -302,7 +319,9 @@ BEGIN
|
|||||||
'email', v_email,
|
'email', v_email,
|
||||||
'user_level', v_user_level,
|
'user_level', v_user_level,
|
||||||
'session_id', v_new_session_token,
|
'session_id', v_new_session_token,
|
||||||
'roles', string_to_array(COALESCE(v_roles, ''), ',')
|
'roles', string_to_array(COALESCE(v_roles, ''), ','),
|
||||||
|
'program_user_id', COALESCE(v_program_user_id, 0),
|
||||||
|
'program_user_table', COALESCE(v_program_user_table, '')
|
||||||
);
|
);
|
||||||
END;
|
END;
|
||||||
$$ LANGUAGE plpgsql;
|
$$ LANGUAGE plpgsql;
|
||||||
@@ -439,6 +458,8 @@ DECLARE
|
|||||||
v_ip_address TEXT;
|
v_ip_address TEXT;
|
||||||
v_user_agent TEXT;
|
v_user_agent TEXT;
|
||||||
v_roles_array TEXT[];
|
v_roles_array TEXT[];
|
||||||
|
v_program_user_id INTEGER;
|
||||||
|
v_program_user_table TEXT;
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Extract registration request fields
|
-- Extract registration request fields
|
||||||
v_username := p_request->>'username';
|
v_username := p_request->>'username';
|
||||||
@@ -447,6 +468,8 @@ BEGIN
|
|||||||
v_user_level := COALESCE((p_request->>'user_level')::integer, 0);
|
v_user_level := COALESCE((p_request->>'user_level')::integer, 0);
|
||||||
v_ip_address := p_request->'claims'->>'ip_address';
|
v_ip_address := p_request->'claims'->>'ip_address';
|
||||||
v_user_agent := p_request->'claims'->>'user_agent';
|
v_user_agent := p_request->'claims'->>'user_agent';
|
||||||
|
v_program_user_id := COALESCE((p_request->>'program_user_id')::integer, 0);
|
||||||
|
v_program_user_table := COALESCE(p_request->>'program_user_table', '');
|
||||||
|
|
||||||
-- Convert roles array from JSON to comma-separated string
|
-- Convert roles array from JSON to comma-separated string
|
||||||
SELECT array_to_string(ARRAY(SELECT jsonb_array_elements_text(p_request->'roles')), ',')
|
SELECT array_to_string(ARRAY(SELECT jsonb_array_elements_text(p_request->'roles')), ',')
|
||||||
@@ -485,8 +508,8 @@ BEGIN
|
|||||||
-- v_password := crypt(v_password, gen_salt('bf'));
|
-- v_password := crypt(v_password, gen_salt('bf'));
|
||||||
|
|
||||||
-- Create new user
|
-- Create new user
|
||||||
INSERT INTO users (username, email, password, user_level, roles, is_active, created_at, updated_at)
|
INSERT INTO users (username, email, password, user_level, roles, is_active, created_at, updated_at, program_user_id, program_user_table)
|
||||||
VALUES (v_username, v_email, v_password, v_user_level, v_roles, true, now(), now())
|
VALUES (v_username, v_email, v_password, v_user_level, v_roles, true, now(), now(), v_program_user_id, v_program_user_table)
|
||||||
RETURNING id INTO v_user_id;
|
RETURNING id INTO v_user_id;
|
||||||
|
|
||||||
-- Generate session token
|
-- Generate session token
|
||||||
@@ -512,7 +535,9 @@ BEGIN
|
|||||||
'email', v_email,
|
'email', v_email,
|
||||||
'user_level', v_user_level,
|
'user_level', v_user_level,
|
||||||
'roles', string_to_array(COALESCE(v_roles, ''), ','),
|
'roles', string_to_array(COALESCE(v_roles, ''), ','),
|
||||||
'session_id', v_session_token
|
'session_id', v_session_token,
|
||||||
|
'program_user_id', v_program_user_id,
|
||||||
|
'program_user_table', v_program_user_table
|
||||||
),
|
),
|
||||||
'expires_in', 86400 -- 24 hours in seconds
|
'expires_in', 86400 -- 24 hours in seconds
|
||||||
);
|
);
|
||||||
@@ -671,12 +696,16 @@ DECLARE
|
|||||||
v_user_level INTEGER;
|
v_user_level INTEGER;
|
||||||
v_roles TEXT;
|
v_roles TEXT;
|
||||||
v_expires_at TIMESTAMP;
|
v_expires_at TIMESTAMP;
|
||||||
|
v_program_user_id INTEGER;
|
||||||
|
v_program_user_table TEXT;
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Query session and user data from user_sessions table
|
-- Query session and user data from user_sessions table
|
||||||
SELECT
|
SELECT
|
||||||
s.user_id, u.username, u.email, u.user_level, u.roles, s.expires_at
|
s.user_id, u.username, u.email, u.user_level, u.roles, s.expires_at,
|
||||||
|
u.program_user_id, u.program_user_table
|
||||||
INTO
|
INTO
|
||||||
v_user_id, v_username, v_email, v_user_level, v_roles, v_expires_at
|
v_user_id, v_username, v_email, v_user_level, v_roles, v_expires_at,
|
||||||
|
v_program_user_id, v_program_user_table
|
||||||
FROM user_sessions s
|
FROM user_sessions s
|
||||||
JOIN users u ON s.user_id = u.id
|
JOIN users u ON s.user_id = u.id
|
||||||
WHERE s.session_token = p_session_token
|
WHERE s.session_token = p_session_token
|
||||||
@@ -698,7 +727,9 @@ BEGIN
|
|||||||
'email', v_email,
|
'email', v_email,
|
||||||
'user_level', v_user_level,
|
'user_level', v_user_level,
|
||||||
'session_id', p_session_token,
|
'session_id', p_session_token,
|
||||||
'roles', string_to_array(COALESCE(v_roles, ''), ',')
|
'roles', string_to_array(COALESCE(v_roles, ''), ','),
|
||||||
|
'program_user_id', COALESCE(v_program_user_id, 0),
|
||||||
|
'program_user_table', COALESCE(v_program_user_table, '')
|
||||||
);
|
);
|
||||||
END;
|
END;
|
||||||
$$ LANGUAGE plpgsql;
|
$$ LANGUAGE plpgsql;
|
||||||
@@ -815,10 +846,12 @@ DECLARE
|
|||||||
v_email TEXT;
|
v_email TEXT;
|
||||||
v_user_level INTEGER;
|
v_user_level INTEGER;
|
||||||
v_roles TEXT;
|
v_roles TEXT;
|
||||||
|
v_program_user_id INTEGER;
|
||||||
|
v_program_user_table TEXT;
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Query user data
|
-- Query user data
|
||||||
SELECT username, email, user_level, roles
|
SELECT username, email, user_level, roles, program_user_id, program_user_table
|
||||||
INTO v_username, v_email, v_user_level, v_roles
|
INTO v_username, v_email, v_user_level, v_roles, v_program_user_id, v_program_user_table
|
||||||
FROM users
|
FROM users
|
||||||
WHERE id = p_user_id
|
WHERE id = p_user_id
|
||||||
AND is_active = true;
|
AND is_active = true;
|
||||||
@@ -837,7 +870,9 @@ BEGIN
|
|||||||
'user_name', v_username,
|
'user_name', v_username,
|
||||||
'email', v_email,
|
'email', v_email,
|
||||||
'user_level', v_user_level,
|
'user_level', v_user_level,
|
||||||
'roles', string_to_array(COALESCE(v_roles, ''), ',')
|
'roles', string_to_array(COALESCE(v_roles, ''), ','),
|
||||||
|
'program_user_id', COALESCE(v_program_user_id, 0),
|
||||||
|
'program_user_table', COALESCE(v_program_user_table, '')
|
||||||
);
|
);
|
||||||
END;
|
END;
|
||||||
$$ LANGUAGE plpgsql;
|
$$ LANGUAGE plpgsql;
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ type UserContext struct {
|
|||||||
Claims map[string]any `json:"claims"`
|
Claims map[string]any `json:"claims"`
|
||||||
Meta map[string]any `json:"meta"` // Additional metadata that can hold any JSON-serializable values
|
Meta map[string]any `json:"meta"` // Additional metadata that can hold any JSON-serializable values
|
||||||
TwoFactorEnabled bool `json:"two_factor_enabled"` // Indicates if 2FA is enabled for this user
|
TwoFactorEnabled bool `json:"two_factor_enabled"` // Indicates if 2FA is enabled for this user
|
||||||
|
ProgramUserID int `json:"program_user_id"`
|
||||||
|
ProgramUserTable string `json:"program_user_table"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoginRequest contains credentials for login
|
// LoginRequest contains credentials for login
|
||||||
|
|||||||
Reference in New Issue
Block a user