Code to update device with api

kevcar917 years ago

Regards;
I am using in api to develop a proper web interface in php (laravel), but I have a problem when trying to update a device, the code in the model is the following

public function update(Request $request, $id){
        $data = [
            'name'     => $request->name,
            'uniqueId' => $request->uniqueid,
            'model'    => $request->model,
            'contact'  => $request->contact,
            'phone'    => $request->phonecontact,
            'category' => $request->category,
        ];

        $device = new GuzzleHttp\Client([
            'base_uri' => 'http://domain:8082/api/devices/',
            'headers'  => ['content-type' => 'application/json', 'Accept' => 'application/json'],
            'body' => json_encode($data),
        ]);
        
        $res = $device->request('PUT', $id, ['auth' => ['user', 'password']]);

        $status = $res->getStatusCode();
        if ($status == 200) {
            Flash::success(trans('content.alerts.deviceUpdateSuccess'))->important();  
            return redirect::to('devices');
        }else{
            Flash::success(trans('content.alerts.deviceUpdateError'))->important();  
            return redirect::to('devices');
        }
    }

But I get the following error:

Client error: PUT http://domain:8082/api/devices/1 resulted in a 400 Bad Request response:
Device access denied - SecurityException (PermissionsManager:194 < DeviceResource:81 < ...)

Also try in javascript with the following code.

<script type="text/javascript">
      var name = "test device";
      var uid = "12345678";
      $.ajax({
        type: 'put',
        url: 'http://domain:8082/api/devices/1',
        headers: {
            "Authorization": "Basic " + btoa("user:password"),
            'Accept':'application/json'
        },
        contentType:"application/json",
        data:JSON.stringify({
          name:name,
          uniqueId:uid
        }),
        success: function (response) {
            console.table(response);
        },
        error: function (response) {
            console.log(response);
        }
      });
</script>

Device access denied - SecurityException (PermissionsManager:194 < DeviceResource:81 < ...)

But I get the same error.

The devices you try to update if they belong to the user whose credentials I use to log on through the api.

If you could tell me what to correct in the code or else I should do thank you, in advance thanks.

Anton Tananaev7 years ago

It looks like you are using old version of Traccar. I would recommend to upgrade it.

As for the error, it usually means that your used doesn't have access to the device.

kevcar917 years ago

I understand the lack of permissions, but for example I can see the positions of that device even delete it, it is more with the credentials that I am using to log in is that I created that device.

How can I make sure that I actually have permissions to access the device?

Anton Tananaev7 years ago

How can you see positions when you remove device?

kevcar917 years ago

No, I mean, I can

  1. View device positions
  2. Remove the device

Of the devices removed obviously no record remains

Anton Tananaev7 years ago

I see. Possibly the problem is that you don't provide the whole device object in the request.

kevcar917 years ago

There is some way to check if I am missing permissions, to be able to get such permissions or some code and / or reference to update the way I work with the api (you indicated that it was advisable to update as I am working with the old version of Traccar, at the moment I am taking reference from https://www.traccar.org/api-reference/ and some code found on the web and forum)

Thanks in advance

Anton Tananaev7 years ago

Try to include device id in the request.

kevcar917 years ago

Thank you, I already made it work, Adding the device id in the data

public function update(Request $request, $id){
        $data = [
            'id'       => $id, //add this
            'name'     => $request->name,
            'uniqueId' => $request->uniqueid,
            'model'    => $request->model,
            'contact'  => $request->contact,
            'phone'    => $request->phonecontact,
            'category' => $request->category,
        ];

        $device = new GuzzleHttp\Client([
            'base_uri' => 'http://domain:8082/api/devices/',
            'headers'  => ['content-type' => 'application/json', 'Accept' => 'application/json'],
            'body' => json_encode($data),
        ]);
        
        $res = $device->request('PUT', $id, ['auth' => [username, password]]);

        $status = $res->getStatusCode();
        if ($status == 200) {
            Flash::success(trans('content.alerts.deviceUpdateSuccess'))->important();  
            return redirect::to('devices');
        }else{
            Flash::success(trans('content.alerts.deviceUpdateError'))->important();  
            return redirect::to('devices');
        }
}
AsifB5 years ago

Hi Kevcar -
I am also trying to do something similar with Laravel. From where are you getting the password ? I mean, are you reading it from Laravel's 'user' table and using it for calls to traccar API ?

I have created one id with a known password and am generating a session id with that. Then use that session id for future calls. I am not very comfortable with that due to security concerns.

kevcar915 years ago

Hello AsifB -
This project is old and is no longer in my charge for about 2 years, what I did at the time was to check the password, send it in the request and discard it, just for possible security flaws; This is because if it encrypted or manipulated the password in another way it was not readable for the api to traccar.

I know it's a big security bug but it's what the api allowed me at the time.