We recommend Drupal session authentication and then use the normal Commerce entity access system to determine an API user's access to perform operations on our resources. However, just because a user has access to view a product doesn't mean the user should have access to an API endpoint that can return them the full JSON representation of the product. There is data in the full representation of an entity that a casual user might not otherwise have access to, so we should ensure that by enabling a resource the site isn't opening up all if its data to be read by any user.

Comments

marcus178’s picture

I think another reason for implementing this is at the moment I can't see a way for a anonymous user to be able to add a product to the cart. At the moment an anonymous user could only add a line item to the order if the permission Edit any order of any type was enabled for anonymous users which would obviously be a bad idea.

tyler.frankenstein’s picture

Status: Active » Needs review
FileSize
910 bytes

Great module! I'm glad to see it has this much offered with it so far.

Here is a start to this issue with just a hook_permission() implementation. I didn't want to go too far down the wrong road here, so if this patch looks like it is headed in the right direction, I'll continue implementing it. @rszrama, please let me know if this is what you had in mind. If not, please share any alternatives thoughts, thanks!

P.S. The reason I started on this patch was a need for anonymous users to be able to create and modify the contents of a shopping cart. As @marcus178 mentioned, this currently requires the 'Create orders of any type' and 'Edit any order of any type' permissions, and that isn't very desirable.

torgosPizza’s picture

Issue summary: View changes

We're beginning work on our mobile stuff and this looks like the way to go. We also want people to at least add stuff to their cart without requiring authentication first (we ask for that at Checkout).

Thanks Tyler!

dzutaro’s picture

Now I am working on a mobile application that using line-item resource provided by Commerce Services module.

The problem is that a mobile application's user cannot add/remove line items to/from his order if he does not have Edit own orders or Edit own Order orders permissions.

It is because access callbacks of line-item/create and line-item/delete resources call a commerce_order_access() function to check user access.

So I made a patch that creates permissions for line-item resource and checks them where it is needed.

jamescook’s picture

Thanks dzutaro and all others here

We have the same "problem" - being unwilling to grant extreme permissions to anonymous users - but needing anonymous users to be able to add and remove line items in an anonymous order.

The patch at #4 does allow us to do this.

But my question is - isn't this still a risk? (OK - only via "Commerce Services" and not elsewhere, so the risk is reduced compared to the alternatives). But AFAICT an anonymous user "could" influence any other order (if the order id was known) via Commerce Services.

Our idea here would be to limit such changes to orders which have not already been paid. i.e. there should be an extra check in the line-items services.

Something like:

  if (user_access('use line-item/create method') || commerce_order_access('update', $order)) {
      $balance = commerce_payment_order_balance($order);

      if ($balance['amount'] !== 0) {
        return TRUE;
      }	else {
        return services_error(t('Access to this operation not granted'), 401);
      }  
  }
  else {
    return services_error(t('Access to this operation not granted'), 401);
  }
torgosPizza’s picture

@jamescook: IMO you shouldn't make any API calls with an anonymous user. What we've done in the past is create an API User with access permissions for all API operations including creating carts, etc. That way your risk is mitigated - and any "anonymous user" will actually be interacting with an API user, so while the user herself is anonymous the API is still called via a user with correct permissions.

jamescook’s picture

Hallo torgosPizza

thanks for your response.

I can see how insisting on having a non anonymous user in all cases would simplify things.
My question is how do you log in as this API user? Do you login in from the client - i.e. with user name and password (thus exposing the password) or do you use another approach? I'm not quite clear how the risk is mitigated if the credentials for the API user are public.

I may be missing something obvious!

torgosPizza’s picture

@james: It wasn't intuitive for me, either :) Indeed, the API User would be the user that the app logs in with, separate from any users who are logged in as users of the site/app itself. It's really up to you how the app itself logs in (it depends on what authentication methods are available on your server - OAuth is a common and flexible method, and the one most places use these days).

Using a 2-legged OAuth would make sure your app is secure despite "exposing" the password, and of course you might also want to make sure your API requests are made via HTTPS to prevent unauthorized snooping.

By using those methods you can be confident that your app functions securely over the wire, without having to enable higher-level permissions for non-admin users.

jamescook’s picture

Thanks for your reply.

We run https only. But the password for the apiuser is now hardcoded into the client...
Still the window where other orders may potentially be seen is small. On checkout the order is assigned to a real (new) user in any case.

I've moved over to having an apiuser (actually even with her own role at the moment).
It looks quite promising - I don't have to hack the permissons in the _access services functions...

I suppose it's worth noting here that you probably need to modify the webshop rules which create a user from anonymous orders on checkout. (I haven't actually got to checking/doing this yet).

jamescook’s picture

The "problem" with using an "api user" user to create orders is that the handling is not quite the same as for the webshop.
Many rules trigger for the anonymous user - which you now have to clone and edit etc.

So far so good.

But because the order always belongs to a user the code to check if the user name is unique is fired at the wrong time (if at all).
I haven't been able to fully get to the bottom of this but when the order is passed on to the "true" (newly created user) no adjustment is
made to the user name before creation ("mail_username") to ensure it is unique. So you can end up with an error on DB insert of the user.