You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

102 lines
3.9 KiB

# -*- coding: utf-8 -*-
# Copyright 2016 SYLEAM
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import datetime
import dateutil
import time
from collections import defaultdict
from openerp import models, api, fields
from openerp.tools.safe_eval import safe_eval
class OAuthProviderScope(models.Model):
_name = 'oauth.provider.scope'
_description = 'OAuth Provider Scope'
name = fields.Char(
required=True, translate=True,
help='Name of the scope, displayed to the user.')
code = fields.Char(
required=True, help='Code of the scope, used in OAuth requests.')
description = fields.Text(
required=True, translate=True,
help='Description of the scope, displayed to the user.')
model_id = fields.Many2one(
comodel_name='ir.model', string='Model', required=True,
help='Model allowed to be accessed by this scope.')
model = fields.Char(
related='model_id.model', string='Model Name', readonly=True,
help='Name of the model allowed to be accessed by this scope.')
filter_id = fields.Many2one(
comodel_name='ir.filters', string='Filter',
domain="[('model_id', '=', model)]",
help='Filter applied to retrieve records allowed by this scope.')
field_ids = fields.Many2many(
comodel_name='ir.model.fields', string='Fields',
domain="[('model_id', '=', model_id)]",
help='Fields allowed by this scope.')
_sql_constraints = [
('code_unique', 'UNIQUE (code)',
'The code of the scopes must be unique !'),
]
@api.model
def _get_ir_filter_eval_context(self):
""" Returns the base eval context for ir.filter domains evaluation """
return {
'datetime': datetime,
'dateutil': dateutil,
'time': time,
'uid': self.env.uid,
'user': self.env.user,
}
@api.multi
def get_data_for_model(self, model, res_id=None, all_scopes_match=False):
""" Return the data matching the scopes from the requested model """
data = defaultdict(dict)
eval_context = self._get_ir_filter_eval_context()
all_scopes_records = self.env[model]
for scope in self.filtered(lambda record: record.model == model):
# Retrieve the scope's domain
filter_domain = [(1, '=', 1)]
if scope.filter_id:
filter_domain = safe_eval(
scope.filter_id.sudo().domain, eval_context)
if res_id is not None:
filter_domain.append(('id', '=', res_id))
# Retrieve data of the matching records, depending on the scope's
# fields
records = self.env[model].search(filter_domain)
for record_data in records.read(scope.field_ids.mapped('name')):
for field, value in record_data.items():
if isinstance(value, tuple):
# Return only the name for a many2one
data[record_data['id']][field] = value[1]
else:
data[record_data['id']][field] = value
# Keep a list of records that match all scopes
if not all_scopes_records:
all_scopes_records = records
else:
all_scopes_records &= records
# If all scopes are required to match, filter the results to keep only
# those mathing all scopes
if all_scopes_match:
data = dict(filter(
lambda record_data: record_data[0] in all_scopes_records.ids,
data.items()))
# If a single record was requested, return only data coming from this
# record
# Return an empty dictionnary if this record didn't recieve data to
# return
if res_id is not None:
data = data.get(res_id, {})
return data