Questions and discussion about developing processes and programming in PHP, JavaScript, web services & REST API.

Moderator: amosbatto

Forum rules: Please search to see if a question has already asked before creating a new topic. Please don't post the same question in multiple forums.
#823814
New security restrictions have been added to REST. Now your logged-in user needs to currently be assigned to an open task in the case in order to use GET /api/1.0/workflow/cases/{app_uid}/variables.

I recommend that you install the extraRest plugin and then use GET extrarest/case/{app_uid}/ to get the case variables which can be found in the APP_DATA element of the returned object.
#825650
amosbatto wrote: Fri Apr 05, 2019 7:15 pm New security restrictions have been added to REST. Now your logged-in user needs to currently be assigned to an open task in the case in order to use GET /api/1.0/workflow/cases/{app_uid}/variables.

I recommend that you install the extraRest plugin and then use GET extrarest/case/{app_uid}/ to get the case variables which can be found in the APP_DATA element of the returned object.
Hi,
do you have an info on this new security limitation? I could not find anything about that.

I have a case started via REST. However, I cannot get the variables from a case via REST where the logged in user is definitely assigned to an open case. I have installed the extrarest plugin to verify that this is the case.
The case is in status DRAFT.
#825666
I just checked the code for that REST endpoint in PM 3.3.10 and it is totally screwed up. When security was added, it broke the endpoint and it was never tested and never documented.

I recommend using my extraRest endpoint for now, but if you want to fix the source code here is what you need to do:

1. Edit workflow/engine/src/ProcessMaker/Services/Api/Cases.php with a plain text editor.

2. Replace these lines:
Code: Select all
    /**
     * Get Case Variables
     *
     * @access protected
     * @class  AccessControl {@className \ProcessMaker\Services\Api\Cases}
     * @url GET /:app_uid/variables
     *
     * @param string $app_uid {@min 1}{@max 32}
     * @param string $dyn_uid 
     * @param string $pro_uid
     * @param string $act_uid
     * @param int $app_index
     * @return mixed
     * @throws RestException
     */
    public function doGetCaseVariables($app_uid, $dyn_uid = null, $pro_uid = null, $act_uid = null, $app_index = null)
    {
        try {
            $usr_uid = $this->getUserId();
            $cases = new BmCases();
            $response = $cases->getCaseVariables($app_uid, $usr_uid, $dyn_uid, $pro_uid, $act_uid, $app_index);
            return DateTime::convertUtcToIso8601($response);
        } catch (Exception $e) {
            throw (new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage()));
        }
    }
With:
Code: Select all
    /**
     * Get Case Variables
     *
     * @access protected
     * @class  AccessControl {@className \ProcessMaker\Services\Api\Cases}
     * @url GET /:app_uid/variables
     *
     * @param string $app_uid   {@min 1}{@max 32}
     * @param string $dyn_uid   {@from query}
     * @param string $pro_uid   {@from query}
     * @param string $act_uid   {@from query}
     * @param int    $del_index {@from query}
     * @return mixed
     * @throws RestException
     */
    public function doGetCaseVariables($app_uid, $dyn_uid = null, $pro_uid = null, $act_uid = null, $del_index = null)
    {
        try {
            $usr_uid = $this->getUserId();
            $cases = new BmCases();
            $response = $cases->getCaseVariables($app_uid, $usr_uid, $dyn_uid, $pro_uid, $act_uid, $del_index);
            return DateTime::convertUtcToIso8601($response);
        } catch (Exception $e) {
            throw (new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage()));
        }
    }
3. Replace these lines:
Code: Select all
    public function __isAllowed()
    {
        try {
            $methodName = $this->restler->apiMethodInfo->methodName;
            $arrayArgs  = $this->restler->apiMethodInfo->arguments;
            switch ($methodName) {
                case 'doGetCaseVariables':
                    $applicationUid = $this->parameters[$arrayArgs['app_uid']];
                    $dynaformUid = $this->parameters[$arrayArgs['dyn_uid']];
                    $delIndex = $this->parameters[$arrayArgs['app_index']];
                    $userUid = $this->getUserId();
                    //Check if the user has the case
                    $appDelegation = new AppDelegation();
                    $aCurUser = $appDelegation->getCurrentUsers($applicationUid, $delIndex);
                    if (!empty($aCurUser)) {
                        foreach ($aCurUser as $key => $value) {
                            if ($value === $userUid) {
                                return true;
                            }
                        }
                    }
                    //Check if the user has Permissions
                    $oCases = new BmCases();
                    return $oCases->checkUserHasPermissionsOrSupervisor($userUid, $applicationUid, $dynaformUid);
                    break;
With:
Code: Select all
    public function __isAllowed()
    {
        try {
            $methodName = $this->restler->apiMethodInfo->methodName;
            $arrayArgs  = $this->restler->apiMethodInfo->arguments;
            switch ($methodName) {
                case 'doGetCaseVariables':
                    $userUid = $this->getUserId();
                    $applicationUid = $this->parameters[$arrayArgs['app_uid']];
                    $dynaformUid = $this->parameters[$arrayArgs['dyn_uid']];
                    $delIndex = $this->parameters[$arrayArgs['del_index']];
                    
                    if (empty($delIndex)) {
                        $oCase = new \Cases();
                        try {
                            $delIndex = $oCase->getCurrentDelegation($applicationUid, $userUid, false);
                        }
                        catch (Exception $e) {
                            $msg = $e->getMessage();
                            if ($msg != 'This case has 0 current delegations') {
                                throw new Exception($msg);
                            }
                        }    
                    }
                    
                    if (!empty($delIndex)) {
                        //Check if the user has the case
                        $appDelegation = new AppDelegation();
                        $aCurUser = $appDelegation->getCurrentUsers($applicationUid, $delIndex);
                        if (!empty($aCurUser)) {
                            foreach ($aCurUser as $key => $value) {
                                if ($value === $userUid) {
                                    return true;
                                }
                            }
                        }
                    }
                    //Check if the user has Permissions
                    $oCases = new BmCases();
                    return $oCases->checkUserHasPermissionsOrSupervisor($userUid, $applicationUid, $dynaformUid);
                    break;
OK, let's also fix some other things in this file while we are here:

1. If you are using version 3.3.10 or later, then replace {@from path} with {@from query} everywhere in the file.

2. Change:
Code: Select all
    /**
     * Get process list for start case
     *
     * @url GET /start-cases
     *
     * @param string $type_view
To:
Code: Select all
    /**
     * Get process list for start case
     *
     * @url GET /start-cases
     *
     * @param string $type_view {@from query}

3. Change:
Code: Select all
    /**
     * Get process list bookmark for start case
     *
     * @url GET /bookmark-start-cases
     *
     * @param string $type_view 
To:
Code: Select all
    /**
     * Get process list bookmark for start case
     *
     * @url GET /bookmark-start-cases
     *
     * @param string $type_view {@from query}

Now it should work.
It should no longer be necessary to specify the delegation index if the logged-in user is assigned to a delegation (i.e., task in the case), but you can specify it like this:
GET /api/1.0/workflow/cases/{app_uid}/variables?del_index={index}
Where {index} is the delegation index which starts with the number 1 and counts each time a user is assigned to a task in the case.

If you have a Process Supervisor or someone with Process Permissions who needs to access the case's variables, then do it this way:
GET /api/1.0/workflow/cases/{app_uid}/variables?pro_uid={pro_uid}&act_uid={act_uid}&dyn_uid={dyn_uid}
Where {pro_uid} is the process ID, {act_uid} is the task ID, and {dyn_uid} is the Dynaform ID.

Note: I haven't had a chance to test whether you need all of these parameters or only some of them, so you might have to experiment to see what works with Process Supervisors and Process Permissions.
#825682
Wow. Thank you for your help!

After experimenting with the code above and extrarest, I decided to add my own REST endpoints to my plugin I already had coded. I used your extrarest plugin to look how this works.

This Wiki page has examples that did not work for me:
https://wiki.processmaker.com/3.0/Creat ... _Endpoints

After some struggling I found out, that the constructor must not have parameters. Bummer!
My REST endpoint works now. I think, this was the right way to go, for me at least.

Thanks again for your help and the extrarest plugin!

Capture.PNG I have use this javascript code to ad[…]

Having a business, especially when it involves tra[…]

The condition is not workable

Hi there, Recently I've encountered the amount wh[…]

Yes i'm using vue js to load the data.