Example #1
0
 def _search(self, args, offset=0, limit=None, order=None, count=False, access_rights_uid=None):
     if self._uid != SUPERUSER_ID and args:
         domain_fields = {term[0] for term in args if isinstance(term, (tuple, list))}
         if domain_fields.intersection(USER_PRIVATE_FIELDS):
             raise AccessError(_('Invalid search criterion'))
     return super(Users, self)._search(args, offset=offset, limit=limit, order=order, count=count,
                                       access_rights_uid=access_rights_uid)
Example #2
0
 def cancel(self):
     """
     cancel one or more order.line, update order status and unlink existing cashmoves
     """
     if self.user_has_groups("lunch.group_lunch_manager"):
         self.state = 'cancelled'
         self.cashmove.unlink()
     else:
         raise AccessError(_("Only your lunch manager cancels the orders."))
Example #3
0
 def order(self):
     """
     The order_line is ordered to the vendor but isn't received yet
     """
     if self.user_has_groups("lunch.group_lunch_manager"):
         self.state = 'ordered'
     else:
         raise AccessError(
             _("Only your lunch manager processes the orders."))
Example #4
0
 def write(self, values):
     employee_id = values.get('employee_id', False)
     if not self._check_state_access_right(values):
         raise AccessError(
             _('You cannot set a leave request as \'%s\'. Contact a human resource manager.'
               ) % values.get('state'))
     result = super(Holidays, self).write(values)
     self.add_follower(employee_id)
     if 'employee_id' in values:
         self._onchange_employee_id()
     return result
Example #5
0
    def check(self, mode, values=None):
        """Restricts the access to an ir.attachment, according to referred model
        In the 'document' module, it is overriden to relax this hard rule, since
        more complex ones apply there.
        """
        # collect the records to check (by model)
        model_ids = defaultdict(set)  # {model_name: set(ids)}
        require_employee = False
        if self:
            self._cr.execute(
                'SELECT res_model, res_id, create_uid, public FROM ir_attachment WHERE id IN %s',
                [tuple(self.ids)])
            for res_model, res_id, create_uid, public in self._cr.fetchall():
                if public and mode == 'read':
                    continue
                if not (res_model and res_id):
                    if create_uid != self._uid:
                        require_employee = True
                    continue
                model_ids[res_model].add(res_id)
        if values and values.get('res_model') and values.get('res_id'):
            model_ids[values['res_model']].add(values['res_id'])

        # check access rights on the records
        for res_model, res_ids in model_ids.items():
            # ignore attachments that are not attached to a resource anymore
            # when checking access rights (resource was deleted but attachment
            # was not)
            if res_model not in self.env:
                require_employee = True
                continue
            elif res_model == 'res.users' and len(
                    res_ids) == 1 and self._uid == list(res_ids)[0]:
                # by default a user cannot write on itself, despite the list of writeable fields
                # e.g. in the case of a user inserting an image into his image signature
                # we need to bypass this check which would needlessly throw us away
                continue
            records = self.env[res_model].browse(res_ids).exists()
            if len(records) < len(res_ids):
                require_employee = True
            # For related models, check if we can write to the model, as unlinking
            # and creating attachments can be seen as an update to the model
            records.check_access_rights('write' if mode in (
                'create', 'unlink') else mode)
            records.check_access_rule(mode)

        if require_employee:
            if not (self.env.user._is_admin()
                    or self.env.user.has_group('base.group_user')):
                raise AccessError(
                    _("Sorry, you are not allowed to access this document."))
Example #6
0
 def check_access_rule(self, operation):
     """ Add Access rules of mail.message for non-employee user:
         - read:
             - raise if the type is comment and subtype NULL (internal note)
     """
     if self.user_has_groups('base.group_public'):
         self.env.cr.execute(
             'SELECT id FROM "%s" WHERE website_published IS FALSE AND id = ANY (%%s)'
             % (self._table), (self.ids, ))
         if self.env.cr.fetchall():
             raise AccessError(
                 _('The requested operation cannot be completed due to security restrictions. Please contact your system administrator.\n\n(Document type: %s, Operation: %s)'
                   ) % (self._description, operation))
     return super(MailMessage, self).check_access_rule(operation=operation)
Example #7
0
    def force_storage(self):
        """Force all attachments to be stored in the currently configured storage"""
        if not self.env.user._is_admin():
            raise AccessError(
                _('Only administrators can execute this action.'))

        # domain to retrieve the attachments to migrate
        domain = {
            'db': [('store_fname', '!=', False)],
            'file': [('db_datas', '!=', False)],
        }[self._storage()]

        for attach in self.search(domain):
            attach.write({'datas': attach.datas})
        return True
Example #8
0
 def confirm(self):
     """
     confirm one or more order line, update order status and create new cashmove
     """
     if self.user_has_groups("lunch.group_lunch_manager"):
         if self.state != 'confirmed':
             values = {
                 'user_id': self.user_id.id,
                 'amount': -self.price,
                 'description': self.product_id.name,
                 'order_id': self.id,
                 'state': 'order',
                 'date': self.date,
             }
             self.env['lunch.cashmove'].create(values)
             self.state = 'confirmed'
     else:
         raise AccessError(
             _("Only your lunch manager sets the orders as received."))
Example #9
0
 def create(self, values):
     """ Override to avoid automatic logging of creation """
     employee_id = values.get('employee_id', False)
     if not self._check_state_access_right(values):
         raise AccessError(
             _('You cannot set a leave request as \'%s\'. Contact a human resource manager.'
               ) % values.get('state'))
     if not values.get('department_id'):
         values.update({
             'department_id':
             self.env['hr.employee'].browse(employee_id).department_id.id
         })
     holiday = super(
         Holidays,
         self.with_context(mail_create_nolog=True,
                           mail_create_nosubscribe=True)).create(values)
     holiday.add_follower(employee_id)
     if 'employee_id' in values:
         holiday._onchange_employee_id()
     return holiday
Example #10
0
 def read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True):
     groupby_fields = set([groupby] if isinstance(groupby, pycompat.string_types) else groupby)
     if groupby_fields.intersection(USER_PRIVATE_FIELDS):
         raise AccessError(_("Invalid 'group by' parameter"))
     return super(Users, self).read_group(domain, fields, groupby, offset=offset, limit=limit, orderby=orderby, lazy=lazy)
Example #11
0
    def execute(self):
        self.ensure_one()
        if not self.env.user._is_superuser() and not self.env.user.has_group(
                'base.group_system'):
            raise AccessError(_("Only administrators can change the settings"))

        self = self.with_context(active_test=False)
        classified = self._get_classified_fields()

        # default values fields
        IrDefault = self.env['ir.default'].sudo()
        for name, model, field in classified['default']:
            if isinstance(self[name], models.BaseModel):
                if self._fields[name].type == 'many2one':
                    value = self[name].id
                else:
                    value = self[name].ids
            else:
                value = self[name]
            IrDefault.set(model, field, value)

        # group fields: modify group / implied groups
        current_settings = self.default_get(list(self.fields_get()))
        with self.env.norecompute():
            for name, groups, implied_group in classified['group']:
                if self[name] == current_settings[name]:
                    continue
                if self[name]:
                    groups.write({'implied_ids': [(4, implied_group.id)]})
                else:
                    groups.write({'implied_ids': [(3, implied_group.id)]})
                    implied_group.write({
                        'users':
                        [(3, user.id) for user in groups.mapped('users')]
                    })
        self.recompute()

        # other fields: execute method 'set_values'
        # Methods that start with `set_` are now deprecated
        for method in dir(self):
            if method.startswith('set_') and method is not 'set_values':
                _logger.warning(
                    _('Methods that start with `set_` are deprecated. Override `set_values` instead (Method %s)'
                      ) % method)
        self.set_values()

        # module fields: install/uninstall the selected modules
        to_install = []
        to_uninstall_modules = self.env['ir.module.module']
        lm = len('module_')
        for name, module in classified['module']:
            if self[name]:
                to_install.append((name[lm:], module))
            else:
                if module and module.state in ('installed', 'to upgrade'):
                    to_uninstall_modules += module

        if to_uninstall_modules:
            to_uninstall_modules.button_immediate_uninstall()

        self._install_modules(to_install)

        if to_install or to_uninstall_modules:
            # After the uninstall/install calls, the registry and environments
            # are no longer valid. So we reset the environment.
            self.env.reset()
            self = self.env()[self._name]

        # pylint: disable=next-method-called
        config = self.env['res.config'].next() or {}
        if config.get('type') not in ('ir.actions.act_window_close', ):
            return config

        # force client-side reload (update user menu and current view)
        return {
            'type': 'ir.actions.client',
            'tag': 'reload',
        }
Example #12
0
    def check_access_rule(self, operation):
        """ Access rules of mail.message:
            - read: if
                - author_id == pid, uid is the author OR
                - uid is in the recipients (partner_ids) OR
                - uid has been notified (needaction) OR
                - uid is member of a listern channel (channel_ids.partner_ids) OR
                - uid have read access to the related document if model, res_id
                - otherwise: raise
            - create: if
                - no model, no res_id (private message) OR
                - pid in message_follower_ids if model, res_id OR
                - uid can read the parent OR
                - uid have write or create access on the related document if model, res_id, OR
                - otherwise: raise
            - write: if
                - author_id == pid, uid is the author, OR
                - uid is in the recipients (partner_ids) OR
                - uid has write or create access on the related document if model, res_id
                - otherwise: raise
            - unlink: if
                - uid has write or create access on the related document if model, res_id
                - otherwise: raise

        Specific case: non employee users see only messages with subtype (aka do
        not see internal logs).
        """
        def _generate_model_record_ids(msg_val, msg_ids):
            """ :param model_record_ids: {'model': {'res_id': (msg_id, msg_id)}, ... }
                :param message_values: {'msg_id': {'model': .., 'res_id': .., 'author_id': ..}}
            """
            model_record_ids = {}
            for id in msg_ids:
                vals = msg_val.get(id, {})
                if vals.get('model') and vals.get('res_id'):
                    model_record_ids.setdefault(vals['model'], set()).add(vals['res_id'])
            return model_record_ids

        if self._uid == SUPERUSER_ID:
            return
        # Non employees see only messages with a subtype (aka, not internal logs)
        if not self.env['res.users'].has_group('base.group_user'):
            self._cr.execute('''SELECT DISTINCT message.id, message.subtype_id, subtype.internal
                                FROM "%s" AS message
                                LEFT JOIN "mail_message_subtype" as subtype
                                ON message.subtype_id = subtype.id
                                WHERE message.message_type = %%s AND (message.subtype_id IS NULL OR subtype.internal IS TRUE) AND message.id = ANY (%%s)''' % (self._table), ('comment', self.ids,))
            if self._cr.fetchall():
                raise AccessError(
                    _('The requested operation cannot be completed due to security restrictions. Please contact your system administrator.\n\n(Document type: %s, Operation: %s)') %
                    (self._description, operation))

        # Read mail_message.ids to have their values
        message_values = dict((res_id, {}) for res_id in self.ids)

        if operation in ['read', 'write']:
            self._cr.execute("""
                SELECT DISTINCT m.id, m.model, m.res_id, m.author_id, m.parent_id,
                                COALESCE(partner_rel.res_partner_id, needaction_rel.res_partner_id),
                                channel_partner.channel_id as channel_id
                FROM "%s" m
                LEFT JOIN "mail_message_res_partner_rel" partner_rel
                ON partner_rel.mail_message_id = m.id AND partner_rel.res_partner_id = %%(pid)s
                LEFT JOIN "mail_message_res_partner_needaction_rel" needaction_rel
                ON needaction_rel.mail_message_id = m.id AND needaction_rel.res_partner_id = %%(pid)s
                LEFT JOIN "mail_message_mail_channel_rel" channel_rel
                ON channel_rel.mail_message_id = m.id
                LEFT JOIN "mail_channel" channel
                ON channel.id = channel_rel.mail_channel_id
                LEFT JOIN "mail_channel_partner" channel_partner
                ON channel_partner.channel_id = channel.id AND channel_partner.partner_id = %%(pid)s
                WHERE m.id = ANY (%%(ids)s)""" % self._table, dict(pid=self.env.user.partner_id.id, ids=self.ids))
            for mid, rmod, rid, author_id, parent_id, partner_id, channel_id in self._cr.fetchall():
                message_values[mid] = {
                    'model': rmod,
                    'res_id': rid,
                    'author_id': author_id,
                    'parent_id': parent_id,
                    'notified': any((message_values[mid].get('notified'), partner_id, channel_id))
                }
        else:
            self._cr.execute("""SELECT DISTINCT id, model, res_id, author_id, parent_id FROM "%s" WHERE id = ANY (%%s)""" % self._table, (self.ids,))
            for mid, rmod, rid, author_id, parent_id in self._cr.fetchall():
                message_values[mid] = {'model': rmod, 'res_id': rid, 'author_id': author_id, 'parent_id': parent_id}

        # Author condition (READ, WRITE, CREATE (private))
        author_ids = []
        if operation == 'read' or operation == 'write':
            author_ids = [mid for mid, message in message_values.items()
                          if message.get('author_id') and message.get('author_id') == self.env.user.partner_id.id]
        elif operation == 'create':
            author_ids = [mid for mid, message in message_values.items()
                          if not message.get('model') and not message.get('res_id')]

        # Parent condition, for create (check for received notifications for the created message parent)
        notified_ids = []
        if operation == 'create':
            # TDE: probably clean me
            parent_ids = [message.get('parent_id') for message in message_values.values()
                          if message.get('parent_id')]
            self._cr.execute("""SELECT DISTINCT m.id, partner_rel.res_partner_id, channel_partner.partner_id FROM "%s" m
                LEFT JOIN "mail_message_res_partner_rel" partner_rel
                ON partner_rel.mail_message_id = m.id AND partner_rel.res_partner_id = (%%s)
                LEFT JOIN "mail_message_mail_channel_rel" channel_rel
                ON channel_rel.mail_message_id = m.id
                LEFT JOIN "mail_channel" channel
                ON channel.id = channel_rel.mail_channel_id
                LEFT JOIN "mail_channel_partner" channel_partner
                ON channel_partner.channel_id = channel.id AND channel_partner.partner_id = (%%s)
                WHERE m.id = ANY (%%s)""" % self._table, (self.env.user.partner_id.id, self.env.user.partner_id.id, parent_ids,))
            not_parent_ids = [mid[0] for mid in self._cr.fetchall() if any([mid[1], mid[2]])]
            notified_ids += [mid for mid, message in message_values.items()
                             if message.get('parent_id') in not_parent_ids]

        # Recipients condition, for read and write (partner_ids) and create (message_follower_ids)
        other_ids = set(self.ids).difference(set(author_ids), set(notified_ids))
        model_record_ids = _generate_model_record_ids(message_values, other_ids)
        if operation in ['read', 'write']:
            notified_ids = [mid for mid, message in message_values.items() if message.get('notified')]
        elif operation == 'create':
            for doc_model, doc_ids in model_record_ids.items():
                followers = self.env['mail.followers'].sudo().search([
                    ('res_model', '=', doc_model),
                    ('res_id', 'in', list(doc_ids)),
                    ('partner_id', '=', self.env.user.partner_id.id),
                    ])
                fol_mids = [follower.res_id for follower in followers]
                notified_ids += [mid for mid, message in message_values.items()
                                 if message.get('model') == doc_model and message.get('res_id') in fol_mids]

        # CRUD: Access rights related to the document
        other_ids = other_ids.difference(set(notified_ids))
        model_record_ids = _generate_model_record_ids(message_values, other_ids)
        document_related_ids = []
        for model, doc_ids in model_record_ids.items():
            DocumentModel = self.env[model]
            mids = DocumentModel.browse(doc_ids).exists()
            if hasattr(DocumentModel, 'check_mail_message_access'):
                DocumentModel.check_mail_message_access(mids.ids, operation)  # ?? mids ?
            else:
                self.env['mail.thread'].check_mail_message_access(mids.ids, operation, model_name=model)
            document_related_ids += [mid for mid, message in message_values.items()
                                     if message.get('model') == model and message.get('res_id') in mids.ids]

        # Calculate remaining ids: if not void, raise an error
        other_ids = other_ids.difference(set(document_related_ids))
        if not (other_ids and self.browse(other_ids).exists()):
            return
        raise AccessError(
            _('The requested operation cannot be completed due to security restrictions. Please contact your system administrator.\n\n(Document type: %s, Operation: %s)') %
            (self._description, operation))
Example #13
0
 def read(self, fields=None, load='_classic_read'):
     if self.search_count([('id', 'in', self._ids),
                           ('name', '=', 'NOACCESS')]):
         raise AccessError('Sorry')
     return super(Category, self).read(fields=fields, load=load)
Example #14
0
    def web_settings_dashboard_data(self, **kw):
        if not request.env.user.has_group('base.group_erp_manager'):
            raise AccessError("Access Denied")

        installed_apps = request.env['ir.module.module'].search_count([
            ('application', '=', True),
            ('state', 'in', ['installed', 'to upgrade', 'to remove'])
        ])
        cr = request.cr
        cr.execute("""
            SELECT count(*)
              FROM res_users
             WHERE active=true AND
                   share=false
        """)
        active_count = cr.dictfetchall()[0].get('count')

        cr.execute("""
            SELECT count(u.*)
            FROM res_users u
            WHERE active=true AND
                  NOT exists(SELECT 1 FROM res_users_log WHERE create_uid=u.id)
        """)
        pending_count = cr.dictfetchall()[0].get('count')

        cr.execute("""
           SELECT id, login
             FROM res_users u
            WHERE active=true
              AND NOT exists(SELECT 1 FROM res_users_log WHERE create_uid=u.id)
         ORDER BY id desc
            LIMIT 10
        """)
        pending_users = cr.fetchall()

        # See update.py for this computation
        limit_date = datetime.now() - timedelta(15)
        enterprise_users = request.env['res.users'].search_count([
            ("login_date", ">=", fields.Datetime.to_string(limit_date)),
            ('share', '=', False)
        ])

        expiration_date = request.env['ir.config_parameter'].sudo().get_param(
            'database.expiration_date')
        return {
            'apps': {
                'installed_apps': installed_apps,
                'enterprise_users': enterprise_users,
            },
            'users_info': {
                'active_users':
                active_count,
                'pending_count':
                pending_count,
                'pending_users':
                pending_users,
                'user_form_view_id':
                request.env['ir.model.data'].xmlid_to_res_id(
                    "base.view_users_form"),
            },
            'share': {
                'server_version': release.version,
                'expiration_date': expiration_date,
                'debug': request.debug,
            },
            'company': {
                'company_id': request.env.user.company_id.id,
                'company_name': request.env.user.company_id.name
            }
        }
Example #15
0
 def check_user(self, uid=None):
     if uid is None:
         uid = request.uid
     is_admin = request.env['res.users'].browse(uid)._is_admin()
     if not is_admin:
         raise AccessError(_("Only administrators can upload a module"))