profile
viewpoint
If you are wondering where the data of this site comes from, please visit https://api.github.com/users/odony/events. GitMemory does not store any data, but only uses NGINX to cache data for a period of time. The idea behind GitMemory is simply to give users a better reading experience.
Olivier Dony odony @Odoo Belgium @Odoo R&D, Security, Platform

odony/php-oe-json 6

OpenERP JSON-RPC lib for PHP

odony/etherpad-lite 1

An Etherpad based on node.js - Our goal is to make collaborative editing the standard on the web

odony/browser-compat-data 0

This repository contains compatibility data for Web technologies

odony/covid19-be 0

Collecting data on belgium covid-19 cases

odony/cubicerp 0

Enterprise and Government Management Software Open Source - Official Public Branch of Cubic ERP - Mailing List cubicerp@googlegroups.com

odony/django-afip 0

⚖️ AFIP invoice integration for django.

odony/dmca 0

Repository with text of DMCA takedown notices as received. GitHub does not endorse or adopt any assertion contained in the following notices. Users identified in the notices are presumed innocent until proven guilty. Additional information about our DMCA policy can be found at

odony/fuzzywuzzy 0

Fuzzy String Matching in Python

odony/gitfs 0

Version controlled file system

pull request commentodoo/odoo

[ADD] core: new field: Domain

I'm not convinced that we have a very good trade-off for this change, be it for 15.0 or later, for that matter.

On the one hand, the cost is not small:

  • makes the API more complex, new devs will need to understand this field, they will ask themselves whether they need to use it (they shouldn't ever use it, it's a super advanced, rather ugly thing, and the framework provides the few ones that are general purpose like ir.filter or ir.rule)
  • more code and special-cases in the framework will be needed (there's always more that what we initially think)
  • e.g. more maintenance work for ir.model and more reflection logic, special support in Studio, ...

On the other hand, the benefit is rather small:

  • a default widget for a couple of fields
  • some extra meta info useful mostly for upgrades, but in reality we already have a list of the well-known ones, and they will stay mostly the same
KangOl

comment created time in 3 days

Pull request review commentodoo/odoo

[FIX] project: Fix user_ids access issues on project sharing

 def write(self, vals):             # reset kanban state when changing stage             if 'kanban_state' not in vals:                 vals['kanban_state'] = 'normal'+        # portal_user_ids change: update user_ids+        if 'portal_user_ids' in vals and 'user_ids' not in vals:+            vals['user_ids'] = vals['portal_user_ids']

@odony I'm not sure I understand your comment over here, could you elaborate ? :)

I meant the obvious: that boilerplate code (_search_portal_user_ids + overrides of create and write for portal_user_ids) should not be necessary, as that's the default behavior of a related field ;-) We'd save quite a bit of code by making that work properly.

tivisse

comment created time in 3 days

PullRequestReviewEvent

Pull request review commentodoo/odoo

[FIX] project: Fix user_ids access issues on project sharing

 def write(self, vals):             # reset kanban state when changing stage             if 'kanban_state' not in vals:                 vals['kanban_state'] = 'normal'+        # portal_user_ids change: update user_ids+        if 'portal_user_ids' in vals and 'user_ids' not in vals:+            vals['user_ids'] = vals['portal_user_ids']

those tricks shouldn't be necessary if the related if correctly implement, should they?

tivisse

comment created time in 3 days

PullRequestReviewEvent

Pull request review commentodoo/odoo

[FIX] project: Fix user_ids access issues on project sharing

 def copy_data(self, default=None):         defaults = super().copy_data(default=default)         return [{k: v for k, v in default.items() if k in self.SELF_READABLE_FIELDS} for default in defaults] +    @api.model+    def new(self, values={}, origin=None, ref=None):

that's awful, we can't keep that super-obscure hack

tivisse

comment created time in 3 days

PullRequestReviewEvent

Pull request review commentodoo/odoo

[FIX] project: Fix user_ids access issues on project sharing

 def _compute_stage_id(self):             else:                 task.stage_id = False +    @api.depends('user_ids')+    def _compute_portal_user_ids(self):+        tasks_search_read = self.search_read([('id', 'in', self.ids), ('user_ids', '!=', False)], ['id', 'user_ids'])+        assignees_by_task = {res['id']: res['user_ids'] for res in tasks_search_read}+        for task in self:+            task.portal_user_ids = [Command.set(assignees_by_task.get(task.id, []))]

at that point this is just a fields.Many2Many(related='user_ids'), which defaults to related_sudo aka compute_sudo=True, no?

except that the cache is probably populated in a non-sudo env first, so when accessed with related_sudo it doesn't retrieve any extra content. Perhaps that's what @xavierbol is referring to?

tivisse

comment created time in 4 days

PullRequestReviewEvent

delete branch odoo-dev/odoo

delete branch : 14.0-2fa-trusted-devices-arg

delete time in 8 days

pull request commentodoo/odoo

[WIP] l10n_es_edi: module for the G417 Llevanza de libros

Thanks @smetl for the updates

@robodoo override=ci/security

  • dependency on PyOpenSSL is legit given the need for establishing a SSL socket (via zeep/urrlib/requests)
  • dependency on cryptography + hazmat usage (indirectly included by PyOpenSSL) seems legit for decoding the certificate
  • requests references are legit for the zeep session
  • file_open usage is legit/safe
jco-odoo

comment created time in 11 days

Pull request review commentodoo/odoo

[IMP] web_editor: improve performance of collaborative security check

 def save_library_media(self, media):          return attachments -    @http.route("/web_editor/get_ice_servers", type='json', auth="user")-    def get_ice_servers(self):-        return request.env['mail.ice.server']._get_ice_servers()+    @http.route("/web_editor/get_editor_collaboration_infos", type='json', auth="user")+    def get_editor_collaboration_infos(self, model_name, field_name, res_id):+        signatures = generate_channel_signatures(request.env, model_name, field_name, res_id)+        return {+            'ice_servers': request.env['mail.ice.server'].sudo()._get_ice_servers(),+            'next_expiration_timestamp': signatures['next_expiration_timestamp'],+            'signatures': signatures['signatures'],

In terms of naming, even though they are technically HMAC digests/signatures, their role is to be (opaque) channel identifiers. As the name appears on the wire, it seems more appropriate to name them channels or channel_ids or something.

Goaman

comment created time in 11 days

PullRequestReviewEvent

Pull request review commentodoo/odoo

[IMP] web_editor: improve performance of collaborative security check

 def save_library_media(self, media):          return attachments -    @http.route("/web_editor/get_ice_servers", type='json', auth="user")-    def get_ice_servers(self):-        return request.env['mail.ice.server']._get_ice_servers()+    @http.route("/web_editor/get_editor_collaboration_infos", type='json', auth="user")

can we use a better name? (also, info/information is uncountable so never plural, just like data ^^)

maybe this?

    @http.route("/web_editor/edit/start", type='json', auth="user")
Goaman

comment created time in 11 days

PullRequestReviewEvent

Pull request review commentodoo/odoo

[IMP] web_editor: improve performance of collaborative security check

 def save_library_media(self, media):          return attachments -    @http.route("/web_editor/get_ice_servers", type='json', auth="user")-    def get_ice_servers(self):-        return request.env['mail.ice.server']._get_ice_servers()+    @http.route("/web_editor/get_editor_collaboration_infos", type='json', auth="user")+    def get_editor_collaboration_infos(self, model_name, field_name, res_id):+        signatures = generate_channel_signatures(request.env, model_name, field_name, res_id)+        return {+            'ice_servers': request.env['mail.ice.server'].sudo()._get_ice_servers(),+            'next_expiration_timestamp': signatures['next_expiration_timestamp'],+            'signatures': signatures['signatures'],+        }      @http.route("/web_editor/bus_broadcast", type="json", auth="user")-    def bus_broadcast(self, model_name, field_name, res_id, bus_data):-        document = request.env[model_name].browse([res_id])--        document.check_access_rights('read')-        document.check_field_access_rights('read', [field_name])-        document.check_access_rule('read')-        document.check_access_rights('write')-        document.check_field_access_rights('write', [field_name])-        document.check_access_rule('write')--        channel = (request.db, 'editor_collaboration', model_name, field_name, int(res_id))-        request.env['bus.bus'].sendone(channel, bus_data)+    def bus_broadcast(self, signature, bus_data):+        request.env['bus.bus'].sendone(f"editor_collaboration_{signature}", bus_data)

yes I prefer to have an explicit route for that. However it deserves a better name. How about something like this?

- @http.route("/web_editor/bus_broadcast", type="json", auth="user")
+ @http.route("/web_editor/edit/notify", type="json", auth="user")
Goaman

comment created time in 11 days

PullRequestReviewEvent

Pull request review commentodoo/odoo

[WIP] l10n_es_edi: module for the G417 Llevanza de libros

+# -*- coding: utf-8 -*-+# Part of Odoo. See LICENSE file for full copyright and licensing details.++# Thanks to AEOdoo and the Spanish community+# Specially among others Ignacio Ibeas, Pedro Baeza and Landoo++{+    'name': "Spain - SII EDI Suministro de Libros",+    'version': '1.0',+    'category': 'Accounting/Localizations/EDI',+    'description': """+        This module sends the taxes information (mostly VAT) of the +        vendor bills and customer invoices to the SII.  It is called +        Procedimiento G417 - IVA. Llevanza de libros registro.  It is +        required for every company with a turnover of +6M€ and others can +        already make use of it.  The invoices are automatically +        sent after validation.  +        +        How the information is sent to the SII depends on the +        configuration that is put in the taxes.  The taxes +        that were in the chart template (l10n_es) are automatically +        configured to have the right type.  It is possible however +        that extra taxes need to be created for certain exempt/no sujeta reasons.   +        +        You need to configure your certificate and the tax agency.  +    """,+    'depends': [+        'l10n_es',+        'account_edi_extended',+    ],+    'data': [+        'data/account_tax_data.xml',+        'data/account_edi_data.xml',+        'data/res_partner_data.xml',++        'security/ir.model.access.csv',++        'views/account_tax_views.xml',+        'views/l10n_es_edi_certificate_views.xml',+        'views/res_config_settings_views.xml',+    ],+    'demo': [+        'demo/demo_company.xml'+    ],+    'external_dependencies': {+        'python': ['cryptography'],

the dependency is now pyOpenSSL again ;-)

        'python': ["pyOpenSSL"],
jco-odoo

comment created time in 11 days

PullRequestReviewEvent

delete branch odoo-dev/odoo

delete branch : master-discuss-start-a-meeting-wil

delete time in 11 days

pull request commentodoo/odoo

[FIX] base: unclosed file descriptor

En fait le code n'existe plus, all good

and a proper fix would be with tools.file_open(<relative_addons_path>) rather than open(), to simplify the code (no need for get_module_resource() etc) and to avoid other security risks ;-)

Julien00859

comment created time in 11 days

pull request commentodoo/odoo

OWL reporting views

@robodoo delegate=Polymorphe57

Polymorphe57

comment created time in 12 days

pull request commentodoo/odoo

OWL reporting views

@robodoo override=ci/security Cfr explanations by @kebeclibre, but pending further double-check post-freeze.

Note: using Markup + t-out should replace t-raw, not sure what are the plans for supporting this in owl? It would be nice to be consistent here for v15, considering that non-own JS and Python code have been converted. /cc @kebeclibre @aab-odoo @xmo-odoo

Polymorphe57

comment created time in 12 days

pull request commentodoo/odoo

Master editor collab nby

@robodoo override=ci/security According to the authors, the various problems that were detected have been fixed, and the code of the bus notifications will be fixed in a subsequent PR. Pending double-check by @mart-e who did the first part of the review.

Goaman

comment created time in 12 days

Pull request review commentodoo/odoo

Master editor collab nby

+# -*- coding: utf-8 -*-+# Part of Odoo. See LICENSE file for full copyright and licensing details.++import re++from odoo.http import request+from odoo.addons.bus.controllers.main import BusController+++class EditorCollaborationController(BusController):+    # ---------------------------+    # Extends BUS Controller Poll+    # ---------------------------+    def _poll(self, dbname, channels, last, options):+        if request.session.uid:+            # Do not alter original list.+            channels = list(channels)+            for channel in channels:+                if isinstance(channel, str):+                    match = re.match(r'editor_collaboration:(\w+(?:.\w+)*):(\w+):([\d]+)', channel)

Instead of using a pseudo-channel-uuid that is parsed just for the access check, I propose to simplify this and use a real opaque channel-id, generated based on a crypto hmac signature, derived from the database secret key. In order to permit access checks, it would be generated server-side only after checking that the user has the necessary access. And then it could be used everywhere on the client-side like a "normal" opaque channel (like for livechat).

If we want to reinforce the security and avoid giving the user a "permanent" channel that they could continue to use for months, even if their access is blocked, we can add a timestamp in the signature, and return the timestamp along with the hash. This way the client-side knows that it may need to ask for a new channel.

some pseudo-code to explain:

# the method to obtain the channel ID, located on some model,
# perhaps bus.bus, and called from a controller that may need it?
def _editor_serialization_channel(model_name, field_name, res_id):
    # verify access to the edition channel
    if not self.env.user.has_group('base.group_user'):
        raise AccessDenied()
    recs = self.env[model_name].browse(res_id)
    recs.check_access_rights('write')
    recs.check_access_rule('write')
    (...)

    # generate unique channel id as HMAC
    # looks like this: 3e1ef9e86...3036d65 (64 chars)
    # timestamp is only valid 1 week, then you have to renew it
    exp_timestamp = int(time.time() // (7 * 24 * 3600)) + 1  # +1 for next week
    sig = odoo.tools.hmac(
        self.env, 'editor_serialization', f"{model_name}:{field_name}:{res_id}:{exp_timestamp}")

    # The result contains the signature (channel_id), followed by the expiration
    # timestamp for that channel.
    # If the result of calling `int(time.time() // (7 * 24 * 3600))` on
    # the client side gives a different timestamp, it means the channel has expired, and
    # a new one should be requested.
    return f"{sig}:{exp_timestamp}"
Goaman

comment created time in 12 days

PullRequestReviewEvent

pull request commentodoo/odoo

[FW][FIX] web_editor: limit size of generated images

@fw-bot r+

fw-bot

comment created time in 13 days

pull request commentodoo/odoo

[FIX] web_editor: limit size of generated images

@robodoo r+

odony

comment created time in 15 days

PR opened odoo/odoo

[FIX] web_editor: limit size of generated images

This should avoid disrupting layouts.

+1 -1

0 comment

1 changed file

pr created time in 15 days

create barnchodoo-dev/odoo

branch : 12.0-f2i-cap-size

created branch time in 15 days