mirror of
https://github.com/microsoft/onefuzz.git
synced 2025-06-18 04:38:09 +00:00
Remove client_secret
from config, add env var (#1918)
This commit is contained in:
@ -14,7 +14,6 @@ def main(req: func.HttpRequest) -> func.HttpResponse:
|
|||||||
endpoint=os.environ.get("ONEFUZZ_ENDPOINT"),
|
endpoint=os.environ.get("ONEFUZZ_ENDPOINT"),
|
||||||
authority=os.environ.get("ONEFUZZ_AUTHORITY"),
|
authority=os.environ.get("ONEFUZZ_AUTHORITY"),
|
||||||
client_id=os.environ.get("ONEFUZZ_CLIENT_ID"),
|
client_id=os.environ.get("ONEFUZZ_CLIENT_ID"),
|
||||||
client_secret=os.environ.get("ONEFUZZ_CLIENT_SECRET"),
|
|
||||||
)
|
)
|
||||||
info = o.info.get()
|
info = o.info.get()
|
||||||
return func.HttpResponse(info.json())
|
return func.HttpResponse(info.json())
|
||||||
|
@ -53,6 +53,9 @@ REPRO_SSH_FORWARD = "1337:127.0.0.1:1337"
|
|||||||
|
|
||||||
UUID_RE = r"^[a-f0-9]{8}-?[a-f0-9]{4}-?[a-f0-9]{4}-?[a-f0-9]{4}-?[a-f0-9]{12}\Z"
|
UUID_RE = r"^[a-f0-9]{8}-?[a-f0-9]{4}-?[a-f0-9]{4}-?[a-f0-9]{4}-?[a-f0-9]{12}\Z"
|
||||||
|
|
||||||
|
# Environment variable optionally used for setting an application client secret.
|
||||||
|
CLIENT_SECRET_ENV_VAR = "ONEFUZZ_CLIENT_SECRET" # nosec
|
||||||
|
|
||||||
|
|
||||||
class PreviewFeature(Enum):
|
class PreviewFeature(Enum):
|
||||||
job_templates = "job_templates"
|
job_templates = "job_templates"
|
||||||
@ -1639,11 +1642,22 @@ class Utils(Command):
|
|||||||
|
|
||||||
class Onefuzz:
|
class Onefuzz:
|
||||||
def __init__(
|
def __init__(
|
||||||
self, config_path: Optional[str] = None, token_path: Optional[str] = None
|
self,
|
||||||
|
config_path: Optional[str] = None,
|
||||||
|
token_path: Optional[str] = None,
|
||||||
|
client_secret: Optional[str] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.logger = logging.getLogger("onefuzz")
|
self.logger = logging.getLogger("onefuzz")
|
||||||
|
|
||||||
|
if client_secret is None:
|
||||||
|
# If not explicitly provided, check the environment for a user-provided client secret.
|
||||||
|
client_secret = self._client_secret_from_env()
|
||||||
|
|
||||||
self._backend = Backend(
|
self._backend = Backend(
|
||||||
config=DEFAULT, config_path=config_path, token_path=token_path
|
config=DEFAULT,
|
||||||
|
config_path=config_path,
|
||||||
|
token_path=token_path,
|
||||||
|
client_secret=client_secret,
|
||||||
)
|
)
|
||||||
self.containers = Containers(self)
|
self.containers = Containers(self)
|
||||||
self.repro = Repro(self)
|
self.repro = Repro(self)
|
||||||
@ -1670,6 +1684,12 @@ class Onefuzz:
|
|||||||
|
|
||||||
self.__setup__()
|
self.__setup__()
|
||||||
|
|
||||||
|
# Try to obtain a confidential client secret from the environment.
|
||||||
|
#
|
||||||
|
# If not set, return `None`.
|
||||||
|
def _client_secret_from_env(self) -> Optional[str]:
|
||||||
|
return os.environ.get(CLIENT_SECRET_ENV_VAR)
|
||||||
|
|
||||||
def __setup__(
|
def __setup__(
|
||||||
self,
|
self,
|
||||||
endpoint: Optional[str] = None,
|
endpoint: Optional[str] = None,
|
||||||
@ -1686,7 +1706,7 @@ class Onefuzz:
|
|||||||
if client_id is not None:
|
if client_id is not None:
|
||||||
self._backend.config.client_id = client_id
|
self._backend.config.client_id = client_id
|
||||||
if client_secret is not None:
|
if client_secret is not None:
|
||||||
self._backend.config.client_secret = client_secret
|
self._backend.client_secret = client_secret
|
||||||
if tenant_domain is not None:
|
if tenant_domain is not None:
|
||||||
self._backend.config.tenant_domain = tenant_domain
|
self._backend.config.tenant_domain = tenant_domain
|
||||||
|
|
||||||
@ -1730,7 +1750,6 @@ class Onefuzz:
|
|||||||
endpoint: Optional[str] = None,
|
endpoint: Optional[str] = None,
|
||||||
authority: Optional[str] = None,
|
authority: Optional[str] = None,
|
||||||
client_id: Optional[str] = None,
|
client_id: Optional[str] = None,
|
||||||
client_secret: Optional[str] = None,
|
|
||||||
enable_feature: Optional[PreviewFeature] = None,
|
enable_feature: Optional[PreviewFeature] = None,
|
||||||
tenant_domain: Optional[str] = None,
|
tenant_domain: Optional[str] = None,
|
||||||
reset: Optional[bool] = None,
|
reset: Optional[bool] = None,
|
||||||
@ -1759,8 +1778,6 @@ class Onefuzz:
|
|||||||
self._backend.config.authority = authority
|
self._backend.config.authority = authority
|
||||||
if client_id is not None:
|
if client_id is not None:
|
||||||
self._backend.config.client_id = client_id
|
self._backend.config.client_id = client_id
|
||||||
if client_secret is not None:
|
|
||||||
self._backend.config.client_secret = client_secret
|
|
||||||
if enable_feature:
|
if enable_feature:
|
||||||
self._backend.enable_feature(enable_feature.name)
|
self._backend.enable_feature(enable_feature.name)
|
||||||
if tenant_domain is not None:
|
if tenant_domain is not None:
|
||||||
@ -1769,9 +1786,6 @@ class Onefuzz:
|
|||||||
self._backend.save_config()
|
self._backend.save_config()
|
||||||
|
|
||||||
data = self._backend.config.copy(deep=True)
|
data = self._backend.config.copy(deep=True)
|
||||||
if data.client_secret is not None:
|
|
||||||
# replace existing secrets with "*** for user display
|
|
||||||
data.client_secret = "***" # nosec
|
|
||||||
|
|
||||||
if not data.endpoint:
|
if not data.endpoint:
|
||||||
self.logger.warning("endpoint not configured yet")
|
self.logger.warning("endpoint not configured yet")
|
||||||
|
@ -88,7 +88,6 @@ def check_application_error(response: requests.Response) -> None:
|
|||||||
class BackendConfig(BaseModel):
|
class BackendConfig(BaseModel):
|
||||||
authority: str
|
authority: str
|
||||||
client_id: str
|
client_id: str
|
||||||
client_secret: Optional[str]
|
|
||||||
endpoint: Optional[str]
|
endpoint: Optional[str]
|
||||||
features: Set[str] = Field(default_factory=set)
|
features: Set[str] = Field(default_factory=set)
|
||||||
tenant_domain: Optional[str]
|
tenant_domain: Optional[str]
|
||||||
@ -100,9 +99,11 @@ class Backend:
|
|||||||
config: BackendConfig,
|
config: BackendConfig,
|
||||||
config_path: Optional[str] = None,
|
config_path: Optional[str] = None,
|
||||||
token_path: Optional[str] = None,
|
token_path: Optional[str] = None,
|
||||||
|
client_secret: Optional[str] = None,
|
||||||
):
|
):
|
||||||
self.config_path = os.path.expanduser(config_path or DEFAULT_CONFIG_PATH)
|
self.config_path = os.path.expanduser(config_path or DEFAULT_CONFIG_PATH)
|
||||||
self.token_path = os.path.expanduser(token_path or DEFAULT_TOKEN_PATH)
|
self.token_path = os.path.expanduser(token_path or DEFAULT_TOKEN_PATH)
|
||||||
|
self.client_secret = client_secret
|
||||||
self.config = config
|
self.config = config
|
||||||
self.token_cache: Optional[msal.SerializableTokenCache] = None
|
self.token_cache: Optional[msal.SerializableTokenCache] = None
|
||||||
self.init_cache()
|
self.init_cache()
|
||||||
@ -187,16 +188,17 @@ class Backend:
|
|||||||
f"https://{netloc}/.default", # before 3.0.0 release
|
f"https://{netloc}/.default", # before 3.0.0 release
|
||||||
]
|
]
|
||||||
|
|
||||||
if self.config.client_secret:
|
if self.client_secret:
|
||||||
return self.client_secret(scopes)
|
return self.access_token_from_client_secret(scopes)
|
||||||
|
|
||||||
return self.device_login(scopes)
|
return self.device_login(scopes)
|
||||||
|
|
||||||
def client_secret(self, scopes: List[str]) -> Any:
|
def access_token_from_client_secret(self, scopes: List[str]) -> Any:
|
||||||
if not self.app:
|
if not self.app:
|
||||||
self.app = msal.ConfidentialClientApplication(
|
self.app = msal.ConfidentialClientApplication(
|
||||||
self.config.client_id,
|
self.config.client_id,
|
||||||
authority=self.config.authority,
|
authority=self.config.authority,
|
||||||
client_credential=self.config.client_secret,
|
client_credential=self.client_secret,
|
||||||
token_cache=self.token_cache,
|
token_cache=self.token_cache,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@ JMES_HELP = (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Call `Onefuzz.setup()`, which enables overriding configuration and authentication parameters.
|
||||||
def call_setup(api: Any, args: argparse.Namespace) -> None:
|
def call_setup(api: Any, args: argparse.Namespace) -> None:
|
||||||
setup = getattr(api, "__setup__", None)
|
setup = getattr(api, "__setup__", None)
|
||||||
if setup is None:
|
if setup is None:
|
||||||
|
Reference in New Issue
Block a user