Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
slapos.core
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
Rafael Monnerat
slapos.core
Commits
55c22a39
Commit
55c22a39
authored
Sep 14, 2023
by
Rafael Monnerat
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
slapos_erp5: Drop/Update CertificateAuthorityTool related constraint
parent
334e4816
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
0 additions
and
472 deletions
+0
-472
master/bt5/slapos_configurator/TestTemplateItem/portal_components/test.erp5.testSlapOSConfigurator.py
...tem/portal_components/test.erp5.testSlapOSConfigurator.py
+0
-31
master/bt5/slapos_erp5/PortalTypePropertySheetTemplateItem/property_sheet_list.xml
...rtalTypePropertySheetTemplateItem/property_sheet_list.xml
+0
-3
master/bt5/slapos_erp5/PortalTypeTemplateItem/portal_types/Certificate%20Authority%20Tool.xml
...plateItem/portal_types/Certificate%20Authority%20Tool.xml
+0
-131
master/bt5/slapos_erp5/PropertySheetTemplateItem/portal_property_sheets/CertificateAuthorityToolConsistencyConstraint.xml
..._sheets/CertificateAuthorityToolConsistencyConstraint.xml
+0
-66
master/bt5/slapos_erp5/PropertySheetTemplateItem/portal_property_sheets/CertificateAuthorityToolConsistencyConstraint/certificate_authority_consistency_constraint_constraint.xml
...rtificate_authority_consistency_constraint_constraint.xml
+0
-80
master/bt5/slapos_erp5/SkinTemplateItem/portal_skins/slapos_erp5/CertificateAuthorityTool_checkCertificateAuthorityConsistency.py
...cateAuthorityTool_checkCertificateAuthorityConsistency.py
+0
-28
master/bt5/slapos_erp5/SkinTemplateItem/portal_skins/slapos_erp5/CertificateAuthorityTool_checkCertificateAuthorityConsistency.xml
...ateAuthorityTool_checkCertificateAuthorityConsistency.xml
+0
-62
master/bt5/slapos_erp5/TestTemplateItem/portal_components/test.erp5.testSlapOSCodingStyle.py
...Item/portal_components/test.erp5.testSlapOSCodingStyle.py
+0
-2
master/bt5/slapos_erp5/bt/template_portal_type_id_list
master/bt5/slapos_erp5/bt/template_portal_type_id_list
+0
-1
master/bt5/slapos_erp5/bt/template_portal_type_property_sheet_list
...5/slapos_erp5/bt/template_portal_type_property_sheet_list
+0
-1
master/bt5/slapos_erp5/bt/template_property_sheet_id_list
master/bt5/slapos_erp5/bt/template_property_sheet_id_list
+0
-1
master/product/SlapOS/tests/testSlapOSMixin.py
master/product/SlapOS/tests/testSlapOSMixin.py
+0
-66
No files found.
master/bt5/slapos_configurator/TestTemplateItem/portal_components/test.erp5.testSlapOSConfigurator.py
View file @
55c22a39
...
...
@@ -23,8 +23,6 @@
from
erp5.component.test.SlapOSTestCaseMixin
import
\
SlapOSTestCaseMixin
import
os
class
TestSlapOSConfigurator
(
SlapOSTestCaseMixin
):
...
...
@@ -66,17 +64,6 @@ class TestSlapOSConfigurator(SlapOSTestCaseMixin):
self
.
assertEqual
(
len
(
consistency_list
),
1
)
self
.
assertEqual
(
str
(
consistency_list
[
0
]),
'The System Preference subscription assignment should have a destination_project'
)
def
testConfiguredCertificateAuthoringConstraint
(
self
):
"""Make sure Certificate Authoring was configured well,
invoking checkConsistency.
Make sure PAS is well configured."""
# The certificate_authority_path is modified by the setup, invoke
# fixConsistency here to restore it like the originally expected.
self
.
portal
.
portal_certificate_authority
.
fixConsistency
()
self
.
assertEqual
(
self
.
portal
.
portal_certificate_authority
.
checkConsistency
(),
[])
def
testConfiguredTemplateToolViaConstraint
(
self
):
""" Make sure Template Tool Repositories was configured well,
invoking checkConsistency """
...
...
@@ -100,24 +87,6 @@ class TestSlapOSConfigurator(SlapOSTestCaseMixin):
"https://cloudooo1.erp5.net/"
]
self
.
assertSameSet
(
preference_tool
.
getPreferredDocumentConversionServerUrlList
(),
conversion_url
)
def
testConfiguredCertificateAuthoring
(
self
):
""" Make sure Certificate Authoting is
well configured. """
if
self
.
isLiveTest
():
# This test is redundant with testConfiguredVolatileCacheViaPromise
# and it is only aims to verify if test environment is behaving as
# expected, nothing else, and if alamrs were invoked.
return
# The certificate_authority_path is modified by the setup, invoke
# fixConsistency here to restore it like the originally expected.
self
.
portal
.
portal_certificate_authority
.
fixConsistency
()
self
.
assertTrue
(
self
.
portal
.
hasObject
(
'portal_certificate_authority'
))
self
.
assertEqual
(
os
.
environ
[
'TEST_CA_PATH'
],
self
.
portal
.
portal_certificate_authority
.
certificate_authority_path
)
def
testAlarmIsSubscribed
(
self
):
""" Make sure portal_alarms is subscribed. """
self
.
assertTrue
(
self
.
portal
.
portal_alarms
.
isSubscribed
())
...
...
master/bt5/slapos_erp5/PortalTypePropertySheetTemplateItem/property_sheet_list.xml
View file @
55c22a39
...
...
@@ -2,9 +2,6 @@
<portal_type
id=
"Category Tool"
>
<item>
CategoryToolUpgraderRegionConstraint
</item>
</portal_type>
<portal_type
id=
"Certificate Authority Tool"
>
<item>
CertificateAuthorityToolConsistencyConstraint
</item>
</portal_type>
<portal_type
id=
"Contract Invitation Token"
>
<item>
Reference
</item>
<item>
SlapOSCloudContractAccounting
</item>
...
...
master/bt5/slapos_erp5/PortalTypeTemplateItem/portal_types/Certificate%20Authority%20Tool.xml
deleted
100644 → 0
View file @
334e4816
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Base Type"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_property_domain_dict
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
short_title
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAM=
</string>
</persistent>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
acquire_local_roles
</string>
</key>
<value>
<int>
1
</int>
</value>
</item>
<item>
<key>
<string>
content_icon
</string>
</key>
<value>
<string>
folder_icon.gif
</string>
</value>
</item>
<item>
<key>
<string>
content_meta_type
</string>
</key>
<value>
<string>
ERP5 Folder
</string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<string>
Certificate Authority Tool contains Certificate Authority.
</string>
</value>
</item>
<item>
<key>
<string>
factory
</string>
</key>
<value>
<string>
addFolder
</string>
</value>
</item>
<item>
<key>
<string>
filter_content_types
</string>
</key>
<value>
<int>
1
</int>
</value>
</item>
<item>
<key>
<string>
group_list
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
Certificate Authority Tool
</string>
</value>
</item>
<item>
<key>
<string>
init_script
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
permission
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
searchable_text_property_id
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
type_class
</string>
</key>
<value>
<string>
CertificateAuthorityTool
</string>
</value>
</item>
<item>
<key>
<string>
type_interface
</string>
</key>
<value>
<tuple/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"TranslationInformation"
module=
"Products.ERP5Type.TranslationProviderBase"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
domain_name
</string>
</key>
<value>
<string>
erp5_ui
</string>
</value>
</item>
<item>
<key>
<string>
property_name
</string>
</key>
<value>
<string>
short_title
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"TranslationInformation"
module=
"Products.ERP5Type.TranslationProviderBase"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
domain_name
</string>
</key>
<value>
<string>
erp5_ui
</string>
</value>
</item>
<item>
<key>
<string>
property_name
</string>
</key>
<value>
<string>
title
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
master/bt5/slapos_erp5/PropertySheetTemplateItem/portal_property_sheets/CertificateAuthorityToolConsistencyConstraint.xml
deleted
100644 → 0
View file @
334e4816
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Property Sheet"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_count
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
_mt_index
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAM=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
_tree
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAQ=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
CertificateAuthorityToolConsistencyConstraint
</string>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Property Sheet
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"Length"
module=
"BTrees.Length"
/>
</pickle>
<pickle>
<int>
0
</int>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"OOBTree"
module=
"BTrees.OOBTree"
/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
<record
id=
"4"
aka=
"AAAAAAAAAAQ="
>
<pickle>
<global
name=
"OOBTree"
module=
"BTrees.OOBTree"
/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
</ZopeData>
master/bt5/slapos_erp5/PropertySheetTemplateItem/portal_property_sheets/CertificateAuthorityToolConsistencyConstraint/certificate_authority_consistency_constraint_constraint.xml
deleted
100644 → 0
View file @
334e4816
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Script Constraint"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_identity_criterion
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
_range_criterion
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAM=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
categories
</string>
</key>
<value>
<tuple>
<string>
constraint_type/post_upgrade
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
certificate_authority_consistency_constraint_constraint
</string>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Script Constraint
</string>
</value>
</item>
<item>
<key>
<string>
script_id
</string>
</key>
<value>
<string>
CertificateAuthorityTool_checkCertificateAuthorityConsistency
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
data
</string>
</key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
data
</string>
</key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
master/bt5/slapos_erp5/SkinTemplateItem/portal_skins/slapos_erp5/CertificateAuthorityTool_checkCertificateAuthorityConsistency.py
deleted
100644 → 0
View file @
334e4816
portal
=
context
.
getPortalObject
()
error_list
=
[]
portal_certificate_authority
=
getattr
(
portal
,
'portal_certificate_authority'
,
None
)
promise_ca_path
=
portal
.
getPromiseParameter
(
'portal_certificate_authority'
,
'certificate_authority_path'
)
def
installCertificateAuthority
():
portal_certificate_authority
=
getattr
(
portal
,
'portal_certificate_authority'
,
None
)
if
portal_certificate_authority
is
None
:
portal
.
manage_addProduct
[
'ERP5'
].
manage_addTool
(
'ERP5 Certificate Authority Tool'
,
None
)
portal_certificate_authority
=
getattr
(
portal
,
'portal_certificate_authority'
)
portal_certificate_authority
.
manage_editCertificateAuthorityTool
(
certificate_authority_path
=
promise_ca_path
)
if
promise_ca_path
is
not
None
:
if
portal_certificate_authority
is
None
:
error_list
.
append
(
"Certificate Authority Tool is not present"
)
elif
portal_certificate_authority
.
certificate_authority_path
!=
promise_ca_path
:
error_list
.
append
(
"Certificate Authority Tool (OpenSSL)is not configured as Expected: %s"
%
"Expect %s
\
n
Got %s"
%
(
portal_certificate_authority
.
certificate_authority_path
,
promise_ca_path
))
if
len
(
error_list
)
>
0
and
fixit
:
installCertificateAuthority
()
return
error_list
master/bt5/slapos_erp5/SkinTemplateItem/portal_skins/slapos_erp5/CertificateAuthorityTool_checkCertificateAuthorityConsistency.xml
deleted
100644 → 0
View file @
334e4816
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"PythonScript"
module=
"Products.PythonScripts.PythonScript"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_bind_names
</string>
</key>
<value>
<object>
<klass>
<global
name=
"_reconstructor"
module=
"copy_reg"
/>
</klass>
<tuple>
<global
name=
"NameAssignments"
module=
"Shared.DC.Scripts.Bindings"
/>
<global
name=
"object"
module=
"__builtin__"
/>
<none/>
</tuple>
<state>
<dictionary>
<item>
<key>
<string>
_asgns
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
name_container
</string>
</key>
<value>
<string>
container
</string>
</value>
</item>
<item>
<key>
<string>
name_context
</string>
</key>
<value>
<string>
context
</string>
</value>
</item>
<item>
<key>
<string>
name_m_self
</string>
</key>
<value>
<string>
script
</string>
</value>
</item>
<item>
<key>
<string>
name_subpath
</string>
</key>
<value>
<string>
traverse_subpath
</string>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key>
<string>
_params
</string>
</key>
<value>
<string>
fixit=False, **kw
</string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
CertificateAuthorityTool_checkCertificateAuthorityConsistency
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
master/bt5/slapos_erp5/TestTemplateItem/portal_components/test.erp5.testSlapOSCodingStyle.py
View file @
55c22a39
...
...
@@ -204,7 +204,6 @@ def makeTestSlapOSCodingStyleTestCase(tested_business_template):
'slapos_base/Login_isPasswordExpired'
,
'slapos_base/Login_notifyPasswordExpire'
,
'slapos_base/Person_applyContractInvitation'
,
'slapos_erp5/CertificateAuthorityTool_checkCertificateAuthorityConsistency'
,
'slapos_panel_compatibility/Base_getComputerToken'
,
'slapos_panel_compatibility/Person_requestComputer'
,
'slapos_panel/AllocationSupply_invalidateComputeNodeList'
,
...
...
@@ -343,7 +342,6 @@ def makeTestSlapOSCodingStyleTestCase(tested_business_template):
'slapos_configurator/BusinessConfiguration_runPostUpgradeConsistency'
,
'slapos_configurator/BusinessConfiguration_setupSlapOSMasterStandardBT5'
]
SlapOSTestCaseMixin
.
afterSetUp
(
self
)
def
getBusinessTemplateList
(
self
):
...
...
master/bt5/slapos_erp5/bt/template_portal_type_id_list
View file @
55c22a39
Certificate Authority Tool
Contract Invitation Token
Document Module
File
...
...
master/bt5/slapos_erp5/bt/template_portal_type_property_sheet_list
View file @
55c22a39
Certificate Authority Tool | CertificateAuthorityToolConsistencyConstraint
Category Tool | CategoryToolUpgraderRegionConstraint
Contract Invitation Token | Reference
Contract Invitation Token | SlapOSCloudContractAccounting
...
...
master/bt5/slapos_erp5/bt/template_property_sheet_id_list
View file @
55c22a39
CategoryToolUpgraderRegionConstraint
CertificateAuthorityToolConsistencyConstraint
GeographicOrganisation
PreferenceSlapOSConstraintPreference
ShacacheSystemPreference
...
...
master/product/SlapOS/tests/testSlapOSMixin.py
View file @
55c22a39
...
...
@@ -74,71 +74,6 @@ class testSlapOSMixin(ERP5TypeTestCase):
setattr
(
self
,
step_name
,
makeCallAlarm
(
alarm
))
setattr
(
self
,
'stepCallAlarmList'
,
makeCallAlarmList
(
alarm_step_list
))
def
createCertificateAuthorityFile
(
self
):
"""Sets up portal_certificate_authority"""
if
'TEST_CA_PATH'
not
in
os
.
environ
:
return
ca_path
=
os
.
path
.
join
(
os
.
environ
[
'TEST_CA_PATH'
],
self
.
__class__
.
__name__
)
if
os
.
path
.
exists
(
ca_path
):
shutil
.
rmtree
(
ca_path
)
os
.
mkdir
(
ca_path
)
os
.
mkdir
(
os
.
path
.
join
(
ca_path
,
'private'
))
os
.
mkdir
(
os
.
path
.
join
(
ca_path
,
'crl'
))
os
.
mkdir
(
os
.
path
.
join
(
ca_path
,
'certs'
))
os
.
mkdir
(
os
.
path
.
join
(
ca_path
,
'requests'
))
os
.
mkdir
(
os
.
path
.
join
(
ca_path
,
'newcerts'
))
with
open
(
os
.
path
.
join
(
os
.
environ
[
'TEST_CA_PATH'
],
'openssl.cnf'
),
"r"
)
as
f
:
original_openssl_cnf
=
f
.
read
()
openssl_cnf_with_updated_path
=
original_openssl_cnf
.
replace
(
os
.
environ
[
'TEST_CA_PATH'
],
ca_path
)
# SlapOS Master requires unique subjects
openssl_cnf
=
openssl_cnf_with_updated_path
.
replace
(
"unique_subject = no"
,
"unique_subject = yes"
)
with
open
(
os
.
path
.
join
(
ca_path
,
'openssl.cnf'
),
"w"
)
as
f
:
f
.
write
(
openssl_cnf
)
shutil
.
copy
(
os
.
path
.
join
(
os
.
environ
[
'TEST_CA_PATH'
],
'cacert.pem'
),
os
.
path
.
join
(
ca_path
,
'cacert.pem'
))
shutil
.
copy
(
os
.
path
.
join
(
os
.
environ
[
'TEST_CA_PATH'
],
'private'
,
'cakey.pem'
),
os
.
path
.
join
(
ca_path
,
'private'
,
'cakey.pem'
))
# reset test CA to have it always count from 0
with
open
(
os
.
path
.
join
(
ca_path
,
'serial'
),
"w"
)
as
f
:
f
.
write
(
'01'
)
with
open
(
os
.
path
.
join
(
ca_path
,
'index.txt'
),
"w"
)
as
f
:
f
.
write
(
'01'
)
with
open
(
os
.
path
.
join
(
ca_path
,
'crlnumber'
),
"w"
)
as
f
:
f
.
write
(
''
)
private_list
=
glob
.
glob
(
'%s/*.key'
%
os
.
path
.
join
(
ca_path
,
'private'
))
for
private
in
private_list
:
os
.
remove
(
private
)
crl_list
=
glob
.
glob
(
'%s/*'
%
os
.
path
.
join
(
ca_path
,
'crl'
))
for
crl
in
crl_list
:
os
.
remove
(
crl
)
certs_list
=
glob
.
glob
(
'%s/*'
%
os
.
path
.
join
(
ca_path
,
'certs'
))
for
cert
in
certs_list
:
os
.
remove
(
cert
)
newcerts_list
=
glob
.
glob
(
'%s/*'
%
os
.
path
.
join
(
ca_path
,
'newcerts'
))
for
newcert
in
newcerts_list
:
os
.
remove
(
newcert
)
self
.
portal
.
portal_certificate_authority
.
manage_editCertificateAuthorityTool
(
certificate_authority_path
=
ca_path
)
def
isLiveTest
(
self
):
#return 'ERP5TypeLiveTestCase' in [q.__name__ for q in self.__class__.mro()]
# XXX - What is the better way to know if we are in live test mode ?
...
...
@@ -170,7 +105,6 @@ class testSlapOSMixin(ERP5TypeTestCase):
if
self
.
isLiveTest
():
return
self
.
createCertificateAuthorityFile
()
self
.
commit
()
self
.
portal
.
portal_caches
.
updateCache
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment