USE [Elyse_DB] GO /****** Object: StoredProcedure [internal].[usp_AUTHENTICATE_doc_grp_ed_pm] Script Date: Fri 02-10-2026 8:29:40 PM ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- ============================================= -- Author: Silkwood Software -- Create date: 18-12-2023 -- Description: Checks whether the connected user has edit permission -- for a given document group. -- Also returns fail if the id does not exist. -- Input is a the id of the document group to be checked. -- Output is a status string of 'Pass' or 'Fail'. /* COPYRIGHT NOTICE This database schema and stored procedures are protected by copyright. Copyright. Silkwood Software Pty. Ltd. 2023 */ -- =============================================== CREATE PROCEDURE [internal].[usp_AUTHENTICATE_doc_grp_ed_pm] @doc_grp_to_check_ep bigint = NULL, @user_authentication_reslt_dgep nvarchar(10) OUTPUT AS BEGIN -- SET NOCOUNT ON added to prevent extra result sets from -- interfering with SELECT statements. SET NOCOUNT ON; DECLARE @usersid varbinary(100) = NULL, -- The SID of the connected user @sid_id bigint = NULL, @failure_type nvarchar(1000) = NULL, @now datetime2(7) = SYSDATETIME(), @privilege_name nvarchar(50) = '', @user_authentication_reslt_dgep_udg nvarchar(10) = ''; SET @user_authentication_reslt_dgep = 'Fail'; SET @usersid = SUSER_SID(ORIGINAL_LOGIN()); -- Read the SID of the connected user SELECT @sid_id = sid_id FROM user_restr.sid_list WHERE sid = @usersid; SET @privilege_name = (SELECT attr_name FROM xref.doc_group_names WHERE doc_group_id = @doc_grp_to_check_ep) -- To have edit permission for a document the user must first have view permission for that document -- Edit permissions work differently from view permissions. With view permissions a document -- is viewable by default. With edit permissions the document is restricted by default. -- A user has edit permission for a document if there is a chain from the document ID through -- either a function list or a people list to a sid in the sid list which is the sid for the user. -- Check if the user has view permission for the document group. EXEC [internal].[usp_AUTHENTICATE_user_doc_grp] @docgroupid_to_check_vp = @doc_grp_to_check_ep, @user_authentication_result = @user_authentication_reslt_dgep_udg OUTPUT SET @user_authentication_reslt_dgep = @user_authentication_reslt_dgep_udg; -- Check if the user is linked to the document group through either a function list or a people list IF @user_authentication_reslt_dgep = 'Pass' AND (EXISTS (SELECT df.function_id AS dfid FROM xref.doc_group_names AS dgn LEFT JOIN user_restr.doc_group_edit_perm_funct_lst AS dgepfl -- Check for membership of a duty function list ON dgn.doc_group_id = dgepfl.doc_group_id LEFT JOIN people.function_list_names AS fln ON dgepfl.function_list_id = fln.function_list_id LEFT JOIN people.function_lists AS fl ON fln.function_list_id = fl.function_list_id LEFT JOIN people.duty_functions AS df ON fl.function_id = df.function_id LEFT JOIN people.duty_function_sid_links AS dfsl ON dfsl.function_id = df.function_id LEFT JOIN user_restr.sid_list AS sl ON dfsl.sid_id = sl.sid_id WHERE dgn.doc_group_id = @doc_grp_to_check_ep AND sl.sid = @usersid -- Check time-bound restrictions AND (dgepfl.valid_from IS NULL OR dgepfl.valid_from <= @now) AND (dgepfl.valid_until IS NULL OR dgepfl.valid_until >= @now) AND (fl.valid_from IS NULL OR fl.valid_from <= @now) AND (fl.valid_until IS NULL OR fl.valid_until >= @now) AND (dfsl.valid_from IS NULL OR dfsl.valid_from <= @now) AND (dfsl.valid_until IS NULL OR dfsl.valid_until >= @now) UNION ALL (SELECT pl.sid_id AS sid FROM xref.doc_group_names AS dgn LEFT JOIN user_restr.doc_group_edit_perm_people_lst AS dgeppl -- Check for membership of a people list ON dgn.doc_group_id = dgeppl.doc_group_id LEFT JOIN people.people_list_names AS pln ON dgeppl.people_list_id = pln.people_list_id LEFT JOIN people.people_lists AS pl ON pln.people_list_id = pl.people_list_id LEFT JOIN user_restr.sid_list AS sl ON pl.sid_id = sl.sid_id WHERE dgn.doc_group_id = @doc_grp_to_check_ep AND sl.sid = @usersid -- Check time-bound restrictions AND (dgeppl.valid_from IS NULL OR dgeppl.valid_from <= @now) AND (dgeppl.valid_until IS NULL OR dgeppl.valid_until >= @now) AND (pl.valid_from IS NULL OR pl.valid_from <= @now) AND (pl.valid_until IS NULL OR pl.valid_until >= @now) ))) BEGIN -- The user has permission for this action SET @user_authentication_reslt_dgep = 'Pass'; END ELSE -- The user does not have permission for this action. BEGIN SET @user_authentication_reslt_dgep = 'Fail'; -- ============================================================================================ -- Authorisation failure diagnostics -- Write to authorisation fail log SET @failure_type = 'User does not have edit privileges for the document group' BEGIN DECLARE @view_failure nvarchar(1000) = NULL, @function_failure nvarchar(1000) = NULL, @people_failure nvarchar(1000) = NULL; -- ============================================================ -- VIEW PERMISSION -- ============================================================ IF @user_authentication_reslt_dgep_udg <> 'Pass' BEGIN SET @view_failure = 'View: Permission Failed'; END; -- ============================================================ -- FUNCTION LIST PATH -- -- Function path is: -- -- Function-list authorization -- AND Function-list validity -- AND SID authorization -- AND SID authorization validity -- -- We diagnose the path independently of the authorization -- decision above. -- ============================================================ -- Document group -> Function List authorization exists IF NOT EXISTS ( SELECT 1 FROM user_restr.doc_group_edit_perm_funct_lst AS dgepfl WHERE dgepfl.doc_group_id = @doc_grp_to_check_ep ) BEGIN SET @function_failure = CONCAT_WS('; ', @function_failure, 'Function Path: Authorization Not Found' ); END ELSE BEGIN -- Document group -> Function List authorization is currently valid IF NOT EXISTS ( SELECT 1 FROM user_restr.doc_group_edit_perm_funct_lst AS dgepfl WHERE dgepfl.doc_group_id = @doc_grp_to_check_ep AND (dgepfl.valid_from IS NULL OR dgepfl.valid_from <= @now) AND (dgepfl.valid_until IS NULL OR dgepfl.valid_until >= @now) ) BEGIN SET @function_failure = CONCAT_WS('; ', @function_failure, 'Function Path: Authorization Not Currently Valid' ); END; -- Function List exists IF NOT EXISTS ( SELECT 1 FROM user_restr.doc_group_edit_perm_funct_lst AS dgepfl INNER JOIN people.function_list_names AS fln ON dgepfl.function_list_id = fln.function_list_id INNER JOIN people.function_lists AS fl ON fln.function_list_id = fl.function_list_id WHERE dgepfl.doc_group_id = @doc_grp_to_check_ep ) BEGIN SET @function_failure = CONCAT_WS('; ', @function_failure, 'Function Path: Function List Not Found' ); END ELSE BEGIN -- Function List is currently valid IF NOT EXISTS ( SELECT 1 FROM user_restr.doc_group_edit_perm_funct_lst AS dgepfl INNER JOIN people.function_list_names AS fln ON dgepfl.function_list_id = fln.function_list_id INNER JOIN people.function_lists AS fl ON fln.function_list_id = fl.function_list_id WHERE dgepfl.doc_group_id = @doc_grp_to_check_ep AND (fl.valid_from IS NULL OR fl.valid_from <= @now) AND (fl.valid_until IS NULL OR fl.valid_until >= @now) ) BEGIN SET @function_failure = CONCAT_WS('; ', @function_failure, 'Function Path: Function List Not Currently Valid' ); END; -- User has a SID link through the function IF NOT EXISTS ( SELECT 1 FROM user_restr.doc_group_edit_perm_funct_lst AS dgepfl INNER JOIN people.function_list_names AS fln ON dgepfl.function_list_id = fln.function_list_id INNER JOIN people.function_lists AS fl ON fln.function_list_id = fl.function_list_id INNER JOIN people.duty_functions AS df ON fl.function_id = df.function_id INNER JOIN people.duty_function_sid_links AS dfsl ON df.function_id = dfsl.function_id INNER JOIN user_restr.sid_list AS sl ON dfsl.sid_id = sl.sid_id WHERE dgepfl.doc_group_id = @doc_grp_to_check_ep AND sl.sid = @usersid ) BEGIN SET @function_failure = CONCAT_WS('; ', @function_failure, 'Function Path: User SID Not Linked Through Duty Function' ); END ELSE BEGIN -- User's SID link is currently valid IF NOT EXISTS ( SELECT 1 FROM user_restr.doc_group_edit_perm_funct_lst AS dgepfl INNER JOIN people.function_list_names AS fln ON dgepfl.function_list_id = fln.function_list_id INNER JOIN people.function_lists AS fl ON fln.function_list_id = fl.function_list_id INNER JOIN people.duty_functions AS df ON fl.function_id = df.function_id INNER JOIN people.duty_function_sid_links AS dfsl ON df.function_id = dfsl.function_id INNER JOIN user_restr.sid_list AS sl ON dfsl.sid_id = sl.sid_id WHERE dgepfl.doc_group_id = @doc_grp_to_check_ep AND sl.sid = @usersid AND (dgepfl.valid_from IS NULL OR dgepfl.valid_from <= @now) AND (dgepfl.valid_until IS NULL OR dgepfl.valid_until >= @now) AND (fl.valid_from IS NULL OR fl.valid_from <= @now) AND (fl.valid_until IS NULL OR fl.valid_until >= @now) AND (dfsl.valid_from IS NULL OR dfsl.valid_from <= @now) AND (dfsl.valid_until IS NULL OR dfsl.valid_until >= @now) ) BEGIN SET @function_failure = CONCAT_WS('; ', @function_failure, 'Function Path: Duty Function SID Link Not Currently Valid' ); END; END; END; END; -- ============================================================ -- PEOPLE LIST PATH -- -- People path is: -- -- People-list authorization -- AND People-list validity -- AND SID membership -- AND membership validity -- -- Again, diagnosed independently of the authorization decision. -- ============================================================ -- Document group -> People List authorization exists IF NOT EXISTS ( SELECT 1 FROM user_restr.doc_group_edit_perm_people_lst AS dgeppl WHERE dgeppl.doc_group_id = @doc_grp_to_check_ep ) BEGIN SET @people_failure = CONCAT_WS('; ', @people_failure, 'People Path: Authorization Not Found' ); END ELSE BEGIN -- Document group -> People List authorization is currently valid IF NOT EXISTS ( SELECT 1 FROM user_restr.doc_group_edit_perm_people_lst AS dgeppl WHERE dgeppl.doc_group_id = @doc_grp_to_check_ep AND (dgeppl.valid_from IS NULL OR dgeppl.valid_from <= @now) AND (dgeppl.valid_until IS NULL OR dgeppl.valid_until >= @now) ) BEGIN SET @people_failure = CONCAT_WS('; ', @people_failure, 'People Path: Authorization Not Currently Valid' ); END; -- People List exists IF NOT EXISTS ( SELECT 1 FROM user_restr.doc_group_edit_perm_people_lst AS dgeppl INNER JOIN people.people_list_names AS pln ON dgeppl.people_list_id = pln.people_list_id INNER JOIN people.people_lists AS pl ON pln.people_list_id = pl.people_list_id WHERE dgeppl.doc_group_id = @doc_grp_to_check_ep ) BEGIN SET @people_failure = CONCAT_WS('; ', @people_failure, 'People Path: People List Not Found' ); END ELSE BEGIN -- People List is currently valid IF NOT EXISTS ( SELECT 1 FROM user_restr.doc_group_edit_perm_people_lst AS dgeppl INNER JOIN people.people_list_names AS pln ON dgeppl.people_list_id = pln.people_list_id INNER JOIN people.people_lists AS pl ON pln.people_list_id = pl.people_list_id WHERE dgeppl.doc_group_id = @doc_grp_to_check_ep AND (pl.valid_from IS NULL OR pl.valid_from <= @now) AND (pl.valid_until IS NULL OR pl.valid_until >= @now) ) BEGIN SET @people_failure = CONCAT_WS('; ', @people_failure, 'People Path: People List Not Currently Valid' ); END; -- User is a member of the People List IF NOT EXISTS ( SELECT 1 FROM user_restr.doc_group_edit_perm_people_lst AS dgeppl INNER JOIN people.people_list_names AS pln ON dgeppl.people_list_id = pln.people_list_id INNER JOIN people.people_lists AS pl ON pln.people_list_id = pl.people_list_id INNER JOIN user_restr.sid_list AS sl ON pl.sid_id = sl.sid_id WHERE dgeppl.doc_group_id = @doc_grp_to_check_ep AND sl.sid = @usersid ) BEGIN SET @people_failure = CONCAT_WS('; ', @people_failure, 'People Path: People List Membership Not Found' ); END ELSE BEGIN -- User's People List membership is currently valid IF NOT EXISTS ( SELECT 1 FROM user_restr.doc_group_edit_perm_people_lst AS dgeppl INNER JOIN people.people_list_names AS pln ON dgeppl.people_list_id = pln.people_list_id INNER JOIN people.people_lists AS pl ON pln.people_list_id = pl.people_list_id INNER JOIN user_restr.sid_list AS sl ON pl.sid_id = sl.sid_id WHERE dgeppl.doc_group_id = @doc_grp_to_check_ep AND sl.sid = @usersid AND (dgeppl.valid_from IS NULL OR dgeppl.valid_from <= @now) AND (dgeppl.valid_until IS NULL OR dgeppl.valid_until >= @now) AND (pl.valid_from IS NULL OR pl.valid_from <= @now) AND (pl.valid_until IS NULL OR pl.valid_until >= @now) ) BEGIN SET @people_failure = CONCAT_WS('; ', @people_failure, 'People Path: People List Membership Not Currently Valid' ); END; END; END; END; -- ============================================================ -- COMBINE THE DIAGNOSTIC RESULTS -- ============================================================ SET @failure_type = CONCAT_WS('; ', @view_failure, @function_failure, @people_failure ); END -- End authorisation failure diagnostics -- ============================================================================================ -- Write to the log INSERT INTO user_restr.authorisation_fail_log (sid_id, privilege_type, privilege_id, privilege_name, stored_procedure, failure_type) VALUES ( @sid_id, 'Document Group Edit Permission', @doc_grp_to_check_ep, @privilege_name, '[internal].[usp_AUTHENTICATE_doc_grp_ed_pm]', @failure_type ) END -- END User does not have permission for this action END GO