URL: https://github.com/freeipa/freeipa/pull/427
Author: MartinBasti
 Title: #427: [Py3] WSGI part 2
Action: synchronized

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/427/head:pr427
git checkout pr427
From 090bc4b7d6fa8b7ed79f04f46c85f98b271d2fe8 Mon Sep 17 00:00:00 2001
From: Martin Basti <mba...@redhat.com>
Date: Tue, 24 Jan 2017 17:49:06 +0100
Subject: [PATCH 1/7] py3: base64 encoding/decoding returns always bytes don't
 mix it

Using unicode(bytes) call causes undesired side effect that is inserting
`b` character to result. This obviously causes issues with binary base64 data

https://fedorahosted.org/freeipa/ticket/4985
---
 ipaserver/plugins/baseldap.py | 2 +-
 ipaserver/plugins/ca.py       | 4 +---
 ipaserver/plugins/cert.py     | 2 +-
 ipaserver/secrets/client.py   | 6 ++++--
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/ipaserver/plugins/baseldap.py b/ipaserver/plugins/baseldap.py
index e7bf43c..24b6db7 100644
--- a/ipaserver/plugins/baseldap.py
+++ b/ipaserver/plugins/baseldap.py
@@ -1036,7 +1036,7 @@ def process_attr_options(self, entry_attrs, dn, keys, options):
                     except ValueError:
                         if isinstance(delval, bytes):
                             # This is a Binary value, base64 encode it
-                            delval = unicode(base64.b64encode(delval))
+                            delval = base64.b64encode(delval).decode('ascii')
                         raise errors.AttrValueNotFound(attr=attr, value=delval)
 
         # normalize all values
diff --git a/ipaserver/plugins/ca.py b/ipaserver/plugins/ca.py
index 4f24278..3a052a1 100644
--- a/ipaserver/plugins/ca.py
+++ b/ipaserver/plugins/ca.py
@@ -4,8 +4,6 @@
 
 import base64
 
-import six
-
 from ipalib import api, errors, output, Bytes, DNParam, Flag, Str
 from ipalib.constants import IPA_CA_CN
 from ipalib.plugable import Registry
@@ -176,7 +174,7 @@ def set_certificate_attrs(entry, options, want_cert=True):
     with api.Backend.ra_lightweight_ca as ca_api:
         if want_cert or full:
             der = ca_api.read_ca_cert(ca_id)
-            entry['certificate'] = six.text_type(base64.b64encode(der))
+            entry['certificate'] = base64.b64encode(der).decode('ascii')
 
         if want_chain or full:
             pkcs7_der = ca_api.read_ca_chain(ca_id)
diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py
index 5bf4cfb..6bf5c03 100644
--- a/ipaserver/plugins/cert.py
+++ b/ipaserver/plugins/cert.py
@@ -1260,7 +1260,7 @@ def _get_cert_key(self, cert):
         return (DN(cert_obj.issuer), cert_obj.serial)
 
     def _get_cert_obj(self, cert, all, raw, pkey_only):
-        obj = {'certificate': unicode(base64.b64encode(cert))}
+        obj = {'certificate': base64.b64encode(cert).decode('ascii')}
 
         full = not pkey_only and all
         if not raw:
diff --git a/ipaserver/secrets/client.py b/ipaserver/secrets/client.py
index a04b9a6..a945e01 100644
--- a/ipaserver/secrets/client.py
+++ b/ipaserver/secrets/client.py
@@ -70,7 +70,8 @@ def init_creds(self):
         name = gssapi.Name(self.client_service,
                            gssapi.NameType.hostbased_service)
         store = {'client_keytab': self.keytab,
-                 'ccache': 'MEMORY:Custodia_%s' % b64encode(os.urandom(8))}
+                 'ccache': 'MEMORY:Custodia_%s' % b64encode(
+                     os.urandom(8)).decode('ascii')}
         return gssapi.Credentials(name=name, store=store, usage='initiate')
 
     def _auth_header(self):
@@ -78,7 +79,8 @@ def _auth_header(self):
             self.creds = self.init_creds()
         ctx = gssapi.SecurityContext(name=self.service_name, creds=self.creds)
         authtok = ctx.step()
-        return {'Authorization': 'Negotiate %s' % b64encode(authtok)}
+        return {'Authorization': 'Negotiate %s' % b64encode(
+            authtok).decode('ascii')}
 
     def fetch_key(self, keyname, store=True):
 

From cc25007e23504097f63173fa18324b9586aad675 Mon Sep 17 00:00:00 2001
From: Martin Basti <mba...@redhat.com>
Date: Wed, 25 Jan 2017 14:56:07 +0100
Subject: [PATCH 2/7] py3: remove_entry_from_group: attribute name must be
 string

Do not encode attribute names

https://fedorahosted.org/freeipa/ticket/4985
---
 ipaserver/plugins/ldap2.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ipaserver/plugins/ldap2.py b/ipaserver/plugins/ldap2.py
index 71c095d..e671ecb 100644
--- a/ipaserver/plugins/ldap2.py
+++ b/ipaserver/plugins/ldap2.py
@@ -442,7 +442,7 @@ def remove_entry_from_group(self, dn, group_dn, member_attr='member'):
         # update group entry
         try:
             with self.error_handler():
-                modlist = [(a, self.encode(b), self.encode(c))
+                modlist = [(a, b, self.encode(c))
                            for a, b, c in modlist]
                 self.conn.modify_s(str(group_dn), modlist)
         except errors.MidairCollision:

From 6252fcae506ecbacecf6bf10fb877d11054af951 Mon Sep 17 00:00:00 2001
From: Martin Basti <mba...@redhat.com>
Date: Wed, 25 Jan 2017 15:38:03 +0100
Subject: [PATCH 3/7] py3: _ptrrecord_precallaback: use bytes with labels

DNS labels are bytes so bytes must be used for comparison

https://fedorahosted.org/freeipa/ticket/4985
---
 ipaserver/plugins/dns.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ipaserver/plugins/dns.py b/ipaserver/plugins/dns.py
index 08f9c6d..0838161 100644
--- a/ipaserver/plugins/dns.py
+++ b/ipaserver/plugins/dns.py
@@ -3098,7 +3098,7 @@ def _ptrrecord_pre_callback(self, ldap, dn, entry_attrs, *keys, **options):
 
         # Classless zones (0/25.0.0.10.in-addr.arpa.) -> skip check
         # zone has to be checked without reverse domain suffix (in-addr.arpa.)
-        for sign in ('/', '-'):
+        for sign in (b'/', b'-'):
             for name in (zone, addr):
                 for label in name.labels:
                     if sign in label:

From e59181bcb75537be5132602577a804d45bbdc15f Mon Sep 17 00:00:00 2001
From: Martin Basti <mba...@redhat.com>
Date: Thu, 26 Jan 2017 10:25:46 +0100
Subject: [PATCH 4/7] py3: DNS: get_record_entry_attrs: do not modify dict
 during iteration

In py3 keys() doesn't return list but iterator so it must be transformed
to tuple otherwise iterator will be broken.

https://fedorahosted.org/freeipa/ticket/4985
---
 ipaserver/plugins/dns.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ipaserver/plugins/dns.py b/ipaserver/plugins/dns.py
index 0838161..97f6527 100644
--- a/ipaserver/plugins/dns.py
+++ b/ipaserver/plugins/dns.py
@@ -3195,7 +3195,7 @@ def get_dns_masters(self):
 
     def get_record_entry_attrs(self, entry_attrs):
         entry_attrs = entry_attrs.copy()
-        for attr in entry_attrs.keys():
+        for attr in tuple(entry_attrs.keys()):
             if attr not in self.params or self.params[attr].primary_key:
                 del entry_attrs[attr]
         return entry_attrs

From 4570fb0d5f3fac8bab912a84871e84e10272fa81 Mon Sep 17 00:00:00 2001
From: Martin Basti <mba...@redhat.com>
Date: Fri, 27 Jan 2017 12:06:54 +0100
Subject: [PATCH 5/7] py3: _convert_to_idna: fix bytes/unicode mistmatch

ToASCII() returns bytes, it must be decoded to unicode

https://fedorahosted.org/freeipa/ticket/4985
---
 ipaserver/plugins/dns.py | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/ipaserver/plugins/dns.py b/ipaserver/plugins/dns.py
index 97f6527..40c9b51 100644
--- a/ipaserver/plugins/dns.py
+++ b/ipaserver/plugins/dns.py
@@ -1620,8 +1620,9 @@ def _convert_to_idna(value):
         idna_val = encodings.idna.nameprep(idna_val)
         idna_val = re.split(r'(?<!\\)\.', idna_val)
         idna_val = u'%s%s%s' % (start_dot,
-                                u'.'.join(encodings.idna.ToASCII(x)
-                                          for x in idna_val),
+                                u'.'.join(
+                                    encodings.idna.ToASCII(x).decode('ascii')
+                                    for x in idna_val),
                                 end_dot)
         return idna_val
     except Exception:

From 27b44c7d78d60875198266e4c784dba951501cd6 Mon Sep 17 00:00:00 2001
From: Martin Basti <mba...@redhat.com>
Date: Mon, 6 Feb 2017 18:42:08 +0100
Subject: [PATCH 6/7] py3: ipaldap: properly encode DNSName to bytes

The encode method of LDAPClient didn't return DNSName as bytes but
string in py3. In py2 it returns non-unicode string so it can be encoded
safely by ascii as to_text() method returns only ascii characters.

https://fedorahosted.org/freeipa/ticket/4985
---
 ipapython/ipaldap.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ipapython/ipaldap.py b/ipapython/ipaldap.py
index 497b947..37d23d7 100644
--- a/ipapython/ipaldap.py
+++ b/ipapython/ipaldap.py
@@ -849,7 +849,7 @@ def encode(self, val):
                               Principal)):
             return six.text_type(val).encode('utf-8')
         elif isinstance(val, DNSName):
-            return val.to_text()
+            return val.to_text().encode('ascii')
         elif isinstance(val, bytes):
             return val
         elif isinstance(val, list):

From 9964f642ca7bf378fd5b38167ebeceb27473b960 Mon Sep 17 00:00:00 2001
From: Martin Basti <mba...@redhat.com>
Date: Tue, 7 Feb 2017 17:46:08 +0100
Subject: [PATCH 7/7] py3: send Decimal number as string instead of base64
 encoded value

for Decimal only from client to server direction uses __base64__
notation. Server replies with pure string for Decimal data, and also
server is able to parse string and create decimal values where needed.

without this we need ugly py3 code:
-        return {'__base64__': base64.b64encode(str(val))}
+        return {'__base64__': base64.b64encode(
+            str(val).encode('ascii')).decode('ascii')}

https://fedorahosted.org/freeipa/ticket/4985
---
 ipalib/rpc.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ipalib/rpc.py b/ipalib/rpc.py
index 356ec42..7d9f6ec 100644
--- a/ipalib/rpc.py
+++ b/ipalib/rpc.py
@@ -308,7 +308,7 @@ def json_encode_binary(val, version):
             encoded = encoded.decode('ascii')
         return {'__base64__': encoded}
     elif isinstance(val, Decimal):
-        return {'__base64__': base64.b64encode(str(val))}
+        return unicode(val)
     elif isinstance(val, DN):
         return str(val)
     elif isinstance(val, datetime.datetime):
-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to