AMF/Flash Support in Zope 2
Introduction
This package allows you to query Zope 2 from a flash using Flex with Actionscript 2 or Actionscript 3 throught AMF0 or AMF3.
We are just providing here the Zope layer. The lower layer has been done using the PyAMF package (see http://pyamf.org).
Let’s write a simple AMF view that echoes various types of input:
>>> from Products.Five import BrowserView
>>> from datetime import datetime
>>> import elementtree.ElementTree as etree
>>> class EchoView(BrowserView):
...
... def echoString(self, value):
... return "%s" % value
...
... def echoProtectedString(self, value):
... return "%s" % value
...
... def echoList(self, value):
... return list(value)
...
... def echoDict(self, value):
... return dict(value)
...
... def echoVoid(self, value):
... pass
...
... def echoTuple(self, value):
... return tuple(value)
...
... def echoParams(self, value1, value2):
... return "%s-%s" % (value1, value2)
...
... def echoDate(self):
... return datetime(2008, 11, 17, 11, 11)
...
... def echoXML(self, value):
... root = etree.Element("html")
... body = etree.SubElement(root, 'body')
... body.text = value
... return root
Now we’ll register it as a Flash view. For now we’ll just register the view for folder objects and call it on the default folder of the user:
>>> from zope.configuration import xmlconfig
>>> ignored = xmlconfig.string("""
... <configure
... xmlns="http://namespaces.zope.org/zope"
... xmlns:browser="http://namespaces.zope.org/browser"
... xmlns:flash="http://namespaces.zope.org/flash"
... >
...
... <include package="z3c.amf" file="meta.zcml" />
... <include package="Products.Five" file="meta.zcml" />
... <include package="z3c.amf" />
...
... <flash:view
... for="OFS.interfaces.IFolder"
... methods="echoString echoList echoDict echoVoid echoTuple
... echoDate echoXML echoParams"
... class="z3c.amf.README.EchoView"
... permission="zope.Public"
... />
...
... <flash:view
... for="OFS.interfaces.IFolder"
... methods="echoProtectedString"
... class="z3c.amf.README.EchoView"
... permission="zope2.FlashAccess"
... />
...
... </configure>
... """)
We create some helper functions. For Requests:
>>> def createAMFRequest(target, body, username=None, password=None, multiParameters=False): ... envelope = remoting.Envelope(pyamf.AMF0, pyamf.ClientTypes.Flash9) ... if username is not None and password is not None: ... envelope.headers['Credentials'] = dict(userid=unicode(username), ... password=unicode(password)) ... if multiParameters: ... request = remoting.Request(target, body, envelope) ... else: ... request = remoting.Request(target, [body], envelope) ... envelope[u'/1'] = request ... amfRequest = remoting.encode(envelope) ... amfRequest.seek(0) ... return amfRequest.read()
For Responses:
>>> import pyamf >>> from pyamf import remoting >>> def printAMFResponse(response): ... context = pyamf.amf0.Context ... requests = remoting.decode(response.body, context()) ... for name, value in requests.items(): ... print (name, value, type(value.body))
Basic Types
String
>>> amfRequest = createAMFRequest(target='echoString', body='Hello World!') >>> amfRequest '\x00\x03\x00\x00\x00\x01\x00\nechoString\x00\x02/1\x00\x00\x00\x00\n\x00\x00\x00\x01\x02\x00\x0cHello World!' >>> response = http(r""" ... POST /test_folder_1_ HTTP/1.0 ... Content-Length: 102 ... Content-Type: application/x-amf ... ... %s""" % amfRequest) >>> printAMFResponse(response) (u'/1', <Response status=/onResult>Hello World!</Response>, <type 'unicode'>)
List
>>> amfRequest = createAMFRequest(target='echoList', body=[u'Hé', u'Ho']) >>> response = http(r""" ... POST /test_folder_1_ HTTP/1.0 ... Content-Length: 102 ... Content-Type: application/x-amf ... ... %s""" % amfRequest) >>> printAMFResponse(response) (u'/1', <Response status=/onResult>[u'H\xc3\xa9', u'Ho']</Response>, <type 'list'>)
Dictionary
>>> amfRequest = createAMFRequest(target='echoDict',
... body={'fruit': 'orange'})
>>> response = http(r"""
... POST /test_folder_1_ HTTP/1.0
... Content-Length: 102
... Content-Type: application/x-amf
...
... %s""" % amfRequest)
>>> printAMFResponse(response)
(u'/1', <Response status=/onResult>{u'fruit': u'orange'}</Response>,
<class 'pyamf.ASObject'>)
Without return
>>> amfRequest = createAMFRequest(target='echoVoid', body='Hello World!') >>> response = http(r""" ... POST /test_folder_1_ HTTP/1.0 ... Content-Length: 102 ... Content-Type: application/x-amf ... ... %s""" % amfRequest) >>> printAMFResponse(response) (u'/1', <Response status=/onResult>None</Response>, <type 'NoneType'>)
Tuple
>>> amfRequest = createAMFRequest(target='echoTuple', body=['foo', 'bar']) >>> response = http(r""" ... POST /test_folder_1_ HTTP/1.0 ... Content-Length: 102 ... Content-Type: application/x-amf ... ... %s""" % amfRequest) >>> printAMFResponse(response) (u'/1', <Response status=/onResult>[u'foo', u'bar']</Response>, <type 'list'>)
Datetime
>>> amfRequest = createAMFRequest(target='echoDate', body=None) >>> response = http(r""" ... POST /test_folder_1_ HTTP/1.0 ... Content-Length: 102 ... Content-Type: application/x-amf ... ... %s""" % amfRequest) >>> printAMFResponse(response) (u'/1', <Response status=/onResult>2008-11-17 11:11:00</Response>, <type 'datetime.datetime'>)
XML
>>> amfRequest = createAMFRequest(target='echoXML', body='It works!') >>> response = http(r""" ... POST /test_folder_1_ HTTP/1.0 ... Content-Length: 102 ... Content-Type: application/x-amf ... ... %s""" % amfRequest) >>> printAMFResponse(response) (u'/1', <Response status=/onResult><Element html at ...></Response>, <type 'instance'>)
Multi Parameters
>>> amfRequest = createAMFRequest(target='echoParams', body=['foo', 'bar'], ... multiParameters=True) >>> response = http(r""" ... POST /test_folder_1_ HTTP/1.0 ... Content-Length: 102 ... Content-Type: application/x-amf ... ... %s""" % amfRequest) >>> printAMFResponse(response) (u'/1', <Response status=/onResult>foo-bar</Response>, <type 'unicode'>)
Errors
>>> amfRequest = createAMFRequest(target='echoUnknown', body=['foo', 'bar']) >>> response = http(r""" ... POST /test_folder_1_ HTTP/1.0 ... Content-Length: 102 ... Content-Type: application/x-amf ... ... %s""" % amfRequest) >>> printAMFResponse(response) (u'/1', <Response status=/onStatus><ErrorFault level=error code=NotFound type=Resource not found... ...
User authentication
Try to access our protected view without providing login/pass in flash:
>>> amfRequest = createAMFRequest(target='echoProtectedString', ... body='It works!') >>> response = http(r""" ... POST /test_folder_1_ HTTP/1.0 ... Content-Length: 102 ... Content-Type: application/x-amf ... ... %s""" % amfRequest) >>> printAMFResponse(response) (u'/1', <Response status=/onStatus><ErrorFault level=error code=zExceptions.unauthorized.Unauthorized type=Not authorized></Response>, <class 'pyamf.remoting.ErrorFault'>)
Now try to access with login/pass:
>>> from Testing.ZopeTestCase import user_name, user_password >>> amfRequest = createAMFRequest(target='echoProtectedString', ... body="Hello World!", username=user_name, ... password=user_password) >>> response = http(r""" ... POST /test_folder_1_ HTTP/1.0 ... Content-Length: 200 ... Content-Type: application/x-amf ... ... %s""" % amfRequest) >>> printAMFResponse(response) (u'/1', <Response status=/onResult>Hello World!</Response>, <type 'unicode'>)
Path in service
>>> amfRequest = createAMFRequest(target='test_folder_1_.echoProtectedString', ... body='It works!', username=user_name, ... password=user_password) >>> response = http(r""" ... POST / HTTP/1.0 ... Content-Length: 200 ... Content-Type: application/x-amf ... ... %s""" % amfRequest) >>> printAMFResponse(response) (u'/1', <Response status=/onResult>It works!</Response>, <type 'unicode'>)
Changelog
0.2 - (2008-11-25)
Handle path change in service
register crossdomain.xml view
0.1 - (2008-11-17)
Initial release
Metadata
Release files for z3c.amf 0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| z3c.amf-0.2.tar.gz | 22.4 kB | Without provenance | Details for z3c.amf-0.2.tar.gz |
Release files / z3c.amf-0.2.tar.gz
| Download URL | z3c.amf-0.2.tar.gz |
|---|---|
| Size | 22.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
71717476062744dba6d8cbccb84804d3087922644c820a5fe2b2c4f8c798aa6a
|
|
BLAKE2b-256 checksum How to use checksums |
7c0dc4e1409b33da70922732afdb22515894ac4ad2cb4e88f92bca2f879fea1c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
Security for z3c.amf 0.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.