Source code for censys.common.config

"""Interact with the config file."""

import configparser
import contextlib
import os
from pathlib import Path

DEFAULT = "DEFAULT"
HOME_PATH = str(Path.home())
CENSYS_PATH = os.path.join(HOME_PATH, ".config", "censys")
CONFIG_PATH = os.path.join(CENSYS_PATH, "censys.cfg")

default_config = {
    "api_id": "",
    "api_secret": "",
    "asm_api_key": "",
    "color": "auto",
}


[docs] def get_config_path() -> str: """Returns the path to the config file. Returns: str: Path to config file. """ alt_path = os.getenv("CENSYS_CONFIG_PATH") if alt_path: return alt_path return CONFIG_PATH
def _restricted_opener(path: str, flags: int) -> int: """Opener that creates files readable and writable by the owner only. Args: path (str): Path to open. flags (int): Flags passed by `open()`. Returns: int: File descriptor. """ return os.open(path, flags, 0o600) def _try_chmod(path: str, mode: int) -> None: """Best-effort permission tightening. Files are already created owner-only by `_restricted_opener`, so failing to tighten an existing path must never stop the config from being written. Args: path (str): Path to tighten. mode (int): Desired permission bits. """ with contextlib.suppress(OSError): os.chmod(path, mode)
[docs] def write_config(config: configparser.ConfigParser) -> None: """Writes config to file. The config file contains API credentials, so the directory and file are created owner-only (0700/0600). Existing paths are tightened on a best-effort basis; the requested modes are still subject to the umask. Args: config (configparser.ConfigParser): Configuration to write. Raises: PermissionError: If the config file is not writable. """ config_path = get_config_path() if config_path == CONFIG_PATH: if not os.access(HOME_PATH, os.W_OK): raise PermissionError( "Cannot write to home directory. Please set the `CENSYS_CONFIG_PATH` environmental variable to a writeable location." ) elif not os.path.isdir(CENSYS_PATH): os.makedirs(CENSYS_PATH, mode=0o700) else: _try_chmod(CENSYS_PATH, 0o700) if os.path.isfile(config_path): _try_chmod(config_path, 0o600) with open(config_path, "w", opener=_restricted_opener) as configfile: config.write(configfile)
[docs] def get_config() -> configparser.ConfigParser: """Reads and returns config. Returns: configparser.ConfigParser: Config for Censys. """ config = configparser.ConfigParser(defaults=default_config, default_section=DEFAULT) config_path = get_config_path() if os.path.isfile(config_path): config.read(config_path) return config