Re: [Freeipa-devel] [PATCH] 0003 Fix JSON binary encode and decode errors (rebase)

2010-03-04 Thread Rob Crittenden

John Dennis wrote:

On 03/04/2010 03:08 PM, Rob Crittenden wrote:

John Dennis wrote:

[Note: same patch as earlier but rebased]

Traverse the objects passed to JSON for encoding and decoding.
When binary data is seen during encode replace the binary
data with a dict {'__base64__' : base64_encoding_of_binary_value}.

On decode if a dict is seen whose single key is '__base64__' replace
that dict with the base64 decoded value of the key's value.


This works in that the UI no longer crashes but the certificate is show
thusly in the UI:

Certificate [object Object]

I know we talked about moving to storing certs as PEM which should fix
this problem at some point but is this an acceptable interim solution?
Or do we want to just leave base64-encoded objects encoded?

rob


The patch was to fix the JSON transport traceback. It wasn't meant to 
address how binary data was rendered in the UI. You're right this needs 
to be addressed (but not by this patch).


You can add this to my list of tasks.



Works for me. This definitely is a step forward.

ack, pushed to master

___
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel


Re: [Freeipa-devel] [PATCH] 0003 Fix JSON binary encode and decode errors (rebase)

2010-03-04 Thread John Dennis

On 03/04/2010 03:08 PM, Rob Crittenden wrote:

John Dennis wrote:

[Note: same patch as earlier but rebased]

Traverse the objects passed to JSON for encoding and decoding.
When binary data is seen during encode replace the binary
data with a dict {'__base64__' : base64_encoding_of_binary_value}.

On decode if a dict is seen whose single key is '__base64__' replace
that dict with the base64 decoded value of the key's value.


This works in that the UI no longer crashes but the certificate is show
thusly in the UI:

Certificate [object Object]

I know we talked about moving to storing certs as PEM which should fix
this problem at some point but is this an acceptable interim solution?
Or do we want to just leave base64-encoded objects encoded?

rob


The patch was to fix the JSON transport traceback. It wasn't meant to 
address how binary data was rendered in the UI. You're right this needs 
to be addressed (but not by this patch).


You can add this to my list of tasks.

--
John Dennis 

Looking to carve out IT costs?
www.redhat.com/carveoutcosts/

___
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel


Re: [Freeipa-devel] [PATCH] 0003 Fix JSON binary encode and decode errors (rebase)

2010-03-04 Thread Rob Crittenden

John Dennis wrote:

[Note: same patch as earlier but rebased]

Traverse the objects passed to JSON for encoding and decoding.
When binary data is seen during encode replace the binary
data with a dict {'__base64__' : base64_encoding_of_binary_value}.

On decode if a dict is seen whose single key is '__base64__' replace
that dict with the base64 decoded value of the key's value.


This works in that the UI no longer crashes but the certificate is show 
thusly in the UI:


Certificate [object Object]

I know we talked about moving to storing certs as PEM which should fix 
this problem at some point but is this an acceptable interim solution? 
Or do we want to just leave base64-encoded objects encoded?


rob

___
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel


[Freeipa-devel] [PATCH] 0003 Fix JSON binary encode and decode errors (rebase)

2010-03-02 Thread John Dennis

[Note: same patch as earlier but rebased]

Traverse the objects passed to JSON for encoding and decoding.
When binary data is seen during encode replace the binary
data with a dict {'__base64__' : base64_encoding_of_binary_value}.

On decode if a dict is seen whose single key is '__base64__' replace
that dict with the base64 decoded value of the key's value.

--
John Dennis 

Looking to carve out IT costs?
www.redhat.com/carveoutcosts/
>From d3627d87ff2b26b380a4a4d0a349ad2d432c1ca3 Mon Sep 17 00:00:00 2001
From: John Dennis 
Date: Mon, 1 Mar 2010 18:55:39 -0500
Subject: [PATCH] Fix JSON binary encode and decode errors
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="1.6.6.1"

This is a multi-part message in MIME format.
--1.6.6.1
Content-Type: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding: 8bit


Traverse the objects passed to JSON for encoding and decoding.
When binary data is seen during encode replace the binary
data with a dict {'__base64__' : base64_encoding_of_binary_value}.

On decode if a dict is seen whose single key is '__base64__' replace
that dict with the base64 decoded value of the key's value.
---
 ipaserver/rpcserver.py |  101 +++-
 1 files changed, 99 insertions(+), 2 deletions(-)


--1.6.6.1
Content-Type: text/x-patch; name="0003-Fix-JSON-binary-encode-and-decode-errors.patch"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment; filename="0003-Fix-JSON-binary-encode-and-decode-errors.patch"

diff --git a/ipaserver/rpcserver.py b/ipaserver/rpcserver.py
index ad402cd..967ee33 100644
--- a/ipaserver/rpcserver.py
+++ b/ipaserver/rpcserver.py
@@ -33,7 +33,7 @@ from ipalib.rpc import xml_dumps, xml_loads
 from ipalib.util import make_repr
 from ipalib.compat import json
 from wsgiref.util import shift_path_info
-
+import base64
 
 _not_found_template = """
 
@@ -60,7 +60,6 @@ def not_found(environ, start_response):
 )
 return [output]
 
-
 def read_input(environ):
 """
 Read the request body from environ['wsgi.input'].
@@ -300,6 +299,102 @@ class xmlserver(WSGIExecutioner):
 return xml_dumps(response, methodresponse=True)
 
 
+def json_encode_binary(val):
+'''
+   JSON cannot encode binary values. We encode binary values in Python str
+   objects and text in Python unicode objects. In order to allow a binary
+   object to be passed through JSON we base64 encode it thus converting it to
+   text which JSON can transport. To assure we recognize the value is a base64
+   encoded representation of the original binary value and not confuse it with
+   other text we convert the binary value to a dict in this form:
+
+   {'__base64__' : base64_encoding_of_binary_value}
+
+   This modification of the original input value cannot be done "in place" as
+   one might first assume (e.g. replacing any binary items in a container
+   (e.g. list, tuple, dict) with the base64 dict because the container might be
+   an immutable object (i.e. a tuple). Therefore this function returns a copy
+   of any container objects it encounters with tuples replaced by lists. This
+   is O.K. because the JSON encoding will map both lists and tuples to JSON
+   arrays.
+   '''
+
+if isinstance(val, dict):
+new_dict = {}
+for k,v in val.items():
+if isinstance(v, str):
+new_dict[k] = {'__base64__' : base64.b64encode(v)}
+else:
+new_dict[k] = json_encode_binary(v)
+del val
+return new_dict
+elif isinstance(val, (list, tuple)):
+new_list = []
+n = len(val)
+i = 0
+while i < n:
+v = val[i]
+if isinstance(v, str):
+new_list.append({'__base64__' : base64.b64encode(v)})
+else:
+new_list.append(json_encode_binary(v))
+i += 1
+del val
+return new_list
+elif isinstance(val, str):
+return {'__base64__' : base64.b64encode(val)}
+else:
+return val
+
+def json_decode_binary(val):
+'''
+JSON cannot transport binary data. In order to transport binary data we
+convert binary data to a form like this:
+
+   {'__base64__' : base64_encoding_of_binary_value}
+
+   see json_encode_binary()
+
+After JSON had decoded the JSON stream back into a Python object we must
+recursively scan the object looking for any dicts which might represent
+binary values and replace the dict containing the base64 encoding of the
+binary value with the decoded binary value. Unlike the encoding problem
+where the input might consist of immutable object, all JSON decoded
+container are mutable so the conversion could be done in place. However we
+don't modify objects in place because of side effects which may be
+dangerous. Thus we elect to spend a few more cycles