# Path: fds/auth/common.py
# class Common(object):
#   XIAOMI_HEADER_PREFIX = "x-xiaomi-"
#   XIAOMI_HEADER_DATE = "x-xiaomi-date"
# 
#   GALAXY_ACCESS_KEY_ID = "GalaxyAccessKeyId"
#   SIGNATURE = "Signature"
#   EXPIRES = "Expires"
# 
#   AUTHORIZATION = "authorization"
#   CONTENT_MD5 = "content-md5"
#   CONTENT_TYPE = "content-type"
#   DATE = "date"
#   RANGE = 'range'
# 
#   REQUEST_TIME_LIMIT = 900000  # 15min
# 
#   CACHE_CONTROL = "cache-control"
#   CONTENT_ENCODING = "content-encoding"
#   CONTENT_LENGTH = "content-length"
#   LAST_MODIFIED = "last-modified"
#   LAST_CHECKED = "last-checked"
#   UPLOAD_TIME = "upload-time"
#   CONTENT_RANGE = "content-range"
#   EXPIRATION_TIME = "expiration-time"
#   OBJECT_OWNER_ID = "object-owner-id"
#   FILE_MODE = "file-mode"
#   MULITPART_UPLOAD_MODE = XIAOMI_HEADER_PREFIX + "multipart-upload-mode"
#   PREVIOUS_VERSION_ID = "pre-version-id"
#   SERVER_SIDE_ENCRYPTION = XIAOMI_HEADER_PREFIX + "server-side-encryption"
#   STORAGE_CLASS = XIAOMI_HEADER_PREFIX + "storage-class"
#   ONGOING_RESTORE = XIAOMI_HEADER_PREFIX + "ongoing-restore"
#   RESTORE_EXPIRY_DATE = XIAOMI_HEADER_PREFIX + "restore-expiry";
# 
#   DEFAULT_FDS_SERVICE_BASE_URI = "http://files.fds.api.xiaomi.com/"
#   DEFAULT_CDN_SERVICE_URI = "http://cdn.fds.api.xiaomi.com/"
# 
# Path: fds/model/subresource.py
# class SubResource(object):
#   '''
#   The sub-resource class.
#   '''
#   ACL = "acl"
#   QUOTA = "quota"
#   UPLOADS = "uploads"
#   PART_NUMBER = "partNumber"
#   UPLOAD_ID = "uploadId"
#   STORAGE_ACCESS_TOKEN = "storageAccessToken"
#   METADATA = "metadata"
# 
#   @staticmethod
#   def get_all_subresource():
#     return [SubResource.ACL,
#             SubResource.QUOTA,
#             SubResource.UPLOADS,
#             SubResource.PART_NUMBER,
#             SubResource.UPLOAD_ID,
#             SubResource.STORAGE_ACCESS_TOKEN,
#             SubResource.METADATA
#             ]


import base64
import hmac
from email.utils import formatdate
from hashlib import sha1
from sys import version_info
from requests.auth import AuthBase
  from urllib.parse import unquote, urlparse
  from urllib import unquote
  from urlparse import urlparse
from fds.auth.common import Common
from fds.model.subresource import SubResource
    :param headers:    The request headers to sign
    :param url:        The request uri to sign
    :param app_secret: The secret used to sign the request
    :return: The signed result, aka the signature
    '''
    signature = self._sign(method, headers, url, app_secret)
    if IS_PY3:
      return base64.encodebytes(signature).decode(encoding='utf-8').strip()
    else:
      return base64.encodestring(signature).strip()

  def _construct_string_to_sign(self, http_method, http_headers, uri):
    '''
    Construct the string used to sign the request.
    '''
    result = str()
    result += '%s\n' % http_method
    result += '%s\n' % self._get_header_value(http_headers,
                                              Common.CONTENT_MD5)
    result += '%s\n' % self._get_header_value(http_headers,
                                              Common.CONTENT_TYPE)
    expires = self._get_expires(uri)

    if expires > 0:
      result += '%s\n' % expires
    else:
      xiaomi_date = self._get_header_value(http_headers,
                                           Common.XIAOMI_HEADER_DATE)
      date = str()
      if len(xiaomi_date) == 0:

# Path: fds/auth/common.py
# class Common(object):
#   XIAOMI_HEADER_PREFIX = "x-xiaomi-"
#   XIAOMI_HEADER_DATE = "x-xiaomi-date"
# 
#   GALAXY_ACCESS_KEY_ID = "GalaxyAccessKeyId"
#   SIGNATURE = "Signature"
#   EXPIRES = "Expires"
# 
#   AUTHORIZATION = "authorization"
#   CONTENT_MD5 = "content-md5"
#   CONTENT_TYPE = "content-type"
#   DATE = "date"
#   RANGE = 'range'
# 
#   REQUEST_TIME_LIMIT = 900000  # 15min
# 
#   CACHE_CONTROL = "cache-control"
#   CONTENT_ENCODING = "content-encoding"
#   CONTENT_LENGTH = "content-length"
#   LAST_MODIFIED = "last-modified"
#   LAST_CHECKED = "last-checked"
#   UPLOAD_TIME = "upload-time"
#   CONTENT_RANGE = "content-range"
#   EXPIRATION_TIME = "expiration-time"
#   OBJECT_OWNER_ID = "object-owner-id"
#   FILE_MODE = "file-mode"
#   MULITPART_UPLOAD_MODE = XIAOMI_HEADER_PREFIX + "multipart-upload-mode"
#   PREVIOUS_VERSION_ID = "pre-version-id"
#   SERVER_SIDE_ENCRYPTION = XIAOMI_HEADER_PREFIX + "server-side-encryption"
#   STORAGE_CLASS = XIAOMI_HEADER_PREFIX + "storage-class"
#   ONGOING_RESTORE = XIAOMI_HEADER_PREFIX + "ongoing-restore"
#   RESTORE_EXPIRY_DATE = XIAOMI_HEADER_PREFIX + "restore-expiry";
# 
#   DEFAULT_FDS_SERVICE_BASE_URI = "http://files.fds.api.xiaomi.com/"
#   DEFAULT_CDN_SERVICE_URI = "http://cdn.fds.api.xiaomi.com/"
# 
# Path: fds/model/subresource.py
# class SubResource(object):
#   '''
#   The sub-resource class.
#   '''
#   ACL = "acl"
#   QUOTA = "quota"
#   UPLOADS = "uploads"
#   PART_NUMBER = "partNumber"
#   UPLOAD_ID = "uploadId"
#   STORAGE_ACCESS_TOKEN = "storageAccessToken"
#   METADATA = "metadata"
# 
#   @staticmethod
#   def get_all_subresource():
#     return [SubResource.ACL,
#             SubResource.QUOTA,
#             SubResource.UPLOADS,
#             SubResource.PART_NUMBER,
#             SubResource.UPLOAD_ID,
#             SubResource.STORAGE_ACCESS_TOKEN,
#             SubResource.METADATA
#             ]


# Path: fds/auth/signature/signer.py
import base64
import hmac
from email.utils import formatdate
from hashlib import sha1
from sys import version_info
from requests.auth import AuthBase
  from urllib.parse import unquote, urlparse
  from urllib import unquote
  from urlparse import urlparse
from fds.auth.common import Common
from fds.model.subresource import SubResource

    :param headers:    The request headers to sign
    :param url:        The request uri to sign
    :param app_secret: The secret used to sign the request
    :return: The signed result, aka the signature
    '''
    signature = self._sign(method, headers, url, app_secret)
    if IS_PY3:
      return base64.encodebytes(signature).decode(encoding='utf-8').strip()
    else:
      return base64.encodestring(signature).strip()

  def _construct_string_to_sign(self, http_method, http_headers, uri):
    '''
    Construct the string used to sign the request.
    '''
    result = str()
    result += '%s\n' % http_method
    result += '%s\n' % self._get_header_value(http_headers,
                                              Common.CONTENT_MD5)
    result += '%s\n' % self._get_header_value(http_headers,
                                              Common.CONTENT_TYPE)
    expires = self._get_expires(uri)

    if expires > 0:
      result += '%s\n' % expires
    else:
      xiaomi_date = self._get_header_value(http_headers,
                                           Common.XIAOMI_HEADER_DATE)
      date = str()
      if len(xiaomi_date) == 0:

        date = self._get_header_value(http_headers, Common.DATE)