Security on GET with query params - rest

I have a dilemma. What do you return for a GET REST request where a user doesn't have the right to use a certain query param.
For example : GET /transactions?user=admin
If an user, that is not the admin tries the following example, what should be the proper response 403 or an empty list?
He has the right to search for any other user, but not the user admin.

Related

Salesforce SOQL to fetch all the accounts assigned to the logged in user

I have the accessToken of the logged in user and currently my query looks like below
https://xxx.salesforce.com/services/data/v45.0/query?q=SELECT Id,Name,Industry,Ownership,AnnualRevenue,NumberOfEmployees,Phone,Website FROM account ORDER BY LastModifiedDate DESC LIMIT 10
The above query will return last 10 modified accounts that the loggedin user has access to. What I want is to get only those accounts that are assigned to the logged in user.
You need a query similar to
SELECT Id, Name
FROM Account
WHERE OwnerId = '005...'
ORDER BY LastModifiedDate DESC
LIMIT 10
All users' ids in all SF instances in the world start with 005.
You can get the user id from the login success response. Which OAuth2 flow you've used? https://help.salesforce.com/articleView?id=sf.remoteaccess_oauth_user_agent_flow.htm&type=5 ?
In that example the user's id is hidden in the OAuth "id" field (identity, service that returns some info about the user. name, email, preferred language, locale, timezone...)
https://www.customercontactinfo.com/user_callback.jsp#
access_token=00Dx0000000BV7z%21AR8AQBM8J_xr9kLqmZIRyQxZgLcM4HVi41aGtW0qW3JCzf5xd
TGGGSoVim8FfJkZEqxbjaFbberKGk8v8AnYrvChG4qJbQo8&
refresh_token=5Aep8614iLM.Dq661ePDmPEgaAW9Oh_L3JKkDpB4xReb54_pZfVti1dPEk8aimw4Hr9ne7VXXVSIQ%3D%3D&
instance_url=https://yourInstance.salesforce.com&
id=https://login.salesforce.com%2Fid%2F00Dx0000000BV7z%2F005x00000012Q9P&
issued_at=1278448101416&
signature=miQQ1J4sdMPiduBsvyRYPCDozqhe43KRc1i9LmZHR70%3D&
scope=id+api+refresh_token&
token_type=Bearer&
state=mystate
It's bit hard to see but if you would receive this response you need to extract the 005x00000012Q9P part. If you don't trust parsing that url - well, call that "id" endpoint. See https://salesforce.stackexchange.com/q/11728/799 for response format and some more ideas.

REST-API users.list with the eppn

Since we have some integrations with Rocket.Chat, we do use the API to create, query and subscribe User of a System to the Rocket.Chat.
We use the SAML authentication and we work with the eppn parameter.
Before it was easy to search for a user in rocket chat with the eppn, since you could query the eppn with the API users.list.
api/v1/users.list?query={"eppn":"eppn-of-user"}
After I upgraded the Rocket.Chat to the 3.9 Version, I saw that it is not possible to query the eppn with the users.list API.
The structure of User is changed and now the eppn parameter is a child of services.saml.
I can query the eppn in the MongoDB like this:
coll.find({'services.saml.eppn': "user-eepn"})
But no way to query the eppn with the API:
api/v1/users.list?query={'services.saml.eppn': "user-eppn"}
{
"success": false,
"error": "Invalid query parameter provided: \"{'services.saml.eppn': \"user-eppn\"}\" [error-invalid-query]",
"errorType": "error-invalid-query",
"details": {
"helperMethod": "parseJsonQuery"
}
}
Does anyone have an idea about it?
Thank you!
So everyone, I just got the solution to my problem, if any one will have the same problem.
First of all for the EJSON parse function the query must be written like this:
api/v1/users.list?query={"services.saml.eppn": "user-eppn"}
But the second problem is that Rocket.Chat doesn't allow a query on the services parameter.
It is a problem of permissions, so to query the services parameter and then the eppn parameter, there must be permission given to the User.

When to know when I should put the parameters in the body or not?

I was thinking about the most logical request for my api, while trying to think about rest, but I can't wrap my head around which one of these three choices is correct: what would be the best design for the request, supposing that I want to send 10 from some user triggering the request to user2?
1)
POST /pay
body: {"username": "user2", "amount": 10}
2)
POST /pay/users/user2
body: {"amount": 10}
3)
POST /pay/users/user2/10
I don't know how much information should be in the URL vs. how much information should be in the URL.
Suppose you have many users and some functions that users can perform.
So your api could be like:
GET /users # get user list
POST /users + {"name": "John"} # create user
DELETE /users/{userId} # remove user
GET /users/{userId} # get user by id
GET /users/{userId}/payments # get users payments
POST /users/{userId}/payments + {"amount": 10} # submit new payment
GET /users/{userId}/payments/{paymentId} # get users payment details
As you can see it is a very simple resource tree.
I recommend taking a look at restful-api-guidelines
You want to put an Canonical Identifier in the URL and any other data in the body.
For a POST (which is used to create an new resource) the Canonical Identifier generaly does not yet exist therefor it doesn't need one.
The server then creates one and returns it to the client in the location header.
If you mean to update instead of insert, PUT or PATCH should be used. If the username is your Identifier, then option 2 should be used. An identifier should in general not be editable.
Since your "adding" an new payment I would suggest using option 1. But I would call it payment and perhaps add more information about the payment.

REST GET URL Naming

What is the best way to design or name an API URL that would get a specific user with a given unique identifier? I'm using cognitoId as the unique identifier.
Which of the following should I use?
/profiles/profile, then pass the cognitoId as URL Query String Parameters
/profiles/{id}
/profiles/profile then check 'Invoke with caller credentials'
If it is an API where any authorized user can get anyone's username by passing a unique ID, then you could use something like this: /profiles/{id} For example, https://api.github.com/user/1
If it is an API that returns the username of the caller by using the cognito ID, then /profiles/profile should work. See $context.identity variables in documentation to fetch the cognito ID.

How Can I filter Facebook Events Using Location by FQL

How Can I fitler Facebook Events Using Location By FQL
ex. I want to get all event which will be in Egypt
SELECT name FROM event
WHERE strpos(lower(name), 'Egypt') >= 0
https://developers.facebook.com/tools/explorer?fql=SELECT%20name%0AFROM%20event%20%0AWHERE%20strpos%28lower%28name%29%2C%20%27Egypt%27%29%20%3E%3D%200
But when I try to use the above Query it returns that for me:
Your statement is not indexable. The WHERE clause must contain an
indexable column. Such columns are marked with * in the tables linked
from http://developers.facebook.com/docs/reference/fql
Note : I hope to get the public events filtered by event name contains.
With the changes that they have made, queries using an app access_token cannot
use the above query:
SELECT name,location FROM event WHERE contains('egypt')
The query works with session tokens (user access_tokens), however, with an app access_token
it just returns:
{
"error": {
"message": "(#200) Must have a valid access_token to access this endpoint",
"type": "OAuthException",
"code": 200
}
It was surprising to me since I could still use any other query else than contains on the events table with an app access_token
UPDATE:
After looking at their documentations, I found out that you can only use the app access token for very limited set of queries:
https://developers.facebook.com/docs/reference/api/search/
What I finally did was I used the following to obtain a session access_token from my user as a page_manager
https://www.facebook.com/dialog/oauth?client_id={MY_CLIENT_ID}&scope=manage_pages&redirect_uri={MY_REDIRECT_URI}&response_type=token
The above query returns your your access_token and you can use it to run your query successfully. What it basically does is that it appends your access_token to you as a hashed attributed
{MY_REDIRECT_URI}#access_token={MY_ACCESS_TOKEN}
If you would like to parse the access token on the server, this would not work for you, since the hashed attribute is not sent with the request to your server. What you can do is to append type=web_server to the above request to facebook. In that case the access_token will be returned as a request parameter named code
The closest you can get is to use the contains predicate
SELECT name,location FROM event WHERE contains('egypt')
Which will get you some events that contain "egypt" in the text