# Path: drift/core/extensions/tenancy.py
# def drift_init_extension(app, **kwargs):
# def get_tenant_name(request_headers=None):
# def _flask_get_tenant_name():
# def _get_tenant_from_hostname(*args, **kw):
# def split_host(host):
# def _is_valid_ipv4_address(address):
# 
# Path: drift/core/extensions/urlregistry.py
# class Endpoints(object):
#     """
#     A class to register endpoint defitions functions
#     at import time
#     """
#     def __init__(self):
#         self.registry_funcs = []
# 
#     def init_app(self, app):
#         """
#         when app is initialized, the registered endpoints are handed to the registry
#         """
#         for f in self.registry_funcs:
#             registry.register_app_endpoints(app, f)
# 
#     def register(self, f):
#         """
#         At import time, register endpoint functions here
#         """
#         self.registry_funcs.append(f)
#         return f
# 
# Path: drift/fixers.py
# class CustomJSONEncoder(JSONEncoder):
#     '''Extend the JSON encoder to treat date-time objects as strict
#     rfc3339 types.
#     '''
#     def default(self, obj):
#         from drift.orm import ModelBase
#         if isinstance(obj, date):
#             return obj.isoformat() + "Z"
#         elif isinstance(obj, ModelBase):
#             return obj.as_dict()
#         else:
#             return JSONEncoder.default(self, obj)
# 
# Path: drift/utils.py
# def get_tier_name(fail_hard=True):
#     """
#     Get tier name from environment
#     """
#     if 'DRIFT_TIER' in os.environ:
#         return os.environ['DRIFT_TIER']
# 
#     if fail_hard:
#         raise RuntimeError(
#             "No tier specified. Specify one in "
#             "'DRIFT_TIER' environment variable, or use the --tier command "
#             "line argument."
#         )


import json
import logging
import re
import string
import copy
import jwt
import marshmallow as ma
from datetime import datetime, timedelta
from functools import wraps
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.serialization import load_pem_public_key
from flask import current_app, request, _request_ctx_stack, g, url_for, redirect, make_response
from flask.views import MethodView
from flask_smorest import Blueprint, abort
from six.moves import http_client
from werkzeug.local import LocalProxy
from werkzeug.security import gen_salt
from drift.core.extensions.tenancy import current_tenant_name, split_host
from drift.core.extensions.urlregistry import Endpoints
from drift.fixers import CustomJSONEncoder
from drift.utils import get_tier_name
    from drift.flaskfactory import load_flask_config
    from driftconfig.util import get_default_drift_config
        from driftconfig.util import get_default_drift_config
    jti = gen_salt(20)
    iss = g.conf.deployable['deployable_name']

    standard_claims = {
        # JWT standard fields
        'iat': iat,
        'exp': exp,
        'jti': jti,
        'iss': iss,

        # Drift fields
        'tier': g.conf.tier['tier_name'],
        'tenant': g.conf.tenant_name['tenant_name'],
    }

    return standard_claims


# Cache token in Redis so that a JTI can be used instead of a JWT.  A valid JTI is implicitly trusted.
def cache_token(payload, expire=None):
    expire = expire or 86400

    # Add fudge to 'expire' so the token will live at least a little bit longer in the
    # Redis cache than the actual expiration date.
    expire += 60 * 10  # Ten minutes

    try:
        jti = payload['jti']
        key = "jwt:{}".format(jti)
        if hasattr(g, 'redis'):

# Path: drift/core/extensions/tenancy.py
# def drift_init_extension(app, **kwargs):
# def get_tenant_name(request_headers=None):
# def _flask_get_tenant_name():
# def _get_tenant_from_hostname(*args, **kw):
# def split_host(host):
# def _is_valid_ipv4_address(address):
# 
# Path: drift/core/extensions/urlregistry.py
# class Endpoints(object):
#     """
#     A class to register endpoint defitions functions
#     at import time
#     """
#     def __init__(self):
#         self.registry_funcs = []
# 
#     def init_app(self, app):
#         """
#         when app is initialized, the registered endpoints are handed to the registry
#         """
#         for f in self.registry_funcs:
#             registry.register_app_endpoints(app, f)
# 
#     def register(self, f):
#         """
#         At import time, register endpoint functions here
#         """
#         self.registry_funcs.append(f)
#         return f
# 
# Path: drift/fixers.py
# class CustomJSONEncoder(JSONEncoder):
#     '''Extend the JSON encoder to treat date-time objects as strict
#     rfc3339 types.
#     '''
#     def default(self, obj):
#         from drift.orm import ModelBase
#         if isinstance(obj, date):
#             return obj.isoformat() + "Z"
#         elif isinstance(obj, ModelBase):
#             return obj.as_dict()
#         else:
#             return JSONEncoder.default(self, obj)
# 
# Path: drift/utils.py
# def get_tier_name(fail_hard=True):
#     """
#     Get tier name from environment
#     """
#     if 'DRIFT_TIER' in os.environ:
#         return os.environ['DRIFT_TIER']
# 
#     if fail_hard:
#         raise RuntimeError(
#             "No tier specified. Specify one in "
#             "'DRIFT_TIER' environment variable, or use the --tier command "
#             "line argument."
#         )


# Path: drift/core/extensions/jwt.py
import json
import logging
import re
import string
import copy
import jwt
import marshmallow as ma
from datetime import datetime, timedelta
from functools import wraps
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.serialization import load_pem_public_key
from flask import current_app, request, _request_ctx_stack, g, url_for, redirect, make_response
from flask.views import MethodView
from flask_smorest import Blueprint, abort
from six.moves import http_client
from werkzeug.local import LocalProxy
from werkzeug.security import gen_salt
from drift.core.extensions.tenancy import current_tenant_name, split_host
from drift.core.extensions.urlregistry import Endpoints
from drift.fixers import CustomJSONEncoder
from drift.utils import get_tier_name
    from drift.flaskfactory import load_flask_config
    from driftconfig.util import get_default_drift_config
        from driftconfig.util import get_default_drift_config

    jti = gen_salt(20)
    iss = g.conf.deployable['deployable_name']

    standard_claims = {
        # JWT standard fields
        'iat': iat,
        'exp': exp,
        'jti': jti,
        'iss': iss,

        # Drift fields
        'tier': g.conf.tier['tier_name'],
        'tenant': g.conf.tenant_name['tenant_name'],
    }

    return standard_claims


# Cache token in Redis so that a JTI can be used instead of a JWT.  A valid JTI is implicitly trusted.
def cache_token(payload, expire=None):
    expire = expire or 86400

    # Add fudge to 'expire' so the token will live at least a little bit longer in the
    # Redis cache than the actual expiration date.
    expire += 60 * 10  # Ten minutes

    try:
        jti = payload['jti']
        key = "jwt:{}".format(jti)
        if hasattr(g, 'redis'):

            g.redis.set(key, json.dumps(payload, cls=CustomJSONEncoder), expire=expire)