0001-api-include-roles-in-bundle-export-68036.patch
tests/api/test_export_import.py | ||
---|---|---|
91 | 91 | |
92 | 92 | |
93 | 93 |
def test_export_import_dependencies(pub): |
94 |
role = pub.role_class(name='Test role') |
|
95 |
role.store() |
|
96 | ||
94 | 97 |
formdef = FormDef() |
95 | 98 |
formdef.name = 'Test' |
96 | 99 |
formdef.store() |
... | ... | |
111 | 114 |
workflow.variables_formdef.fields = [StringField(label='Test', id='1')] |
112 | 115 | |
113 | 116 |
status = workflow.add_status('New') |
114 |
status.add_action('form') |
|
117 |
action = status.add_action('form') |
|
118 |
action.by = [role.id] |
|
115 | 119 | |
116 | 120 |
data_source = NamedDataSource(name='foobar') |
117 | 121 |
data_source.store() |
... | ... | |
121 | 125 |
display_form.formdef.fields.append(StringField(label='Test', data_source={'type': 'foobar'})) |
122 | 126 | |
123 | 127 |
send_mail = status.add_action('sendmail') |
128 |
send_mail.to = [role.id] |
|
124 | 129 | |
125 | 130 |
workflow.store() |
126 | 131 | |
... | ... | |
132 | 137 | |
133 | 138 |
resp = get_app(pub).get(sign_uri('/api/export-import/forms/')) |
134 | 139 |
resp = get_app(pub).get(sign_uri(resp.json['data'][0]['urls']['dependencies'])) |
135 |
assert resp.json['data'] |
|
136 | 140 |
assert {(x['id'], x['type']) for x in resp.json['data']} == {('test', 'workflows'), ('test', 'blocks')} |
141 |
for dependency in resp.json['data']: |
|
142 |
get_app(pub).get(sign_uri(dependency['urls']['export'])) |
|
137 | 143 | |
138 | 144 |
resp = get_app(pub).get(sign_uri('/api/export-import/workflows/')) |
139 | 145 |
resp = get_app(pub).get(sign_uri(resp.json['data'][0]['urls']['dependencies'])) |
140 |
assert resp.json['data'] |
|
141 | 146 |
assert {(x['id'], x['type']) for x in resp.json['data']} == { |
142 | 147 |
('foobar', 'data-sources'), |
143 | 148 |
('test', 'blocks'), |
149 |
('test-role', 'roles'), |
|
144 | 150 |
} |
151 |
for dependency in resp.json['data']: |
|
152 |
resp = get_app(pub).get(sign_uri(dependency['urls']['export'])) |
|
153 |
if 'test-role' in dependency['urls']['export']: |
|
154 |
assert resp.json == {'name': 'Test role', 'slug': 'test-role', 'uuid': None} |
|
155 |
assert resp.content_type == 'application/json' |
|
156 |
else: |
|
157 |
assert resp.content_type == 'text/xml' |
|
145 | 158 | |
146 | 159 |
mail_template = MailTemplate(name='test mail template') |
147 | 160 |
mail_template.store() |
... | ... | |
149 | 162 |
workflow.store() |
150 | 163 |
resp = get_app(pub).get(sign_uri('/api/export-import/workflows/')) |
151 | 164 |
resp = get_app(pub).get(sign_uri(resp.json['data'][0]['urls']['dependencies'])) |
152 |
assert resp.json['data'] |
|
153 | 165 |
assert {(x['id'], x['type']) for x in resp.json['data']} == { |
154 | 166 |
('foobar', 'data-sources'), |
155 | 167 |
('test', 'blocks'), |
156 | 168 |
('test-mail-template', 'mail-templates'), |
169 |
('test-role', 'roles'), |
|
157 | 170 |
} |
171 |
for dependency in resp.json['data']: |
|
172 |
get_app(pub).get(sign_uri(dependency['urls']['export'])) |
|
158 | 173 |
resp = get_app(pub).get(sign_uri(resp.json['data'][-1]['urls']['dependencies'])) |
159 | 174 |
assert resp.json['data'] == [] |
160 | 175 | |
... | ... | |
165 | 180 |
resp = get_app(pub).get(sign_uri('/api/export-import/workflows/')) |
166 | 181 |
resp = get_app(pub).get(sign_uri(resp.json['data'][0]['urls']['dependencies'])) |
167 | 182 |
resp = get_app(pub).get(sign_uri(resp.json['data'][-1]['urls']['dependencies'])) |
168 |
assert resp.json['data'] |
|
169 | 183 |
assert {(x['id'], x['type']) for x in resp.json['data']} == {('cat', 'mail-templates-categories')} |
184 |
for dependency in resp.json['data']: |
|
185 |
get_app(pub).get(sign_uri(dependency['urls']['export'])) |
|
170 | 186 | |
171 | 187 |
resp = get_app(pub).get(sign_uri('/api/export-import/workflows/')) |
172 | 188 |
resp = get_app(pub).get(sign_uri(resp.json['data'][0]['urls']['dependencies'])) |
... | ... | |
179 | 195 |
data_source.store() |
180 | 196 |
resp = get_app(pub).get(sign_uri('/api/export-import/workflows/')) |
181 | 197 |
resp = get_app(pub).get(sign_uri(resp.json['data'][0]['urls']['dependencies'])) |
182 |
resp = get_app(pub).get(sign_uri(resp.json['data'][1]['urls']['dependencies'])) |
|
198 |
data_sources_entry = [x for x in resp.json['data'] if x['type'] == 'data-sources'][0] |
|
199 |
resp = get_app(pub).get(sign_uri(data_sources_entry['urls']['dependencies'])) |
|
183 | 200 |
assert {(x['id'], x['type']) for x in resp.json['data']} == {('cat', 'data-sources-categories')} |
184 | 201 | |
185 | 202 |
wcs/api_export_import.py | ||
---|---|---|
36 | 36 |
from wcs.data_sources import NamedDataSource, StubNamedDataSource |
37 | 37 |
from wcs.formdef import FormDef |
38 | 38 |
from wcs.mail_templates import MailTemplate |
39 |
from wcs.sql import Role |
|
39 | 40 |
from wcs.workflows import Workflow |
40 | 41 |
from wcs.wscalls import NamedWsCall |
41 | 42 | |
... | ... | |
52 | 53 |
'data-sources-categories': DataSourceCategory, |
53 | 54 |
'forms-categories': Category, |
54 | 55 |
'forms': FormDef, |
56 |
'roles': Role, |
|
55 | 57 |
'mail-templates-categories': MailTemplateCategory, |
56 | 58 |
'mail-templates': MailTemplate, |
57 | 59 |
'workflows-categories': WorkflowCategory, |
... | ... | |
117 | 119 |
'singular': _('Category (data Sources)'), |
118 | 120 |
'minor': True, |
119 | 121 |
}, |
122 |
{ |
|
123 |
'id': 'roles', |
|
124 |
'text': _('Roles'), |
|
125 |
'singular': _('Role'), |
|
126 |
'minor': True, |
|
127 |
}, |
|
120 | 128 |
] |
121 | 129 |
for obj in response: |
122 | 130 |
obj['urls'] = { |
... | ... | |
166 | 174 |
obj = get_object(objects, slug) |
167 | 175 |
if obj is None: |
168 | 176 |
raise Http404() |
169 |
etree = obj.export_to_xml(include_id=True) |
|
170 |
indent_xml(etree) |
|
171 |
return HttpResponse(ET.tostring(etree), content_type='text/xml') |
|
177 |
if hasattr(obj, 'export_for_application'): |
|
178 |
content, content_type = obj.export_for_application() |
|
179 |
else: |
|
180 |
etree = obj.export_to_xml(include_id=True) |
|
181 |
indent_xml(etree) |
|
182 |
content = ET.tostring(etree) |
|
183 |
content_type = 'text/xml' |
|
184 |
return HttpResponse(content, content_type=content_type) |
|
172 | 185 | |
173 | 186 | |
174 | 187 |
@signature_required |
wcs/roles.py | ||
---|---|---|
14 | 14 |
# You should have received a copy of the GNU General Public License |
15 | 15 |
# along with this program; if not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 |
import json |
|
17 | 18 |
import urllib.parse |
18 | 19 |
import xml.etree.ElementTree as ET |
19 | 20 | |
... | ... | |
114 | 115 |
ET.SubElement(root, boolean_attribute).text = value |
115 | 116 |
return root |
116 | 117 | |
118 |
def export_for_application(self): |
|
119 |
return (json.dumps({'name': self.name, 'slug': self.slug, 'uuid': self.uuid}), 'application/json') |
|
120 | ||
117 | 121 |
@classmethod |
118 | 122 |
def import_from_xml(cls, fd, charset=None, include_id=False): |
119 | 123 |
try: |
wcs/wf/dispatch.py | ||
---|---|---|
21 | 21 |
from quixote.html import htmltext |
22 | 22 | |
23 | 23 |
from wcs.roles import get_user_roles |
24 |
from wcs.workflows import WorkflowStatusItem, XmlSerialisable, get_role_name_and_slug, register_item_class |
|
24 |
from wcs.workflows import ( |
|
25 |
WorkflowStatusItem, |
|
26 |
XmlSerialisable, |
|
27 |
get_role_dependencies, |
|
28 |
get_role_name_and_slug, |
|
29 |
register_item_class, |
|
30 |
) |
|
25 | 31 | |
26 | 32 |
from ..qommon import _ |
27 | 33 |
from ..qommon.form import ( |
... | ... | |
136 | 142 |
if rules: |
137 | 143 |
self.rules = rules |
138 | 144 | |
145 |
def get_dependencies(self): |
|
146 |
yield from get_role_dependencies([self.role_id]) |
|
147 |
yield from get_role_dependencies([x.get('role_id') for x in self.rules]) |
|
148 | ||
139 | 149 |
def get_line_details(self): |
140 | 150 |
if self.role_key: |
141 | 151 |
function_label = self.parent.parent.roles.get(self.role_key, '?') |
wcs/wf/form.py | ||
---|---|---|
193 | 193 |
return changed |
194 | 194 | |
195 | 195 |
def get_dependencies(self): |
196 |
yield from super().get_dependencies() |
|
196 | 197 |
if self.formdef and self.formdef.fields: |
197 | 198 |
for field in self.formdef.fields: |
198 | 199 |
yield from field.get_dependencies() |
wcs/wf/roles.py | ||
---|---|---|
20 | 20 | |
21 | 21 |
from wcs.api_utils import MissingSecret, get_secret_and_orig, sign_url |
22 | 22 |
from wcs.roles import get_user_roles |
23 |
from wcs.workflows import WorkflowStatusItem, register_item_class |
|
23 |
from wcs.workflows import WorkflowStatusItem, get_role_dependencies, register_item_class
|
|
24 | 24 | |
25 | 25 |
from ..qommon import _ |
26 | 26 |
from ..qommon.form import SingleSelectWidgetWithOther |
... | ... | |
57 | 57 |
return role.name |
58 | 58 |
return _('unknown - %s') % self.role_id |
59 | 59 | |
60 |
def get_dependencies(self): |
|
61 |
yield from get_role_dependencies([self.role_id]) |
|
62 | ||
60 | 63 | |
61 | 64 |
class AddRoleWorkflowStatusItem(RoleMixin, WorkflowStatusItem): |
62 | 65 |
description = _('Role Addition') |
wcs/wf/sendmail.py | ||
---|---|---|
70 | 70 |
comment = None |
71 | 71 | |
72 | 72 |
def get_dependencies(self): |
73 |
yield from super().get_dependencies() |
|
73 | 74 |
yield MailTemplate.get_by_slug(self.mail_template) |
74 | 75 | |
75 | 76 |
def _get_role_id_from_xml(self, elem, charset, include_id=False, snapshot=False): |
wcs/workflows.py | ||
---|---|---|
142 | 142 |
pass |
143 | 143 | |
144 | 144 | |
145 |
def get_role_dependencies(roles): |
|
146 |
for role_id in roles or []: |
|
147 |
if not role_id: |
|
148 |
continue |
|
149 |
role_id = str(role_id) |
|
150 |
if role_id.startswith('_') or role_id == 'logged-users': |
|
151 |
continue |
|
152 |
yield get_publisher().role_class.get(role_id, ignore_errors=True) |
|
153 | ||
154 | ||
145 | 155 |
class AttachmentSubstitutionProxy: |
146 | 156 |
def __init__(self, formdata, attachment_evolution_part): |
147 | 157 |
self.formdata = formdata |
... | ... | |
638 | 648 |
if self.possible_status: |
639 | 649 |
for status in self.possible_status: |
640 | 650 |
yield from status.get_dependencies() |
651 |
if self.global_actions: |
|
652 |
for action in self.global_actions: |
|
653 |
yield from action.get_dependencies() |
|
641 | 654 | |
642 | 655 |
@classmethod |
643 | 656 |
def get(cls, id, ignore_errors=False, ignore_migration=False): |
... | ... | |
1329 | 1342 |
def roles_init_with_xml(self, elem, charset, include_id=False, snapshot=False): |
1330 | 1343 |
self._roles_init_with_xml('roles', elem, charset, include_id=include_id, snapshot=snapshot) |
1331 | 1344 | |
1345 |
def get_dependencies(self): |
|
1346 |
yield from get_role_dependencies(self.roles) |
|
1347 | ||
1332 | 1348 | |
1333 | 1349 |
class WorkflowGlobalActionTimeoutTriggerMarker(EvolutionPart): |
1334 | 1350 |
def __init__(self, timeout_id): |
... | ... | |
1637 | 1653 |
) |
1638 | 1654 |
break |
1639 | 1655 | |
1656 |
def get_dependencies(self): |
|
1657 |
return [] |
|
1658 | ||
1640 | 1659 | |
1641 | 1660 |
class WorkflowGlobalActionWebserviceTrigger(WorkflowGlobalActionManualTrigger): |
1642 | 1661 |
key = 'webservice' |
... | ... | |
1673 | 1692 | |
1674 | 1693 |
return [('hooks', WorkflowGlobalActionWebserviceHooksDirectory(formdata))] |
1675 | 1694 | |
1695 |
def get_dependencies(self): |
|
1696 |
return [] |
|
1697 | ||
1676 | 1698 | |
1677 | 1699 |
class SerieOfActionsMixin: |
1678 | 1700 |
items = None |
... | ... | |
1782 | 1804 |
trigger_o.parent = self |
1783 | 1805 |
trigger_o.init_with_xml(trigger, charset, include_id=include_id, snapshot=snapshot) |
1784 | 1806 | |
1807 |
def get_dependencies(self): |
|
1808 |
yield from super().get_dependencies() |
|
1809 |
for trigger in self.triggers or []: |
|
1810 |
yield from trigger.get_dependencies() |
|
1811 | ||
1785 | 1812 | |
1786 | 1813 |
class WorkflowCriticalityLevel: |
1787 | 1814 |
id = None |
... | ... | |
2194 | 2221 |
return self.parent.parent.get_add_role_label() |
2195 | 2222 | |
2196 | 2223 |
def get_dependencies(self): |
2197 |
return [] |
|
2224 |
yield from get_role_dependencies(getattr(self, 'by', None)) |
|
2225 |
yield from get_role_dependencies(getattr(self, 'to', None)) |
|
2198 | 2226 | |
2199 | 2227 |
@noop_mark |
2200 | 2228 |
def perform(self, formdata): |
2201 |
- |