prepare IM room for rocket.chat users? - rest

I'm currently looking at the rocket.chat REST-API and can't find a way to prepare a IM-room for two users. Both users do not have the permission to create a direct message (missing create-d). But I do have a privileged admin/bot-user, which should connect them, at any time.
I tried to im.open a roomId with both user id's (I've noticed, that direct messaging rooms are groups, without name and concat(userid1, userid2) as id). But I always receive:
{
"success": false,
"error": "[invalid-channel]",
"errorType": "invalid-channel"
}
The im.create method cannot be used, since I can't tell the API which two users I want to connect (the first is always "me"/the logged in user).
Using group.create would create a room with 3 members (user1, user2, me). Which isn't what I want either.
Is there a way to create a IM between two users? Without the permission "create-d" on these two?

Related

How to get user clientroles via REST-API from keycloak?

I am aware of this question especially this answer.
According to the documentation calling GET /{realm}/users gets you a UserRepresentation, which lists clientRoles as optional. That suggests, that it should be available in principle. But I do not know how I can leverage this.
I defined the endpoint as
const usersEndpoint = `${adminEndpoint}/realms/${realm}/users`;
Which should be correct.
Or am I reading something wrong?
I was thinking about it the wrong way. You are able to get a list of users having a role or a group by:
GET /{realm}/clients/{id}/roles/{role-name}/users
resp.
GET /{realm}/groups/{id}/members.
In order to get the list of every user having which roles, you could iterate over all roles and request their repective users and merge it.
Or in my way, retrieving the list of users having a discrete role was enough to achieve what I wanted.

Using Firebase Security rules, how can I check for available usernames without making the entire node public?

In my Firebase database, I have a section for storing usernames that are taken.
There is a “usernames” node, where the username is the key, and the user’s ID is stored in a “userId” atrribute.
usernames
{
username1
userId : "exampleId1"
username2
userId : "exampleId2"
username3
userId : "exampleId3"
...
}
When a user is signing up, before they create an account and are Authenticated, the app must check that the username is not taken.
In order for this to work, the “usernames” node has been set to public in the Firebase Security Rules:
"usernames": {
".read": true
}
Unfortunately, this will make every taken username and internal user ID visible, which is a security concern and not something that should be done.
(for those that don’t know, public nodes can be accessed through a browser like so):
https://mydatabasename.firebaseio.com/usernames.json
There are other nodes for banned usernames and emails that work in a similar way; they have to be checked before a user is Authenticated, and should not be fully exposed to the public.
My question is: When a user is signing up, how can I check for available usernames without making the entire node public?
To know if a specific user name is already taken, the user doesn't need read permission to /usernames but it's suffice to give them read access to /usernames/$username. So:
"usernames": {
"$username": {
".read": true
}
}
With these rules, you code can check whether the specific user name that the user wants to claim is already taken (by someone else), but they can't request a list of all user names.
Two options comes to mind, the first is allowing the public read access to your database while the second method is what I would do in a real project:
Method 1: Maintain a Separate "Usernames" Node
With this method you create a secondary node, let's say it's called usernamesInUse and this would be world readable. Its structure would look like this:
{
"usernamesInUse": {
"username1": true,
"username2": true,
"username3": true
}
}
Checking if a username exists is as simple as:
db().ref('usernamesInUse/username2').once('value', (snapshot) => if (snapshot.exists()) ...)
The downsides to this method are that you have to have processes in place to update this node whenever a new user is added, modified or deleted. However this would give secure read access to usernames and nothing else.
Method 2: Create a Cloud Function (How I would do it)
Create a simple Cloud Function with an HTTPS endpoint that checks for the existence of the username and returns a 200 or 404 status code. Your database would not need any world readable permissions.
This avoids the need to duplicate data, prevents users from downloading a full list of every user in your system and prevents the world from unmetered access to your database. You also have the opportunity to block access to abusive anonymous visitors.
Tell me if you like the idea. :)
I would create a singleton with all func and variable private which will only return a Bool and take Username variable.
This way no one can access data or func from this part. No injections possible.
Insisde the singleton you can check all usernames and do whatever you want.
return only Bool.

Modelling URI to demonstrate many to many relationship between 2 API resources

A credit card account (Account) can belong to multiple customers and One customer (Customer) can own multiple credit card accounts. I need to design REST API(s) which can return all accounts owned by a customer. The account number is coming from a manual input by an end user like a service rep into a freeform text box. Following is a constraint though
End consumers/developers know only account number & have no knowledge of customer id (unique identifier of a customer) upfront so to retrieve a list of accounts belonging to a customer -
1.1 find the customer owning the account in question
1.2 then find all the accounts owned by a customer.
I can think of couple of options but feel either they will make interaction chattier or may not be restful.
Only GET scenario has been discussed in below options
Option 1
Ideal way to interact with two separate resources but makes interaction very chatty and will put undue load on the system. Two calls everytime to know all accounts owned by a customer. So 20 Million calls/day in SOAP/RPC will become 40 million calls in REST.
/accounts/{account_nbr}/customers --> returns a list of customers for a specific account
/customers/{customer_id}/accounts --> returns a list of accounts for a customer
Option 2
I don't think this will be restful because query parameter is supposed to be used for identifying a resource in a non-hiearchical data
/customers/accounts?account_nbr = XXXX
Option 3
This option indicates that a list of accounts linked to account_nbr is being returned which is not right because list of accounts are linked to a customer
/accounts/{account_nbr}/linked_accounts
Option 4
Term the relationship between customer and an account as a new type of resource. Its trying to indicate get a list of customer to account relationships and identify specific instance where an account in customer_account_relationships has a value of XXXX.
/customer_account_relationships?account_nbr=XXXX or
Which of the above option, if any, is close to being restful representation? Is there any other way to design this interface?
EDIT
Expected response
{
"customerName" : "Bob",
"customerId" : 1234,
"listOfAccounts": [
{
"accountNbr" : "abcd"
"accountType": "creditcard"
},
{
"accountNbr" : "qrst"
"accountType": "creditcard"
}
]
}
You correctly rejected the first three options. I see two reasonable choices for you. One is to go with option 4:
GET /customer-summaries?account-number=<account-number>
The other is to just make /accounts top-level and do essentially the same thing:
GET /accounts?same-owner-as-account=<account-number>
In the former case, you'd get an instance of your resource above. In the second, you'd just get a list of accounts, each of which presumably has a link to the account owner. It's up to you as to which better suits your use case.
Note that option 4 may return multiple records if there are multiple owners for the same account. That's a common situation for married couples.

REST API - filters, child entities or is leaking information really so bad?

The basic problem
I have a rest API. For the sake of this example, let's say I have users, they can be members in any number of groups, and both users and groups can own objects.
Any user can filter objects by various criteria:
/objects?color=green
/objects?created=yesterday
but only members of a given group can filter by group ownership:
/objects?groupId=1
and only the actual user can filter by user ownership:
/objects?userId=55
There are now two basic patterns - one could make the object a child entity of the group, such as:
/groups/4/objects/1
with 4 being the group ID and 1 being the object ID. the other option is having group and objects side-by-side:
/groups/4
and
/objects/1
making the object a child of the group and/or user would eliminate the other filtering options - essentially, i have one object with multiple paths to it.
The actual question
If I want to limit access for a regular user so that he/she can only access objects that are directly owned by him/her or by groups that he/she is a member of, it does work as a filter on the collection - but what about the entity level?
If I try:
/objects/9
But the object is owned by a group I am not a member of, I would expect an authorization error, while if the object doesn't exist at all, i would expect a "not found" - this, however, would leak information about the book's existence, and I also would have to retrieve the object in order to be able to determine whether or not the user has the right to see it.
So I came up with this:
/objects/9?groupId=4
or
/objects/9?userId=55
In this, I can base the initial decision on authorization on the group ID or user ID, and then try to retrieve the object with the additional restriction.
If the user is NOT a member of group 4, I can say not authorized, and if the book doesn't exist, I can say not found, meaning not that the object doesn't exist, but that the object doesn't exist in group 4. This answer is more clear, and also I would not have to retrieve the object first.
The alternative would be to return an authorization error regardless of whether it is due to the fact I am not authorized OR due to the fact that the object doesn't exist. This answer is slightly imprecise, but it would put less of a burden on the caller.
Another possibility would be to map multiple paths:
/objects
/groups/4/objects
/users/9/objects
/colors/green/objects
This seems rather messy and would violate the principle of having a single path for a single concept.
Does anyone have any practical insight on this? Any reasons (apart from the ones mentioned) why one or the other would be preferable?
If I understand you correct, every object is linked to (at least) one group or (at least) one user, so you don't have the problem of having an object without a group or user.
If this is the case I don't see the point in using filters as it would not make sense in a REST way and also not give any benefit to the client site.
So as you suggested you could just use the following:
/groups/$groupID/objects/$objectID
and
/user/$userID/objects/$objectID
Now you server should check if the client is authorized ("the user a member of the group" / "the current user") given the $groupID xor the $userID
if not authorized: not even check if object is there. Just give the not authorized error.
if authorized: give standard response codes
I don't see a benefit for a non authorized client to get information if a resource is available or not as its not important for him, because he cant access it either way. And as you suggested it would result in a information leak which could result in a security problem (but that is completely depending on your API and what its information and usage).
Now lets go through the scenarios for group calls:
User Arnold (member of groups: 1,2,3) wants to access existing object 7 of the member group 3.
GET /groups/3/objects/7
response: #200
User Arnold (member of groups: 1,2,3) wants to access non existing object 55 of his member group 2.
GET /groups/2/objects/55
response: #404
User Arnold (member of groups: 1,2,3) wants to access existing object 11 of a non member group 5.
GET /groups/5/objects/11
response: #401
User Arnold (member of groups: 1,2,3) wants to access non existing object 19 of a non member group 5.
GET /groups/5/objects/19
response: #401
And for user objects:
User Arnold wants to access his non existing object 56.
GET /user/arnold/objects/56
response: #404
User Arnold wants to access his existing object 13.
GET /user/arnold/objects/13
response: #200
User Arnold wants to access Jon's existing object 77.
GET /user/jon/objects/77
response: #401
User Arnold wants to access Jon's non existing object 88.
GET /user/jon/objects/88
response: #401
As you can see the server just responds with #401 if the client is non authorzied. Additional it would be great to give a error message in the body e.g. Sorry, but you are not authorized to see content of user "Jon" or Sorry, but you are not authorized to see content of group "ABYZX", so the client knows what the problem is.
This seems rather messy and would violate the principle of having a single path for a single concept.
I don't see it that way as also different sources (1) (3) and SO answers say its really no problem to have multiple paths or URIs.
Each resource in a service suite will have at least one URI identifying it.
It could help clients understand the authorization process and with that help them to navigate through your API.
Any of the URI choices you describe are fine. I perfer flat URIs, but it doesn't really matter.
The real question is how to handle unauthorized requests. In that case, I suggest responding with 404 in all cases including when the resource exists, but the user doesn't have access. It avoids the information leaking problem and it is completely compatible with the HTTP specification.
This pattern makes sense logically too. From the perspective of the user with insufficient permissions, the resource doesn't exist.
If you have ever tried to view a private Github project without having permissions to view it, you would have seen this pattern in action. Github will respond with 404 even if the project actually exists.

How to ensure that all WebAPI/OData requests pertain to a specific user?

I found this process simpler when consuming a WCF service (SOAP), but here goes...
Where Users 1..* Categories:
In exposing an OData RESTful service (MVC4, WebAPI, OData), client-side code could be issued like:
/odata/Categories?$filter=startswith(CategoryName,'paid')
Or even
/odata/Categories
Would return all categories for all users. Not very secure.
I want to ensure that all requests issued when a user is logged in (I'm using forms authentication with my own custom role provider) only return data related to that user (where userID=x). Is there a custom filter that needs to be created, whereby even if a logged in user saw the outgoing WebAPI/OData request paths (often defined in JavaScript), they can't try to get other user's information?
Each navigation property or related table in the db has a UserID field where the "AND UserID=x" could be used.
Would this involve creating some sort of FilterQueryValidator (actually query addition) similar to what's found at the bottom of this page?
I'm just not sure on how this works, and would like some pointers.
FYI: This may be related to this other question, but more specific on user-based requests.
You can use a filter attribute or you can override GET / POST etc in your ODataContoller to add the UserID == X to the Linq expression.
e.g.
public override IQueryable<Product> Get()
{
return _context.Products.Where(x => x.UserID == user_id);
}