Odoo v8: How to limit user access to contacts - security

I'm using Odoo v8 and need a means to prevent certain users (either (preferably) in a sales team or in a user group) from accessing certain contacts (assigned to a different sales team) or the contacts at all.
I tried to achieve this via Record rules but don't seem to get this to work.

Users and user roles are critical points concerning internal security in OpenERP. OpenERP provides several security mechanisms concerning user roles, all implemented in the OpenERP Server. They are implemented in the lowest server level, which is the ORM engine. OpenERP distinguishes three different concepts:
user: a person identified by its login and password. Note that all employees of a company are not necessarily OpenERP users; an user is somebody who accesses the application.
group: a group of users that has some access rights. A group gives its access rights to the users that belong to the group. Ex: Sales Manager, Accountant, etc.
security rule: a rule that defines the access rights a given group grants to its users. Security rules are attached to a given resource, for example the Invoice model.
Security rules are attached to groups. Users are assigned to several groups. This gives users the rights that are attached to their groups. Therefore controlling user roles is done by managing user groups and adding or modifying security rules attached to those groups.
Users
Users represent physical persons using OpenERP. They are identified with a login and a password,they use OpenERP, they can edit their own preferences, … By default, a user has no access right. The more we assign groups to the user, the more he or she gets rights to perform some actions. A user may belong to several groups.
User groups
The groups determine the access rights to the different resources. A user may belong to several groups. If he belongs to several groups, we always use the group with the highest rights for a selected resource. A group can inherit all the rights from another group
Rights
Security rules are attached to groups. You can assign several security rules at the group level, each rule being of one of the following types :
- access rights are global rights on an object,
- record rules are records access filters,
- fields access right,
- workflow transition rules are operations rights.
You can also define rules that are global, i.e. they are applied to all users, indiscriminately of the groups they belong to. For example, the multi-company rules are global; a user can only see invoices of the companies he or she belongs to.
Concerning configuration, it is difficult to have default generic configurations that suit all applications. Therefore, like SAP, OpenERP is by default pre-configured with best-practices.
Access rights
Access rights are rules that define the access a user can have on a particular object . Those global rights are defined per document type or model. Rights follow the CRUD model: create, read (search), update (write), delete. For example, you can define rules on invoice creation. By default, adding a right to an object gives the right to all records of that specific object.
Record rules
When accessing an object, records are filtered based on record rules. Record rules or access filters are therefore filters that limits records of an object a group can access. A record rule is a condition that each record must satisfy to be created, read, updated (written) or deleted. Records that do not meet the constraints are filtered.
For example, you can create a rule to limit a group in such a way that users of that group will see business opportunities in which he or she is flagged as the salesman. The rule can be salesman = connected_user. With that rule, only records respecting the rule will be displayed.
Field access rights
New in version 7.0.
OpenERP now supports real access control at the field level, not just on the view side. Previously it was already possible to set a groups attribute on a <field> element (or in fact most view elements), but with cosmetics effects only: the element was made invisible on the client side, while still perfectly available for read/write access at the RPC level.
As of OpenERP 7.0 the existing behavior is preserved on the view level, but a new groups attribute is available on all model fields, introducing a model-level access control on each field. The syntax is the same as for the view-level attribute:
_columns = {
'secret_key': fields.char('Secret Key', groups="base.group_erp_manager,base.group_system")
}
There is a major difference with the view-level groups attribute: restricting the access at the model level really means that the field will be completely unavailable for users who do not belong to the authorized groups:
Restricted fields will be completely removed from all related views, not just hidden. This is important to keep in mind because it means the field value will not be available at all on the client side, and thus unavailable e.g. for on_change calls.
Restricted fields will not be returned as part of a call to fields_get() or fields_view_get() This is in order to avoid them appearing in the list of fields available for advanced search filters, for example. This does not prevent getting the list of a model’s fields by querying ir.model.fields directly, which is fine.
Any attempt to read or write directly the value of the restricted fields will result in an AccessError exception.
As a consequence of the previous item, restricted fields will not be available for use within search filters (domains) or anything that would require read or write access.
It is quite possible to set groups attributes for the same field both at the model and view level, even with different values. Both will carry their effect, with the model-level restriction taking precedence and removing the field completely in case of restriction.
Note
The tests related to this feature are in openerp/tests/test_acl.py.
Warning
At the time of writing the implementation of this feature is partial
and does not yet restrict read/write RPC access to the field. The
corresponding test is written already but currently disabled.

You can add a Rule for a group of users. I just made it and it's work fine.

Related

Appropriate use of Azure AD Groups to manage permissions

I am creating an application that uses Azure AD user groups to grant permissions to specific resources. For example, a particular set of documents can only be accessed by users in specific groups. The application receives the group ids as claims on the JWT and ensures that only documents assigned to groups in the claims are visible.
Now, the question is how to manage groups correctly in Azure AD. When users are assigned to a group become a member of that group and any groups that group is nested in. This seems to imply that my group nesting should be the reverse of the tree structure I would like. Something like this:
Admin --> member of --> Group with most access --> member of --> group with less access --> member of --> group with least access.
To me this seems backwards but it provides the correct access rights to users added to each group.
Am I way off base here or is this a reasonable way to manage access rights with AD groups?
#JoyWang already covered some good points in answer above. Here are some additional considerations. Disclaimer: Due to nature of question, my answer here is mostly opinion and learning from some cases. Idea is to share how I have seen groups getting used along with some related info.
Are the groups specific to your application or more general purpose? Group membership and nested groups are usually used to organize users & groups logically/intuitively rather than design permissions for specific application
Many times Azure AD Groups are used by more than one application and may have a lifetime longer than any one specific application you're developing.
The way you are thinking about nesting groups based on which one has more access v/s less access you're probably concerned about only one particular application that you're developing and thinking about a group's access to this application. This approach will work out if the groups you plan to create are also very application specific and will NOT be used for any other purpose.
Example1: Your application is a blogging app and groups you create in Azure AD are Viewer, Contributor and Admin. (Admin > Contributor > Viewer)
Example2: You have an enterprise using Azure AD and groups organize users logically, say deparatment wise Marketing, Human Resources, Engineering etc.
So, the way you describe nested groups based on lower access permissions to higher, it will technically work out for a simpler scenario like in Example1 but not for Example2 where groups are more general purpose.
Many times general purpose groups already exist and you're expected to reuse them rather than create new ones for your application which require new assignments/membership all over again, but this may or may not be applicable in your specific case.
Also, there can be multiple people managing these groups and their membership so any design/organization pattern you come up with should give importance to intuitiveness even if you have to sacrifice minor application specific efficiency sometimes.
In my opinion, you can look at both flat or nested groups.. if it makes sense from an organization of users and groups standpoint, not just access permissions. Another fictious example: Marketing Group can have a member group like Marketing Content Approvers because it's a subset of Marketing people.
Do consider Application Roles.
They are specific to an application, tied to it's manifest and can be available to you as part of claims in token.
There can be situations like individual resource based access where you want to give permissions to a specific resource where Application Roles may or may not make sense and you still need to rely on groups or users directly. In any case, it's another helpful option available to you.
Managing Groups (as you've asked about this in comments)
Take a look at Self Service Group Management Scenarios (Delegated v/s Self-service) and also Dynamic Groups for dynamic membership rules based on attributes (requires Premium license though).
In AAD, the permissions of a member in the groups depend on the biggest permission of the group which he is a member of. For example, group A can access a resource and group B can't access it, the man is both in group A and B, then he will be able to access the resource.
To me this seems backwards but it provides the correct access rights to users added to each group.
Let we call the three groups as A,B,C, the permission of them is A > B >C. Obviously, if you add A to B, the permissions of A and B both have not been affected. But if you add B to A, the members in A or B will both have the biggest permission, it is no what you want. The same with B and C. This is why it provides the correct access rights to users added to each group as you said.
So in my personal opinion, seems no need to use nested groups, just use three groups with different permissions, it's enough.

Entity-level access restriction in the microservice architecture based on user or group membership

In the systems, there may be data that is restricted in nature.
Sometimes access to specific entities should be easily restricted or granted based on user or group membership.
What is the best way to implement this in the microservice architecture?
#1
Should access control, managing permissions etc. be the responsibility of the microserive itself? Developers will have to implement access control, store, and update permissions for every service. Seems like not very robust and error-prone approach.
#2
Create dedicated microservice handling permission management? This service will be called by other microserives to check access permissions for each entity and filtering entities before returning results. Centralized permissions storage and management is an advantage but microservice will have to make a call to "Permission Service" for each entity to check access rights what may have a negative influence on performance. And developers still have to integrate access checks into their services what leaves space for an error.
#3
Make access control responsibility of the API Gateway or Service Mesh. It is possible to think of an implementation that will automatically filter responses of all services. But in the case when the microservice returns list of entities permissions should be checked for each entity. Still a potential performance problem.
Example
Consider the following synthetic example.
Healthcare system dealing with test results, X-Ray images etc. Health information is very sensitive and should not be disclosed.
Test results should be available only to:
patient
doctor
laboratory
Attending doctor may send the patient to another specialist. A new doctor should have access to test results too. So access can be granted dynamically.
So each entity (e.g. test results, X-Ray image) has a set of rules what users and groups are allowed to access it.
Imagine there is a microservice called "Test Results Service" dealing with test results. Should it be responsible for access control, manage permissions etc.? Or permissions management should be extracted to separate microservice?
Healthcare system may also handle visits to a doctor. Information about patient's visit to the doctor should be available to:
patient
doctor
clinic receptionist
This is the example of a different entity type that requires entity level access restriction based on user or group membership.
It is easy to imagine even more examples when entity level access control is required.
I came to the following generic solution.
ACL security model is used. Each object in the system has associated set of permissions. Permissions defines who and what actions can perform on the object.
Microservices are responsible for entity-level authorization and filter objects in responses based on permissions of the objects.
Central Access Control Service is responsible for the creation, update, and deletion of permissions for all objects in the system. Access Control Service database is the primary store of objects' permissions.
Permissions stored in microservices databases are synchronized with Access Control Service database using event-carried state transfer. Every time, permissions are changed an event is sent to the message broker. Microservices can subscribe to these events to synchronize permissions.
API Gateway can be used as the additional protection layer. API Gateway can call Access Control Service directly (RPC) to check response objects' permissions or load recently revoked permissions.
Design features:
A way to uniquely identify each object in the system is required (e.g. UUID).
Permissions synchronization in microservices are eventual consistent. In case of partitioning between message broker and microservice permissions will not be synchronized. It may be a problem with revocation of the permissions. The solution to this problem is a separate topic.
Looks like security is a part of business logic here. In both examples.
Then security could be a part of data scheme.
For example,
Patient can see his tests:
select * from test_result where patient_id=*patient_id*
Doctor can see all test from his medical department:
select * from test_result where branch_id=*doctor_branch*
I believe that to have separate MS for access control is a really bad idea and could lead serious performance problems. Just imagine situation that somebody with zero entity access tries to fetch all entities each time :) You will always need to handle larger result sets than actually needed.
Firstly, this is very bad idea to have a separate (per microservice) security model. It should be single always cross-cutting all application, because it can lead to a hell with access management, permissions granting and mapping between entities in different microservices.
In second, I assume that you are wrong with understanding how to organize microservices..? You should dedicate the principle of splitting functionality into microservices: by features, by domain, etc. Look at Single Responsibility, DDD and other approaches which helps you to achieve clear behavior of your MS.
So, in best case, you should have to:
Choose right security model ABAC or RBAC - there are a lot of other options, but looking at your example I guess the ABAC is the best one
Create separate MS for access management - the main responsibility of this MS is a CRUD and assignment of groups/roles/permissions/attributes to the people accounts.
Create separate MS for providing only permitted health information.
In third, how it works?:
With ABAC you can setup hierarchical roles/permissions (based on groups/attributes) - it helps you to resolve a delegation path of who is permitted to the data
Setup authorization (via auth-MS) and store the list of permissions (in session, cookies, etc)
Check access for a given user for a needed data in health-info-MS. Here we have several options how to do this:
If you use memory-grids (hazelcast, coherence), you can easily create filters with predicates based on security attributes.
If you're using SQL (hibernate, plain SQL, etc.) you should generate queries to return only permitted data - add security specific criteria to the where clause
Few more details about SQL queries with security check in where: before the SQL execution (if hibernate & spring is easy to do with spring-method-auth hook) you should resolve all permissions assigned to a user - you can do this with call to auth-MS.
Example
We created CRUD permissions for TestResult entity - VIEW, EDIT, DELETE.
The role DOCTOR can see any TestResults - so, it has VIEW permission
The role PATIENT can see only his/her TestResults
So, you create a business rules which provide the correct where clause for each business role (DOCTOR, PATIENT, LAB, etc.) and at the end the SQL request would be like:
For patient who has assigned VIEW permission:
select * from test_result where id=*patient_id* and 1=1
For patient who hasn't assigned VIEW permission:
select * from test_result where id=*patient_id* and 1!=1
NOTE: In business rules we can add 1=1 or 1!=1 to permit/restrict query result

security access for groups symfony

Hi i have a group system and i'd like to add some security to it.
Users can belong to multiple groups and id like to know the best way to authorize people to see the groups only if they are in it. If they aren't i want to redirect them to a another page, which is different according to the group.
For now i created a service but i have to use it in every controller...
I've heard of multiple things but not sure if they are appropriate for my situation.
Thanks for your help
There are several different ways to do this depending on the approach/complexity. Here are a few:
1) Use Symfony ACLS. When a user is added to a particular group, you can use the symfony ACL system to grant them view access to that group, and then later check isGranted() against that group to see if they have view permissions.
2) Create a custom voter
http://symfony.com/doc/current/cookbook/security/voters.html#creating-a-custom-voter
3) If the number of groups is limited in number, you could even use Doctrine query filters to automatically add a where clause to all queries where the group_id is in a list of allowed groups for that user. You can bypass this for all admin users. http://doctrine-orm.readthedocs.org/en/latest/reference/filters.html

Can I rate-limit requests to Parse.com on a per-user basis?

I'm developing an app using Parse.com for BaaS. Aside from regular security checks, it's my understanding/philosophy that part of security is to assume someone HAS broken in, and then limit the amount they can access/delete/mess up.
One way I'd like to do this is to have a per-user rate limit on certain API requests. I can imagine a sort of naive method where I keep a list of who has accessed recently and when, and check that list before allowing a request of that type to go through (I'm thinking beforeSave for various custom classes).
Is there a better, ideally built-in way?
Though Parse.com doesn't have options for configuring this, parse claims that they keep track of suspicious activities and attempt for DDoS attacks are monitored. But not sure to what extend this is possible, because this specific problem is scenario wise relevant/irrelevant.
You dont have an option to do user level rate limit, but they will report any suspicious activities found like redundant hits from same device.
As given in the Parse docs here, They support two levels of permissions, Class level (via Data browser) & Object level (using ACLs)
Configuring class-level permissions
Parse lets you specify what operations are allowed per class. This
lets you restrict the ways in which clients can access or modify your
classes. To change these settings, go to the Data Browser, select a
class, open the "More" dropdown, and click the "Set permissions" item.
Class level permissions is a manual way of giving access to specific users or roles on a class.
In your case, you might probably need object level permissions based on Access Control Lists(ACL).
Access Control Lists
The idea behind an ACL is that each object has a list of users and roles along with what permissions that user or
role has. A user needs read permissions (or must belong to a role that
has read permissions) in order to retrieve an object's data, and a
user needs write permissions (or must belong to a role that has write
permissions) in order to update or delete that object
Create a new role and add list of users to that role who can access. Then set an ACL like this on the other objects.
{ "role:YourRoleName":{"read":true, "write" : true}}
You can now dynamically add or remove users in that role without updating individual objects.

Where security role is used

I have created a form for a specific group of users in my CRM 2011 system. I want only them to be able to see this form. I can copy their a security role and set the form for this security role only, but I will have a a problem:
they are currently in a security role with another group of users. If I copy the security role, the will not longer see the specific customization's all over across the system.
I only want one form to be different from the others. Is there any way I can find all the forms that are enabled for the specific security role (in order to give the new role this rights too)?
Assumptions based on your question: You already have default form for the entity that is used by all users (All Users). You want to add an additional form to that entity that is only available to some of the users (Select Users). All Users are currently assigned a security role that gives them the necessary access to the system.
Create a new security role (Form Specific Role). You don't have to give this role any privileges just a name.
Assign the Select Users the Form Specific Role. Do NOT remove their other security role(s).
Add the new form the entity, Restricted Form.
Highlight the new form and click Enable Security Roles. Select the option Display only to these selected security roles and select the Form Specific Role you created in step # 1. Make sure Enabled for fallback is unchecked. Click Ok.
From the forms list Form Order and select Main Form Set (or the appropriate form type if you are working on a Mobile or Quick Create Form.
Use the Up/Down arrows to make the new, Restricted Form, the top choice.
Save and Publish all changes.
Now whenever a user that has been assigned the security role accesses this entity their default form choice will be the Restricted Form. There will be NO impact to any other forms they are accessing or any of their privileges in the rest of the system, as required by your problem statement.

Resources