Skip to content

Commit

Permalink
fix(security): let the user decide to disable SSL verification
Browse files Browse the repository at this point in the history
Signed-off-by: Sylvain Leclerc <[email protected]>
  • Loading branch information
sylvlecl committed Sep 12, 2024
1 parent fcd2ccd commit 472e2a5
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 23 deletions.
15 changes: 13 additions & 2 deletions antarest/tools/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@
from typing import Optional

import click
from httpx import Client

from antarest.study.model import NEW_DEFAULT_STUDY_VERSION
from antarest.study.storage.study_upgrader import StudyUpgrader
from antarest.tools.lib import extract_commands, generate_diff, generate_study
from antarest.tools.lib import create_http_client, extract_commands, generate_diff, generate_study


@click.group(context_settings={"max_content_width": 120})
Expand All @@ -43,6 +44,12 @@ def commands() -> None:
type=str,
help="Authentication token if server needs one",
)
@click.option(
"--no-verify",
is_flag=True,
default=False,
help="Disables SSL certificate verification",
)
@click.option(
"--output",
"-o",
Expand Down Expand Up @@ -82,6 +89,7 @@ def cli_apply_script(
output: Optional[str],
host: Optional[str],
auth_token: Optional[str],
no_verify: bool,
version: str,
) -> None:
"""Apply a variant script onto an AntaresWeb study variant"""
Expand All @@ -95,7 +103,10 @@ def cli_apply_script(
print("--study_id must be set")
exit(1)

res = generate_study(Path(input), study_id, output, host, auth_token, version)
client = None
if host:
client = create_http_client(verify=not no_verify, auth_token=auth_token)
res = generate_study(Path(input), study_id, output, host, client, version)
print(res)


Expand Down
40 changes: 20 additions & 20 deletions antarest/tools/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,29 +51,28 @@ def apply_commands(self, commands: List[CommandDTO], matrices_dir: Path) -> Gene
raise NotImplementedError()


def set_auth_token(client: Client, auth_token: Optional[str] = None) -> Client:
if auth_token is not None:
client.headers.update({"Authorization": f"Bearer {auth_token}"})
return client


def create_http_client(verify: bool, auth_token: Optional[str] = None) -> Client:
client = Client(verify=verify)
set_auth_token(client, auth_token)
return client


class RemoteVariantGenerator(IVariantGenerator):
def __init__(
self,
study_id: str,
host: Optional[str] = None,
token: Optional[str] = None,
session: Optional[Client] = None,
host: str,

Check failure

Code scanning / SonarCloud

Server certificates should be verified during SSL/TLS connections High

Enable server certificate validation on this SSL/TLS connection. See more on SonarCloud
session: Client,
):
self.study_id = study_id

# todo: find the correct way to handle certificates.
# By default, Httpx verifies SSL certificates for HTTPS requests.
# When verify is set to `False`, requests will accept any TLS certificate presented
# by the server, and will ignore hostname mismatches and/or expired certificates,
# which will make your application vulnerable to man-in-the-middle (MitM) attacks.
# Setting verify to `False` may be useful during local development or testing.
self.session = session or Client(verify=False)

self.session = session
self.host = host
if session is None and host is None:
raise ValueError("Missing either session or host")
if token is not None:
self.session.headers.update({"Authorization": f"Bearer {token}"})

def apply_commands(
self,
Expand Down Expand Up @@ -333,7 +332,7 @@ def generate_study(
study_id: Optional[str],
output: Optional[str] = None,
host: Optional[str] = None,
token: Optional[str] = None,
session: Optional[Client] = None,
study_version: str = NEW_DEFAULT_STUDY_VERSION,
) -> GenerationResultInfoDTO:
"""
Expand All @@ -347,16 +346,17 @@ def generate_study(
If `study_id` and `host` are not provided, this must be specified.
host: The URL of the Antares server to use for generating the new study.
If `study_id` is not provided, this is ignored.
token: The authentication token to use when connecting to the Antares server.
session: The session to use when connecting to the Antares server.
If `host` is not provided, this is ignored.
study_version: The target version of the generated study.
Returns:
GenerationResultInfoDTO: A data transfer object containing information about the generation result.
"""
generator: Union[RemoteVariantGenerator, LocalVariantGenerator]
if study_id is not None and host is not None:
generator = RemoteVariantGenerator(study_id, host, token)

if study_id is not None and host is not None and session is not None:
generator = RemoteVariantGenerator(study_id, host, session)
elif output is None:
raise TypeError("'output' must be set")
else:
Expand Down
6 changes: 5 additions & 1 deletion tests/integration/test_integration_variantmanager_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,12 @@
COMMAND_FILE,
MATRIX_STORE_DIR,
RemoteVariantGenerator,
create_http_client,
extract_commands,
generate_diff,
generate_study,
parse_commands,
set_auth_token,
)
from tests.integration.assets import ASSETS_DIR

Expand Down Expand Up @@ -62,7 +64,9 @@ def generate_study_with_server(
)
assert res.status_code == 200, res.json()
variant_id = res.json()
generator = RemoteVariantGenerator(variant_id, session=client, token=admin_credentials["access_token"])

set_auth_token(client, admin_credentials["access_token"])
generator = RemoteVariantGenerator(variant_id, host="", session=client)
return generator.apply_commands(commands, matrices_dir), variant_id


Expand Down

0 comments on commit 472e2a5

Please sign in to comment.