TapKey - Getting a 403 forbidden error when trying to view own locks via the API - tapkey

On the TapKey Integrator Portal I have a Client Credentials OAuth client, which I created after logging into my owner account.
I can use this to successfully authenticate against https://login.tapkey.com/connect/token with the following scopes:
write:ip:users read:ip:users read:owneraccounts write:owneraccounts read:core:entities write:core:entities read:grants write:grants
However, when I try and call GET https://my.tapkey.com/api/v1/Owners/{my-owner-id}/BoundLocks using the bearer token returned from the connect/token endpoint, I am getting a 403 back.
The locks are owned by the same account I logged into the Integrator portal and created the OAuth client with.
What am I doing wrong?
Thanks

First thing to check in this case is, if the Client Credentials client has administrator rights to the owner account.
As you most likely know, this client acts as its own user and the user identified with an email address in format {oauth_client_id}#iam.serviceaccount.tapkey.com must be added as a co-administrator of the desired owner account.
The option to do this automatically is available when you are creating such OAuth client (as a checkbox), but can assigned manually later as well.
The reason for this not being done always automatically is, that the OAuth client doest not necesarrily need to manage the owner account it has been created in.

Related

No emails are sent to the added and granted user, nor does the user see any locks via the tapkey app while the grants for looks are set

I tried to add a user using the Web API via client credentials and via identity provider. Neither resulted in the invited user receiving an email or seeing the granted lock in his app.
I called /api/v1/Owners to get the owner account's ID for the locks I want a new user to grant access for.
I created a new contact by posting to /api/v1/Owners//Contacts only setting email as identifier (not posting any other data) and using the ownerAccountId from step 1
With the newly created contact id from step 2, ownerAccountId from step 1 and boundlock id I did a put request to /api/v1/Owners//Grants
This resulted in a 200 response, but the new contact did not get any notify or invite email.
When I login to my.portal.nl as owner of the lock I do see the the added user as smartphone user with correct lock and validFrom and validBefore
I expect the invited user in step 4 to be emailed. What am I missing? In your comment you say : Generally speaking, Tapkey will usually not send emails to users.
But how do new users get notified about new locks the can open?
Via the API I do see the users and grants are actually added. I have checked spam folders, but no emails.
When I register as one of these user by using the emailadress I setup as identity and login into the tapkey app, still no locks.
The client ID I'm using is c2f11e47604639323320d08f8e4038f4 and the owner account id is e12e4145-3afb-45ae-81f5-2cdd57d89fb5
I will just summarize what was already explained by Markus in his answer:
Regarding the question about the email:
User will not be informed by email if you create a grant for him.
Regarding the permissions:
If you have created permissions for an user with an identity provider tapkey then these grants are visible for the user once he logs in into the Tapkey app and navigates to his smartphone keys.
If you have created permissions for an user with your own identity provider, these are not displayed in the Tapkey app for a granted user and you need to implement your own application to handle these keys.
We had a look on the grants you have created and as you correctly said, they were created successfuly. All, but one, have been created with your own identity provider and therefore they are not visible in Tapkey app for the granted user. Due to the privacy reasons, I don't want to share anymore details regarding your data here.

Token exchange flow - how to register and login user

Here is my understanding of the token exchange flow:
First i should follow this section of the docs: https://developers.tapkey.io/api/authentication/identity_providers/
After I created identity provider, I want to register my test user using this endpoint https://developers.tapkey.io/openapi/tapkey_access_management_web_api_v1/#/Identity%20Provider%20Users/OwnerIdentityProviderUsers_Put
First question related to the endpoint above is, how do i authorize this request? On swagger documentation there is only clientCredential and AuthorizationCodeAuth options. Does this mean i need one of this types of authorization, so that i can authorize request from my server (from application point of view, lets say).
For endpoints like:
List all owners
Register user
etc.
Now let's say i registered a user, using client credentials to authorize a request.
I am trying to login, following Token Exchange section in docs.
There it says I need to use this POST https://login.tapkey.com/connect/token, i am formatting the jwt as said in the docs, and sending to this endpoint. I am using client_id from my token exchange oAuth client. I got an error with the following message, which is pretty clear to me, but i can't find the solution for it.
{ error: 'unauthorized_client', error_description: 'Client not authorized' }
Mostly, the listet authentication types in the swagger documents are to be able to test the endpoints within the swagger ui. So it is possible to create a oAuth client, pass it to the swagger ui and test the endpoints.
The endpoints itself do not differ between authentication type.
Depending on the purposes the authentication method should be used.
Authorization Code Flow
If you have a service, which works on behalf of a Tapkey user, the authorization code flow should be used.
E.g. you have a booking platform, and your customer should be able to grant access to locks owned by them.
It is not possible to use the authorization code flow to login into the Tapkey Mobile SDK and unlock locks. An authorization client can not request the therefore required scopes.
Client Credential Flow
For server 2 server communication to manage your services, e.g. for adding identity provider users or managing locks which are owned by your services, then the client credential flow would be a good choice.
For that, the client credential client must be authorized as an administrator to the specific locking system.
Token Exchange Flow
To login your users into your app and using the Tapkey Mobile SDK to unlock locks, you have to sign your own JWT tokens on your server and exchange then on the client with the token exchange flow.
Please be aware: It is not possible to use the authorization code flow to sign in as a Tapkey user and then exchange it via token exchange.

How to block Facebook webhook calls for app specific users? [duplicate]

There is documentation for test users in the Facebook Developer online documentation but how do you delete actual users where the application doesn't show in their app list anymore? This is with the knowledge of the access_token and facebook_user_id.
Used to delete Test Users:
https://graph.facebook.com/893450345999?method=delete&access_token=A2ADI1YMySweBABBGrWPNwKMlubZA5ZCrQbxwhtlEd9FIQUrOVjsGD3mnIWEbUhzDz7dkuBekMFdHvjvJ9CZAU7EMSSaZBsgN60FkMCi3AAZDZD
Running the test user link produces the following error:
"error": {
"message": "(#100) Can only call this method on valid test users for your app",
"type": "OAuthException",
"code": 100
}
You seek for application de-authorization:
You can de-authorize an application or revoke a specific extended permissions on behalf of a user by issuing an HTTP DELETE request to PROFILE_ID/permissions with a user access_token for that app.
permission - The permission you wish to revoke. If you don't specify a permission then this will de-authorize the application completely.
To achieve this issue request to:
https://graph.facebook.com/me/permissions?method=delete&access_token=...
Once application de-authorized it will not appear in the list of user's applications.
Update December 2021
Follow the reference for Requesting & Revoking Permissions:
To remove single permission issue a DELETE request to /{user-id}/permissions/{permission-name} passing user access token or an app access token
To de-authorize an app completely issue similar request to the /{user-id}/permissions endpoint
Real users 'delete' themselves from your app when they remove your app from their account, you don't have to do anything.
If you would like to know when users de-authorize your app like this, you can specify a Deauthorize Callback URL in your app's settings. As described in the docs at https://developers.facebook.com/docs/authentication/:
Upon app removal we will send an HTTP POST request containing a single parameter, signed_request, which, once decoded, will yield a JSON object containing the user_id of the user who just deauthorized your app. You will not receive an user access token in this request and all existing user access tokens that were previously issued on behalf of that user will become invalid.
UPDATE: To remove your own app from the user's authorized applications, issue an HTTP DELETE to https://graph.facebook.com/[userid]/permissions?access_token=... as per https://developers.facebook.com/docs/reference/api/user/.
Typically Graph API calls also support doing an HTTP POST with an extra parameter, method=DELETE, in case DELETE calls are not possible/supported.
To do it:
You must have the user access token.
Visit https://developers.facebook.com/tools/debug/accesstoken/ and debug the user access token.
Copy App-Scoped User ID
Via API call HTTP DELETE to https://graph.facebook.com/[App-Scoped User ID]/permissions?method=delete&access_token=[YOUR-APP-ACCESS-TOKEN]

Office365 resource end points for O365-D-vnext (dedicated, not multi-tenants) deployment

We are having issues with obtaining access tokens for Sharepoint/Exchange resources for a non-multi-tenan Office365 deployment.
This tenant has an O365-D-vnext (dedicated, not multi-tenants) environment which seems to use a different resource end points for sharepoint and exchange, and possibly the management APIs as well.
We use the 'client credential flow' (app-only) to authenticate the global admin for this tenant. The authentication went through, and we got back an auth token (which we discard as it’s not applicable in app-only authentication flow) and tenant-id (we verified the tenant id with the customer). We then tried to get tokens for 3 different APIs using
login.microsoftonline.com//oauth2/token
Here is where we are at with this:
1) We were able to get token for
https://graph.windows.net
and access the active directory groups (we should be able to fetch the users as well)
2) We were able to obtain an access token for exchange resource endpoint
https://outlook.office365.com/
but when we tried to use it, we got 404 for users that we know have mailboxes. We are not sure if outlook.office365.com works for O365-D-vnext (dedicated, not multi-tenants) environment.
3) We were able to get token for
https://{tenant}-my.sharepoint.com"
but when we tried to use the token to access user’s Onedrive, it returned this error: {“error":"invalid_client","error_description":"Invalid audience Uri 'https://{tenant}-my.sharepoint.com/'} . We were told by our customer that this endpoint would not work for their non-multi-tenants environment.
We subsequently tried a couple of other vanity URIs that the users of this customer use to access their sharepoint onedrive documents. But we were NOT able to get token for the URIs provided by our customers. We received the following error when using these URIs provided:
{"error":"invalid_resource","error_description":"AADSTS50001: The application named https://<tenant-my-site>.com was not found in the tenant named https://<tenant>-my.sharepoint.com/. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant.  You might have sent your authentication request to the wrong tenant.\r\nTrace ID: … ”error_codes":[50001] …}
Any ideas on how to get access tokens for this type of deployments?

OAuth 2.0 client ids in Django/tastypie implementation

I'm trying to implement OAuth 2.0 for my API. I'm using a third party library to act as the basic OAuth provider, django-oauth2-provider,
and Tastypie as the framework. Those details shouldn't matter too much. The OAuth 2.0 works -- when a user is created, an OAuth 2 client
that manages the user's secret_key and their id is created. A customer can then supply the user ID they get back from the user creation
endpoint along with their username and password to get an access token which allows them to use API endpoints.·
Where I run into issues is retrieving the client id (which must be passed into requests for the access token). Obviously when a user is first created
I can return the client_id with the HTTP response. After that, however, there will obviously be cases where the user doesn't have their client id·
stored locally (this is a traditional user/app setup, not something like Google APIs where your client id is always visible). I want to protect
GET requests to the customer resource with OAuth, but that means I can't query the API for a given user's client ID. And it seems like the whole point
of OAuth is defeated if I can always just pass in a username and password to retrieve my client id from some oauth endpoint. Am I thinking about this wrong?
Also, from reading the OAuth specs I'm under the impression that a client id and client secret are all that should be supplied for getting granted an access token. Yet the implementation I'm using defaults to forcing the user to supply a client id, client secret, username, and password. I've overridden the implementation to require only the client id and secret, but I want to make sure that was the right call and I'm not missing something.
Edit for flup's response:
I'm dealing with a Django API as the resource server, and a user of an iPhone app as the resource owner. The iPhone app is directly associated with the server -- in other words, there are no third parties involved here and no plans to involve them in the future; all software is ours. I would think that the password flow would be what I would need in that case. Indeed, that seems to be what django-oauth2-provider supplies by default. I'd like to stay somewhat in line with what they are doing to not have to completely reinvent the wheel.
The goal of oauth2 is to let the resource owner give a client a valet key which authorizes it to access certain resources on your server on his behalf.
If there are no third parties involved, there is no client to authorize and no need to use oauth2.
Instead, you could use the standard authentication mechanisms present in tastypie.