{"action":"created","issue":{"url":"https://api.github.com/repos/OCA/server-tools/issues/396","repository_url":"https://api.github.com/repos/OCA/server-tools","labels_url":"https://api.github.com/repos/OCA/server-tools/issues/396/labels{/name}","comments_url":"https://api.github.com/repos/OCA/server-tools/issues/396/comments","events_url":"https://api.github.com/repos/OCA/server-tools/issues/396/events","html_url":"https://github.com/OCA/server-tools/pull/396","id":142305854,"number":396,"title":"[ADD] base_mixin_restrict_field_access","user":{"login":"hbrunn","id":2563186,"avatar_url":"https://avatars.githubusercontent.com/u/2563186?v=3","gravatar_id":"","url":"https://api.github.com/users/hbrunn","html_url":"https://github.com/hbrunn","followers_url":"https://api.github.com/users/hbrunn/followers","following_url":"https://api.github.com/users/hbrunn/following{/other_user}","gists_url":"https://api.github.com/users/hbrunn/gists{/gist_id}","starred_url":"https://api.github.com/users/hbrunn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hbrunn/subscriptions","organizations_url":"https://api.github.com/users/hbrunn/orgs","repos_url":"https://api.github.com/users/hbrunn/repos","events_url":"https://api.github.com/users/hbrunn/events{/privacy}","received_events_url":"https://api.github.com/users/hbrunn/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/OCA/server-tools/labels/needs%20review","name":"needs review","color":"fbca04"}],"state":"open","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/OCA/server-tools/milestones/3","html_url":"https://github.com/OCA/server-tools/milestones/8.0","labels_url":"https://api.github.com/repos/OCA/server-tools/milestones/3/labels","id":983662,"number":3,"title":"8.0","description":"","creator":{"login":"max3903","id":939952,"avatar_url":"https://avatars.githubusercontent.com/u/939952?v=3","gravatar_id":"","url":"https://api.github.com/users/max3903","html_url":"https://github.com/max3903","followers_url":"https://api.github.com/users/max3903/followers","following_url":"https://api.github.com/users/max3903/following{/other_user}","gists_url":"https://api.github.com/users/max3903/gists{/gist_id}","starred_url":"https://api.github.com/users/max3903/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/max3903/subscriptions","organizations_url":"https://api.github.com/users/max3903/orgs","repos_url":"https://api.github.com/users/max3903/repos","events_url":"https://api.github.com/users/max3903/events{/privacy}","received_events_url":"https://api.github.com/users/max3903/received_events","type":"User","site_admin":false},"open_issues":36,"closed_issues":55,"state":"open","created_at":"2015-02-17T21:52:00Z","updated_at":"2016-03-21T13:04:21Z","due_on":null,"closed_at":null},"comments":9,"created_at":"2016-03-21T10:17:22Z","updated_at":"2016-03-22T16:20:03Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/OCA/server-tools/pulls/396","html_url":"https://github.com/OCA/server-tools/pull/396","diff_url":"https://github.com/OCA/server-tools/pull/396.diff","patch_url":"https://github.com/OCA/server-tools/pull/396.patch"},"body":"This is the result of https://github.com/OCA/server-tools/issues/332:\r\n\r\n=====================\r\nRestrict field access\r\n=====================\r\n\r\nThis module was written to help developers restricting access to fields in a\r\nsecure and flexible manner.\r\n\r\nIf you're not a developer, this module is not for you as you need to write code\r\nin order to actually use it.\r\n\r\nUsage\r\n=====\r\n\r\nTo use this module, you need to:\r\n\r\n```python\r\n    class ResPartner(models.Model):\r\n        # inherit from the mixin\r\n        _inherit = ['restrict.field.access.mixin', 'res.partner']\r\n        _name = 'res.partner'\r\n\r\n        @api.multi\r\n        def _restrict_field_access_get_field_whitelist(self, action='read'):\r\n            # return a whitelist (or a blacklist) of fields, depending on the\r\n            # action passed\r\n            whitelist = [\r\n                'name', 'parent_id', 'is_company', 'firstname', 'lastname',\r\n                'infix', 'initials',\r\n            ] + super(ResPartner, self)\\\r\n                ._restrict_field_access_get_field_whitelist(action=action)\r\n            if action == 'read':\r\n                whitelist.extend(['section_id', 'user_id'])\r\n            return whitelist\r\n\r\n        @api.multi\r\n        def _restrict_field_access_is_field_accessible(self, field_name,\r\n                                                       action='read'):\r\n            # in case the whitelist is not enough, you can also decide for\r\n            # specific records if an action can be carried out on it or not\r\n            result = super(ResPartner, self)\\\r\n                ._restrict_field_access_is_field_accessible(\r\n                    field_name, action=action)\r\n            if result or not self:\r\n                return result\r\n            return all(this.section_id in self.env.user.section_ids or\r\n                       this.user_id == self.env.user\r\n                       for this in self)\r\n\r\n        @api.multi\r\n        @api.onchange('section_id', 'user_id')\r\n        @api.depends('section_id', 'user_id')\r\n        def _compute_restrict_field_access(self):\r\n            # if your decision depends on other fields, you probably need to\r\n            # override this function in order to attach the correct onchange/\r\n            # depends decorators\r\n            return super(ResPartner, self)._compute_restrict_field_access()\r\n\r\n        @api.model\r\n        def _restrict_field_access_inject_restrict_field_access_domain(\r\n                self, domain):\r\n            # you also might want to decide with a domain expression which\r\n            # records are visible in the first place\r\n            domain[:] = expression.AND([\r\n                domain,\r\n                [\r\n                    '|',\r\n                    ('section_id', 'in', self.env.user.section_ids.ids),\r\n                    ('user_id', '=', self.env.user.id),\r\n                ],\r\n            ])\r\n```\r\nThe example code here will allow only reading a few fields for partners of\r\nwhich the current user is neither the sales person nor in this partner's sales\r\nteam."},"comment":{"url":"https://api.github.com/repos/OCA/server-tools/issues/comments/199888057","html_url":"https://github.com/OCA/server-tools/pull/396#issuecomment-199888057","issue_url":"https://api.github.com/repos/OCA/server-tools/issues/396","id":199888057,"user":{"login":"pedrobaeza","id":7165771,"avatar_url":"https://avatars.githubusercontent.com/u/7165771?v=3","gravatar_id":"","url":"https://api.github.com/users/pedrobaeza","html_url":"https://github.com/pedrobaeza","followers_url":"https://api.github.com/users/pedrobaeza/followers","following_url":"https://api.github.com/users/pedrobaeza/following{/other_user}","gists_url":"https://api.github.com/users/pedrobaeza/gists{/gist_id}","starred_url":"https://api.github.com/users/pedrobaeza/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pedrobaeza/subscriptions","organizations_url":"https://api.github.com/users/pedrobaeza/orgs","repos_url":"https://api.github.com/users/pedrobaeza/repos","events_url":"https://api.github.com/users/pedrobaeza/events{/privacy}","received_events_url":"https://api.github.com/users/pedrobaeza/received_events","type":"User","site_admin":false},"created_at":"2016-03-22T16:20:02Z","updated_at":"2016-03-22T16:20:02Z","body":"Little comment, but :+1: "}}