blob: bf9d3f6f3f685b954a5bc2be5a5f7b9b6a4422fd [file] [log] [blame]
# Copyright (C) 2018 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import os
_cached_authorized_api_keys = frozenset([])
_AUTHORIZATION_SCHEME = "apikey"
def _path_to_authorized_api_keys_file():
return os.path.abspath(os.path.join(os.path.dirname(__file__), "authorized_api_keys.txt"))
def _parse_authorized_api_keys(file):
api_keys = set()
for line in file:
line = line.strip()
if not line or line.startswith("#"): # Skip empty lines and comments
continue
api_keys.add(line)
return frozenset(api_keys)
def authorized_api_keys():
global _cached_authorized_api_keys
if _cached_authorized_api_keys:
return _cached_authorized_api_keys
with open(_path_to_authorized_api_keys_file(), "r") as file:
_cached_authorized_api_keys = _parse_authorized_api_keys(file)
return _cached_authorized_api_keys
def _parse_authorization_header(credentials):
# See <https://tools.ietf.org/html/rfc7235#section-4.2>.
parts = credentials.split(" ", 1)
if len(parts) < 2:
return ""
scheme = parts[0]
token68_encoded_value = parts[1]
if scheme.lower() == _AUTHORIZATION_SCHEME:
return token68_encoded_value
return ""
def is_authorized(request):
api_key = ''
credentials = request.headers.get("Authorization")
if credentials:
api_key = _parse_authorization_header(credentials)
if not api_key:
api_key = request.get(_AUTHORIZATION_SCHEME)
return api_key in authorized_api_keys()