Updated login to check user account status.

Merged changes with Jamie's changes from earlier this week.

git-svn-id: http://locode01.ad.dom/svn/WEBMIP/trunk@2904 248e525c-4dfb-0310-94bc-949c084e9493
This commit is contained in:
mullenm
2007-11-29 10:58:31 +00:00
parent 69c2ead1ee
commit 030c682c3a

View File

@@ -6,7 +6,7 @@ CREATE OR REPLACE PACKAGE mip_security AS
/** Perform user authentication and login /** Perform user authentication and login
An authenticated login for an expired password will result in flow to the 'Change Password' An authenticated login for an expired password will result in flow to the 'Change Password'
page. page.
%param p_uname username %param p_uname username
%param p_password password %param p_password password
%param p_session_id APEX session number %param p_session_id APEX session number
%param p_flow_page the app:page to which flow should pass on successful authentication %param p_flow_page the app:page to which flow should pass on successful authentication
@@ -19,25 +19,25 @@ CREATE OR REPLACE PACKAGE mip_security AS
/** Generate a hash from the given username and password /** Generate a hash from the given username and password
The system does not record users passwords 'in the plain', instead we The system does not record users passwords 'in the plain', instead we
recordThe resultant hash is recorded as the username 'password hash' recordThe resultant hash is recorded as the username 'password hash'
*/ */
FUNCTION get_hash(p_username IN VARCHAR2 FUNCTION get_hash(p_username IN VARCHAR2
,p_password IN VARCHAR2) RETURN VARCHAR2; ,p_password IN VARCHAR2) RETURN VARCHAR2;
/** /**
%obs private function %obs private function
*/ */
PROCEDURE valid_user2(p_username IN VARCHAR2 PROCEDURE valid_user2(p_username IN VARCHAR2
,p_password IN VARCHAR2); ,p_password IN VARCHAR2);
/** /**
%obs replaced by authenticate_user %obs replaced by authenticate_user
*/ */
FUNCTION valid_user(p_username IN VARCHAR2 FUNCTION valid_user(p_username IN VARCHAR2
,p_password IN VARCHAR2) RETURN BOOLEAN; ,p_password IN VARCHAR2) RETURN BOOLEAN;
/** Authenticates the given username and password /** Authenticates the given username and password
%return TRUE for authenticated username and password combination %return TRUE for authenticated username and password combination
%rep valid_user, valid_user2 %rep valid_user, valid_user2
*/ */
@@ -83,12 +83,13 @@ recordThe resultant hash is recorded as the username 'password hash'
,p_component_name IN apex_authorization.component_name%TYPE ,p_component_name IN apex_authorization.component_name%TYPE
,p_privilege IN apex_authorization.privilege%TYPE DEFAULT 'A') ,p_privilege IN apex_authorization.privilege%TYPE DEFAULT 'A')
RETURN BOOLEAN; RETURN BOOLEAN;
END mip_security; END mip_security;
/ /
CREATE OR REPLACE PACKAGE BODY mip_security AS CREATE OR REPLACE PACKAGE BODY mip_security AS
/* /*
returns the current status of the user returns the current status of the user
*/ */
FUNCTION get_user_status(p_username IN VARCHAR2) RETURN VARCHAR2 AS FUNCTION get_user_status(p_username IN VARCHAR2) RETURN VARCHAR2 AS
@@ -98,7 +99,7 @@ CREATE OR REPLACE PACKAGE BODY mip_security AS
INTO l_status INTO l_status
FROM parties p FROM parties p
WHERE upper(p.username) = upper(p_username); WHERE upper(p.username) = upper(p_username);
RETURN l_status; RETURN l_status;
EXCEPTION EXCEPTION
WHEN no_data_found THEN WHEN no_data_found THEN
@@ -108,9 +109,20 @@ CREATE OR REPLACE PACKAGE BODY mip_security AS
END get_user_status; END get_user_status;
-- --
/** Updates the user status
*/
PROCEDURE set_user_status(p_username IN VARCHAR2, p_status IN VARCHAR2) IS
BEGIN
UPDATE parties prty
SET prty.status = upper(p_status)
WHERE upper(prty.username) = upper(p_username);
COMMIT;
END;
/** /**
Logs the user into the system and registers with APEX. Logs the user into the system and registers with APEX.
if the user account is 'OPEN', log them in and flow to the requested page if the user account is 'OPEN', log them in and flow to the requested page
if the user account is 'EXPIRED', log them in and flow to the 'Change Password' page if the user account is 'EXPIRED', log them in and flow to the 'Change Password' page
if the user account is 'LOCKED', log the user out and flow to the 'Locked' page if the user account is 'LOCKED', log the user out and flow to the 'Locked' page
@@ -119,7 +131,30 @@ CREATE OR REPLACE PACKAGE BODY mip_security AS
,p_password IN VARCHAR2 ,p_password IN VARCHAR2
,p_session_id IN VARCHAR2 ,p_session_id IN VARCHAR2
,p_flow_page IN VARCHAR2) IS ,p_flow_page IN VARCHAR2) IS
l_password_days NUMBER;
l_password_created_on DATE;
BEGIN BEGIN
-- check that the account is still valid (password etc.).
l_password_created_on := mip_parties.get_user_password_created(p_uname, p_password);
--
l_password_days := to_date(SYSDATE,'dd/mm/rrrr') - to_date(l_password_created_on,'dd/mm/rrrr');
-- check the user's password/account has not expired
IF NOT l_password_days
< to_number(cout_system_configuration.get_configuration_item(p_parameter => 'USER_ACCOUNT_LOCK')) THEN
-- user account has expired, set the user account to locked and continue on our journey
set_user_status(p_username => p_uname
,p_status => 'LOCKED');
ELSIF NOT l_password_days
< to_number(cout_system_configuration.get_configuration_item(p_parameter => 'PASSWORD_EXPIRY_LIMIT')) THEN
-- user password has expired, set the user account to expired and continue on our journey
set_user_status(p_username => p_uname
,p_status => 'EXPIRED');
END IF;
--
--
IF get_user_status(p_uname) = 'OPEN' THEN IF get_user_status(p_uname) = 'OPEN' THEN
-- log in and flow to the requested page -- log in and flow to the requested page
wwv_flow_custom_auth_std.login(p_uname => p_uname wwv_flow_custom_auth_std.login(p_uname => p_uname
@@ -133,16 +168,16 @@ CREATE OR REPLACE PACKAGE BODY mip_security AS
,p_session_id => p_session_id ,p_session_id => p_session_id
,p_flow_page => v('APP_ID') || ':102'); ,p_flow_page => v('APP_ID') || ':102');
ELSE ELSE
-- user password has been locked. Log them off and tell them -- user password has been locked. Log them off and tell them
wwv_flow_custom_auth_std.logout(p_this_flow => v('APP_ID') wwv_flow_custom_auth_std.logout(p_this_flow => v('APP_ID')
,p_next_flow_page_sess => v('APP_ID') || ,p_next_flow_page_sess => v('APP_ID') ||
':501'); ':501');
END IF; END IF;
END login; END login;
/** Produce a 'password hash' from the given username and password /** Produce a 'password hash' from the given username and password
Uses the dbms_obfuscation_toolkit to produce the hash. Uses the dbms_obfuscation_toolkit to produce the hash.
*/ */
FUNCTION get_hash(p_username IN VARCHAR2 FUNCTION get_hash(p_username IN VARCHAR2
@@ -153,7 +188,7 @@ CREATE OR REPLACE PACKAGE BODY mip_security AS
END get_hash; END get_hash;
/** Authenticates the given username and password /** Authenticates the given username and password
%return TRUE for authenticated username and password combination %return TRUE for authenticated username and password combination
%rep valid_user, valid_user2 %rep valid_user, valid_user2
*/ */
@@ -174,6 +209,8 @@ CREATE OR REPLACE PACKAGE BODY mip_security AS
WHERE pwd.created_on = pwd.latest_pwd_date WHERE pwd.created_on = pwd.latest_pwd_date
AND pwd.password_hash = get_hash(p_username AND pwd.password_hash = get_hash(p_username
,p_password); ,p_password);
RETURN TRUE; RETURN TRUE;
EXCEPTION EXCEPTION
@@ -182,10 +219,10 @@ CREATE OR REPLACE PACKAGE BODY mip_security AS
END authenticate_user; END authenticate_user;
/** Authenticates the given p_username and p_password /** Authenticates the given p_username and p_password
Checks the {%link passwords} table for a hash value matching that produced from the Checks the {%link passwords} table for a hash value matching that produced from the
given p_username and p_password. given p_username and p_password.
%raises -20000 when unable to authenticate %raises -20000 when unable to authenticate
%obs Replaced by authenticate_user %obs Replaced by authenticate_user
*/ */
@@ -206,7 +243,7 @@ CREATE OR REPLACE PACKAGE BODY mip_security AS
WHERE pwd.created_on = pwd.latest_pwd_date WHERE pwd.created_on = pwd.latest_pwd_date
AND pwd.password_hash = get_hash(p_username AND pwd.password_hash = get_hash(p_username
,p_password); ,p_password);
EXCEPTION EXCEPTION
WHEN no_data_found THEN WHEN no_data_found THEN
raise_application_error(-20000 raise_application_error(-20000
@@ -214,7 +251,7 @@ CREATE OR REPLACE PACKAGE BODY mip_security AS
END valid_user2; END valid_user2;
/** Authenticates the given username and password /** Authenticates the given username and password
%obs Replaced by authenticate_user %obs Replaced by authenticate_user
*/ */
FUNCTION valid_user(p_username IN VARCHAR2 FUNCTION valid_user(p_username IN VARCHAR2
@@ -230,16 +267,16 @@ CREATE OR REPLACE PACKAGE BODY mip_security AS
END valid_user; END valid_user;
/** Checks for authorization to access the given component /** Checks for authorization to access the given component
%param p_app_user username %param p_app_user username
%param p_component_name name of the component to be accessed %param p_component_name name of the component to be accessed
%param p_component_type the type of component to be accessed %param p_component_type the type of component to be accessed
%param p_privilege the access privilege being sought %param p_privilege the access privilege being sought
%return TRUE if the given p_app_user is authorized %return TRUE if the given p_app_user is authorized
Checks the roles assigned to the given p_app_user to see whether they are authorized Checks the roles assigned to the given p_app_user to see whether they are authorized
to access the given component. to access the given component.
If configuration item APEX_AUTHORIZATION_DEFAULT_MODE = PUBLIC, all components If configuration item APEX_AUTHORIZATION_DEFAULT_MODE = PUBLIC, all components
are considered to be accessible to all unless specifically listed in the are considered to be accessible to all unless specifically listed in the
apex_authorization table. Otherwise, the requested access must be listed in the apex_authorization table. Otherwise, the requested access must be listed in the
@@ -252,7 +289,7 @@ CREATE OR REPLACE PACKAGE BODY mip_security AS
RETURN BOOLEAN IS RETURN BOOLEAN IS
l_access_allowed VARCHAR2(3); l_access_allowed VARCHAR2(3);
BEGIN BEGIN
-- --
-- for development purposes, assume that all components are unprotected unless they are -- for development purposes, assume that all components are unprotected unless they are
-- specifically recorded in the authorization table -- specifically recorded in the authorization table
@@ -274,8 +311,6 @@ CREATE OR REPLACE PACKAGE BODY mip_security AS
RETURN TRUE; RETURN TRUE;
END; END;
END IF; END IF;
--JP added block here due to error when no data found
BEGIN
SELECT access_allowed SELECT access_allowed
INTO l_access_allowed INTO l_access_allowed
FROM (SELECT auth.component_name FROM (SELECT auth.component_name
@@ -303,11 +338,6 @@ CREATE OR REPLACE PACKAGE BODY mip_security AS
AND auth.component_type = p_component_type AND auth.component_type = p_component_type
ORDER BY parl.rt_code) ORDER BY parl.rt_code)
WHERE rownum < 2; WHERE rownum < 2;
EXCEPTION
WHEN no_data_found THEN
-- no access if we can't find any data
RETURN FALSE;
END;
IF nvl(l_access_allowed IF nvl(l_access_allowed
,'NO') = 'YES' THEN ,'NO') = 'YES' THEN
RETURN TRUE; RETURN TRUE;
@@ -317,9 +347,9 @@ CREATE OR REPLACE PACKAGE BODY mip_security AS
END authorization; END authorization;
/** Checks for authorization to access the given page /** Checks for authorization to access the given page
Calls the authorization function to perform the check Calls the authorization function to perform the check
%param p_app_user username %param p_app_user username
%param p_page_id page number to be accessed %param p_page_id page number to be accessed
%param p_privilege the access privilege being sought %param p_privilege the access privilege being sought
@@ -338,9 +368,9 @@ CREATE OR REPLACE PACKAGE BODY mip_security AS
END page_authorization; END page_authorization;
/** Checks for authorization to access the given component /** Checks for authorization to access the given component
Calls the authorization function to perform the check Calls the authorization function to perform the check
%param p_app_user username %param p_app_user username
%param p_component_name name of the component to be accessed %param p_component_name name of the component to be accessed
%param p_privilege the access privilege being sought %param p_privilege the access privilege being sought
@@ -351,7 +381,7 @@ CREATE OR REPLACE PACKAGE BODY mip_security AS
,p_privilege IN apex_authorization.privilege%TYPE DEFAULT 'A') ,p_privilege IN apex_authorization.privilege%TYPE DEFAULT 'A')
RETURN BOOLEAN IS RETURN BOOLEAN IS
BEGIN BEGIN
RETURN authorization(p_app_user => p_app_user RETURN authorization(p_app_user => p_app_user
,p_component_name => p_component_name ,p_component_name => p_component_name
,p_component_type => 'C' ,p_component_type => 'C'
@@ -359,9 +389,9 @@ CREATE OR REPLACE PACKAGE BODY mip_security AS
END component_authorization; END component_authorization;
/** Checks for authorization to access the given page /** Checks for authorization to access the given page
Calls the authorization function to perform the check Calls the authorization function to perform the check
%param p_app_user username %param p_app_user username
%param p_component_name name of the region to be accessed %param p_component_name name of the region to be accessed
%param p_privilege the access privilege being sought %param p_privilege the access privilege being sought
@@ -372,7 +402,7 @@ CREATE OR REPLACE PACKAGE BODY mip_security AS
,p_privilege IN apex_authorization.privilege%TYPE DEFAULT 'A') ,p_privilege IN apex_authorization.privilege%TYPE DEFAULT 'A')
RETURN BOOLEAN IS RETURN BOOLEAN IS
BEGIN BEGIN
RETURN authorization(p_app_user => p_app_user RETURN authorization(p_app_user => p_app_user
,p_component_name => p_component_name ,p_component_name => p_component_name
,p_component_type => 'R' ,p_component_type => 'R'
@@ -387,7 +417,7 @@ CREATE OR REPLACE PACKAGE BODY mip_security AS
FROM parties au FROM parties au
WHERE upper(username) = upper(p_username); WHERE upper(username) = upper(p_username);
--AND upper(au.role) IN ('ADMIN', 'USER'); --AND upper(au.role) IN ('ADMIN', 'USER');
RETURN TRUE; RETURN TRUE;
EXCEPTION EXCEPTION
WHEN OTHERS THEN WHEN OTHERS THEN
@@ -402,7 +432,7 @@ CREATE OR REPLACE PACKAGE BODY mip_security AS
FROM parties au FROM parties au
WHERE upper(username) = upper(p_username); WHERE upper(username) = upper(p_username);
--AND upper(au.role) = 'ADMIN'; --AND upper(au.role) = 'ADMIN';
RETURN TRUE; RETURN TRUE;
EXCEPTION EXCEPTION
WHEN OTHERS THEN WHEN OTHERS THEN
@@ -422,7 +452,7 @@ CREATE OR REPLACE PACKAGE BODY mip_security AS
INTO l_prty_id INTO l_prty_id
FROM parties FROM parties
WHERE upper(username) = upper(p_username); WHERE upper(username) = upper(p_username);
INSERT INTO passwords INSERT INTO passwords
(prty_id (prty_id
,password_hash ,password_hash
@@ -434,18 +464,19 @@ CREATE OR REPLACE PACKAGE BODY mip_security AS
,p_password) ,p_password)
,SYSDATE ,SYSDATE
,NULL); ,NULL);
-- now we ned to update the user's status to OPEN -- now we need to update the user's status to OPEN
UPDATE parties UPDATE parties
SET status = 'OPEN' SET status = 'OPEN'
WHERE id = l_prty_id; WHERE id = l_prty_id;
EXCEPTION EXCEPTION
WHEN OTHERS THEN WHEN OTHERS THEN
raise_application_error(-20002 raise_application_error(-20002
,SQLERRM); ,SQLERRM);
END new_password; END new_password;
--
--
PROCEDURE redirect_on_expired_account(p_username IN VARCHAR2) IS PROCEDURE redirect_on_expired_account(p_username IN VARCHAR2) IS
BEGIN BEGIN
IF get_user_status(p_username) = 'EXPIRED' THEN IF get_user_status(p_username) = 'EXPIRED' THEN