Why the record rules are not working as expected Odoo 10? - record

I am using odoo 10. I want to restrict the project users to see or edit their own tasks only. And the project manager can assign tasks to them and can see all the tasks. That means project manager should have full permissions.
I tried many solutions from the forums but none of them are working as expected. Any help is highly appreciated.
I have created a new record rule:
Object: project.task
Domain filter: [('user_id','=',user.id)]
When I save it as global then each task is seen by its assignee only but this rule is applying for project manager also. Project manager also not able to see or create his tasks for his team now. But I need project manager to have full permissions.
If I select the group as Project/User: In this case the effect is gone and all the users are able to see all tasks.
Also I have created a record rule for Project/Manager with domain filter [(1, '=', 1)]. But still my required result is not achieved.

First you need to read the documentation about Odoo Security carefully. Basically Odoo provides two main data-driven mechanisms to manage or restrict access to data.
Access Control
Record Rules
In your case you just need to copy the setting from other similar case. For example "Sales Manager" and "User: Own Documents Only" for sales.
Access Control. Create both groups and give permission to the model, in your case project.tasks
Rules. Add a rule only for the "User: Own Documents Only", in your case "Project/User":

Read this carefully. https://www.odoo.com/documentation/12.0/reference/security.html
Global rules are subtractive, they must all be matched for a record to be accessible
Group rules are additive, if any of them matches (and all global rules match) then the record is accessible
Turns out the global rules are subtractive, the group rules are additive. If you apply globally then only users that satisfy your domain user_id = user.id will be readable/writable. But if you apply only to a group, it won't restrict the access because it's additive and users are granted access somewhere else.
What I did for a similar scenario is apply a global rule so that
task is only seen by its assignee. Then apply a group rule to manager so that manager can see all tasks.
Hope this could help you

Related

How to show selective templates in the rule group?

Is there any way to show only selective templates corresponding to the rule group ?
For Ex. - I have to rule-groups (MobilePages & WebSearchPages), when I go to create a new landing page templates for mobile are also available in template selection for WebSearchPages And similarly templates created for the use in full-site are available in group for MobilePages.
Is there any way to avoid this, or offer only selective templates for pages corresponding to the rule-group ?
In templates I can only specify the entry of Zone & Page-style but not for rule-group -
<ContentTemplate xmlns="http://endeca.com/schema/content-template/2008" type="PageTemplate" id="MobileSubCategoryPage">
<RuleInfo zone="MobileCategoryPageZone" style="PageStyle"/>
Thanks in advance !
To the best of my knowledge you cannot restrict which types of rules are placed into specific groups.
I have sought such functionality as well. You would think that with group level permissions one would be able to control what goes into the groups as well.
This has likely changed substantially with the move to experience manager that does not have the same group concepts.

Manage conflicting roles in chef

I am relatively new to chef, so I may be missing something extremely basic. After much searching I am not finding what I need, so here goes:
In Chef, I have roles that are conflicting. I need for all servers of a certain type to have roleA, except for servers with roleB.
The best way I can think of to describe it is with an example:
syslog1, syslog2
web1, web2, web3
db1, db2
mail1, mail2
Every server within this environment(dozens) has a role called syslog_client, except syslog1 and syslog2, which need to have the role syslog_server.
The syslog-server and syslog-client roles conflict, because they configure the same pieces of software differently.
These are roles rather than recipes because they actually encompass several recipes.
I thought of doing something like this:
roles/base.rb:
name "base"
description "base configuration"
override_attributes(
)
default_attributes(
)
run_list(
"recipe[one]",
"recipe[two]",
"recipe[three]",
"role[uno]"
)
unless node[:roles].include?('syslog_server')
run_list('role[syslog_client]')
end
The problem there is that the node object does not exist at this point. I have thought about moving it into the recipe, but I could not come up with a good way to do it there either. I was able to use this in the base recipe:
unless node[:roles].include?('syslog_server')
node[:roles]+=['syslog_client']
end
This adds syslog_client to the roles attribute (or doesn't) correctly, but it never actually runs the syslog_client role.
I have considered moving syslog_client into a self-contained recipe rather than a role, and moving the role attributes to the environment. This would work, because then I can just call include_recipe "syslog::client". The problem there is that virtually all of our recipes are assigned from roles (not from other recipes), and I fear that making this change will create a one-off that will be hard to keep track of. Besides that, as I mentioned already, these are actually several recipes, so adding them as a single recipe is not ideal.
We have many different server types/roles in the environment I'm currently working in, and adding role[syslog_client] to them is feasible, but not ideal. With multiple people working on this, it seems likely that someone will forget to add the recipe to a new role.
In an ideal world, something like my first solution would be possible, because that allows us to keep our environment as consistent as possible. I am open to other options though.
So to wrap up, I think what I need is someone to tell me how to:
Make the first solution work. Add a role to a run list only if another role is not present
If I cannot have #1, I'd like opinions on the best way to achieve this using the ways I've listed or other ideas I have not thought of
Please let me know if I'm missing any details about our chef setup that will be helpful.
Disclaimer: The above example is really a very simplified version of what I'm actually trying to achieve. I'm not even working with syslog, but the company it is for is very security-conscious and would not be happy with details of their environment being posted publicly. I will be as detailed as I possibly can if I've left anything out and I need to add further info.
Extending what was said above what's the issue with creating two roles. A Client and a server
The Client role includes the base role and the client function. It will get applied to all servers through replacing references to 'base' with this role in all other roles. Meaning those roles still get base but get client as well.
The server is a stand-alone role which only applies to those servers and has the base and then the server role?
That way both client and server get the base role applied to them without duplicating the definition of what the base role is. You still manage that base role as you want but you use aggregation in the creation of roles?
When a new role is created the user won't start by adding base but instead adding the syslog_client role which gives them base as well.
To me that feels like the way Chef is pushing you with the creation of roles. What we have is 1 role that applies to all servers, some that apply to 1 subtype of servers but not anothers. That way our leaf role as in the one that gets applied actually consists of 4 or 5 other roles. What's common is modelled in a way that can be shared without the need for logic within?
The other option would be to add the client recipe to every node and the first exeuction step is to check the nodes role and if it says server just basically skip the recipe execution? Which would be the same as the logic which you were wanting to use to add the recipe but it would live in the recipe and control the execution?
unless node[:roles].include?('syslog_server')
#Do your client install
end

different permissions based on workflow state

I need to set up different permission on an object based on its workflow state. For instance, 'manager group' can edit the object only if state=draft but 'super manager group' can edit it also if state=validated.
It seems that's not possible using ir.model.access and I'm evaluating if it could be done using ir.rule. It seems not...
Is there a official way to get this or do I need to implement this feature (maybe by adding a condition into ir.model.access machinery).
This is not possible by default with ir.model.access, because this permission model is designed to act like simple Unix permission on CRUD operations, and it is statically defined, per-model and per-group.
You may be able to implement something like this using ir.rule, as it implements dynamic per-record access control based on field values. By having a set of rules defined only on the write and unlink operations and based on the state field, you will be able to prevent some groups from modifying records in certain states. By using the technique of an always-true rule [(1,'=',1)] you can then relax a non-global rule for users who have a "super-access" group. See also this answer.
This option will have important caveats however:
Be careful not to make those rules apply for read, as it will make the records completely disappear, and generally wreak havoc in your processes
The interface will not become read-only when the rule is in effect, and if you want to make the fields and buttons read-only you will have to find a way to specify this via attrs in a manner that depends on the user's groups. See also this Launchpad question.
the Save button in the UI will not be disabled
The standard error reporting in case of ir.rule restriction is not very clear, so it will certainly confuse users (note: it's being improved for 7.0)
As you see, using ir.rule filters for this purpose is far from a perfect solution, and you will first need to find appropriate solutions for the above issues.
Ultimately, you might have an easier task of implementing your own logic for this, plugging a new mechanism in the ORM primitive API methods: fields_view_get (for making fields dynamically read-only based on the user groups) and the CRUD methods (for actually restricting the operations)
There is another way instead of hacking web-client.
You can always have 2 views for the same Object .
For manager group.
For super manager group.
In manager group you can use attrs = {'readonly': [('state', '!=', 'draft')]}
or any condition as you needed.
And in the same way in super manager group, you can put his condition for fields.
I have this feature working on a production environment, using just Record Rules: in Project Issues, "basic users" can create and cancel issues, but can't open or close them.
Despite the GUI limitations mentioned by #odony, it works perfectly.
These are the Record Rules used::
There is a special case that needs attention: changing from a read-write State to a read-only State:
In the action's method, if the the State is changed after other write operations, the user will be able to change the State; but if there are some write operations after the State update, the user will not be able to change State.
In my example, the Project Issue method to Open an issue is case_open(). It first changes State and then does additional changes, like settting Open Date, User and Message history. Because of this, basic users can't Open issues. If you want them to be able to do so, case_open() must be overridden so that it changes State after all other write operations are done.
I got a similar requirement...
My requirement was to make a char field(say "test_123") readonly in the sale.order if the user comes under the group "sale user" otherwise editable for the group "Sale Manager".
That is, if the sale order is in draft state then anyone can edit, but it the sale order is confirmed then this field "test_123" is only editable for "Sale Manger"
What I did is I added a functional field (is_group_manager) which returns True if the user comes under the group "sale manager" and the state is not "draft" otherwise false.
Then in the xml view I added the field "test_123" with attribute attrs="{'readonly':[('is_group_manager','=',0)]}"
for example
<field name="is_group_manager" invisible="1"/>
<field name="test_123" attrs="{'readonly':[('is_group_manager','=',0)]}"/>
This will work only in openerp v6.0. Maybe this will be helpful for you. :)

What exactly are "tasks" in Yii's RBAC?

I'm diving into RBAC while designing new and rather big/complex site.
I'm trying to figure out if to create a task or simply an operation with biz rule.
Now, I've read most if not all existing documentation. The current documentation says that "a task consists of operations". This wiki article says that the different terms are simply naming conventions and the only limitation that exists is structural one - roles must include tasks (or other roles); tasks should include operations (or other tasks) and operations is the atomic term that is not further composed by other entities.
I've also read the relevant sections in the "Agile web dev..." and "Yii cookbook" books - both do not shed further light on this issue (at least as seen through my glasses).
Lets go to my example where I'll present the question. Actually, lets use an example similar to that demonstrated in most of the documentation resources mentioned above: Lets say I have a blog post and I want/need to have its author be able to "update own post". Now, why should this be a task as commonly demonstrated in the documentation resources and not an operation with a biz rule?
I think that the question above reveals the inclear definition of a "task" (in the RBAC context of course).
Please help me distill a better definition for an RBAC task.
EDIT:
I was suggested the following definitions of the mentioned terms that help conceptualize them in a useful way. In short and in its simplest form: operations are the basic building blocks. They are the material developers work with and only them. Developers compose tasks of and on top of operations. Roles are composed of tasks, like a set of tasks. Roles and tasks are what the site administrators should play with - assign and revoke to users but not operations.
That's a nice way to look and grasp those entities (roles, tasks and operations).
Do you have another option to conceptualize differently? Any comments will be appreciated.
TIA!
Boaz.
I'd say the same as you did in your question edit. A task is simply a composition of operations a user can do that have something in common. So you have for example operations oList, oView, oCreate and oUpdate these are the operation developer assigns to controller actions for access control, where the first two are only read- and the second two have write access to data (that's what they have in common). So you now want to combine those to tasks tInspect and tManage which both hold 2 operations, the first one can list and view and the second one can create and update. Optionally you could make tInspect a sub-task of tManage so a user that has tManage can list, view, update and create but normally you just give his role both tasks.
Regarding the classification of role -> task -> operation, they are essentially the same thing, as you can see in the code they are of class CAuthItem. We name them differently mainly from user point of view.
Operations are only used by developers and they represent the finest level of permission.
Tasks are built on top of operations by developers. They represent the basic building units to be used by RBAC administrators.
Roles are built on top of tasks by administrators and may be assigned to users or user groups.
The above is a recommendation, not requirement. In general, administrators can only see tasks and roles, while developers only care about operations and tasks.
Check this out : http://www.yiiframework.com/forum/index.php/topic/2313-rbac-confusion/page_p_16035#entry16035
if there are two user
1)admin
2)user
so we set role updatePost for update page.
and admin is parent of updatePost so admin can update.
user have updateOwnPost permission.updateOwnPost is parent of updatePost with bizrule.so if bizrule satisfy he can update

CakePHP: model-based permissions?

Struggling with a decision on how best to handle Client-level authentication with the following model hierarchy:
Client -> Store -> Product (Staff, EquipmentItem, etc.)
...where Client hasMany Stores, Store hasMany Products(hasMany Staff, hasMany EquipmentItem, etc.)
I've set up a HABTM relationship between User and Client, which is straightforward and accessible through the Auth session or a static method on the User model if necessary (see afterFind description below).
Right now, I'm waffling between evaluating the results in each model's afterFind callback, checking for relationship to Client based on the model I'm querying against the Clients that the current User is a member of. i.e. if the current model is Client, check the id; if the current model is a Store, check Store.clientid, and finally if Product, get parent Store from Item.storeid and check Store.clientid accordingly.
However, to keep in line with proper MVC, I return true or false from the afterFind, and then have to check the return from the calling action -- this is ok, but I have no way I can think of to determine if the Model->find (or Model->read, etc.) is returning false because of invalid id in the find or because of Client permissions in the afterFind; it also means I'd have to modify every action as well.
The other method I've been playing with is to evaluate the request in app_controller.beforeFilter and by breaking down the request into controller/action/id, I can then query the appropriate model(s) and eval the fields against the Auth.User.clients array to determine whether User has access to the requested Client. This seems ok, but doesn't leave me any way (afaik) to handle /controller/index -- it seems logical that the index results would reflect Client membership.
Flaws in both include a lengthy list of conditional "rules" I need to break down to determine where the current model/action/id is in the context of the client. All in all, both feel a little brittle and convoluted to me.
Is there a 3rd option I'm not looking at?
This sounds like a job for Cake ACL. It is a bit of a learning curve, but once you figure it out, this method is very powerful and flexible.
Cake's ACLs (Access Control Lists) allow you to match users to controllers down to the CRUD (Create Read Update Delete) level. Why use it?
1) The code is already there for you to use. The AuthComponent already has it built in.
2) It is powerful and integrated to allow you to control permissions every action in your site.
3) You will be able to find help from other cake developers who have already used it.
4) Once you get it setup the first time, it will be much easier and faster to implement full site permissions on any other application.
Here are a few links:
http://bakery.cakephp.org/articles/view/how-to-use-acl-in-1-2-x
http://book.cakephp.org/view/171/Access-Control-Lists
http://blog.jails.fr/cakephp/index.php?post/2007/08/15/AuthComponent-and-ACL
Or you could just google for CakePHP ACL