SET PATH *LIBL ; 

CREATE OR REPLACE FUNCTION SAILPOINT.ES_V2_CREATE_USER_PROFILE ( 
	AUTHORIZATIONNAME VARCHAR(10) , 
	TEXTDESCRIPTION VARCHAR(50) DEFAULT  NULL  , 
	USERCLASSNAME VARCHAR(10) DEFAULT  NULL  , 
	STATUS VARCHAR(10) DEFAULT  NULL  , 
	SETPASSWORDTOEXPIRE VARCHAR(10) DEFAULT  NULL  , 
	USEROWNER VARCHAR(10) DEFAULT  NULL  , 
	GROUPPROFILENAME VARCHAR(10) DEFAULT  NULL  , 
	ACCOUNTINGCODE VARCHAR(20) DEFAULT  NULL  , 
	JOBDESCRIPTIONNAME VARCHAR(10) DEFAULT  NULL  , 
	OUTPUTQUEUENAME VARCHAR(21) DEFAULT  NULL  , 
	MESSAGEQUEUENAME VARCHAR(21) DEFAULT  NULL  , 
	LIMITCAPABILITIES VARCHAR(10) DEFAULT  NULL  , 
	SPECIALAUTHORITIESJSON VARCHAR(1024) DEFAULT  NULL  ) 
	RETURNS CLOB(2147483647)   
	LANGUAGE SQL 
	SPECIFIC SAILPOINT.V2_ESICRTUSR 
	NOT DETERMINISTIC 
	MODIFIES SQL DATA 
	CALLED ON NULL INPUT 
	NOT FENCED 
	SET OPTION  ALWBLK = *ALLREAD , 
	ALWCPYDTA = *OPTIMIZE , 
	COMMIT = *NONE , 
	DBGVIEW = *SOURCE , 
	DECRESULT = (31, 31, 00) , 
	DLYPRP = *NO , 
	DYNDFTCOL = *NO , 
	DYNUSRPRF = *OWNER , 
	SRTSEQ = *HEX   
	BEGIN 
DECLARE CMD_OUTPUT CLOB ( 64 K ) DEFAULT '' ; 
DECLARE CMD_STMT VARCHAR ( 2048 ) DEFAULT '' ; 
DECLARE ERROR_RESPONSE CLOB ( 2 G ) DEFAULT '' ; 
DECLARE SPECIALAUTHS VARCHAR ( 1000 ) ; 
-- Uniform error handler - returns pre-built error JSON 
DECLARE CONTINUE HANDLER FOR SQLSTATE '38001' RETURN ERROR_RESPONSE ; 
-- Handle QCMD exception (38501 = external routine error) 
DECLARE EXIT HANDLER FOR SQLSTATE '38501' 
RETURN JSON_OBJECT ( 
'data' : JSON_ARRAY ( ) , 
'errors' : JSON_ARRAY ( JSON_OBJECT ( 
'status' : 409 , 
'message' : 'User profile already exists or command failed' 
) ) 
) ; 
-- Convert JSON array to space-separated list 
IF SPECIALAUTHORITIESJSON IS NOT NULL THEN 
SET SPECIALAUTHS = ( 
SELECT LISTAGG ( TRIM ( FRAGMENT ) , ' ' ) 
FROM TABLE ( 
CISTOOLS . SPLIT_STRING ( 
REGEXP_REPLACE ( 
CAST ( 
SPECIALAUTHORITIESJSON AS VARCHAR ( 1000 ) 
CCSID 37 ) , '[\[|\]|\{|\}|\""|\,|\s+]' , 
' ' ) , ' ' ) 
) 
WHERE FRAGMENT <> '' 
AND FRAGMENT IS NOT NULL ) ; 
END IF ; 
-- Build the command 
SET CMD_STMT = 'CRTUSRPRF USRPRF(' || TRIM ( AUTHORIZATIONNAME ) || ')' ; 
IF TEXTDESCRIPTION IS NOT NULL THEN 
SET CMD_STMT = CMD_STMT || ' TEXT(' || 
CISTOOLS . GET_QUOTED ( TEXTDESCRIPTION ) || ')' ; 
END IF ; 
IF USERCLASSNAME IS NOT NULL THEN 
SET CMD_STMT = CMD_STMT || ' USRCLS(' || USERCLASSNAME || ')' ; 
END IF ; 
IF STATUS IS NOT NULL THEN 
SET CMD_STMT = CMD_STMT || ' STATUS(' || STATUS || ')' ; 
END IF ; 
IF SETPASSWORDTOEXPIRE IS NOT NULL THEN 
SET CMD_STMT = CMD_STMT || ' PWDEXP(' || SETPASSWORDTOEXPIRE || 
')' ; 
END IF ; 
IF USEROWNER IS NOT NULL THEN 
SET CMD_STMT = CMD_STMT || ' OWNER(' || USEROWNER || ')' ; 
END IF ; 
IF GROUPPROFILENAME IS NOT NULL THEN 
SET CMD_STMT = CMD_STMT || ' GRPPRF(' || GROUPPROFILENAME || ')' ; 
END IF ; 
IF ACCOUNTINGCODE IS NOT NULL THEN 
SET CMD_STMT = CMD_STMT || ' ACGCDE(' || ACCOUNTINGCODE || ')' ; 
END IF ; 
IF JOBDESCRIPTIONNAME IS NOT NULL THEN 
SET CMD_STMT = CMD_STMT || ' JOBD(' || JOBDESCRIPTIONNAME || ')' ; 
END IF ; 
IF OUTPUTQUEUENAME IS NOT NULL THEN 
SET CMD_STMT = CMD_STMT || ' OUTQ(' || OUTPUTQUEUENAME || ')' ; 
END IF ; 
IF MESSAGEQUEUENAME IS NOT NULL THEN 
SET CMD_STMT = CMD_STMT || ' MSGQ(' || MESSAGEQUEUENAME || ')' ; 
END IF ; 
IF LIMITCAPABILITIES IS NOT NULL THEN 
SET CMD_STMT = CMD_STMT || ' LMTCPB(' || LIMITCAPABILITIES || ')' ; 
ELSE 
SET CMD_STMT = CMD_STMT || ' LMTCPB(*YES)' ; 
END IF ; 
IF SPECIALAUTHS IS NOT NULL 
AND LENGTH ( TRIM ( SPECIALAUTHS ) ) > 0 THEN 
SET CMD_STMT = CMD_STMT || ' SPCAUT(' || SPECIALAUTHS || ')' ; 
END IF ; 
-- Execute via QCMD and capture output 
SET CMD_OUTPUT = CISTOOLS . QCMD ( CMD_STMT ) ; 
-- Check if any CPF/CPD errors exist (CPF=failure, CPD=diagnostic, CPC=completio--n/success) 
IF CMD_OUTPUT LIKE '%CPF%' 
OR CMD_OUTPUT LIKE '%CPD%' THEN 
-- Build errors array from all error lines in output 
SET ERROR_RESPONSE = ( 
SELECT JSON_OBJECT ( 
'data' : JSON_ARRAY ( ) , 'errors' : JSON_ARRAYAGG ( 
JSON_OBJECT ( 
'status' : 
CASE 
WHEN FRAGMENT LIKE '%CPF2214%' THEN 409 
WHEN FRAGMENT LIKE '%CPF2213%' THEN 403 
WHEN FRAGMENT LIKE '%CPF2225%' THEN 403 
WHEN FRAGMENT LIKE '%CPF2203%' THEN 404 
WHEN FRAGMENT LIKE '%CPF2209%' THEN 404 
WHEN FRAGMENT LIKE '%CPF2283%' THEN 400 
ELSE 500 
END , 'message' : 
CASE 
WHEN 
FRAGMENT LIKE '%CPF2214%' 
THEN 'User profile already exists' 
WHEN FRAGMENT LIKE '%CPF2213%' THEN 
'Not authorized to create user profiles' 
WHEN FRAGMENT LIKE '%CPF2225%' THEN 
'*SECADM required to create or change user profiles' 
WHEN 
FRAGMENT LIKE '%CPF2203%' 
THEN 'Group profile not found' 
WHEN 
FRAGMENT LIKE '%CPF2209%' 
THEN 'Library not found' 
WHEN 
FRAGMENT LIKE '%CPF2283%' 
THEN 'Maximum storage value not valid' 
ELSE TRIM ( FRAGMENT ) 
END 
) 
) 
) 
FROM TABLE ( 
CISTOOLS . SPLIT_STRING ( CMD_OUTPUT , X'25' ) 
) AS T 
WHERE FRAGMENT LIKE '%CPF%' 
OR FRAGMENT LIKE '%CPD%' ) ; 
SIGNAL SQLSTATE '38001' ; 
END IF ; 
-- Success - return user info with specialAuthorities as array 
RETURN 
( 
SELECT JSON_OBJECT ( 
'data' : JSON_ARRAY ( JSON_OBJECT ( 
'authorizationName' VALUE CAST ( 
AUTHORIZATION_NAME AS VARCHAR ( 256 ) CCSID 37 ) , 
'tempPassword' VALUE CAST ( 
AUTHORIZATION_NAME AS VARCHAR ( 256 ) CCSID 37 ) , 
'textDescription' VALUE CAST ( 
TEXT_DESCRIPTION AS VARCHAR ( 256 ) CCSID 37 ) , 
'userClassName' VALUE CAST ( 
USER_CLASS_NAME AS VARCHAR ( 256 ) CCSID 37 ) , 
'status' VALUE CAST ( STATUS AS VARCHAR ( 256 ) CCSID 37 ) , 
'userOwner' VALUE CAST ( 
USER_OWNER AS VARCHAR ( 256 ) CCSID 37 ) , 
'groupProfileName' VALUE CAST ( 
GROUP_PROFILE_NAME AS VARCHAR ( 256 ) CCSID 37 ) , 
'accountingCode' VALUE CAST ( 
ACCOUNTING_CODE AS VARCHAR ( 256 ) CCSID 37 ) , 
'homeDirectory' VALUE CAST ( 
HOME_DIRECTORY AS VARCHAR ( 256 ) CCSID 37 ) , 
'limitCapabilities' VALUE CAST ( 
LIMIT_CAPABILITIES AS VARCHAR ( 528 ) CCSID 37 ) , 
'specialAuthorities' VALUE ( 
SELECT JSON_ARRAYAGG ( 
TRIM ( FRAGMENT ) 
) 
FROM TABLE ( 
CISTOOLS . SPLIT_STRING ( 
TRIM ( 
CAST ( 
A . SPECIAL_AUTHORITIES AS VARCHAR ( 
528 ) CCSID 37 ) ) , ' ' ) 
) 
WHERE TRIM ( FRAGMENT ) <> '' ) , 
'creationTimestamp' VALUE CREATION_TIMESTAMP 
) ) , 'errors' : JSON_ARRAY ( ) 
) 
FROM QSYS2 . USER_INFO A 
WHERE AUTHORIZATION_NAME = UPPER ( AUTHORIZATIONNAME ) ) ; 
END  ; 

GRANT ALTER , EXECUTE   
ON SPECIFIC FUNCTION SAILPOINT.V2_ESICRTUSR 
TO AMAPICS WITH GRANT OPTION ; 

GRANT EXECUTE   
ON SPECIFIC FUNCTION SAILPOINT.V2_ESICRTUSR 
TO PUBLIC ; 

