Commit 807dc150 authored by Arnaud Fontaine's avatar Arnaud Fontaine

Merge remote-tracking branch 'origin/master' into zope4py2

parents f7d47011 593b6cf6
Pipeline #21141 failed with stage
...@@ -643,34 +643,6 @@ div.download-document-format-list-menu ul li.toggle-hidden-format-dialog-selecti ...@@ -643,34 +643,6 @@ div.download-document-format-list-menu ul li.toggle-hidden-format-dialog-selecti
height:20px; height:20px;
} }
/* DMS PDF navigation */
div.pdf-preview-navigation img{
width: 4px;
height: 8px;
margin-right: 4px;
background-repeat: no-repeat;
vertical-align: middle;
}
div.pdf-preview-navigation img.shaded{
opacity: 0.2;
}
div.pdf-preview-navigation img.first{
background-image:url("km_img/2leftarrowv.png");
}
div.pdf-preview-navigation img.previous{
background-image:url("km_img/1leftarrowv.png");
}
div.pdf-preview-navigation img.next{
background-image:url("km_img/1rightarrowv.png");
}
div.pdf-preview-navigation img.last{
background-image:url("km_img/2rightarrowv.png");
width: 5px;
}
/* Editable mode actions */ /* Editable mode actions */
.actions{ .actions{
......
...@@ -146,66 +146,6 @@ function initialize_form(){ ...@@ -146,66 +146,6 @@ function initialize_form(){
} }
} }
// function make_pdf_navigation_asynchronous_form(){
// /*
// Make default PDF navigation in preview in asynchronous way.
// */
//
// function splitUrl(url){
// jQuery.url.setUrl(image_src)
// base_url = jQuery.url.attr("base") + jQuery.url.attr("path");
// query_dict = {"display": jQuery.url.param("display"),
// "format": jQuery.url.param("format"),
// "resolution:int": jQuery.url.param("resolution:int"),
// "frame": parseInt(jQuery.url.param("frame"))};
// query_string = $.param(query_dict);
// console.log(base_url);
// console.log(query_string);
// }
//
// function loadThumbnail(event){
// event.preventDefault();
// navigation_url = this.href;
//
// image = $("div.pdf-preview-content img");
// image_url = image.attr("src");
//
// // read current image URL
// jQuery.url.setUrl(image_url);
// base_url = jQuery.url.attr("base") + jQuery.url.attr("path");
// query_dict = {"display": jQuery.url.param("display"),
// "format": jQuery.url.param("format"),
// "resolution:int": jQuery.url.param("resolution:int")};
//
//
// // get frame index from navigation link
// jQuery.url.setUrl(navigation_url);
// frame = parseInt(jQuery.url.param("selection_index"))
// query_dict["frame"]=frame;
//
// // construct new thumbnail URL
// query_string = $.param(query_dict);
// new_image_url = base_url + "?" +query_string;
// console.log(new_image_url);
//
// image.attr("src", new_image_url);
//
// }
//
// pdf_preview_navigation = $('div.pdf-preview-navigation');
// if(pdf_preview_navigation.length){
//
// // XXX: set hooks
// // $("div.pdf-preview-navigation a img.first").parent("a").click(loadThumbnail);
// // $("div.pdf-preview-navigation a img.previous").parent("a").click(loadThumbnail);
// // $("div.pdf-preview-navigation a img.next").parent("a").click(loadThumbnail);
// // $("div.pdf-preview-navigation a img.last").parent("a").click(loadThumbnail);
//
// }
// }
// $(document).ready(make_pdf_navigation_asynchronous_form);
jQuery.fn.highlight = function (str, className) { jQuery.fn.highlight = function (str, className) {
/* /*
Highlight search word in HTML content. Highlight search word in HTML content.
......
...@@ -469,16 +469,6 @@ div.bottom_actions button#input-save-view span.image { ...@@ -469,16 +469,6 @@ div.bottom_actions button#input-save-view span.image {
background-image: url('<tal:block tal:replace="site_url"/>/images/save-preview.png'); background-image: url('<tal:block tal:replace="site_url"/>/images/save-preview.png');
} }
div.pdf-preview-navigation {
font-size:120%;
text-align:center;
}
div.pdf-preview-navigation img {
float:none;
margin:0;
}
div.error > div > input, div.error > div > input,
div.error > div > textarea { div.error > div > textarea {
border:1px solid red; border:1px solid red;
...@@ -687,35 +677,4 @@ div#main_content table.listbox tfoot .pageNavigation button:hover { ...@@ -687,35 +677,4 @@ div#main_content table.listbox tfoot .pageNavigation button:hover {
background: #eee; background: #eee;
} }
/* DMS PDF navigation
XXX: probably part of erp5_dms.bt5 */
div.pdf-preview-navigation img{
width: 22px;
height: 22px;
margin-right: 1px;
background-repeat: no-repeat;
vertical-align: middle;
}
div.pdf-preview-navigation img.shaded{
opacity: 0.2;
}
div.pdf-preview-navigation img.first{
background-image:url("images/2leftarrowb.png");
}
div.pdf-preview-navigation img.previous{
background-image:url("images/1leftarrowb.png");
}
div.pdf-preview-navigation img.next{
background-image:url("images/1rightarrowb.png");
}
div.pdf-preview-navigation img.last{
background-image:url("images/2rightarrowb.png");
}
</tal:block> </tal:block>
\ No newline at end of file
...@@ -27,6 +27,7 @@ from __future__ import absolute_import ...@@ -27,6 +27,7 @@ from __future__ import absolute_import
# #
############################################################################## ##############################################################################
import copy
import socket import socket
import urllib import urllib
import threading import threading
...@@ -195,6 +196,9 @@ class Message(BaseMessage): ...@@ -195,6 +196,9 @@ class Message(BaseMessage):
exc_type = None exc_type = None
is_executed = MESSAGE_NOT_EXECUTED is_executed = MESSAGE_NOT_EXECUTED
traceback = None traceback = None
user_name = None
user_object = None
user_folder_path = None
document_uid = None document_uid = None
is_registered = False is_registered = False
line = None line = None
...@@ -224,7 +228,14 @@ class Message(BaseMessage): ...@@ -224,7 +228,14 @@ class Message(BaseMessage):
# was generated. # was generated.
# Strip last stack entry, since it will always be the same. # Strip last stack entry, since it will always be the same.
self.call_traceback = ''.join(format_list(extract_stack()[:-1])) self.call_traceback = ''.join(format_list(extract_stack()[:-1]))
self.user_name = getSecurityManager().getUser().getIdOrUserName() user = getSecurityManager().getUser()
self.user_object = copy.deepcopy(aq_base(user))
# Note: userfolders are not ERP5 objects, so use OFS API.
self.user_folder_path = getattr(
aq_parent(user),
'getPhysicalPath',
lambda: None,
)()
# Store REQUEST Info # Store REQUEST Info
self.request_info = {} self.request_info = {}
if request is not None: if request is not None:
...@@ -298,31 +309,42 @@ class Message(BaseMessage): ...@@ -298,31 +309,42 @@ class Message(BaseMessage):
pass pass
return 1 return 1
def changeUser(self, user_name, activity_tool): def changeUser(self, activity_tool):
"""restore the security context for the calling user.""" """restore the security context for the calling user."""
portal = activity_tool.getPortalObject() portal = activity_tool.getPortalObject()
portal_uf = portal.acl_users user = self.user_object
uf = portal_uf if user is None and self.user_name is not None: # BBB
user = uf.getUserById(user_name) user_name = self.user_name
user_folder = portal_user_folder = portal.acl_users
user = user_folder.getUserById(user_name)
# if the user is not found, try to get it from a parent acl_users # if the user is not found, try to get it from a parent acl_users
# XXX this is still far from perfect, because we need to store all # XXX this is still far from perfect, because we need to store all
# information about the user (like original user folder, roles) to # information about the user (like original user folder, roles) to
# replay the activity with exactly the same security context as if # replay the activity with exactly the same security context as if
# it had been executed without activity. # it had been executed without activity.
if user is None: if user is None:
uf = portal.aq_parent.acl_users user_folder = portal.aq_parent.acl_users
user = uf.getUserById(user_name) user = user_folder.getUserById(user_name)
if user is None and user_name == system_user.getUserName(): if user is None and user_name == system_user.getUserName():
# The following logic partly comes from unrestricted_apply() # The following logic partly comes from unrestricted_apply()
# implementation in ERP5Type.UnrestrictedMethod but we get roles # implementation in ERP5Type.UnrestrictedMethod but we get roles
# from the portal to have more roles. # from the portal to have more roles.
uf = portal_uf user_folder = portal_user_folder
role_list = uf.valid_roles() user = PrivilegedUser(
user = PrivilegedUser(user_name, None, role_list, ()).__of__(uf) user_name,
None,
user_folder.valid_roles(),
(),
)
else:
user_folder = portal.getPhysicalRoot().unrestrictedTraverse(
self.user_folder_path,
)
user_name = user.getIdOrUserName()
if user is not None: if user is not None:
user = user.__of__(uf) user = user.__of__(user_folder)
newSecurityManager(None, user) newSecurityManager(None, user)
transaction.get().setUser(user_name, '/'.join(uf.getPhysicalPath())) transaction.get().setUser(user_name, '/'.join(user_folder.getPhysicalPath()))
else : else :
LOG("CMFActivity", WARNING, LOG("CMFActivity", WARNING,
"Unable to find user %r in the portal" % user_name) "Unable to find user %r in the portal" % user_name)
...@@ -347,7 +369,7 @@ class Message(BaseMessage): ...@@ -347,7 +369,7 @@ class Message(BaseMessage):
try: try:
# Change user if required (TO BE DONE) # Change user if required (TO BE DONE)
# We will change the user only in order to execute this method # We will change the user only in order to execute this method
self.changeUser(self.user_name, activity_tool) self.changeUser(activity_tool)
# XXX: There is no check to see if user is allowed to access # XXX: There is no check to see if user is allowed to access
# that method ! # that method !
method = getattr(obj, self.method_id) method = getattr(obj, self.method_id)
...@@ -420,7 +442,7 @@ Named Parameters: %r ...@@ -420,7 +442,7 @@ Named Parameters: %r
try: try:
# Change user if required (TO BE DONE) # Change user if required (TO BE DONE)
# We will change the user only in order to execute this method # We will change the user only in order to execute this method
user = self.changeUser(self.user_name, activity_tool) user = self.changeUser(activity_tool)
active_obj = obj.activate(activity=activity, **self.activity_kw) active_obj = obj.activate(activity=activity, **self.activity_kw)
getattr(active_obj, self.method_id)(*self.args, **self.kw) getattr(active_obj, self.method_id)(*self.args, **self.kw)
finally: finally:
...@@ -1664,7 +1686,7 @@ class ActivityTool (BaseTool): ...@@ -1664,7 +1686,7 @@ class ActivityTool (BaseTool):
message = m._message message = m._message
if user_name != message.user_name: if user_name != message.user_name:
user_name = message.user_name user_name = message.user_name
message.changeUser(user_name, m.object) message.changeUser(m.object)
m.result = getattr(m.object, method_id)(*m.args, **m.kw) m.result = getattr(m.object, method_id)(*m.args, **m.kw)
except Exception: except Exception:
m.raised() m.raised()
......
...@@ -30,6 +30,10 @@ import inspect ...@@ -30,6 +30,10 @@ import inspect
import warnings import warnings
from functools import wraps from functools import wraps
from itertools import product from itertools import product
from AccessControl.SecurityManagement import getSecurityManager
from AccessControl.SecurityManagement import setSecurityManager
from AccessControl.SecurityManagement import newSecurityManager
from Acquisition import aq_base, aq_parent
from Products.ERP5Type.tests.utils import LogInterceptor from Products.ERP5Type.tests.utils import LogInterceptor
from Testing import ZopeTestCase from Testing import ZopeTestCase
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
...@@ -40,6 +44,7 @@ from Products.CMFActivity.Activity.SQLBase import INVOKE_ERROR_STATE ...@@ -40,6 +44,7 @@ from Products.CMFActivity.Activity.SQLBase import INVOKE_ERROR_STATE
from Products.CMFActivity.Activity.Queue import VALIDATION_ERROR_DELAY from Products.CMFActivity.Activity.Queue import VALIDATION_ERROR_DELAY
from Products.CMFActivity.Activity.SQLDict import SQLDict from Products.CMFActivity.Activity.SQLDict import SQLDict
from Products.CMFActivity.Errors import ActivityPendingError, ActivityFlushError from Products.CMFActivity.Errors import ActivityPendingError, ActivityFlushError
from Products.PluggableAuthService.PropertiedUser import PropertiedUser
from erp5.portal_type import Organisation from erp5.portal_type import Organisation
from AccessControl.SecurityManagement import newSecurityManager from AccessControl.SecurityManagement import newSecurityManager
from zLOG import LOG from zLOG import LOG
...@@ -2798,3 +2803,34 @@ return [x.getObject() for x in context.portal_catalog(limit=100)] ...@@ -2798,3 +2803,34 @@ return [x.getObject() for x in context.portal_catalog(limit=100)]
self.portal.portal_activities.manageActivitiesAdvanced() self.portal.portal_activities.manageActivitiesAdvanced()
self.portal.portal_activities.manageLoadBalancing() self.portal.portal_activities.manageLoadBalancing()
self.assertEqual(catched_warnings, []) self.assertEqual(catched_warnings, [])
@for_each_activity
def testSpawnTimeUserGroupAndRoleUsedDuringExecution(self, activity):
obj = self.portal.organisation_module.newContent(portal_type='Organisation')
self.tic()
# This user cannot be created by userfolder API, validating that activity
# execution does not use it.
# Using a PropertiedUser because it is the lowest-level class which has a
# groups notion.
artificial_user = PropertiedUser(
id='this user does not exist',
login='does not matter',
).__of__(self.portal.acl_users)
artificial_user._addGroups(groups=('group 1', 'group 2'))
artificial_user._addRoles(roles=('role 1', 'role 2'))
initial_security_manager = getSecurityManager()
def checkUserGroupAndRole(organisation_self):
user = getSecurityManager().getUser()
self.assertIs(type(aq_base(user)), PropertiedUser)
self.assertEqual(aq_parent(user), aq_parent(artificial_user))
self.assertEqual(user.getId(), artificial_user.getId())
self.assertItemsEqual(user.getGroups(), artificial_user.getGroups())
self.assertItemsEqual(user.getRoles(), artificial_user.getRoles())
Organisation.checkUserGroupAndRole = checkUserGroupAndRole
try:
newSecurityManager(None, artificial_user)
obj.activate(activity=activity).checkUserGroupAndRole()
self.tic()
finally:
setSecurityManager(initial_security_manager)
del Organisation.checkUserGroupAndRole
...@@ -1162,36 +1162,6 @@ div.search .searchPages .selected{ ...@@ -1162,36 +1162,6 @@ div.search .searchPages .selected{
display:none; display:none;
} }
/* DMS PDF navigation
XXX: probably part of erp5_dms.bt5 */
div.pdf-preview-navigation img{
width: 22px;
height: 22px;
margin-right: 1px;
background-repeat: no-repeat;
vertical-align: middle;
}
div.pdf-preview-navigation img.shaded{
opacity: 0.2;
}
div.pdf-preview-navigation img.first{
background-image:url("images/2leftarrowb.png");
}
div.pdf-preview-navigation img.previous{
background-image:url("images/1leftarrowb.png");
}
div.pdf-preview-navigation img.next{
background-image:url("images/1rightarrowb.png");
}
div.pdf-preview-navigation img.last{
background-image:url("images/2rightarrowb.png");
}
.horizontal_align_form_box > div.input { .horizontal_align_form_box > div.input {
float: right; float: right;
width: 70%; /* because label width is 30%*/ width: 70%; /* because label width is 30%*/
......
##############################################################################
#
# Copyright (c) 2001,2002 Zope Foundation and Contributors.
# Copyright (c) 2002,2005 Nexedi SARL and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
# -*- coding: utf-8 -*-
############################################################################## ##############################################################################
# #
# Copyright (c) 2001,2002 Zope Corporation and Contributors. All Rights Reserved. # Copyright (c) 2001,2002 Zope Corporation and Contributors. All Rights Reserved.
...@@ -22,7 +23,6 @@ from marshal import loads as mloads ...@@ -22,7 +23,6 @@ from marshal import loads as mloads
from .xyap import NoBlanks from .xyap import NoBlanks
from .xyap import xyap from .xyap import xyap
import re
from marshal import dumps as mdumps from marshal import dumps as mdumps
#from zLOG import LOG #from zLOG import LOG
......
# -*- coding: utf-8 -*-
"""Yet another XML parser """Yet another XML parser
This is meant to be very simple: This is meant to be very simple:
......
...@@ -38,7 +38,6 @@ if WITH_LEGACY_WORKFLOW: ...@@ -38,7 +38,6 @@ if WITH_LEGACY_WORKFLOW:
from Products.ERP5Type.patches import BTreeFolder2 from Products.ERP5Type.patches import BTreeFolder2
if WITH_LEGACY_WORKFLOW: if WITH_LEGACY_WORKFLOW:
from Products.ERP5Type.patches import WorkflowTool from Products.ERP5Type.patches import WorkflowTool
from Products.ERP5Type.patches import WorkflowTool
from Products.ERP5Type.patches import DynamicType from Products.ERP5Type.patches import DynamicType
from Products.ERP5Type.patches import Expression from Products.ERP5Type.patches import Expression
from Products.ERP5Type.patches import sqltest from Products.ERP5Type.patches import sqltest
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment