Code to update device with api

kevcar91 10 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 Tananaev 10 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.

kevcar91 10 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 Tananaev 10 years ago

How can you see positions when you remove device?

kevcar91 10 years ago

No, I mean, I can

  1. View device positions
  2. Remove the device

Of the devices removed obviously no record remains

Anton Tananaev 10 years ago

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

kevcar91 10 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 Tananaev 10 years ago

Try to include device id in the request.

kevcar91 10 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');
        }
}
AsifB 7 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.

kevcar91 7 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.