cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

App Broker REST API approvals not working

We are using a slightly older version of 2017 R2.

Using the provided documentation and postman we have successfully gotten Pending requests, Switching Approvers, etc to work.

But for whatever reason when we try to run an approval, it responds with: "Failed to approve the request."

If we enter an incorrect username, it tells us that is not an approver. So the APIs are responding properly.

Presumably we are just missing something in the body but no example is provided.

Provided documentation:

URI Example
[POST] http://localhost/esd/api/requests/27/approve?dn=appportal&un=jsmith
[POST] http://localhost/esd/api/requests/27/reject?dn=appportal&un=jsmith
Request Body Examples
Providing an explanation for the rejection:
{"reason":"my reason"}
Providing an explanation and recommending a rejection:
{"reason":"my reason","recommendReject:true}
Permitting approver to override approval:
{"overrideApprover":true}

(3) Replies

There were some issues with Approve/Reject API's in that release that were fixed in 2018.  You may have to upgrade to 2018 to use those API's successfully.  However, if you can't get the REST API's to work, you may still be able to leverage SOAP by creating your own ASMX leveraging the following web methods...

    [WebMethod]
    public int ApproveRequest(int requestId)
    {
        Log.l1(string.Format("Process approval for App Portal Request ID #{0}", requestId), logfile, (int)LoggingLevel.VERBOSE);
        int retval = 99;
        try
        {
            SelfService.ESD esd = new SelfService.ESD();
            retval = esd.ApproveRequest(requestId, "Approved", "Approved in external system", "", "<insert approver's ADGUID here>", "<insert approver's name or ID here>", false, false, null);
        }
        catch(Exception ex)
        {
            Log.l1(ex.Message, logfile);
        }

        return retval;
    }

    [WebMethod]
    public int RejectRequest(int requestId, string rejectReason)
    {
        Log.l1(string.Format("Process rejection for App Portal Request ID #{0}", requestId), logfile, (int)LoggingLevel.VERBOSE);
        int retval = 99;
        try
        {
            SelfService.ESD esd = new SelfService.ESD();
            retval = esd.RejectRequest(requestId, "Rejected", rejectReason, "", "<insert approver's ADGUID here>", "<insert approver's name or ID here>", false, null);
        }
        catch(Exception ex)
        {
            Log.l1(ex.Message, logfile);
        }

        return retval;
    }

 

 

Anything expressed here is my own view and not necessarily that of my employer, Flexera. If my reply answers a question you have raised, please click "ACCEPT AS SOLUTION".

As I was looking through past projects I've worked on, I stumbled across these PowerShell functions I wrote using the REST API's for approve and reject.  I don't recall what version this was used with.  It was likely either 2017 R2 SP1 or 2018 R1.  Note that these are just supporting functions.  I have not included any calling code, but that should be pretty straight-forward if you've worked with PowerShell at all.

 

############################################################################### 
# Global Variables
###############################################################################
$AppPortalREST = "http://appportal.demo.local/esd/api"
$LogFileRoot = "D:\Program Files (x86)\Flexera Software\App Portal\Logs"
$LogFile = "$LogFileRoot\ApproveReject.log"

###############################################################################
# RequestLog - write entries to the request log in CMTrace format
###############################################################################
Function RequestLog ($LogMsg, $APReqID, $LogComponent="")
{
$UTCOffset = @{$true='';$false='+'}[([int](get-date -DisplayHint Time -UFormat %Z) * -60) -lt 0] + [string]([int](get-date -DisplayHint Time -UFormat %Z) * -60)
$LogFilePath = $($LogFileRoot + 'RequestLog\' + $APReqID + '.log')
[string]$sb = "<!`[LOG`[$LogMsg`]LOG`]!><time=`""
$sb += (Get-Date -DisplayHint Time -Format HH:mm:ss.000) + $UTCOffset
$sb += "`" date=`""
$sb += (Get-Date -DisplayHint Date -Format M-d-yyyy)
$sb += "`" component=`"$LogComponent`" context=`"`" type=`"1`" thread=`"`" file=`"$($ScriptName)`">"
$sb | Out-File -FilePath $LogFilePath -Encoding Default -Append
}

###############################################################################
# Log - write plain text entries to log specified in $LogFile global variable
###############################################################################
function Log([object]$logobj)
{
ForEach ($obj in $logobj)
{
(Get-Date -Format G) + ' ' + $obj.ToString() | Out-File -FilePath $LogFile -Append
}
}

############################################################################### # ApproveRequest ############################################################################### Function ApproveRequest ($APReqID) { # Create a hash table for the headers $htHeaders = @{} $htHeaders["ACCEPT"] = "application/json" $htHeaders["Content-Type"] = "application/json" $responseBody = "" Try { Log "Completing auto-approval step..." $responseBody = Invoke-RestMethod -Uri "$($AppPortalREST)/requests/$($APReqID)/approve?dn=demo&un=svc_appportal" ` -Method Post ` -Headers $htHeaders ` -UseDefaultCredentials Log "Advanced the approval workflow." } Catch [System.Exception] { Log ('EXCEPTION: ' + $_.Exception) RequestLog ('EXCEPTION: ' + $_.Exception) $APReqID 'ApproveRequest' $Error.Clear() return $false } return $true } ############################################################################### # RejectRequest ############################################################################### Function RejectRequest ($APReqID, $RejectReason, $RejectApprover, $RejectTime = "") { # Create a hash table for the headers $htHeaders = @{} $htHeaders["ACCEPT"] = "application/json" $htHeaders["Content-Type"] = "application/json" # Build the rejection reason string $strReason = "Rejected in external system by: $RejectApprover" If ($RejectTime -ne "") { $strReason = "$strReason at $RejectTime" } $strReason = "$strReason. Reason: $RejectReason" $objBodyReason = [PSCustomObject] @{ "Reason" = "$strReason"; } $jsonBodyReason = ConvertTo-Json $objBodyReason $responseBody = "" Try { Log "Rejecting request..." $responseBody = Invoke-RestMethod -Uri "$($AppPortalREST)/requests/$($APReqID)/reject?dn=demo&un=svc_appportal" ` -Method Post ` -Headers $htHeaders ` -Body $jsonBodyReason ` -UseDefaultCredentials Log "Request rejected." } Catch [System.Exception] { Log ('EXCEPTION: ' + $_.Exception) RequestLog ('EXCEPTION: ' + $_.Exception) $APReqID 'RejectRequest' $Error.Clear() return $false } return $true }

 

 

Anything expressed here is my own view and not necessarily that of my employer, Flexera. If my reply answers a question you have raised, please click "ACCEPT AS SOLUTION".
Did either of the above pieces of code help resolve your issue, or are you still having problems?
Anything expressed here is my own view and not necessarily that of my employer, Flexera. If my reply answers a question you have raised, please click "ACCEPT AS SOLUTION".