Saturday, December 20, 2025

Generating HMAC SHA512 Digest for REST API

Recently a request came my way to use a 3rd party API which uses HMAC (Hash-Based Message Authentication Code) to secure requests.

Key Components of HMAC Authentication
1. Secret Key ( Secret_Key ): A confidential key 

2. API Key ( Api_Key ): A unique identifier assigned to the client, typically representing the user or system accessing the API.

3. Nonce ( Nonce ): A unique, single-use number is generated for each request.

Generating an HMAC Signature
To authenticate an API request:

1. Concatenate the Following Elements (each separated by a newline \n ):

        HTTP Method (e.g. PUT,POST,GET,DELETE)
        Resource Path (e.g. sync/v2/profile)
        API Key (e.g. user)
        Nonce (e.g. 123456)
        Date (RFC 1123 format, e.g. Sat, 20 Dec 2025 12:00:00 GMT)

2. Generate the HMAC Digest:

Use the Secret Key with the HMAC-SHA512 algorithm to hash the concatenated string.
Encode the hashed output in Base64.

3. Format the Authorization Header:

Authorization: HmacSHA512 Api_Key:Company_Code:Nonce:Digest

Example Request
Secret Key: my_secret_key
API Key: user
Company Code: STK
Nonce: 123456
Date: Sat, 20 Dec 2025 12:00:00 GMT

Authorization Header Example
Authorization: HmacSHA512 user:STK:123456:px4KjfYAg6RY56sZ93nPSP8aiZqoIPp4DKTIIZKkzZwEAb

PeopleSoft does not provide SHA512 algorithm API calls to handle this natively hence have to use delivered java libraries leveraging the CreateJavaObject peoplecode API.


Local string &companyCode, &clientKey, &secretKey, &resourcePath, &currentDateTime, &Nonce, &DataToSign, &Authorization;
Local object &oByteStr, &signingKey, &Hmac, &Hmacbytes, &oEncoder;

/* static values */
&companyCode = "ABC";
&clientKey = "My_ABC_keyname";
&secretKey = "6Ftp123345AbCdEfgH";
&resourcePath = "/sync/v2/profile";
&currentDateTime = DateTimeToHTTP(%Datetime);
&Nonce = String(Int(Rand() * 1000000));

/* Generate the HMAC Digest */
&oByteStr = CreateJavaObject("java.lang.String", &secretKey);
&signingKey = CreateJavaObject("javax.crypto.spec.SecretKeySpec", &oByteStr.getBytes("UTF8"), "HmacSHA512");
&Hmac = GetJavaClass("javax.crypto.Mac").getInstance("HmacSHA512");
&Hmac.init(&signingKey);
&DataToSign = "GET" | Char(10) | &resourcePath | Char(10) | &clientKey | Char(10) | &Nonce | Char(10) | &currentDateTime;
&Hmacbytes = &Hmac.doFinal(CreateJavaObject("java.lang.String", &DataToSign).getBytes("UTF8"));
&oEncoder = CreateJavaObject("com.peoplesoft.tools.util.Base64");
&Authorization = &oEncoder.encode(&Hmacbytes);
&Authorization = "HmacSHA512 " | &clientKey | ":" | &companyCode | ":" | &Nonce | ":" | &Authorization;

Then send the authorization value in the header of the request, like so.

&bRet = &request.IBInfo.LoadRESTHeaders();
&bRet = &request.IBInfo.IBConnectorInfo.AddConnectorProperties("Authorization", &Authorization, %Header);



Sunday, October 12, 2025

Mass export employee photos

Recently was trying to figure out how to mass download/export employee photos from PeopleSoft and followingis what I came up with. It works but the exported image quality is not that great. We are using the delivered application engine HR_EMPLPHOTO to mass import picutes in. The photos are loaded to PS_EMPL_PHOTO table and it creates four photo sizes - CARD, LIST, ORCH and PAGE. The CARD one is the best in terms of picture quality.

The basic idea is to read this table and write the contents to a file. Based on the upload process I know that the picture file format is JPG. The raw image data is stored in the EMPLOYEE_PHOTO field, but we cannot just select this field. I am looping through the employee population, fetching the data and storing it in the record object and then using the WriteRaw method of the File class to write the image to a file. 


Local string &emplid, &filename;
Local Record &imageRec;
Local SQL &imageSQL;

&imageRec = CreateRecord(Record.EMPL_PHOTO);
&imageSQL = CreateSQL("SELECT EMPLID, PHOTO_SIZENAME, PHOTO_IMGNAME, EMPLOYEE_PHOTO, PSIMAGEVER FROM PS_EMPL_PHOTO WHERE EMPLID = :1 AND PHOTO_SIZENAME = 'CARD'", &emplid);

If &imageSQL.Fetch(&imageRec) Then
   &imageFile = GetFile(&filename, "W", %FilePath_Absolute);
   &imageFile.WriteRaw(&imageRec.EMPLOYEE_PHOTO.Value);
   &imageFile.Close();
End-If;

Monday, January 6, 2025

Taleo Web API - managing user groups in a user profile

I have been using Taleo (or Oracle's) SOAP based web API to transmit data to Taleo from PeopleSoft. As part of this service I am creating/updating user profiles in Taleo based on actions taken in PeopleSoft. Recently received a request to manage/update the user groups associated with a user profile based on action done in PeopleSoft.

I am running PeopleTools 8.61.x, HCM 9.2 but this should be possible as long as you can make a SOAP call out from PeopleSoft. 

User Groups are part of the UserAccount construct as shown below. Following is a simple construct to pull up or search for an user account and then assign a user group to the user account.

<?xml version="1.0" encoding="UTF-8"?> <UserAccount> <Loginname searchType="search" searchTarget="../../.." searchValue="user@emaildomain.com" /> <Groups> <Group> <Name searchTarget="." searchType="search" searchValue="Group-Code-01" /> </Group> </Groups> </UserAccount>
To delete all the User Groups assigned to an user the request XML will be like below.

<?xml version="1.0" encoding="UTF-8"?> <UserAccount> <Loginname searchType="search" searchTarget="../../.." searchValue="user@emaildomain.com" /> <Groups action="reset" /> 
</UserAccount>
  
To delete only a specific user group from the list of assigned user groups on an user profile the request will be like below.

<?xml version="1.0" encoding="UTF-8"?> <UserAccount> <Loginname searchType="search" searchTarget="../../.." searchValue="user@emaildomain.com" /> <Groups> <Group action="remove"> <Name searchType="search" searchTarget="." searchValue="Group-Code-01" /> </Group> </Groups> </UserAccount>

One can combine the above actions in a single request like removing all or one user group and assigning a new user group.