1#-------------------------------------------------------------------------
2# Copyright (c) Microsoft.  All rights reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#   http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14#--------------------------------------------------------------------------
15
16import base64
17import hashlib
18import hmac
19import sys
20from dateutil.tz import tzutc
21
22from .models import (
23    _unicode_type,
24)
25
26
27if sys.version_info < (3,):
28    def _str(value):
29        if isinstance(value, unicode):
30            return value.encode('utf-8')
31
32        return str(value)
33else:
34    _str = str
35
36
37def _to_str(value):
38    return _str(value) if value is not None else None
39
40def _int_to_str(value):
41    return str(int(value)) if value is not None else None
42
43def _bool_to_str(value):
44    if value is None:
45        return None
46
47    if isinstance(value, bool):
48        if value:
49            return 'true'
50        else:
51            return 'false'
52
53    return str(value)
54
55def _to_utc_datetime(value):
56    return value.strftime('%Y-%m-%dT%H:%M:%SZ')
57
58def _datetime_to_utc_string(value):
59    # Azure expects the date value passed in to be UTC.
60    # Azure will always return values as UTC.
61    # If a date is passed in without timezone info, it is assumed to be UTC.
62    if value is None:
63        return None
64
65    if value.tzinfo:
66        value = value.astimezone(tzutc())
67
68    return value.strftime('%a, %d %b %Y %H:%M:%S GMT')
69
70def _encode_base64(data):
71    if isinstance(data, _unicode_type):
72        data = data.encode('utf-8')
73    encoded = base64.b64encode(data)
74    return encoded.decode('utf-8')
75
76
77def _decode_base64_to_bytes(data):
78    if isinstance(data, _unicode_type):
79        data = data.encode('utf-8')
80    return base64.b64decode(data)
81
82
83def _decode_base64_to_text(data):
84    decoded_bytes = _decode_base64_to_bytes(data)
85    return decoded_bytes.decode('utf-8')
86
87
88def _sign_string(key, string_to_sign, key_is_base64=True):
89    if key_is_base64:
90        key = _decode_base64_to_bytes(key)
91    else:
92        if isinstance(key, _unicode_type):
93            key = key.encode('utf-8')
94    if isinstance(string_to_sign, _unicode_type):
95        string_to_sign = string_to_sign.encode('utf-8')
96    signed_hmac_sha256 = hmac.HMAC(key, string_to_sign, hashlib.sha256)
97    digest = signed_hmac_sha256.digest()
98    encoded_digest = _encode_base64(digest)
99    return encoded_digest
100
101
102def _lower(text):
103    return text.lower()
104