Skip to content

Commit

Permalink
Merge pull request #5 from Darnethal0z/main
Browse files Browse the repository at this point in the history
Added the possibility to ignore SSL errors with web client (2.1.1)
  • Loading branch information
Darnethal0z committed Nov 16, 2023
2 parents ffbae1c + bd152c0 commit aa55571
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 47 deletions.
119 changes: 77 additions & 42 deletions anwdlclient/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,43 +148,39 @@ def __init__(self):
def _load_rsa_keys(self):
self.runtime_rsa_wrapper = None

if not self.config_content.get("enable_onetime_rsa_keys"):
public_rsa_key_file_path = self.config_content.get(
"public_rsa_key_file_path"
)
private_rsa_key_file_path = self.config_content.get(
"private_rsa_key_file_path"
)
if self.config_content.get("enable_onetime_rsa_keys"):
return

if not os.path.exists(private_rsa_key_file_path):
createFileRecursively(private_rsa_key_file_path)
public_rsa_key_file_path = self.config_content.get("public_rsa_key_file_path")
private_rsa_key_file_path = self.config_content.get("private_rsa_key_file_path")

self.runtime_rsa_wrapper = RSAWrapper()
if not os.path.exists(private_rsa_key_file_path):
createFileRecursively(private_rsa_key_file_path)

with open(public_rsa_key_file_path, "w") as fd:
fd.write(self.runtime_rsa_wrapper.getPublicKey().decode())
self.runtime_rsa_wrapper = RSAWrapper()

with open(private_rsa_key_file_path, "w") as fd:
fd.write(self.runtime_rsa_wrapper.getPrivateKey().decode())
with open(public_rsa_key_file_path, "w") as fd:
fd.write(self.runtime_rsa_wrapper.getPublicKey().decode())

else:
self.runtime_rsa_wrapper = RSAWrapper(generate_key_pair=False)

with open(private_rsa_key_file_path, "r") as fd:
self.runtime_rsa_wrapper.setPrivateKey(
fd.read().encode(),
derivate_public_key=not os.path.exists(
public_rsa_key_file_path
),
)
with open(private_rsa_key_file_path, "w") as fd:
fd.write(self.runtime_rsa_wrapper.getPrivateKey().decode())

if not os.path.exists(public_rsa_key_file_path):
with open(public_rsa_key_file_path, "w") as fd:
fd.write(self.runtime_rsa_wrapper.getPublicKey().decode())
else:
self.runtime_rsa_wrapper = RSAWrapper(generate_key_pair=False)

else:
with open(public_rsa_key_file_path, "r") as fd:
self.runtime_rsa_wrapper.setPublicKey(fd.read().encode())
with open(private_rsa_key_file_path, "r") as fd:
self.runtime_rsa_wrapper.setPrivateKey(
fd.read().encode(),
derivate_public_key=not os.path.exists(public_rsa_key_file_path),
)

if not os.path.exists(public_rsa_key_file_path):
with open(public_rsa_key_file_path, "w") as fd:
fd.write(self.runtime_rsa_wrapper.getPublicKey().decode())

else:
with open(public_rsa_key_file_path, "r") as fd:
self.runtime_rsa_wrapper.setPublicKey(fd.read().encode())

def _log_stdout(self, message, bypass=False, color=None, end="\n", error=False):
if bypass:
Expand Down Expand Up @@ -216,10 +212,18 @@ def create(self):
"-p", "--port", help="specify the server listen port", type=int
)
parser.add_argument(
"--web", help="use the web version of the client", action="store_true"
"-w", "--web", help="use the web version of the client", action="store_true"
)
parser.add_argument(
"--ssl", help="enable SSL for HTTP requests", action="store_true"
"-s",
"--ssl",
help="enable SSL for HTTP communications",
action="store_true",
)
parser.add_argument(
"--no-ssl-verification",
help="do not verify the server SSL certificate (for self-signed ones)",
action="store_true",
)
parser.add_argument(
"--show-credentials",
Expand Down Expand Up @@ -318,7 +322,9 @@ def create(self):
response_content,
response_error_dict,
) = web_client.sendRequest(
REQUEST_VERB_CREATE, parameters=request_parameters
REQUEST_VERB_CREATE,
parameters=request_parameters,
verify_ssl_certificate=not args.no_ssl_verification,
)

else:
Expand All @@ -330,7 +336,10 @@ def create(self):
rsa_wrapper=self.runtime_rsa_wrapper,
) as client:
client.connectServer()
client.sendRequest(REQUEST_VERB_CREATE, parameters=request_parameters)
client.sendRequest(
REQUEST_VERB_CREATE,
parameters=request_parameters,
)

self._log_stdout(
"Request sent, waiting for response. This can take some time ... ",
Expand Down Expand Up @@ -476,10 +485,18 @@ def destroy(self):
"session_entry_id", help="specify the local session ID", type=int
)
parser.add_argument(
"--web", help="use the web version of the client", action="store_true"
"-w", "--web", help="use the web version of the client", action="store_true"
)
parser.add_argument(
"--ssl", help="enable SSL for HTTP requests", action="store_true"
"-s",
"--ssl",
help="enable SSL for HTTP communications",
action="store_true",
)
parser.add_argument(
"--no-ssl-verification",
help="do not verify the server SSL certificate (for self-signed ones)",
action="store_true",
)
parser.add_argument(
"--do-not-delete",
Expand Down Expand Up @@ -567,7 +584,9 @@ def destroy(self):
response_content,
response_error_dict,
) = client.sendRequest(
REQUEST_VERB_DESTROY, parameters=request_parameters
REQUEST_VERB_DESTROY,
parameters=request_parameters,
verify_ssl_certificate=not args.no_ssl_verification,
)

else:
Expand All @@ -578,7 +597,8 @@ def destroy(self):
) as client:
client.connectServer()
client.sendRequest(
REQUEST_VERB_DESTROY, parameters=request_parameters
REQUEST_VERB_DESTROY,
parameters=request_parameters,
)

(
Expand Down Expand Up @@ -672,10 +692,18 @@ def stat(self):
"-p", "--port", help="specify the server listen port", type=int
)
parser.add_argument(
"--web", help="use the web version of the client", action="store_true"
"-w", "--web", help="use the web version of the client", action="store_true"
)
parser.add_argument(
"--ssl", help="enable SSL for HTTP requests", action="store_true"
"-s",
"--ssl",
help="enable SSL for HTTP communications",
action="store_true",
)
parser.add_argument(
"--no-ssl-verification",
help="do not verify the server SSL certificate (for self-signed ones)",
action="store_true",
)
parser.add_argument(
"--json", help="print output in JSON format", action="store_true"
Expand Down Expand Up @@ -746,7 +774,11 @@ def stat(self):
is_response_valid,
response_content,
response_error_dict,
) = client.sendRequest(REQUEST_VERB_STAT, parameters=request_parameters)
) = client.sendRequest(
REQUEST_VERB_STAT,
parameters=request_parameters,
verify_ssl_certificate=not args.no_ssl_verification,
)

else:
with ClientInterface(
Expand All @@ -757,7 +789,10 @@ def stat(self):
rsa_wrapper=self.runtime_rsa_wrapper,
) as client:
client.connectServer()
client.sendRequest(REQUEST_VERB_STAT, parameters=request_parameters)
client.sendRequest(
REQUEST_VERB_STAT,
parameters=request_parameters,
)

(
is_response_valid,
Expand Down
9 changes: 8 additions & 1 deletion anwdlclient/web/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
DEFAULT_HTTP_SERVER_LISTEN_PORT = 8080
DEFAULT_HTTPS_SERVER_LISTEN_PORT = 4443
DEFAULT_ENABLE_SSL = False
DEFAULT_VERIFY_SSL_CERTIFICATE = True


class WebClientInterface:
Expand All @@ -35,7 +36,12 @@ def __init__(
self.enable_ssl = enable_ssl
self.server_listen_port = server_listen_port

def sendRequest(self, verb: str, parameters: dict = {}) -> None:
def sendRequest(
self,
verb: str,
parameters: dict = {},
verify_ssl_certificate: bool = DEFAULT_VERIFY_SSL_CERTIFICATE,
) -> None:
is_request_valid, request_content, request_errors = makeRequest(
verb, parameters=parameters
)
Expand All @@ -47,6 +53,7 @@ def sendRequest(self, verb: str, parameters: dict = {}) -> None:
f"http{'s' if self.enable_ssl else ''}://{self.server_ip}:{self.server_listen_port}/{verb.lower()}",
data=json.dumps(request_content.get("parameters")),
headers={"Content-Type": "application/json"},
verify=verify_ssl_certificate,
)

if req.status_code >= 300:
Expand Down
13 changes: 12 additions & 1 deletion docs/source/developer_section/api_references/web/client.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Constant name | Value | Definition
*DEFAULT_HTTP_SERVER_LISTEN_PORT* | 8080 | The default HTTP web server listen port.
*DEFAULT_HTTPS_SERVER_LISTEN_PORT* | 4443 | The default HTTPS web server listen port.
*DEFAULT_ENABLE_SSL* | `False` | Enable SSL support by default or not.
*DEFAULT_VERIFY_SSL_CERTIFICATE* | `True` | Verify the server ssl certificate by default or not.

## class *RESTWebServerInterface*

Expand Down Expand Up @@ -51,7 +52,7 @@ If the parameter `enable_ssl` is set to `True`, you will probably need to change

### Request and reponse

```{classmethod} sendRequest(verb, parameters)
```{classmethod} sendRequest(verb, parameters, verify_ssl_certificate)
```

Send an HTTP request to the server.
Expand All @@ -70,6 +71,12 @@ Send an HTTP request to the server.
> The parameters dictionary to send. The content must be an empty dict or a normalized [Request format](https://anweddol-client.readthedocs.io/en/latest/technical_specifications/core/communication.html#request-format) dictionary. Default is an empty dict.
> ```
> ```{attribute} verify_ssl_certificate
> Type : bool
>
> `True` to verify the server SSL certificate, `False` otherwise. Default is `True`.
> ```
**Return value** :

> Type : tuple
Expand Down Expand Up @@ -118,4 +125,8 @@ Send an HTTP request to the server.
```{note}
Unlike the `core` client version under the same name, this method automatically handles the server response in its process.
```

```{warning}
As said in the usage guide, there is a chance that the SSL certificate used by the server to encrypt communications is self-signed : Meaning that `urllib` can raise an SSL error during the process. Use the `--no-ssl-verification` flag to ignore SSL errors if needed.
```
8 changes: 5 additions & 3 deletions docs/source/usage_guide/client_usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
You need to follows the [Installation](installation) section before continuing this tutorial.
```

Here is a typical tutorial on how to interact with a server.
Here is a typical tutorial on how to interact with an Anweddol server.

```{tip}
For each commands below, you can add the `--web` flag to interact with Anweddol servers HTTP REST API, if available.
For each commands below, you can add the `-w` argument to interact with Anweddol servers HTTP REST API, if available.
If you want to use SSL, you should see the last section of this document about self-signed certificates.
```
Expand Down Expand Up @@ -84,4 +84,6 @@ To avoid this, you should tell you HTTP client to ignore the error :

- With browsers :

Refer to the corresponding usage guide to ignore certificate errors.
Refer to the corresponding usage guide to ignore certificate errors.

If you are using the `anwdlclient` CLI, you can simply add the `--no-ssl-verification` flag to the command to ignore SSL certificate verification.

0 comments on commit aa55571

Please sign in to comment.