Elasticsearch: private user documents - elasticsearch

We're considering using Elasticsearch for our webservice. Since ES operates at a low level, for authentication and authorization there has to be some layer above it. I see Shields which apparently can control on a roles-based level what a user, and admin, a developer etc. can do in the search index. What I could not find, however, is how to control data access on a user level: Every user has to have access to all public documents plus his/her private ones.
Is there an ES plugin/paradigm that handles this?

The idea with Shield is to have a user group in the indexed document:
{
"text":"Document 1 is public",
"user_group": ["public"]
}
{
"text":"Document 2 is restricted",
"user_group": ["restricted"]
}
Then you can force a filter to be applied for a specified user group
# For users in group public
{"term" : {"user_group" : "public"}}
# For users in group restricted (can see public as well)
{"terms" : {"user_group" : ["public","restricted"]}}
Elasticsearch 2.0 / Shield 2.0 has improved Document level security. Prior to that you were forced to use Index Aliases.
SearchGuard (a Shield alternative) behaves likes Shield: dlsfilter binds a user group with filter.
In both cases, binding a user to a document might be a difficult (impossible?) task, because everything is based on user groups/roles, not individual users. You could generate a group specific to each user though. Each time you add a user, it will force you to add a user group, and configure its specific grants.

Related

AWS Cognito use custom attribute to map Spring application ROLE instead of cognito:groups

In my application the users are split in 2 macro categories: Customer and Backoffice, every category has a subset of role, for example MANAGER and USER for Customer type and different ones for the Backoffice type.
So a user could be a Customer with a MANAGER role or a Backoffice with, for example, a SALES role.
Every Spring + Cognito guide on web uses cognito:groups to map the Spring ROLE, but for my case I would need to nest groups which is not possible on Cognito.
I've been thinking to use 2 custom attributes ( writable only by the admin) to set the category and role of the user respectively.
My question is, is there any disadvantage to using attributes instead of the groups?
One major concern is, those custom attributes won't be available as claims in the access token. But groups are available. So If you plan to use acces_token you may have to consider that.
There are some other minor considerations that I can think of, which may or may not be related your implementation:
Maximum number of custom attributes per user pool is 50.
Once created, you can not edit the name, min/max length and mutable property of the custom attribute. Also we can not delete that.
Even though nested groups are not supported in Cognito, is it not an option to create groups like: category_role? example: Customer_ MANAGER?

What is the best way to update the large data set on single request

I am working on Social networking application with at least 0.2M users. On the application user can share anything from third parties as well as user can upload own media as post. There are different types of privacy
user privacy
user can be public
user can be private
Any content shared or uploaded by the user will be in a box, and box also has different types of privacy
public box (Everyone can see the content of this box if you are public)
friend only box (Only your followers can see the content of this box)
private (Only you can see the content of this box)
Now the problem is that I have large data set. So when a user change his/her account privacy from public to private or private to public I have to update all the data according to privacy. Also, user can change the privacy of the box too.
So I need to update the user all shared posts of this box accordingly. But most of the time I failed to update due to framework and also technologies that I am using
Technologies that I am using
Lumen (PHP) microservice architecture
MySQL
Elasticsearch (For retrieval with joins)
Redis & Memcached
Postgres
When user shares anything on the platform the shared data is stored in the database and also data inserted in elasticsearch so all the data retrieved from elasticsearch with PHP client.
Now I want to define the architecture like Instagram that whenever user change account privacy or box privacy I have to change the content according to both privacies.
I read different types of articles but didn't get any close idea for this. Kindly suggest any helpful article or idea to me.
I would agree with #KolovosKonstantinos, you should try to model your application data to avoid updates of large data sets.
Also it might be interesting for you to check our concept of Embedded vs Referenced Documents. Here are couple of nice posts on this topic :
https://betterprogramming.pub/embedded-vs-referenced-documents-in-mongodb-how-to-choose-correctly-for-increased-performance-d267769b8671
https://learn.microsoft.com/en-us/azure/cosmos-db/sql/modeling-data
I would suggest trying following approach :
User entity has privacy property and different collections of post ids for every type of box
Every post stored as a separate document in elastic
You have different queries to select post ids from different collections based on the user privacy settings. When privacy of post changed simply move its id from one collection to another. Yes you need second query (sometimes called roundtrip) to storage to retrieve post when you know its id. That's a tradeoff you make. Defining architecture is all about tradeoff.
So you data might look like as following :
User document:
{
"userId": "1",
"privacy": "Public",
"publicBoxPostIds": [1,3],
"friendsBoxPostIds": [2],
"privateBoxPostIds": [],
}
Post documents:
{
"postId": "1",
"postText": "zbzb",
...
},
{
"postId": "2",
"postText": "xcxc",
...
}
...

Access rights for the users in a team

I have users in a team having access to particular fields on lead, opportunity and account entities. I have few users who are in team they just need access to fields on lead and Opportunity entity not on account ?
I thought Ill use field level security on the fields to achieve this, having field level security will have effect other functionality in the system. Any thoughts on how to achieve this ?
Breaking down CRM security levels:
Role level - Entity level (e.g. access to Lead but not marketing list)
Record level - Read/Write/Access (e.g. read lead record but not modify them)
Field level - Field level show/hide (e.g. hide a lead's account field for certain users or team).
In your case, it depends on what defines having access (is it more of a don't need to see or a should not see scenario). If it is just a case of a set of users don't have to deal with certain fields use different CRM forms for different teams, if it is a case of they should not be seeing the data use field level security.
This also would hopefully answer "having field level security will have effect other functionality in the system?" questions, if field level security is implemented, the fields which are restricted read won't show up in the advanced find queries or reports for the users who are not assigned the field level security profiles. Also once you have secured the field, every new user or team needs the field level security profile assigned, else they won't be able to see the field.

Microstrategy - filtering a dashboard depending on the user

I need to filter a dashboard basing on the user.
for example:
if user1 my-attribute = 1
if user2 my-attribute = 2
What method could I use for doing it also in reports and documents?
What you need here are the MicroStrategy Security Filters.
You can create two security filters, let call them:
MyAttributeEqual1
and
MyAttributeEqual2
Security Filters are pretty much similar to normal filters, so you can play with them and figure out the best condition you want to use.
Then you have to modify the users to assign the right filter.
In case you need you can assign Security Filters to a User Group and it will be applied to all users in that group.
Security filters will be added to the SQL code generate by MicroStrategy when you run a report and they will become an additional where condition.
A word of warning, be careful if you assign a security filter to an attribute and then you show data for a parent attribute, in that case the SQL engine will not apply the filter.

Java webapp API id-based security filter

We're building our API and looking for an organized way to grant users access based on what role and permission they have.
From the starting point, we have 3 roles
Admin: can get and edit everything in his organization
Team Admin: can get and edit only his team info and users' info
User: can get any edit his own information
Entity
Team
User
For Security Filters:
We're using JAX-RS with Security Roles and #RoleAllowed to filter access to resources
Id-based filter by if / then / else function. Example with a team admin access to a user.
function isAllowAccess(teamAdminId, userId) {
allowedUserIdsList = queryfor(teamAdminId);
if (userId in allowedUserIdsList) then ... else BAD_REQUEST
}
This code is growing with the increase complexity of multiple roles and many entities. So my questions:
What will be the best way to have an organized id-based filter, is there reputable library for this?
Should we maintain a separate table containing accessible ids of each
entity for each team_admin_id? Then every row updated or inserted will trigger the update of this table.
Is there a formal or widely acceptable method to reduce database
call overhead in each call just to check if the team_admin is
allowed to access a particular user?

Resources