Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
Zope
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
Zope
Commits
ab628670
Commit
ab628670
authored
Aug 14, 2016
by
Hanno Schlichting
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make webdav/ftp methods conditionally available based on ZServer presence.
parent
ed87506a
Changes
14
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
321 additions
and
334 deletions
+321
-334
src/App/ImageFile.py
src/App/ImageFile.py
+8
-6
src/App/bbb.py
src/App/bbb.py
+20
-0
src/OFS/Application.py
src/OFS/Application.py
+10
-9
src/OFS/DTMLMethod.py
src/OFS/DTMLMethod.py
+23
-21
src/OFS/Image.py
src/OFS/Image.py
+45
-43
src/OFS/ObjectManager.py
src/OFS/ObjectManager.py
+87
-86
src/OFS/SimpleItem.py
src/OFS/SimpleItem.py
+72
-71
src/OFS/interfaces.py
src/OFS/interfaces.py
+9
-22
src/OFS/tests/testFTPInterface.py
src/OFS/tests/testFTPInterface.py
+0
-11
src/OFS/tests/testFileAndImage.py
src/OFS/tests/testFileAndImage.py
+0
-21
src/Products/PageTemplates/ZopePageTemplate.py
src/Products/PageTemplates/ZopePageTemplate.py
+24
-21
src/Products/PageTemplates/bbb.py
src/Products/PageTemplates/bbb.py
+20
-0
src/Products/PageTemplates/tests/testZopePageTemplate.py
src/Products/PageTemplates/tests/testZopePageTemplate.py
+3
-11
src/Testing/ZopeTestCase/testFunctional.py
src/Testing/ZopeTestCase/testFunctional.py
+0
-12
No files found.
src/App/ImageFile.py
View file @
ab628670
...
...
@@ -20,6 +20,7 @@ import warnings
from
AccessControl.class_init
import
InitializeClass
from
AccessControl.SecurityInfo
import
ClassSecurityInfo
from
Acquisition
import
Explicit
from
App
import
bbb
from
App.Common
import
package_home
from
App.Common
import
rfc1123_date
from
App.config
import
getConfiguration
...
...
@@ -119,6 +120,7 @@ class ImageFile(Explicit):
return
filestream_iterator
(
self
.
path
,
mode
=
'rb'
)
if
bbb
.
HAS_ZSERVER
:
security
.
declarePublic
(
'HEAD'
)
def
HEAD
(
self
,
REQUEST
,
RESPONSE
):
""" """
...
...
src/
OFS/FTPInterface
.py
→
src/
App/bbb
.py
View file @
ab628670
...
...
@@ -10,45 +10,11 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""FTP Support for Zope classes.
Preliminary FTP support interface. Note, most FTP functions are
provided by existing methods such as PUT and manage_delObjects.
import
pkg_resources
All FTP methods should be governed by a single permission:
'FTP access'.
"""
from
zope.interface
import
implements
from
interfaces
import
IFTPAccess
class
FTPInterface
:
"Interface for FTP objects"
implements
(
IFTPAccess
)
# XXX The stat and list marshal format should probably
# be XML, not marshal, maybe Andrew K's xml-marshal.
# This will probably be changed later.
def
manage_FTPstat
(
self
,
REQUEST
):
"""Returns a stat-like tuple. (marshalled to a string) Used by
FTP for directory listings, and MDTM and SIZE"""
def
manage_FTPlist
(
self
,
REQUEST
):
"""Returns a directory listing consisting of a tuple of
(id,stat) tuples, marshaled to a string. Note, the listing it
should include '..' if there is a Folder above the current
one.
In the case of non-foldoid objects it should return a single
tuple (id,stat) representing itself."""
# Optional method to support FTP download.
# Should not be implemented by Foldoid objects.
def
manage_FTPget
(
self
):
"""Returns the source content of an object. For example, the
source text of a Document, or the data of a file."""
HAS_ZSERVER
=
True
try
:
dist
=
pkg_resources
.
get_distribution
(
'ZServer'
)
except
pkg_resources
.
DistributionNotFound
:
HAS_ZSERVER
=
False
src/OFS/Application.py
View file @
ab628670
...
...
@@ -133,6 +133,7 @@ class Application(ApplicationDefaultPermissions, Folder.Folder):
"""Utility function to return current date/time"""
return
DateTime
(
*
args
)
if
bbb
.
HAS_ZSERVER
:
def
DELETE
(
self
,
REQUEST
,
RESPONSE
):
"""Delete a resource object."""
self
.
dav__init
(
REQUEST
,
RESPONSE
)
...
...
src/OFS/DTMLMethod.py
View file @
ab628670
...
...
@@ -31,6 +31,7 @@ from AccessControl.requestmethod import requestmethod
from
AccessControl.tainted
import
TaintedString
from
DocumentTemplate.permissions
import
change_dtml_methods
from
DocumentTemplate.security
import
RestrictedDTML
from
OFS
import
bbb
from
OFS.Cache
import
Cacheable
from
OFS.History
import
Historical
from
OFS.History
import
html_diff
...
...
@@ -366,6 +367,7 @@ class DTMLMethod(RestrictedDTML,
RESPONSE
.
setHeader
(
'Content-Type'
,
'text/plain'
)
return
self
.
read
()
if
bbb
.
HAS_ZSERVER
:
security
.
declareProtected
(
change_dtml_methods
,
'PUT'
)
def
PUT
(
self
,
REQUEST
,
RESPONSE
):
""" Handle FTP / HTTP PUT requests.
...
...
src/OFS/Image.py
View file @
ab628670
...
...
@@ -37,6 +37,7 @@ from zope.contenttype import guess_content_type
from
zope.interface
import
implementedBy
from
zope.interface
import
implements
from
OFS
import
bbb
from
OFS.Cache
import
Cacheable
from
OFS.interfaces
import
IWriteLock
from
OFS.PropertyManager
import
PropertyManager
...
...
@@ -595,23 +596,6 @@ class File(Persistent, Implicit, PropertyManager,
return
next
,
size
security
.
declareProtected
(
change_images_and_files
,
'PUT'
)
def
PUT
(
self
,
REQUEST
,
RESPONSE
):
"""Handle HTTP PUT requests"""
self
.
dav__init
(
REQUEST
,
RESPONSE
)
self
.
dav__simpleifhandler
(
REQUEST
,
RESPONSE
,
refresh
=
1
)
type
=
REQUEST
.
get_header
(
'content-type'
,
None
)
file
=
REQUEST
[
'BODYFILE'
]
data
,
size
=
self
.
_read_data
(
file
)
content_type
=
self
.
_get_content_type
(
file
,
data
,
self
.
__name__
,
type
or
self
.
content_type
)
self
.
update_data
(
data
,
content_type
,
size
)
RESPONSE
.
setStatus
(
204
)
return
RESPONSE
security
.
declareProtected
(
View
,
'get_size'
)
def
get_size
(
self
):
# Get the size of a file or image.
...
...
@@ -636,6 +620,24 @@ class File(Persistent, Implicit, PropertyManager,
def
__len__
(
self
):
return
1
if
bbb
.
HAS_ZSERVER
:
security
.
declareProtected
(
change_images_and_files
,
'PUT'
)
def
PUT
(
self
,
REQUEST
,
RESPONSE
):
"""Handle HTTP PUT requests"""
self
.
dav__init
(
REQUEST
,
RESPONSE
)
self
.
dav__simpleifhandler
(
REQUEST
,
RESPONSE
,
refresh
=
1
)
type
=
REQUEST
.
get_header
(
'content-type'
,
None
)
file
=
REQUEST
[
'BODYFILE'
]
data
,
size
=
self
.
_read_data
(
file
)
content_type
=
self
.
_get_content_type
(
file
,
data
,
self
.
__name__
,
type
or
self
.
content_type
)
self
.
update_data
(
data
,
content_type
,
size
)
RESPONSE
.
setStatus
(
204
)
return
RESPONSE
security
.
declareProtected
(
ftp_access
,
'manage_FTPstat'
)
security
.
declareProtected
(
ftp_access
,
'manage_FTPlist'
)
...
...
@@ -647,11 +649,11 @@ class File(Persistent, Implicit, PropertyManager,
if
self
.
ZCacheable_isCachingEnabled
():
result
=
self
.
ZCacheable_get
(
default
=
None
)
if
result
is
not
None
:
# We will always get None from RAMCacheManager but we will get
#
something implementing the IStreamIterator interface
# We will always get None from RAMCacheManager but we will
# get
something implementing the IStreamIterator interface
# from FileCacheManager.
# the content-length is required here by HTTPResponse, even
#
though FTP doesn't use it.
# the content-length is required here by HTTPResponse,
# even
though FTP doesn't use it.
RESPONSE
.
setHeader
(
'Content-Length'
,
self
.
size
)
return
result
...
...
src/OFS/ObjectManager.py
View file @
ab628670
...
...
@@ -596,8 +596,15 @@ class ObjectManager(CopyContainer,
listing
.
sort
()
return
listing
# FTP support methods
security
.
declareProtected
(
ftp_access
,
'manage_hasId'
)
def
manage_hasId
(
self
,
REQUEST
):
""" check if the folder has an object with REQUEST['id'] """
if
not
REQUEST
[
'id'
]
in
self
.
objectIds
():
raise
KeyError
(
REQUEST
[
'id'
])
if
bbb
.
HAS_ZSERVER
:
# FTP support methods
security
.
declareProtected
(
ftp_access
,
'manage_FTPlist'
)
def
manage_FTPlist
(
self
,
REQUEST
):
"""Directory listing for FTP.
...
...
@@ -608,7 +615,8 @@ class ObjectManager(CopyContainer,
ob
=
self
while
1
:
if
is_acquired
(
ob
):
raise
ValueError
(
'FTP List not supported on acquired objects'
)
raise
ValueError
(
'FTP List not supported on acquired objects'
)
if
not
hasattr
(
ob
,
'__parent__'
):
break
ob
=
aq_parent
(
ob
)
...
...
@@ -652,13 +660,6 @@ class ObjectManager(CopyContainer,
out
=
out
+
((
k
,
stat
),)
return
marshal
.
dumps
(
out
)
security
.
declareProtected
(
ftp_access
,
'manage_hasId'
)
def
manage_hasId
(
self
,
REQUEST
):
""" check if the folder has an object with REQUEST['id'] """
if
not
REQUEST
[
'id'
]
in
self
.
objectIds
():
raise
KeyError
(
REQUEST
[
'id'
])
security
.
declareProtected
(
ftp_access
,
'manage_FTPstat'
)
def
manage_FTPstat
(
self
,
REQUEST
):
"""Psuedo stat, used by FTP for directory listings.
...
...
src/OFS/SimpleItem.py
View file @
ab628670
...
...
@@ -270,6 +270,7 @@ class Item(Base,
return
()
objectIds
=
objectItems
=
objectValues
if
bbb
.
HAS_ZSERVER
:
# FTP support methods
def
manage_FTPstat
(
self
,
REQUEST
):
...
...
src/OFS/interfaces.py
View file @
ab628670
...
...
@@ -15,6 +15,7 @@
from
zope.component.interfaces
import
IPossibleSite
from
zope.container.interfaces
import
IContainer
from
zope.deferredimport
import
deprecated
from
zope.interface
import
Attribute
from
zope.interface
import
Interface
from
zope.interface.interfaces
import
IObjectEvent
...
...
@@ -171,27 +172,6 @@ class ICopySource(Interface):
"""
# XXX: might contain non-API methods and outdated comments;
# not synced with ZopeBook API Reference;
# based on OFS.FTPInterface.FTPInterface
class
IFTPAccess
(
Interface
):
"""Provide support for FTP access"""
def
manage_FTPstat
(
REQUEST
):
"""Returns a stat-like tuple. (marshalled to a string) Used by
FTP for directory listings, and MDTM and SIZE"""
def
manage_FTPlist
(
REQUEST
):
"""Returns a directory listing consisting of a tuple of
(id,stat) tuples, marshaled to a string. Note, the listing it
should include '..' if there is a Folder above the current
one.
In the case of non-foldoid objects it should return a single
tuple (id,stat) representing itself."""
# XXX: might contain non-API methods and outdated comments;
# not synced with ZopeBook API Reference;
# based on OFS.Traversable.Traversable
...
...
@@ -519,7 +499,7 @@ class ILockItem(Interface):
# XXX: might contain non-API methods and outdated comments;
# not synced with ZopeBook API Reference;
# based on OFS.SimpleItem.Item
class
IItem
(
IZopeObject
,
IManageable
,
IFTPAccess
,
class
IItem
(
IZopeObject
,
IManageable
,
ICopySource
,
ITraversable
,
IOwned
):
__name__
=
BytesLine
(
title
=
u"Name"
)
...
...
@@ -1057,3 +1037,10 @@ class IObjectClonedEvent(IObjectEvent):
event.object is the copied object, already added to its container.
Note that this event is dispatched to all sublocations.
"""
# BBB Zope 5.0
deprecated
(
'Please import from webdav.interfaces.'
,
IFTPAccess
=
'webdav.interfaces:IFTPAccess'
,
)
src/OFS/tests/testFTPInterface.py
deleted
100644 → 0
View file @
ed87506a
import
unittest
class
TestFTPInterface
(
unittest
.
TestCase
):
def
test_interfaces
(
self
):
from
OFS.interfaces
import
IFTPAccess
from
OFS.FTPInterface
import
FTPInterface
from
zope.interface.verify
import
verifyClass
verifyClass
(
IFTPAccess
,
FTPInterface
)
src/OFS/tests/testFileAndImage.py
View file @
ab628670
...
...
@@ -257,27 +257,6 @@ class FileTests(unittest.TestCase):
self
.
assertEqual
(
resp
.
getStatus
(),
200
)
self
.
assertEqual
(
data
,
str
(
self
.
file
.
data
))
def
testPUT
(
self
):
s
=
'# some python
\
n
'
# with content type
data
=
StringIO
(
s
)
req
=
aputrequest
(
data
,
'text/x-python'
)
req
.
processInputs
()
self
.
file
.
PUT
(
req
,
req
.
RESPONSE
)
self
.
assertEqual
(
self
.
file
.
content_type
,
'text/x-python'
)
self
.
assertEqual
(
str
(
self
.
file
.
data
),
s
)
# without content type
data
.
seek
(
0
)
req
=
aputrequest
(
data
,
''
)
req
.
processInputs
()
self
.
file
.
PUT
(
req
,
req
.
RESPONSE
)
self
.
assertEqual
(
self
.
file
.
content_type
,
'text/x-python'
)
self
.
assertEqual
(
str
(
self
.
file
.
data
),
s
)
def
testIndexHtmlWithPdata
(
self
):
self
.
file
.
manage_upload
(
'a'
*
(
2
<<
16
))
# 128K
self
.
file
.
index_html
(
self
.
app
.
REQUEST
,
self
.
app
.
REQUEST
.
RESPONSE
)
...
...
src/Products/PageTemplates/ZopePageTemplate.py
View file @
ab628670
...
...
@@ -37,6 +37,7 @@ from Shared.DC.Scripts.Script import Script
from
Shared.DC.Scripts.Signature
import
FuncCode
from
zExceptions
import
ResourceLockedError
from
Products.PageTemplates
import
bbb
from
Products.PageTemplates.PageTemplate
import
PageTemplate
from
Products.PageTemplates.PageTemplateFile
import
PageTemplateFile
from
Products.PageTemplates.PageTemplateFile
import
guess_type
...
...
@@ -344,6 +345,7 @@ class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable,
'manage_beforeHistoryCopy'
,
'manage_afterHistoryCopy'
)
if
bbb
.
HAS_ZSERVER
:
security
.
declareProtected
(
change_page_templates
,
'PUT'
)
def
PUT
(
self
,
REQUEST
,
RESPONSE
):
""" Handle HTTP PUT requests """
...
...
@@ -359,7 +361,8 @@ class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable,
security
.
declareProtected
(
change_page_templates
,
'manage_FTPput'
)
manage_FTPput
=
PUT
security
.
declareProtected
(
ftp_access
,
'manage_FTPstat'
,
'manage_FTPlist'
)
security
.
declareProtected
(
ftp_access
,
'manage_FTPstat'
)
security
.
declareProtected
(
ftp_access
,
'manage_FTPlist'
)
security
.
declareProtected
(
ftp_access
,
'manage_FTPget'
)
def
manage_FTPget
(
self
):
"Get source for FTP download"
...
...
src/Products/PageTemplates/bbb.py
0 → 100644
View file @
ab628670
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# 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
#
##############################################################################
import
pkg_resources
HAS_ZSERVER
=
True
try
:
dist
=
pkg_resources
.
get_distribution
(
'ZServer'
)
except
pkg_resources
.
DistributionNotFound
:
HAS_ZSERVER
=
False
src/Products/PageTemplates/tests/testZopePageTemplate.py
View file @
ab628670
...
...
@@ -15,6 +15,7 @@ from zope.publisher.http import HTTPCharsets
from
Testing.makerequest
import
makerequest
from
Testing.ZopeTestCase
import
ZopeTestCase
,
installProduct
from
Products.PageTemplates.PageTemplateFile
import
guess_type
from
Products.PageTemplates.ZopePageTemplate
import
ZopePageTemplate
from
Products.PageTemplates.ZopePageTemplate
import
manage_addPageTemplate
from
Products.PageTemplates.utils
import
encodingFromXMLPreamble
...
...
@@ -308,9 +309,8 @@ class ZopePageTemplateFileTests(ZopeTestCase):
def
_put
(
self
,
text
):
zpt
=
self
.
_createZPT
()
REQUEST
=
self
.
app
.
REQUEST
REQUEST
.
set
(
'BODY'
,
text
)
zpt
.
PUT
(
REQUEST
,
REQUEST
.
RESPONSE
)
content_type
=
guess_type
(
''
,
text
)
zpt
.
pt_edit
(
text
,
content_type
)
return
zpt
def
testPutHTMLIso8859_15WithCharsetInfo
(
self
):
...
...
@@ -417,14 +417,6 @@ class ZPTRegressions(unittest.TestCase):
pt
=
self
.
app
.
pt1
self
.
assertEqual
(
pt
.
document_src
(),
self
.
text
)
def
testFTPGet
(
self
):
# check for bug #2269
request
=
self
.
app
.
REQUEST
text
=
'<span tal:content="string:foobar"></span>'
self
.
_addPT
(
'pt1'
,
text
=
text
,
REQUEST
=
request
)
result
=
self
.
app
.
pt1
.
manage_FTPget
()
self
.
assertEqual
(
result
,
text
)
class
ZPTMacros
(
zope
.
component
.
testing
.
PlacelessSetup
,
unittest
.
TestCase
):
...
...
src/Testing/ZopeTestCase/testFunctional.py
View file @
ab628670
...
...
@@ -120,18 +120,6 @@ class TestFunctional(ZopeTestCase.FunctionalTestCase):
self
.
assertEqual
(
response
.
getStatus
(),
200
)
self
.
assertEqual
(
self
.
folder
.
index_html
.
title_or_id
(),
'Foo'
)
def
testPUTExisting
(
self
):
# FTP new data into an existing object
self
.
setPermissions
([
change_dtml_documents
])
put_data
=
StringIO
(
'foo'
)
response
=
self
.
publish
(
self
.
folder_path
+
'/index_html'
,
request_method
=
'PUT'
,
stdin
=
put_data
,
basic
=
self
.
basic_auth
)
self
.
assertEqual
(
response
.
getStatus
(),
204
)
self
.
assertEqual
(
self
.
folder
.
index_html
(),
'foo'
)
def
testHEAD
(
self
):
# HEAD should work without passing stdin
response
=
self
.
publish
(
self
.
folder_path
+
'/index_html'
,
...
...
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