Re: [Freeipa-devel] [PATCH 0397] ipapython: Use custom datetime to LDAP generalized time

2016-01-19 Thread Petr Spacek
On 18.1.2016 08:06, Christian Heimes wrote:
> On 2016-01-15 13:44, Tomas Babej wrote:
>> Hi,
>>
>> For the dates older than 1900, Python is unable to convert the datetime
>> representation to string using strftime:
>>
>> https://bugs.python.org/issue1777412
>>
>> Work around the issue adding a custom method to convert the datetime
>> objects to LDAP generalized time strings.
>>
>> https://fedorahosted.org/freeipa/ticket/5579

Dates before 1900? Seriously? This is a bad idea.

I would rather catch ValueError and inform the user. We seriously do not need
more custom code!

Petr^2 Spacek

> I noticed that all previous strftime() calls and the new code ignore any
> time zone information. This isn't an issue for tz-naive datetime object
> that don't have any time zone information attached. You can't fix them
> anyway and just hope they are always UTC. For tz-aware datetime object
> your approach returns the wrong value.
> 
> You can use datetime.utctimetuple() instead. The method returns a time
> tuple in UTC.
> 
 value
> datetime.datetime(2016, 1, 18, 8, 2, 49, 646270)

> '{0.tm_year:4d}{0.tm_mon:02d}{0.tm_mday:02d}{0.tm_hour:02d}{0.tm_min:02d}{0.tm_sec:02d}Z'.format(value.utctimetuple())
> '20160118080249Z'
> 
> https://docs.python.org/2/library/datetime.html#datetime.datetime.utctimetuple

-- 
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


Re: [Freeipa-devel] [PATCH 0397] ipapython: Use custom datetime to LDAP generalized time

2016-01-17 Thread Christian Heimes
On 2016-01-15 13:44, Tomas Babej wrote:
> Hi,
> 
> For the dates older than 1900, Python is unable to convert the datetime
> representation to string using strftime:
> 
> https://bugs.python.org/issue1777412
> 
> Work around the issue adding a custom method to convert the datetime
> objects to LDAP generalized time strings.
> 
> https://fedorahosted.org/freeipa/ticket/5579

I noticed that all previous strftime() calls and the new code ignore any
time zone information. This isn't an issue for tz-naive datetime object
that don't have any time zone information attached. You can't fix them
anyway and just hope they are always UTC. For tz-aware datetime object
your approach returns the wrong value.

You can use datetime.utctimetuple() instead. The method returns a time
tuple in UTC.

>>> value
datetime.datetime(2016, 1, 18, 8, 2, 49, 646270)
>>>
'{0.tm_year:4d}{0.tm_mon:02d}{0.tm_mday:02d}{0.tm_hour:02d}{0.tm_min:02d}{0.tm_sec:02d}Z'.format(value.utctimetuple())
'20160118080249Z'

https://docs.python.org/2/library/datetime.html#datetime.datetime.utctimetuple



signature.asc
Description: OpenPGP digital signature
-- 
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

[Freeipa-devel] [PATCH 0397] ipapython: Use custom datetime to LDAP generalized time

2016-01-15 Thread Tomas Babej
Hi,

For the dates older than 1900, Python is unable to convert the datetime
representation to string using strftime:

https://bugs.python.org/issue1777412

Work around the issue adding a custom method to convert the datetime
objects to LDAP generalized time strings.

https://fedorahosted.org/freeipa/ticket/5579

Tomas
From d746dd233c07b0dc81f539f502844a16e5cc97e2 Mon Sep 17 00:00:00 2001
From: Tomas Babej 
Date: Fri, 15 Jan 2016 12:20:12 +0100
Subject: [PATCH] ipapython: Use custom datetime to LDAP generalized time
 converter

For the dates older than 1900, Python is unable to convert the datetime
representation to string using strftime:

https://bugs.python.org/issue1777412

Work around the issue adding a custom method to convert the datetime
objects to LDAP generalized time strings.

https://fedorahosted.org/freeipa/ticket/5579
---
 daemons/dnssec/ipa-ods-exporter  |  5 +
 ipalib/cli.py|  5 +++--
 ipalib/rpc.py|  6 +++---
 ipapython/ipaldap.py |  4 ++--
 ipapython/ipautil.py | 17 +
 ipaserver/install/ipa_otptoken_import.py |  4 ++--
 6 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/daemons/dnssec/ipa-ods-exporter b/daemons/dnssec/ipa-ods-exporter
index 2aa936040c373e366e7e15539ed6e3413aac7d55..b2df53dee0ecb8cc08fcde9c20e17f72588b18de 100755
--- a/daemons/dnssec/ipa-ods-exporter
+++ b/daemons/dnssec/ipa-ods-exporter
@@ -83,9 +83,6 @@ def dnskey_flags_to_text_set(flags):
 mask <<= 1
 return flags_set
 
-def datetime2ldap(dt):
-return dt.strftime(ipalib.constants.LDAP_GENERALIZED_TIME_FORMAT)
-
 def sql2datetime(sql_time):
 """Convert SQL date format from local time zone into UTC."""
 localtz = dateutil.tz.tzlocal()
@@ -276,7 +273,7 @@ def get_ods_keys(zone_name):
 
 key_data.update(sql2ldap_algorithm(row['algorithm']))
 key_id = "%s-%s-%s" % (key_type,
-   datetime2ldap(key_data['idnsSecKeyCreated']),
+   ipautil.datetime_to_ldap_gentime(key_data['idnsSecKeyCreated']),
row['HSMkey_id'])
 
 key_data.update(sql2ldap_keyid(row['HSMkey_id']))
diff --git a/ipalib/cli.py b/ipalib/cli.py
index 3b1b5a39371845d59bab07ac2fc32de598a469be..58fbf048fdda4278bec0846486837fd35a581526 100644
--- a/ipalib/cli.py
+++ b/ipalib/cli.py
@@ -56,11 +56,12 @@ from ipalib import plugable
 from ipalib.errors import (PublicError, CommandError, HelpError, InternalError,
NoSuchNamespaceError, ValidationError, NotFound,
NotConfiguredError, PromptFailed)
-from ipalib.constants import CLI_TAB, LDAP_GENERALIZED_TIME_FORMAT
+from ipalib.constants import CLI_TAB
 from ipalib.parameters import File, Str, Enum, Any, Flag
 from ipalib.text import _
 from ipalib import api  # pylint: disable=unused-import
 from ipapython.dnsutil import DNSName
+from ipapython import ipautil
 
 import datetime
 
@@ -169,7 +170,7 @@ class textui(backend.Backend):
 if type(value) is bytes:
 return base64.b64encode(value)
 elif type(value) is datetime.datetime:
-return value.strftime(LDAP_GENERALIZED_TIME_FORMAT)
+return ipautil.datetime_to_ldap_gentime(value)
 elif isinstance(value, DNSName):
 return unicode(value)
 else:
diff --git a/ipalib/rpc.py b/ipalib/rpc.py
index a165491adea5366a14a86d7c8bd6337e36fd1b44..a2ca7cb3374e28074332c8827ab51088cc83a5e7 100644
--- a/ipalib/rpc.py
+++ b/ipalib/rpc.py
@@ -185,7 +185,7 @@ def xml_wrap(value, version):
 if capabilities.client_has_capability(version, 'datetime_values'):
 return DateTime(value)
 else:
-return value.strftime(LDAP_GENERALIZED_TIME_FORMAT)
+return ipautil.datetime_to_ldap_gentime(value)
 
 if isinstance(value, DNSName):
 if capabilities.client_has_capability(version, 'dns_name_values'):
@@ -304,9 +304,9 @@ def json_encode_binary(val, version):
 return str(val)
 elif isinstance(val, datetime.datetime):
 if capabilities.client_has_capability(version, 'datetime_values'):
-return {'__datetime__': val.strftime(LDAP_GENERALIZED_TIME_FORMAT)}
+return {'__datetime__': ipautil.datetime_to_ldap_gentime(val)}
 else:
-return val.strftime(LDAP_GENERALIZED_TIME_FORMAT)
+return ipautil.datetime_to_ldap_gentime(val)
 elif isinstance(val, DNSName):
 if capabilities.client_has_capability(version, 'dns_name_values'):
 return {'__dns_name__': unicode(val)}
diff --git a/ipapython/ipaldap.py b/ipapython/ipaldap.py
index 28bfcb5c2ee2140d38f17248fc9c90861cd251e4..d916fd62698a0ff6fe023357238ec33b5ae099b9 100644
--- a/ipapython/ipaldap.py
+++ b/ipapython/ipaldap.py
@@ -38,7 +38,7 @@ import six
 
 from ipalib import errors, _
 from ipalib.constants