Page 1 of 1

REST API Output Document Download Problem -

Posted: Wed Mar 21, 2018 12:32 pm
by danielwalters
Hi,

I'm trying to download an Output Document using the API (Get Output Document) that I have uploaded to a case via an external application. However, when i make the API call i am hit with the following:
Code: Select all
You don't have privileges to access with those credentials.
The documentation on this call says that a new security feature restricts this access. I have tried to overcome this by setting permissions to my user (admin) on the case. The access_token to make API calls i'm using is one granted with admin credentials. Is this different from a valid login session that the documentation suggests?

http://prntscr.com/iudzyf

I can download the document fine from the front end.

Thanks so much,

Daniel

Re: REST API Output Document Download Problem -

Posted: Thu Mar 22, 2018 12:51 pm
by amosbatto
The easy solution is to disable session validation. Edit your workflow/engine/config/env.ini file and add the following line:
Code: Select all
disable_download_documents_session_validation = 1
Of course, that turns off all security, so anyone can download the files.

If you want ProcessMaker to verify that the logged-in REST user has proper access to the file before downloading, then you can edit the source code of workflow/engine/methods/cases/cases_ShowDocument.php and change the source code from:
Code: Select all
if (empty($_GET['v'])) {
    //Load last version of the document
    $docVersion = $oAppDocument->getLastAppDocVersion($_GET['a']);
} else {
    $docVersion = $_GET['v'];
}

//Check if the user can be download the input Document
//Send the parameter v = Version
//Send the parameter a = Case UID
if (defined('DISABLE_DOWNLOAD_DOCUMENTS_SESSION_VALIDATION') && DISABLE_DOWNLOAD_DOCUMENTS_SESSION_VALIDATION == 0) {
To:
Code: Select all
if (empty($_GET['v'])) {
    //Load last version of the document
    $docVersion = $oAppDocument->getLastAppDocVersion($_GET['a']);
} else {
    $docVersion = $_GET['v'];
}

if (isset( $_GET['sid'] )) {
    Bootstrap::LoadClass( 'sessions' );
    $oSessions = new Sessions();
    if ($aSession = $oSessions->verifySession( $_GET['sid'] )) {
        require_once 'classes/model/Users.php';
        $oUser = new Users();
        $aUser = $oUser->load( $aSession['USR_UID'] );
        $_SESSION['USER_LOGGED'] = $aUser['USR_UID'];
        $_SESSION['USR_USERNAME'] = $aUser['USR_USERNAME'];
        $bRedirect = false;
        if ((preg_match("/msie/i", $_SERVER ['HTTP_USER_AGENT']) != 1 ||
            $config['ie_cookie_lifetime'] == 1) &&
            (!(preg_match("/safari/i", $_SERVER ['HTTP_USER_AGENT']) == 1 && 
            preg_match("/chrome/i", $_SERVER ['HTTP_USER_AGENT']) == 0) ||
            $config['safari_cookie_lifetime'] == 1)) 
        {
            if (PHP_VERSION < 5.2) {
                setcookie(session_name(), session_id(), time() + $timelife, '/', '; HttpOnly');
            } else {
                setcookie(session_name(), session_id(), time() + $timelife, '/', null, G::is_https(), true);
            }
        }
        $RBAC->initRBAC();
        $RBAC->loadUserRolePermission( $RBAC->sSystem, $_SESSION['USER_LOGGED'] );
        $memKey = 'rbacSession' . session_id();
        $memcache->set( $memKey, $RBAC->aUserInfo, PMmemcached::EIGHT_HOURS );
    }
}

//Check if the user can be download the input Document
//Send the parameter v = Version
//Send the parameter a = Case UID
if (defined('DISABLE_DOWNLOAD_DOCUMENTS_SESSION_VALIDATION') && DISABLE_DOWNLOAD_DOCUMENTS_SESSION_VALIDATION == 0) {
Also edit workflow/engine/methods/cases/cases_ShowOutputDocument.php and change the code from:
Code: Select all
$download = $oOutputDocument->Fields['OUT_DOC_OPEN_TYPE'];

//Check if the user can be download the Output Document
if (defined('DISABLE_DOWNLOAD_DOCUMENTS_SESSION_VALIDATION') && DISABLE_DOWNLOAD_DOCUMENTS_SESSION_VALIDATION == 0) {
To:
Code: Select all
$download = $oOutputDocument->Fields['OUT_DOC_OPEN_TYPE'];

if (isset( $_GET['sid'] )) {
    Bootstrap::LoadClass( 'sessions' );
    $oSessions = new Sessions();
    if ($aSession = $oSessions->verifySession( $_GET['sid'] )) {
        require_once 'classes/model/Users.php';
        $oUser = new Users();
        $aUser = $oUser->load( $aSession['USR_UID'] );
        $_SESSION['USER_LOGGED'] = $aUser['USR_UID'];
        $_SESSION['USR_USERNAME'] = $aUser['USR_USERNAME'];
        $bRedirect = false;
        if ((preg_match("/msie/i", $_SERVER ['HTTP_USER_AGENT']) != 1 ||
            $config['ie_cookie_lifetime'] == 1) &&
            (!(preg_match("/safari/i", $_SERVER ['HTTP_USER_AGENT']) == 1 && 
            preg_match("/chrome/i", $_SERVER ['HTTP_USER_AGENT']) == 0) ||
            $config['safari_cookie_lifetime'] == 1)) 
        {
            if (PHP_VERSION < 5.2) {
                setcookie(session_name(), session_id(), time() + $timelife, '/', '; HttpOnly');
            } else {
                setcookie(session_name(), session_id(), time() + $timelife, '/', null, G::is_https(), true);
            }
        }
        $RBAC->initRBAC();
        $RBAC->loadUserRolePermission( $RBAC->sSystem, $_SESSION['USER_LOGGED'] );
        $memKey = 'rbacSession' . session_id();
        $memcache->set( $memKey, $RBAC->aUserInfo, PMmemcached::EIGHT_HOURS );
    }
}

//Check if the user can be download the Output Document
if (defined('DISABLE_DOWNLOAD_DOCUMENTS_SESSION_VALIDATION') && DISABLE_DOWNLOAD_DOCUMENTS_SESSION_VALIDATION == 0) {
Then, download my extraRest plugin:
https://sourceforge.net/p/pmcommunity/c ... /extraRest

Then go to Admin > Plugins > Plugin Manager in ProcessMaker and import the extraRest plugin. Then, activate it.

In your REST code, you can use this endpoint to obtain the session ID:
http{s}://{address}/api/1.0/{workflow}/extrarest/session-id

Then add &sid={session-id} to the URLs to download Input Documents and Output Documents.
For example:
http://example.com/sysworkflow/en/neocl ... 1029627249
http://example.com/sysworkflow/en/neocl ... 1029627249

For example:
Code: Select all
$url = "http://example.com/api/1.0/workflow/extrarest/session-id";
$oRet = pmRestRequest("GET", $url, null, $oToken->access_token);
$sessionId = $oRet->response;
$downloadUrl = "http://example.com/sysworkflow/en/neoclassic/cases/cases_ShowDocument?a=4175861895ab166ed3afe00033095090&sid="  . $sessionId;
$contents = file_get_contents($downloadUrl) or die("Unable to access file $downloadUrl");
Here is the code for the REST endpoint:
Code: Select all
    /**
     * Get a login session ID that can be attached to URLs used in ProcessMaker:
     * http://<address>/sys<workspace>/<lang>/<skin>/<folder>/<method>.php?sid=<session-id> 
     * Ex: http://example.com/sysworkflow/en/neoclassic/cases/cases_ShowDocument?a=4699401854d8262f569e9a1070221206&sid=1234567890abcde1234567890abcde 
     * 
     * @url GET /session-id
     * @access protected
     * 
     * @return string The session ID.
     * 
     * @author Amos Batto <amos@processmaker.com>
     * @copyright Public Domain
     */
    public function getSessionId() {  
        try {    
            $g = new \G();
            $sessionId = $g->generateUniqueID();
            $userId = $this->getUserId();

            $session = new \Session();
            $session->setSesUid( $sessionId );
            $session->setSesStatus( 'ACTIVE' );
            $session->setUsrUid( $userId );
            $session->setSesRemoteIp( $_SERVER['REMOTE_ADDR'] );
            $session->setSesInitDate( date( 'Y-m-d H:i:s' ) );
            $session->setSesDueDate( date( 'Y-m-d H:i:s', mktime( date('H'), 
                date('i') + 15, date('s'), date('m'), date('d'), date('Y') ) ) );
            $session->setSesEndDate( '' );
            $session->Save();
            return $sessionId;
        } 
        catch (\Exception $e) {
            throw new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage());
        }
    } 

Re: REST API Output Document Download Problem -

Posted: Fri Mar 23, 2018 6:12 am
by danielwalters
Doing Gods work amosbatto.. :D :D

This worked seamlessly.

I cant thank you enough.

Daniel

Re: REST API Output Document Download Problem -

Posted: Fri Mar 23, 2018 10:11 am
by amosbatto
danielwalters wrote: Doing Gods work amosbatto.. :D :D
My mom will be so happy that I finally found God in my life! :-)