With nats can I export a stream from one account to different accounts which can import on the same topic? - publish-subscribe

I'm using nats and I'm not sure if it will be able to do what I'm attempting. My understanding is that accounts will allow me to have overlapping subjects since the subject space is not globally shared.
What I'd like to be able to do is have different users (in different accounts) subscribe to the same subject in their account with another application user/account publishing separately to each of them?
So, if I have the following three users/accounts:
accounts: {
A: {
users: [
{user: a, password: a}
]
},
B: {
users: [
{user: b, password: b}
]
},
C: {
users: [
{user: c, password: c}
]
},
}
I'd like users b and c to subscribe to mysubject (which are non-overlapping in their own account) and have user a publish to each of them separately.
Having read and re-read the documentation a few times, it doesn't seem like that's possible because I'd need to export different streams from user a that users b and c could import separately?
I'm really just looking to confirm that this is the case.
Thanks.

Related

Complex firestore rules

I have a top level collection: "organizations", in that collections doc's there is an employees map like this:
employees: {
uid1: {
displayName: John Do
[...]
}
uid2 {
[...]
}
}
I have an other top collection: "customers" with an organization map like this:
organizations: {
organizationId1: some string,
organizationId2: some other string,
[...]
}
where:
uid is the user id from firebase auth
organizationId is the document id of an organization doc.
user can be in multiple organizations, and customers can be share between multiple organizations as well.
I want to restain acces to customer doc, at user who are employee of at least one organization listed in the customer doc.
Has there is no way to loop in firestore.rules
I think the answer may be mapDiff, and custom claims.
user custom claims:
organizations:[organizationId1, organizationId2, ...]
But i have some difficulty to understand the documentation:
https://firebase.google.com/docs/reference/rules/rules.MapDiff
Is there a way to achive that ?
Maybe I didn't understand it correctly, but you can try something like this:
allow read, write: if employeeOrganization in [organization1, organization2...]
https://firebase.google.com/docs/reference/rules/rules.List
I finaly find the ways to set rules for that:
match /customer/{cId} {
allow create: if request.auth != null;
allow read, update: if (request.auth.token.organisations.keys().hasAny(resource.data.organizationIds.keys()));
allow delete: if false;
}
My custom claims are like:
(there is only 1 to 5 organisations so it's not heavy to transmit)
organizations:{
organizationId1: "role",
organizationId2: "admin",
...
}
My file customer docs as a map like this:
organizationIds{
organization1Id: "some AES key used for security purpose",
organization358Id: "some AES key used for security purpose"
}
It work nice and using custom claims save countless read per day.

Firestore rules - use exists with where

In my project I have firestore collection of users and classes. Each user can be part of one or more classes. Classes document has property members which is an array including all users uids in that class.
For instance:
users documents:
doc.id: USER1UID
{ name: 'user1', email: 'user1#user1.com', phone: '+123 456 789 001' }
doc.id: USER2UID
{ name: 'user2', email: 'user2#user2.com', phone: '+123 456 789 002' }
doc.id: USER3UID
{ name: 'user3', email: 'user3#user3.com', phone: '+123 654 789 003' }
classes documents:
doc.id: ABCDEF
{ name="class1", members: ['USER1UID', 'USER2UID'] }
doc.id: GHIJKL
{ name="class2", members: ['USER1UID', 'USER3UID'] }
doc.id: MNOPQR
{ name="class3", members: ['USER3UID'] }
I need to write a rule that will allow user to read details about another user ONLY if they are in the same class. Every user can also read own profile.
In this case user1 can read details of user2 and user3. (they are together in class1 and class2).
User2 can read details only of user1 (they are together in class1).
User3 can read details only of user1 (they are together in class2).
I need something like:
match /users/{userId} {
allow read:
//user is logged in
if request.auth != null
&& (
//user can read own profile
request.auth.id == $(userId)
//there is a class where are both (requesting and requested) users
|| exists( (/databases/$(database)/documents/classes/).where(request.auth.id in members).where($(userId) in members)
)
}
What you're trying to do is not possible with your database schema, because security rules don't allow you to perform queries. You may only request one document at a time using its known path, maximum of 10 documents per rule execution.
What you can do instead is manage each users document to contain a list of all other users who have a class in common with that user. But you will have to write some code to keep that up to date as the roster of the classes might change over time. This might be a good use for Cloud Functions.

Should I have different collections for different users in mongodb?

Im new to databases and mongo. I'm creating a web app that has different types of users that have access to different routes via different UI's. eg: user, company, admin. My question is should I create a single collection that houses all users and simple add a "user-type" or "access-level" as a property on each User object? or should I have 3 different Collections, one for each type of user?
What is common practice for this type of thing?
What would be fields for each type of user? If they are same, use user type option. Same user can be in multiple roles tomorrow. Storing in same collection would be better.
If the fields to be stored are completely different, and there is not a chance that same user can be in 2 roles ever in your application, use 3 collections.
By your question your Schema can have Roles set as ENUM and value as user, company, admin. and role should be accordingly set while you save the data to db
var UserSchema = new Schema({
first_name: {
type: String,
required: true
},
last_name: {
type: String
}, Roles: {
type: String,
enum: ['USER', 'COMPANY', 'ADMIN'],
default: 'ACTIVE'
}
});
UserSchema.index({
username: 1,
role: 1
});

MongoDB Data-Modelling: a pattern for text search in referenced documents

I'm working on a project that use MongoDB; and I would like to hear your opinion about a feature I'd like to implement.
In paticular there are "Users" that reside in "Cities" where they offer "Services".
I have created three Collections representing the three above mentioned entities:
the User collection has a one-to-one reference with City and a one-to-many one with Service.
I would like making a search function that search in the user collection and in referenced collections for a given string available.
Therefor given the following two users, two cities and three services ...
User
{
_id:"u1",
name:"Jhon",
City: ObjectId("c1"),
Services: [
ObjectId("s1"),
ObjectId("s2")
]
}
{
_id:"u2",
name:"Jack",
City: ObjectId("c2"),
Services: [
ObjectId("s2"),
ObjectId("s3")
]
}
City
{
_id:"c1",
name: "Rome"
}
{
_id:"c2",
name: "London"
}
Services
{
_id:"s1",
name: "Repair"
}
{
_id:"s2",
name: "Sell"
}
{
_id:"s3",
name: "Buy"
}
...and searching for the word "R", the result should be the u1 user (due to the R in "Rome" and "Repair").
Given that I cannot do joins, I was thinking making a mongo shell script that adds an additional field to the User collection with all the searcheable referenced strings.
As in the following example
{
_id:"u1",
name:"Jhon",
City: ObjectId("c1"),
Services: [
ObjectId("s1"),
ObjectId("s2")
],
"idx":{
city: "Rome",
services:["Repair","Sell"]
}
}
Finally the question(s)...
Do you think is it a good choice? And Can you propose an alternative solution (or share a link about that, i didn't find nothing usefull)?
And how would you mantain that field constantly updated; for instance, What about if the referenced city name or the services offered by a user change?

Does it make sense to use internal anchors for filtering a REST API's representation?

As a follow up to my previous question about REST URIs for retrieving statistical information for a web forum Resource, I want to know if it is possible to use the internal anchors as filter hints. See example below:
a) Get all statistics:
GET /group/5t7yu8i9io0op/stat
{
group_id: "5t7yu8i9io0op",
top_ranking_users: {
[ { user: "george", posts: 789, rank: 1 },
{ user: "joel", posts: 560, rank: 2 } ...]
},
popular_topics: {
[ ... ]
},
new_topics: {
[ ... ]
}
}
b) GET only popular topics
GET /group/5t7yu8i9io0op/stat#popular_topics
{
group_id: "5t7yu8i9io0op",
popular_topics: {
[ ... ]
}
}
c) GET only top ranking users
GET /group/5t7yu8i9io0op/stat#top_ranking_users
{
group_id: "5t7yu8i9io0op",
top_ranking_users: {
[ { user: "george", posts: 789, rank: 1 },
{ user: "joel", posts: 560, rank: 2 } ...]
}
}
Or should I be using query parameters ?
Not sure what you are trying to do exactly, but make sure you understand that fragment identifiers are not seen by the server, they are chopped off by the client connector.
See: http://www.nordsc.com/blog/?p=17
I've never seen anchors being used that way - it's interesting. That being said, I'd suggest using query parameters for a couple of reasons:
They're standard - and consumers of your api will be comfortable with them. There's nothing more annoying that dealing with a quirky api.
Many frameworks will auto-parse the query parameters and set them in a dictionary on the request object (or whatever analogue exists in your framework / http server library).
I think it would make more sense to have:
/group/5t7yu8i9io0op/stat/top_users
/group/5t7yu8i9io0op/stat/popular_topics
/group/5t7yu8i9io0op/stat/new_topics
/group/5t7yu8i9io0op/stat/user/george
No you cannot do that because as Jan points out the server will never see that fragment identifier. Literally, that part of the url will not reach the server.