[MERGE] forward port of branch 8.0 up to 5e3e41b

This commit is contained in:
Christophe Simonis
2015-03-09 16:06:29 +01:00
9 changed files with 42 additions and 18 deletions
+1 -1
View File
@@ -141,7 +141,7 @@ class mrp_repair(osv.osv):
'location_id': fields.many2one('stock.location', 'Current Location', select=True, required=True, readonly=True, states={'draft': [('readonly', False)], 'confirmed': [('readonly', True)]}),
'location_dest_id': fields.many2one('stock.location', 'Delivery Location', readonly=True, required=True, states={'draft': [('readonly', False)], 'confirmed': [('readonly', True)]}),
'lot_id': fields.many2one('stock.production.lot', 'Repaired Lot', domain="[('product_id','=', product_id)]", help="Products repaired are all belonging to this lot", oldname="prodlot_id"),
'guarantee_limit': fields.date('Warranty Expiration', help="The warranty expiration limit is computed as: last move date + warranty defined on selected product. If the current date is below the warranty expiration limit, each operation and fee you will add will be set as 'not to invoiced' by default. Note that you can change manually afterwards.", states={'confirmed': [('readonly', True)]}),
'guarantee_limit': fields.date('Warranty Expiration', states={'confirmed': [('readonly', True)]}),
'operations': fields.one2many('mrp.repair.line', 'repair_id', 'Operation Lines', readonly=True, states={'draft': [('readonly', False)]}, copy=True),
'pricelist_id': fields.many2one('product.pricelist', 'Pricelist', help='Pricelist of the selected partner.'),
'partner_invoice_id': fields.many2one('res.partner', 'Invoicing Address'),
+3 -3
View File
@@ -306,12 +306,12 @@ class sale_order_line(osv.osv):
return res
# set product uom in context to get virtual stock in current uom
if res.get('value', {}).get('product_uom'):
if 'product_uom' in res.get('value', {}):
# use the uom changed by super call
context.update({'uom': res['value']['product_uom']})
context = dict(context, uom=res['value']['product_uom'])
elif uom:
# fallback on selected
context.update({'uom': uom})
context = dict(context, uom=uom)
#update of result obtained in super function
product_obj = product_obj.browse(cr, uid, product, context=context)
+6
View File
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
from datetime import datetime
import werkzeug.exceptions
import werkzeug.urls
import werkzeug.wrappers
import simplejson
@@ -188,6 +189,11 @@ class WebsiteForum(http.Controller):
@http.route(['''/forum/<model("forum.forum"):forum>/question/<model("forum.post", "[('forum_id','=',forum[0]),('parent_id','=',False)]"):question>'''], type='http', auth="public", website=True)
def question(self, forum, question, **post):
# Hide posts from abusers (negative karma), except for moderators
if not question.can_view:
raise werkzeug.exceptions.NotFound()
# increment view counter
question.sudo().set_viewed()
if question.parent_id:
+12 -7
View File
@@ -154,7 +154,7 @@ class Post(models.Model):
name = fields.Char('Title')
forum_id = fields.Many2one('forum.forum', string='Forum', required=True)
content = fields.Html('Content')
content = fields.Html('Content', strip_style=True)
plain_content = fields.Text('Plain Content', compute='_get_plain_content', store=True)
@api.one
@@ -287,17 +287,21 @@ class Post(models.Model):
can_downvote = fields.Boolean('Can Downvote', compute='_get_post_karma_rights')
can_comment = fields.Boolean('Can Comment', compute='_get_post_karma_rights')
can_comment_convert = fields.Boolean('Can Convert to Comment', compute='_get_post_karma_rights')
can_view = fields.Boolean('Can View', compute='_get_post_karma_rights')
@api.one
def _get_post_karma_rights(self):
user = self.env.user
post = self.sudo()
self.karma_accept = self.parent_id and self.parent_id.create_uid.id == self._uid and self.forum_id.karma_answer_accept_own or self.forum_id.karma_answer_accept_all
self.karma_edit = self.create_uid.id == self._uid and self.forum_id.karma_edit_own or self.forum_id.karma_edit_all
self.karma_close = self.create_uid.id == self._uid and self.forum_id.karma_close_own or self.forum_id.karma_close_all
self.karma_unlink = self.create_uid.id == self._uid and self.forum_id.karma_unlink_own or self.forum_id.karma_unlink_all
self.karma_comment = self.create_uid.id == self._uid and self.forum_id.karma_comment_own or self.forum_id.karma_comment_all
self.karma_comment_convert = self.create_uid.id == self._uid and self.forum_id.karma_comment_convert_own or self.forum_id.karma_comment_convert_all
is_creator = post.create_uid.id == self._uid
self.karma_accept = self.forum_id.karma_answer_accept_own if post.parent_id and post.parent_id.create_uid.id == self._uid else self.forum_id.karma_answer_accept_all
self.karma_edit = self.forum_id.karma_edit_own if is_creator else self.forum_id.karma_edit_all
self.karma_close = self.forum_id.karma_close_own if is_creator else self.forum_id.karma_close_all
self.karma_unlink = self.forum_id.karma_unlink_own if is_creator else self.forum_id.karma_unlink_all
self.karma_comment = self.forum_id.karma_comment_own if is_creator else self.forum_id.karma_comment_all
self.karma_comment_convert = self.forum_id.karma_comment_convert_own if is_creator else self.forum_id.karma_comment_convert_all
self.can_ask = user.karma >= self.forum_id.karma_ask
self.can_answer = user.karma >= self.forum_id.karma_answer
@@ -309,6 +313,7 @@ class Post(models.Model):
self.can_downvote = user.karma >= self.forum_id.karma_downvote
self.can_comment = user.karma >= self.karma_comment
self.can_comment_convert = user.karma >= self.karma_comment_convert
self.can_view = user.karma >= self.karma_close or post.create_uid.karma > 0
@api.one
@api.constrains('post_type', 'forum_id')
+2 -1
View File
@@ -25,7 +25,8 @@ class WebsiteResPartner(osv.Model):
_get_private, fnct_inv=_set_private, fnct_search=_search_private,
type='boolean', string='Private Profile'),
'website_description': fields.html(
'Website Partner Full Description'
'Website Partner Full Description',
strip_style=True
),
'website_short_description': fields.text(
'Website Partner Short Description'
@@ -146,7 +146,7 @@ class TestHtmlField(common.TransactionCase):
% if object.some_field and not object.oriented:
<table>
% if object.other_field:
<tr>
<tr style="border: 10px solid black;">
${object.mako_thing}
<td>
</tr>
@@ -173,5 +173,11 @@ class TestHtmlField(common.TransactionCase):
# sanitize should have closed tags left open in the original html
self.assertIn('</table>', partner.comment, 'Error in HTML field: content does not seem to have been sanitized despise sanitize=True')
self.assertIn('</td>', partner.comment, 'Error in HTML field: content does not seem to have been sanitized despise sanitize=True')
self.assertIn('<tr style="', partner.comment, 'Style attr should not have been stripped')
self.partner._columns['comment'] = fields.html('Stripped Html', sanitize=True, strip_style=True)
self.partner.write(cr, uid, [pid], {'comment': some_ugly_html}, context=context)
partner = self.partner.browse(cr, uid, pid, context=context)
self.assertNotIn('<tr style="', partner.comment, 'Style attr should have been stripped')
self.partner._columns = old_columns
+6 -1
View File
@@ -1076,16 +1076,21 @@ class Text(_String):
class Html(_String):
type = 'html'
sanitize = True # whether value must be sanitized
strip_style = False # whether to strip style attributes
_column_sanitize = property(attrgetter('sanitize'))
_related_sanitize = property(attrgetter('sanitize'))
_description_sanitize = property(attrgetter('sanitize'))
_column_strip_style = property(attrgetter('strip_style'))
_related_strip_style = property(attrgetter('strip_style'))
_description_strip_style = property(attrgetter('strip_style'))
def convert_to_cache(self, value, record, validate=True):
if value is None or value is False:
return False
if validate and self.sanitize:
return html_sanitize(value)
return html_sanitize(value, strip_style=self.strip_style)
return value
+3 -2
View File
@@ -317,11 +317,12 @@ class html(text):
return None
if not self._sanitize:
return value
return html_sanitize(value)
return html_sanitize(value, strip_style=self._strip_style)
def __init__(self, string='unknown', sanitize=True, **args):
def __init__(self, string='unknown', sanitize=True, strip_style=False, **args):
super(html, self).__init__(string=string, **args)
self._sanitize = sanitize
self._strip_style = strip_style
# symbol_set redefinition because of sanitize specific behavior
self._symbol_f = self._symbol_set_html
self._symbol_set = (self._symbol_c, self._symbol_f)
+2 -2
View File
@@ -53,7 +53,7 @@ safe_attrs = clean.defs.safe_attrs | frozenset(
])
def html_sanitize(src, silent=True, strict=False):
def html_sanitize(src, silent=True, strict=False, strip_style=False):
if not src:
return src
src = ustr(src, errors='replace')
@@ -69,7 +69,7 @@ def html_sanitize(src, silent=True, strict=False):
kwargs = {
'page_structure': True,
'style': False, # do not remove style attributes
'style': strip_style, # True = remove style tags/attrs
'forms': True, # remove form tags
'remove_unknown_tags': False,
'allow_tags': allowed_tags,