CREATE OR REPLACE PACKAGE BODY caco_security IS
--
-- Constants
--
c_session_duration_hours CONSTANT NUMBER := TO_NUMBER(cout_system_configuration.get_configuration_item('SESSION_TIMEOUT'),'999.999');
--
-- Use the configuration parameter to set when the password expires following a change, if not found use 30 days as a default.
--
c_password_expiry_period CONSTANT NUMBER := NVL(cout_system_configuration.get_configuration_item('G_ACCOUNT_EXPIRE_PERIOD'),30);
--
-- Private procedural logic
--
FUNCTION scramble(p_string IN VARCHAR2) RETURN VARCHAR2 IS
--
v_return VARCHAR2(30);
--
BEGIN
--
v_return := substr(dbms_obfuscation_toolkit.md5(input => utl_raw.cast_to_raw(p_string))
,1
,30);
--
RETURN v_return;
--
END scramble;
--
-- Get User
--
FUNCTION get_user RETURN VARCHAR2 IS
BEGIN
--
RETURN g_current_user;
--
END get_user;
--
--
--
PROCEDURE get_session_data(p_client_id IN VARCHAR2 DEFAULT NULL) IS
BEGIN
--
IF g_client_id IS NULL THEN
--
IF p_client_id IS NULL THEN
--
g_client_id := wsgl.getclientid;
--
ELSE
--
g_client_id := p_client_id;
--
END IF;
--
END IF;
--
IF g_client_id IS NOT NULL THEN
--
BEGIN
SELECT user_name
,syus_id
,inte_id
,cust_id
INTO g_current_user
,g_current_syus_id
,g_current_inte_id
,g_current_cust_id
FROM sessions
WHERE client_id = g_client_id;
EXCEPTION
WHEN no_data_found THEN
--
-- the client id is invalid
--
g_current_user := NULL;
g_current_syus_id := NULL;
g_current_inte_id := NULL;
g_current_cust_id := NULL;
END;
--
END IF;
--
END;
--
--
--
PROCEDURE storeclientid(p_client_id_str IN VARCHAR2) IS
l_script_name VARCHAR2(80) := owa_util.get_cgi_env('SCRIPT_NAME');
BEGIN
--
IF substr(l_script_name
,-1
,1) = '/' THEN
l_script_name := substr(l_script_name
,1
,length(l_script_name) - 1);
END IF;
owa_util.mime_header('text/html'
,FALSE);
--
owa_cookie.send(wsgl.wsg_clientid_cookie
,p_client_id_str
,NULL
,l_script_name
,NULL);
--
owa_util.http_header_close;
--
END;
-- Check_Session: Check that the supplied client ID is valid
-- for the IP address of the client, that the
-- session is still valid, and that the client
-- ID supplied is not null.
--
FUNCTION check_session(p_client_id IN VARCHAR2) RETURN BOOLEAN IS
l_stored_ip VARCHAR2(30);
l_current_ip VARCHAR2(30);
l_check_ok BOOLEAN;
l_expires DATE;
l_debugging BOOLEAN := caco_debug.debugging;
BEGIN
--
IF p_client_id IS NOT NULL THEN
--
-- Get IP address of client
--
l_current_ip := owa_util.get_cgi_env('REMOTE_ADDR');
l_check_ok := TRUE;
--
-- Check wsgsec_sessions table for an existing session
-- with the specified ID and the current IP address
--
BEGIN
SELECT ip_address
,expires
INTO l_stored_ip
,l_expires
FROM sessions
WHERE client_id = p_client_id
AND ip_address = l_current_ip;
EXCEPTION
WHEN no_data_found THEN
BEGIN
SELECT ip_address
,expires
INTO l_stored_ip
,l_expires
FROM sessions
WHERE client_id = p_client_id;
IF NOT l_debugging THEN
caco_debug.debug_on;
END IF;
caco_debug.putline('Looked for client at ' || l_current_ip ||
' and failed. Found client at IP ' ||
l_stored_ip);
IF (NOT l_debugging)
AND caco_debug.debugging THEN
caco_debug.debug_off;
END IF;
EXCEPTION
WHEN no_data_found THEN
IF NOT l_debugging THEN
caco_debug.debug_on;
END IF;
caco_debug.putline('Looked for client at any IP and failed.');
IF (NOT l_debugging)
AND caco_debug.debugging THEN
caco_debug.debug_off;
END IF;
l_check_ok := FALSE;
l_expires := SYSDATE;
END;
END;
--
-- Check that the session has not expired
--
IF (SYSDATE > l_expires) THEN
l_check_ok := FALSE;
END IF;
--
ELSE
--
-- Supplied client ID was null, so return fail.
--
l_check_ok := FALSE;
--
END IF;
--
-- Check that the license is valid
--
IF NOT saco_licensing.check_license THEN
--
l_check_ok := FALSE;
--
END IF;
--
-- If an invalid session was found (either expired or for
-- another IP address) then delete that session.
--
IF NOT l_check_ok
AND p_client_id IS NOT NULL THEN
--
BEGIN
--
dbms_transaction.begin_discrete_transaction;
--
DELETE FROM sessions
WHERE client_id = p_client_id;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
IF NOT caco_debug.debugging THEN
caco_debug.debug_on;
caco_debug.putline(SQLERRM);
caco_debug.debug_off;
ELSE
caco_debug.putline(SQLERRM);
END IF;
END;
--
END IF;
--
RETURN l_check_ok;
--
END;
--
--
-- Generate_Client_Id: Generate a unique identifier for a new session.
--
FUNCTION generate_client_id RETURN VARCHAR2 IS
--
l_client_id VARCHAR2(240);
l_is_unique BOOLEAN := FALSE;
l_count INTEGER;
--
BEGIN
--
-- Generate a pseudo random number.
SELECT to_char(to_number(userenv('sessionid')) *
to_number(to_char(SYSDATE
,'DDDSSSS')))
INTO l_client_id
FROM sys.dual;
--
-- Check that it is unique in the session table. If it is not, increment
-- it until it is.
--
WHILE NOT l_is_unique LOOP
BEGIN
SELECT COUNT(*)
INTO l_count
FROM sessions
WHERE client_id = l_client_id;
EXCEPTION
WHEN no_data_found THEN
l_count := 0;
END;
IF l_count = 0 THEN
--
-- The ID does not already exist in session table
--
l_is_unique := TRUE;
ELSE
l_client_id := to_number(l_client_id) + 1;
END IF;
END LOOP;
RETURN l_client_id;
END;
PROCEDURE update_session_expiry(p_client_id sessions.client_id%TYPE) IS
PRAGMA AUTONOMOUS_TRANSACTION;
e_resource_busy EXCEPTION;
PRAGMA EXCEPTION_INIT(e_resource_busy
,-54);
l_dummy sessions.client_id%TYPE;
BEGIN
SELECT client_id
INTO l_dummy
FROM sessions
WHERE client_id = p_client_id
FOR UPDATE NOWAIT;
UPDATE sessions
SET expires = SYSDATE + (c_session_duration_hours / 24)
WHERE client_id = p_client_id;
COMMIT;
EXCEPTION
WHEN e_resource_busy THEN
--
-- Unable to lock the client session, must be another update occurring
COMMIT;
END update_session_expiry;
--
--
-- Security_Check: Returns true if the currently logged on user is
-- allowed access to the specified package. If not,
-- will return false. This function will also provide
-- a means for the user to log on.
--
FUNCTION security_check(p_package_name IN VARCHAR2) RETURN BOOLEAN IS
--
l_client_id VARCHAR2(240);
l_username VARCHAR2(30);
l_rows INTEGER := 0;
--
BEGIN
--
-- Get the current client ID
--
l_client_id := wsgl.getclientid;
--
IF l_client_id IS NOT NULL THEN
--
-- Call check_session to ensure current session
-- is valid
--
IF check_session(l_client_id) THEN
--
-- Update the session table to set the expiry date to SYSDATE + session duration
--
update_session_expiry(l_client_id);
--
-- Get user name
--
get_session_data(l_client_id);
--
-- Check that the current user has a responsibility
-- that allows it to access the specified package name
--
IF lower(p_package_name) = 'home' THEN
--
l_rows := 1;
--
ELSE
--
BEGIN
--
SELECT COUNT(*)
INTO l_rows
FROM user_profiles uspr
,profile_options prop
,system_options syop
WHERE uspr.syus_id = g_current_syus_id
AND uspr.sypr_id = prop.sypr_id
AND syop.syop_id = prop.syop_id
AND syop.module_name IS NOT NULL
AND upper(substr(syop.module_name
,1
,decode(instr(syop.module_name
,'$')
,0
,length(syop.module_name)
,instr(syop.module_name
,'$')))) =
upper(substr(p_package_name
,1
,decode(instr(p_package_name
,'$')
,0
,length(p_package_name)
,instr(p_package_name
,'$'))));
--
EXCEPTION
WHEN no_data_found THEN
l_rows := 0;
END;
--
END IF;
--
ELSE
--
-- No valid session was found, so display a
-- logon form.
--
IF saco_licensing.check_license
AND saco_licensing.check_users THEN
--
IF lower(p_package_name) = 'home' THEN
--
show_logon_form(p_embedded => TRUE);
--
ELSE
--
show_logon_form(p_embedded => FALSE);
--
END IF;
--
END IF;
--
RETURN FALSE;
--
END IF;
--
IF l_rows != 0 THEN
--
-- User is logged on and has permission to access
-- the specified package.
--
RETURN TRUE;
--
ELSE
--
-- User is logged on but does not have permission
-- to access the specified package
--
show_no_access;
RETURN FALSE;
--
END IF;
--
ELSE
--
-- No current client ID, so display logon form.
--
IF lower(p_package_name) = 'home' THEN
--
show_logon_form(p_embedded => TRUE);
--
ELSE
--
show_logon_form(p_embedded => FALSE);
--
END IF;
--
RETURN FALSE;
--
END IF;
--
END;
--
-- allow_username_login: allows the user to login using a username or password
--
FUNCTION allow_username_login RETURN BOOLEAN IS
--
l_return BOOLEAN := FALSE;
--
BEGIN
--
IF cout_system_configuration.get_configuration_item('G_ALLOW_USERNAME_LOGIN') = 'Y' THEN
--
l_return := TRUE;
--
END IF;
--
RETURN l_return;
--
END allow_username_login;
--
-- Show_Logon_Form: Renders logon form
--
PROCEDURE show_logon_form(p_embedded IN BOOLEAN
,h_href IN VARCHAR2 DEFAULT NULL) IS
BEGIN
--
IF saco_licensing.check_license
AND saco_licensing.check_users THEN
--
IF NOT p_embedded THEN
--
owa_util.mime_header('text/html'
,FALSE);
htp.p('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
owa_util.http_header_close;
--
htp.p('');
--
htp.headopen;
--
htp.title(wsgl.msggettext(605
,wsglm.sec605_logon_caption));
--
caco_system.content_type;
htp.linkrel('stylesheet'
,'caco_system.css?p_type=general');
--
-- Display the standard menu
--
htp.print(caco_system.menu);
--
htp.headclose;
--
END IF;
--
-- Output JavaScript for handling onLoad event for setting
-- the focus to the username field upon invocation.
--
htp.bodyopen(cattributes => 'onLoad="return Logon_OnLoad()"');
htp.p('');
htp.formopen(curl => 'caco_security.process_logon'
,ctarget => ''
,cmethod => 'POST'
,cattributes => 'NAME="Logonform"');
--
-- Hidden field to store the calling URL
--
htp.formHidden(cname => 'h_href', cvalue => h_href);
--
--
htp.p('
E.ON Földgáz Trade Zrt
');
--
IF allow_username_login THEN
--
htp.p('
Please log in here
');
--
END IF;
--
htp.p('
');
--
htp.formclose;
--
IF NOT p_embedded THEN
caco_system.footer(p_closebody => TRUE);
END IF;
--
END IF;
--
END;
--
PROCEDURE online_user_registration ( p_register_title IN VARCHAR2 DEFAULT NULL
, p_register_first_name IN VARCHAR2 DEFAULT NULL
, p_register_surname IN VARCHAR2 DEFAULT NULL
, p_register_company IN VARCHAR2 DEFAULT NULL
, p_register_email IN VARCHAR2 DEFAULT NULL
, p_register_phone IN VARCHAR2 DEFAULT NULL
, p_register_submit IN VARCHAR2 DEFAULT NULL
) IS
--
l_email_body VARCHAR2(4000);
--
BEGIN
--
-- Output the standard pages headings
--
htp.p('');
htp.p('
');
--
htp.p('');
htp.comment(ctext => 'Copyright 2009 GL Industrial Services');
htp.p('E.ON Földgáz Trade Zrt - User Registration');
htp.p(' ');
htp.p('');
htp.p('
');
htp.p('
');
--
-- Now output the content
--
IF p_register_submit IS NULL THEN
--
htp.formopen(curl => 'caco_security.online_user_registration'
,ctarget => ''
,cmethod => 'POST'
,cattributes => ' onsubmit="return validate_form(this.form);"');
--
END IF;
--
htp.p('
User Registration
');
--
htp.p('
');
--
IF p_register_submit IS NULL THEN
--
-- Personal Identification
--
htp.p('
');
--
END online_user_registration;
--
-- Process_Logon: Accepts submitted logon form and logs user on. If logon
-- fails then notifies user.
--
PROCEDURE process_logon(p_username IN VARCHAR2 DEFAULT NULL
,p_password IN VARCHAR2 DEFAULT NULL
,h_href IN VARCHAR2 DEFAULT NULL
,p_login_button IN VARCHAR2 DEFAULT NULL
) IS
--
l_client_id VARCHAR2(240);
l_success BOOLEAN := FALSE;
l_invalid_password BOOLEAN := FALSE;
l_current_ip VARCHAR2(30);
--
v_message VARCHAR2(2000);
--
CURSOR cur_syus(p_username IN system_users.db_username%TYPE) IS
SELECT syus.syus_id
,syus.cust_id
,syus.inte_id
,syus.password_expires
,syus.grace_logins
,nvl(syus.user_locked
,'N') user_locked
,syus.period_start
,syus.period_end
,NVL(syus.failed_login_attempts,0) failed_login_attempts
,syus.password
FROM system_users syus
WHERE syus.db_username = p_username;
--
r_syus_rec cur_syus%ROWTYPE;
--
BEGIN
--
-- If the request is a login request
--
IF p_login_button = 'Login' THEN
--
-- Retrieve details from system users for the passed username and password
--
IF p_username IS NOT NULL THEN
--
OPEN cur_syus(p_username);
FETCH cur_syus
INTO r_syus_rec;
IF cur_syus%FOUND
THEN
IF scramble(p_username || '/' || p_password) <> r_syus_rec.password
THEN
l_invalid_password := TRUE;
END IF;
END IF;
CLOSE cur_syus;
--
-- Get current client ID
--
l_client_id := wsgl.getclientid;
--
END IF;
--
-- If username/password valid
--
IF r_syus_rec.syus_id IS NOT NULL
AND r_syus_rec.user_locked <> 'Y'
AND saco_licensing.check_users
AND saco_licensing.check_license
AND SYSDATE >= r_syus_rec.period_start -- user validity period
AND SYSDATE < (TRUNC(NVL(r_syus_rec.period_end,SYSDATE)) + 1 - (1/86400)) -- HH24:MI:SS = 23:59:59
AND p_username IS NOT NULL
AND allow_username_login
AND NOT l_invalid_password
THEN
--
-- Check that current client ID is valid
--
IF l_client_id IS NOT NULL
AND check_session(l_client_id) THEN
--
-- Update the session table for this client with
-- the new user
--
dbms_transaction.begin_discrete_transaction;
--
UPDATE sessions
SET user_name = p_username
WHERE client_id = l_client_id;
--
COMMIT;
--
l_success := TRUE;
--
ELSE
--
-- Current client ID is not valid so create a new one
--
l_client_id := generate_client_id;
--
-- Write to browser as a cookie
--
storeclientid(l_client_id);
--
-- Get current IP address
--
l_current_ip := NVL(owa_util.get_cgi_env('REMOTE_ADDR'), '127.0.0.1');
--
-- Create new session in session table
--
dbms_transaction.begin_discrete_transaction;
--
INSERT INTO sessions
(client_id
,user_name
,syus_id
,cust_id
,inte_id
,ip_address
,expires)
VALUES
(l_client_id
,p_username
,r_syus_rec.syus_id
,r_syus_rec.cust_id
,r_syus_rec.inte_id
,l_current_ip
,SYSDATE + (c_session_duration_hours / 24));
--
COMMIT;
--
l_success := TRUE;
--
END IF;
--
UPDATE system_users syus
SET syus.failed_login_attempts = 0
WHERE syus.syus_id = r_syus_rec.syus_id;
--
--
-- User can connect, but check to see if account is nearing expiry
--
IF r_syus_rec.password_expires IS NOT NULL THEN
IF r_syus_rec.password_expires <= SYSDATE THEN
--
IF r_syus_rec.grace_logins = 0 THEN
--
r_syus_rec.user_locked := 'Y';
--
UPDATE system_users syus
SET syus.user_locked = r_syus_rec.user_locked
WHERE syus.syus_id = r_syus_rec.syus_id;
--
l_success := FALSE;
v_message := caco_utilities.get_module_text(1000);
--
ELSIF r_syus_rec.grace_logins = 1 THEN
--
-- password has expired with no grace logins remaining
--
UPDATE system_users syus
SET syus.grace_logins = 0
WHERE syus.syus_id = r_syus_rec.syus_id;
--
v_message := caco_utilities.get_module_text(1001);
--
ELSE
--
-- Password expired, update grace logins
--
UPDATE system_users syus
SET syus.grace_logins = nvl(grace_logins
,3) - 1
WHERE syus.syus_id = r_syus_rec.syus_id;
--
v_message := wsgl.msggettext(p_msgno => NULL
,p_dflttext => caco_utilities.get_module_text(1003)
,p_subst1 => nvl(r_syus_rec.grace_logins
,3) - 1);
--
END IF;
--
ELSIF trunc(r_syus_rec.password_expires) - trunc(SYSDATE) <= 5 THEN
--
v_message := wsgl.msggettext(p_msgno => NULL
,p_dflttext => caco_utilities.get_module_text(1004)
,p_subst1 => trunc(r_syus_rec.password_expires) -
trunc(SYSDATE));
--
END IF;
--
END IF;
--
ELSE
--
-- Invalid username / password
--
IF NOT allow_username_login THEN
--
v_message := caco_utilities.get_module_text(3930); -- username authentication has been disabled.
--
ELSIF l_invalid_password
AND r_syus_rec.syus_id IS NOT NULL
AND NVL(r_syus_rec.user_locked,'N') <> 'Y'
THEN
--
r_syus_rec.failed_login_attempts := NVL(r_syus_rec.failed_login_attempts,0) + 1;
IF r_syus_rec.failed_login_attempts >= C_password_max_tries
THEN
r_syus_rec.user_locked := 'Y';
v_message := caco_utilities.get_module_text(3966);
ELSE
v_message := REPLACE(caco_utilities.get_module_text(3965),'',TO_CHAR((C_password_max_tries - r_syus_rec.failed_login_attempts)));
END IF;
--
UPDATE system_users syus
SET syus.failed_login_attempts = r_syus_rec.failed_login_attempts
, syus.user_locked = r_syus_rec.user_locked
WHERE syus.syus_id = r_syus_rec.syus_id;
--
ELSIF r_syus_rec.syus_id IS NULL THEN
--
v_message := wsgl.msggettext(608
,wsglm.sec608_invalid_logon);
--
ELSIF r_syus_rec.user_locked = 'Y' THEN
--
v_message := caco_utilities.get_module_text(1000);
--
ELSIF NOT saco_licensing.check_users THEN
--
v_message := 'Number of concurrent users exceeded, please try again later.';
--
ELSIF NOT saco_licensing.check_license THEN
--
v_message := 'License is not valid - please contact your system administrator.';
--
ELSIF SYSDATE < r_syus_rec.period_start -- user validity period
OR SYSDATE > (TRUNC(NVL(r_syus_rec.period_end,SYSDATE)) + 1 - (1/86400)) -- HH24:MI:SS = 23:59:59
THEN
-- The user has expired. Please contact your system administrator
v_message := caco_utilities.get_module_text(2518);
--
END IF;
--
-- EFT request to log failed logons
amfr_journal.log_transaction( 'FAILED LOGIN'
, caco_utilities.get_system_name
, name_value_tab(
name_value_rec('USERNAME', p_username )
, name_value_rec('CLIENT_ID', l_client_id )
, name_value_rec('REMOTE_IP', owa_util.get_cgi_env('REMOTE_ADDR') )
, name_value_rec('MESSAGE', v_message )
)
, amfr_journal.g_name_value_tab
);
--
IF l_client_id IS NOT NULL THEN
--
-- Invalid logon so delete the session for the current client.
--
dbms_transaction.begin_discrete_transaction;
--
DELETE FROM sessions
WHERE client_id = l_client_id;
--
COMMIT;
--
END IF;
--
END IF;
--
-- Output HTML to indicate success or failure
--
htp.htmlopen;
--
IF l_success THEN
--
-- Audit the logon action, if enabled
--
IF cout_system_configuration.get_configuration_item('AUDIT_LOGON') = 'Y' THEN
--
-- Populate the global variables for use with other packages
--
caco_security.g_client_id := l_client_id;
--
amfr_journal.log_transaction('LOGON'
,caco_utilities.get_system_name
,amfr_journal.g_name_value_tab
,amfr_journal.g_name_value_tab);
--
END IF;
--
-- Close the login box and navigate back to the application
--
IF v_message IS NOT NULL THEN
--
caco_system.content_type;
htp.linkrel('stylesheet'
,'caco_system.css');
--
-- Display the standard menu
--
htp.print(caco_system.menu);
htp.bodyopen;
htp.header(2
,wsgl.msggettext(606
,wsglm.sec606_logon_success));
--
htp.header(4
,v_message);
htp.tabledata(htf.formsubmit(cname => 'p_button'
,cvalue => caco_utilities.get_module_text(992)
,cattributes => 'onclick="location.href = ''caco_security.change_password'';"') ||
' ' ||
htf.formsubmit(cname => 'p_button'
,cvalue => caco_utilities.get_module_text(993)
,cattributes => 'onclick="location.href = ''home'';"'));
--
ELSE
--
htp.bodyopen;
--
IF h_href IS NULL
OR UPPER(h_href) LIKE '%/HOME?%' THEN
--
htp.script('');
--
ELSE
--
htp.script('');
--
END IF;
--
END IF;
--
ELSE
--
-- Display failure message
--
caco_system.content_type;
htp.linkrel('stylesheet'
,'caco_system.eon_css');
--
-- Display the standard menu
--
htp.p('
');
htp.p('');
htp.p('E.ON Földgáz Trade Zrt - Login
');
htp.p(' ');
htp.p('
');
--
END IF;
--
htp.bodyclose;
htp.htmlclose;
--
ELSIF p_login_button = 'Register' THEN
--
-- Show the user registration page
--
online_user_registration;
--
END IF;
--
END process_logon;
--
-- Process_Logon: Overloaded version for client certificate
--
PROCEDURE process_certificate_logon IS
--
l_client_id VARCHAR2(240);
l_success BOOLEAN := FALSE;
l_current_ip VARCHAR2(30);
--
l_client_certificate VARCHAR2(4000) := SUBSTR(owa_util.get_cgi_env('SSL_CLIENT_CERT'),1,4000);
l_client_cert_serial VARCHAR2(4000) := SUBSTR(owa_util.get_cgi_env('SSL_CLIENT_M_SERIAL'),1,4000);
l_client_cert_start VARCHAR2(4000) := SUBSTR(owa_util.get_cgi_env('SSL_CLIENT_V_START'),1,4000);
l_client_cert_end VARCHAR2(4000) := SUBSTR(owa_util.get_cgi_env('SSL_CLIENT_V_END'),1,4000);
l_client_cert_verify VARCHAR2(4000) := SUBSTR(owa_util.get_cgi_env('SSL_CLIENT_VERIFY'),1,4000);
--
BEGIN
--
IF l_client_certificate IS NOT NULL
AND l_client_cert_serial IS NOT NULL THEN
--
-- Client certificate has been presented, let's check it
--
IF l_client_cert_verify = 'SUCCESS' THEN
--
-- Certificate is valid, check the date range
--
IF SYSDATE BETWEEN TO_DATE(SUBSTR(l_client_cert_start,1,20),'Mon DD HH24:MI:SS YYYY') AND TO_DATE(SUBSTR(l_client_cert_end,1,20),'Mon DD HH24:MI:SS YYYY') THEN
--
-- Change the serial number into a recognised format
--
l_client_cert_serial := SUBSTR(l_client_cert_serial,3,2)||':'||SUBSTR(l_client_cert_serial,5,2)||':'||SUBSTR(l_client_cert_serial,7,2)||':'||SUBSTR(l_client_cert_serial,9,2)||':'||SUBSTR(l_client_cert_serial,11,2)||':'||SUBSTR(l_client_cert_serial,13,2);
--
-- Check to see if this certificate is linked to an active user
--
FOR rec IN (SELECT su.syus_id
,su.db_username
,su.inte_id
,su.cust_id
FROM system_users su
WHERE su.certificate_serial = l_client_cert_serial
AND SYSDATE BETWEEN period_start AND NVL(period_end, SYSDATE)
AND user_locked = 'N'
) LOOP
--
l_client_id := wsgl.getclientid;
--
IF l_client_id IS NOT NULL
AND check_session(l_client_id) THEN
--
-- Update the session table for this client with
-- the new user
--
dbms_transaction.begin_discrete_transaction;
--
UPDATE sessions
SET user_name = rec.db_username
WHERE client_id = l_client_id;
--
COMMIT;
--
l_success := TRUE;
--
ELSE
--
-- Current client ID is not valid so create a new one
--
l_client_id := generate_client_id;
--
-- Write to browser as a cookie
--
storeclientid(l_client_id);
--
-- Get current IP address
--
l_current_ip := NVL(owa_util.get_cgi_env('REMOTE_ADDR'), '127.0.0.1');
--
-- Create new session in session table
--
dbms_transaction.begin_discrete_transaction;
--
INSERT INTO sessions
(client_id
,user_name
,syus_id
,cust_id
,inte_id
,ip_address
,expires)
VALUES
(l_client_id
,rec.db_username
,rec.syus_id
,rec.cust_id
,rec.inte_id
,l_current_ip
,SYSDATE + (c_session_duration_hours / 24));
--
COMMIT;
--
l_success := TRUE;
get_session_data(l_client_id);
--
END IF;
--
END LOOP;
--
ELSE
--
-- Current date falls outside valid range, should never happen as AS should catch this
--
htp.p('Client certificate is not valid at this time. Date from '||l_client_cert_start||' to '||l_client_cert_end);
--
END IF;
--
ELSE
--
-- Client certificate isn't valid - should put out a message, just print out for the moment
--
htp.p('Client certificate is not valid, status is: '||l_client_cert_verify);
--
END IF;
--
-- Journal this request
--
amfr_journal.log_transaction( 'INSERT'
, 'Certificate Login'
, name_value_tab(
name_value_rec('Serial Number', l_client_cert_serial )
)
, amfr_journal.g_name_value_tab
);
--
END IF;
--
END process_certificate_logon;
--
-- Show_No_Access: Displays message to inform user that they do not
-- have access to the application. Provides a link
-- to the logon form.
--
PROCEDURE show_no_access IS
BEGIN
htp.htmlopen;
--
caco_system.content_type;
htp.linkrel('stylesheet'
,'caco_system.css?p_type=logon');
--
htp.headopen;
htp.title('Access Denied');
htp.headclose;
htp.bodyopen;
htp.script('
function show_logon() {
frmLogon = open("caco_security.show_logon_form","winLogon","scrollbars=no,resizable=yes,width=400,height=300");
if (frmLogon.opener == null) {
frmLogon.opener = self;
};
};');
htp.header(2
,wsgl.msggettext(609
,wsglm.sec609_access_denied));
htp.header(4
,wsgl.msggettext(610
,wsglm.sec610_no_permission));
htp.hr;
htp.p('');
htp.p('');
htp.bodyclose;
htp.htmlclose;
END;
--
--
-- Call_Logon_Form: Outputs javascript to popup logon form in new window,
-- or include logon form in current window if javascript
-- is not available.
--
PROCEDURE call_logon_form IS
BEGIN
--
IF saco_licensing.check_license
AND saco_licensing.check_users THEN
--
htp.htmlopen;
--
caco_system.content_type;
htp.linkrel('stylesheet'
,'caco_system.css?p_type=general');
--
htp.bodyopen;
--
htp.script('
');
htp.p('');
--
htp.bodyclose;
htp.htmlclose;
--
END IF;
--
END;
--
--
-- Add_Package_Resp: Adds a respondibility to a package, allowing users
-- with that responsibility to access the application.
-- This is called from the generated application
-- installation script if a value is supplied for
-- preference SECRES.
--
PROCEDURE add_package_resp(p_package_name IN VARCHAR2
,p_responsibility IN VARCHAR2) IS
l_rows INTEGER := 0;
l_syop_id NUMBER;
l_sypr_id NUMBER;
v_exists BOOLEAN;
v_module_to_add system_options.module_name%TYPE;
v_syop_id system_options.syop_id%TYPE;
v_sypr_id system_profiles.sypr_id%TYPE;
FUNCTION get_syop_id(p_module_name IN system_options.module_name%TYPE)
RETURN system_options.syop_id%TYPE IS
v_syop_id system_options.syop_id%TYPE;
BEGIN
v_syop_id := NULL;
FOR v_syop_rec IN (SELECT syop_id
FROM system_options syop
WHERE lower(syop.module_name) =
lower(p_module_name)) LOOP
v_syop_id := v_syop_rec.syop_id;
END LOOP;
IF v_syop_id IS NULL THEN
--
-- this module does not currently exist
--
INSERT INTO system_options
(option_type
,description
,NAME
,module_name)
VALUES
('S'
,'Generated ' || to_char(SYSDATE
,'dd-mon-yy hh24:mi:ss')
,substr(lower(p_module_name)
,1
,40)
,substr(p_module_name
,1
,255))
RETURNING syop_id INTO v_syop_id;
END IF;
RETURN v_syop_id;
END get_syop_id;
FUNCTION get_sypr_id(p_name IN system_profiles.NAME%TYPE)
RETURN system_profiles.sypr_id%TYPE IS
v_sypr_id system_profiles.sypr_id%TYPE;
BEGIN
v_sypr_id := NULL;
FOR v_sypr_rec IN (SELECT sypr_id
FROM system_profiles sypr
WHERE upper(sypr.NAME) = upper(p_name)) LOOP
v_sypr_id := v_sypr_rec.sypr_id;
END LOOP;
IF v_sypr_id IS NULL THEN
--
-- this role does not currently exist
--
INSERT INTO system_profiles
(NAME
,description
,role_name)
VALUES
(p_name
,'Generated ' || to_char(SYSDATE
,'dd-mon-yy hh24:mi:ss') || ' ' ||
p_name
,p_name)
RETURNING sypr_id INTO v_sypr_id;
END IF;
RETURN v_sypr_id;
END get_sypr_id;
BEGIN
--
-- get the role and the option ids
--
v_sypr_id := get_sypr_id(p_responsibility);
--
IF instr(p_package_name
,'$') > 0 THEN
--
v_module_to_add := lower(substr(p_package_name
,1
,instr(p_package_name
,'$'))) || '.startup';
--
ELSE
--
v_module_to_add := p_package_name;
--
END IF;
--
v_syop_id := get_syop_id(v_module_to_add);
v_exists := FALSE;
--
FOR v_package_installed IN (SELECT 1
FROM profile_options
WHERE sypr_id = v_sypr_id
AND syop_id = v_syop_id) LOOP
v_exists := TRUE;
END LOOP;
IF NOT v_exists THEN
INSERT INTO profile_options
(sypr_id
,syop_id)
VALUES
(v_sypr_id
,v_syop_id);
END IF;
END add_package_resp;
--
PROCEDURE logout AS
l_client_id VARCHAR2(240);
l_script_name VARCHAR2(80) := owa_util.get_cgi_env('SCRIPT_NAME');
BEGIN
-- Send a redirect to a public home page
htp.p('Location: ' || caco_system.home_path);
-- Send a cookie to indicate that that you want to logout
owa_cookie.send(NAME => 'WDB_GATEWAY_LOGOUT'
,VALUE => 'YES'
,path => '/');
IF substr(l_script_name
,-1
,1) = '/' THEN
l_script_name := substr(l_script_name
,1
,length(l_script_name) - 1);
END IF;
-- send a cookie to set the clientid to null
owa_cookie.send(NAME => wsgl.wsg_clientid_cookie
,VALUE => NULL
,path => l_script_name);
--
-- Close the http header
--
htp.p;
--
-- Get current client ID
--
l_client_id := wsgl.getclientid;
IF l_client_id IS NOT NULL THEN
--
-- Delete session for this client
--
dbms_transaction.begin_discrete_transaction;
--
IF cout_system_configuration.get_configuration_item('AUDIT_LOGOFF') = 'Y' THEN
--
-- Populate the global variables for use with other packages
--
amfr_journal.log_transaction('LOGOFF'
,caco_utilities.get_system_name
,amfr_journal.g_name_value_tab
,amfr_journal.g_name_value_tab);
--
END IF;
--
DELETE FROM sessions
WHERE client_id = l_client_id;
COMMIT;
END IF;
END;
--
-- Logoff: Removes the current user's session, logging them off. Outputs
-- HTML message when complete.
--
PROCEDURE logoff IS
l_client_id VARCHAR2(240);
BEGIN
htp.htmlopen;
--
caco_system.content_type;
htp.linkrel('stylesheet'
,'caco_system.css?p_type=logon');
--
htp.headopen;
htp.title(wsgl.msggettext(611
,wsglm.sec611_logging_off));
htp.headclose;
htp.bodyopen;
--
-- Get current client ID
--
l_client_id := wsgl.getclientid;
IF l_client_id IS NOT NULL THEN
--
-- Delete session for this client
--
dbms_transaction.begin_discrete_transaction;
--
IF cout_system_configuration.get_configuration_item('AUDIT_LOGOFF') = 'Y' THEN
--
-- Populate the global variables for use with other packages
--
amfr_journal.log_transaction('LOGOFF'
,caco_utilities.get_system_name
,amfr_journal.g_name_value_tab
,amfr_journal.g_name_value_tab);
--
END IF;
--
DELETE FROM sessions
WHERE client_id = l_client_id;
--
COMMIT;
--
END IF;
htp.header(2
,wsgl.msggettext(612
,wsglm.sec612_logged_off));
htp.bodyclose;
htp.htmlclose;
END;
--
---
-- S E T C U R R E N T I N T E C U S T
---
PROCEDURE set_current_inte_cust(p_inte_id IN intermediaries.inte_id%TYPE
,p_cust_id IN customers.cust_id%TYPE) IS
--
CURSOR cur_cust_inte(p_syus_id IN system_users.syus_id%TYPE, p_inte_id IN intermediaries.inte_id%TYPE, p_cust_id IN customers.cust_id%TYPE) IS
SELECT NULL
FROM intermediary_users inus
,customer_intermediaries cuin
WHERE cuin.inte_id = inus.inte_id
AND cuin.cust_id = p_cust_id
AND cuin.inte_id = p_inte_id
AND inus.syus_id = p_syus_id;
--
v_dummy VARCHAR2(10);
--
BEGIN
--
caco_utilities.get_user_data;
--
FOR v_cust_inte IN (SELECT NULL
FROM intermediary_users inus
,customer_intermediaries cuin
WHERE cuin.inte_id = inus.inte_id
AND cuin.cust_id = p_cust_id
AND cuin.inte_id = p_inte_id
AND inus.syus_id =
caco_security.g_current_syus_id) LOOP
--
UPDATE sessions sess
SET sess.cust_id = p_cust_id
,sess.inte_id = nvl(p_inte_id
,sess.inte_id)
WHERE sess.client_id = caco_security.g_client_id;
--
caco_utilities.get_user_data(TRUE);
--
END LOOP;
--
END set_current_inte_cust;
---
-- C H A N G E C U S T I N T E
---
PROCEDURE change_cust_inte(p_inte_id IN intermediaries.inte_id%TYPE DEFAULT NULL
,p_cust_id IN customers.cust_id%TYPE DEFAULT NULL
,p_savebtn IN VARCHAR2 DEFAULT NULL
,p_cancbtn IN VARCHAR2 DEFAULT NULL
,p_message IN VARCHAR2 DEFAULT NULL) IS
--
CURSOR cur_inte IS
SELECT inte.inte_id
,inte.NAME
FROM intermediaries inte
,intermediary_users inus
WHERE inte.inte_id = inus.inte_id
AND inus.syus_id = caco_utilities.get_syus_id
ORDER BY inte.NAME;
--
CURSOR cur_cust(p_inte_id IN intermediaries.inte_id%TYPE DEFAULT NULL) IS
SELECT cust.cust_id
,cust.NAME
FROM customers cust
,customer_intermediaries cuin
,intermediary_users inus
WHERE cuin.inte_id = inus.inte_id
AND cust.cust_id = cuin.cust_id
AND inus.syus_id = caco_utilities.get_syus_id
AND (cuin.inte_id = p_inte_id OR p_inte_id IS NULL)
GROUP BY cust.cust_id
,cust.NAME
ORDER BY cust.NAME;
--
v_array_string VARCHAR2(2000);
v_first_inte_id NUMBER;
v_first BOOLEAN;
--
BEGIN
--
IF NOT caco_security.security_check('caco_security.change_cust_inte') THEN
--
RETURN;
--
END IF;
--
IF p_savebtn IS NULL
AND p_cancbtn IS NULL THEN
--
-- Draw screen
--
htp.htmlopen;
caco_System.content_type;
htp.linkrel('stylesheet'
,'caco_system.css?p_type=general');
--
htp.bodyopen;
htp.p(caco_system.menu);
htp.p(caco_system.statusbar);
htp.bodyclose;
--
htp.p('');
--
htp.title(caco_utilities.get_module_text(3540));
--
htp.header(1
,caco_utilities.get_module_text(3540));
--
htp.bodyopen;
--
IF p_message IS NOT NULL THEN
--
htp.p(htf.italic(p_message));
--
END IF;
--
htp.formopen(curl => 'caco_security.change_cust_inte'
,cmethod => 'POST'
,cattributes => 'NAME="custinte"');
--
htp.tableopen(cborder => '0');
--
htp.tablerowopen;
--
htp.tabledata(calign => 'LEFT'
,cattributes => 'WIDTH="25%"'
,cvalue => htf.bold(caco_utilities.get_module_text(3541)||': '));
--
htp.p('
');
--
htp.formselectopen(cname => 'p_inte_id'
,cattributes => 'onChange="populateCustomer(document.custinte,document.custinte.p_inte_id.options[document.custinte.p_inte_id.selectedIndex].value)"');
--
v_first := TRUE;
--
FOR cur_inte_rec IN cur_inte LOOP
--
htp.formselectoption(cur_inte_rec.NAME
,NULL
,cattributes => 'VALUE="' ||
to_char(cur_inte_rec.inte_id) || '"');
--
IF v_first THEN
--
-- Get the first inte put into the poplist in order to sync the customers
--
v_first_inte_id := cur_inte_rec.inte_id;
v_first := FALSE;
--
END IF;
--
END LOOP;
--
htp.formselectclose;
htp.p('