How to optimally define permissions based on content with TypeORM - sql-server

I'm using MS SQL Server + TypeORM with Nestjs to build an API.
There are different tables created on the already created in the database, like:
User, Client, Country, Building, Asset.
I want that the content that users are able to see is filtered based on some criteria (like Client and Building), for that reason I've defined some intermediate tables to assign permissions to users:
ClientUserPermission, BuildingUserPermission.
All these tables are mapped with TypeORM with their own Entity Repository.
So to get the data from each entity, and what I do to filter the content per user is:
First call to retrieve the ids of an entity from its corresponding permissions table, using the id of the user.
Second call to the targeted entity, filtering the data by the previous ids using the IN operator.
For example, to load all assets that a user can see:
Assets have buildingIds assigned, and BuildingUserPermissions have possible combinations of userId and buildingId, so I do the following:
public async findAllAssetsByUser({...}: QueryParamsDto, userId?: string): Promise<Asset[]> {
...
// Call permissions service, and get allowed buildings per user.
const allowedBuildings= await this.permissionsService.findAllowedBuildingsByUser(userId);
// Retrieve assets filtered by users allowed buildings.
const data = await this.assetsRepo.find({
...,
where: {
...,
buildingId: In([allowedBuildings]),
...,
},
...,
});
return data;
}
I think that there's probably a better way of doing this so I don't have to do one ore more extra calls to get first the permissions.
I've thought that maybe it would be better to query the data using a query builder to automatically do joins with the corresponding permissions table.
If there are better ways please tell me.

Related

How can I reduce the number of database queries for a one to many association in Strawberry GraphQL and FastAPI?

I'm developing a python GraphQL API server using FastAPI and Strawberry, and I'm implementing this feature:
I have two entities, User and Order, which have a one to many association (a User can have many Orders, an Order can only have one User), and I want to get a list of users, each with the list of their orders.
If I were to implement this with a simple REST endpoint, I could make a first query to get the users and then a second query to fetch the orders, sorting out, in the python code, which user each order belongs to based on the foreign key value.
Using Strawberry GraphQL though, it seems I cannot avoid making a query for each user, given that, even using the data loader pattern I would still need to know the order ids beforehand, and this is making the response time much slower.
Is there a solution to this problem? Is my approach completely wrong?
The data loader function itself can do the grouping.
async def load_orders_by_user(keys: list[int]) -> Iterable[list[Order]]:
orders = # select * from order where user_id in keys
groups = {key: [] for key in keys} # dict maintains order
for order in orders:
groups[order.user_id].append(order)
return groups.values()
Variants on that idea:
the loader could also load the users at the same time
the loader could group order ids only and use a different data loader for orders

Separating collections in mongodb database that share a 1-to-1 relationship

I am using mongodb as the database for a project I've been working on and in the database I have a "user" collection and an "account" collection. Every user has one account and every account has a "user" field that is the _id of the corresponding user. The reason I separated these into two collections is because I thought it made sense to keep the user's sensitive data (password, email, legal name, etc.) separate from the account data (things like interests, followers, username, etc.). Also the account collection has a lot of fields so it just seemed easier to not over-saturate the "user" collection with data.
So, my question is - Now that I essentially have 2 collections pointing to the same user, should I use the "user._id" to query both users and accounts? Since each account has a unique "user" field, is there a reason to query those accounts with their own _id property? It seems odd to keep track of two different _id's on the frontend and conditionally send either the user._id or account._id.
The two main drawbacks I have found when using the user._id to query both users and accounts is:
When querying account data, I have to almost always make sure I send the "user" field so I have that id on the front end.
If in the future, I wanted to add the ability for users to create multiple accounts, I would have to change the code to now fetch account data using the "account._id".
Hopefully that all makes sense, and maybe it doesn't even make sense for me to separate those collections. Thank you to anyone who can help!

Query MongoDB to find array that contains elements from another array

For my users table, each user has an emails<Array> property allowing them to associate multiple emails with their accounts. I want to make sure this is still unique so wether they're creating a new account or updating existing I need to query the DB to identify if that email address exists.
I know I can use users.find({ emails: email }) and could loop over that to identify, then check the _id (on update) to ensure everything but that puts me in a loop outside the query.
I'm curious if there's a method I'm not seeing for querying to identify if any emails being submitted match any emails from across the table in the db?

Querying Salesforce Activity History using Power Query raises DataSource.Error

I think what I am doing is quite simple but hitting an unexpected error.
When I navigate the Salesforce.com Object Database using Power Query, and attempt to access the Activity History table I receive the following error.
DataSource.Error: entity type OpenActivity does not support query
Details:
List
Is there such thing as unqueryable tables from Salesforce Object Library or can I access the table using a different method in PowerQuery? List doesn't seem to work...
let
Source = Salesforce.Data("https://login.salesforce.com/", [CreateNavigationProperties = true]),
SFDC_ActivityHistory = SFDC{[Name="ActivityHistory"]}[Data]
in
SFDC_ActivityHistory
I do my usual login and then provide organization wide security credentials. Other tables work fine like accounts and opportunities.
ActivityHistory Table cannot be accessed directly, but you could get query access to it as the child relationship of a primary object. For instance:
Select Name, (Select Subject, ActivityType from ActivityHistories) from Account
Please refer to the last section, "Usage", of the document: https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_objects_activityhistory.htm

django models: more efficient way to retrieve objects via OneToOne relationship

I am using two models, one is User (from django.contrib.auth.models) and the other is Privilege:
class Privilege(models.Model):
user = models.OneToOneField(User)
...
I am able to retrieve the user's privilege:
user = User.objects.get(username=request.user)
if user:
privilege = Privilege.objects.get(user=user)
My question: does it always take two database operations to obtain the privilege object? Can I do it in just one?
Firstly, you don't have to manually do the second query, you can simply traverse the relationship:
try:
privilege = User.objects.get(username=request.user).privilege
except User.DoesNotExist # Use this with get()
pass
but it will do the second query in the background.
So, you can use select_related to make the reverse traversal more efficient (i.e. 1 query)
select_related: Returns a QuerySet that will “follow” foreign-key relationships, selecting additional related-object data when it executes its query. This is a performance booster which results in a single more complex query but means later use of foreign-key relationships won’t require database queries.
privilege = User.objects.select_related("privilege").get(username=request.user).privilege

Resources