ee-client 2.6.2__tar.gz → 2.6.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. {ee_client-2.6.2 → ee_client-2.6.3}/PKG-INFO +1 -1
  2. {ee_client-2.6.2 → ee_client-2.6.3}/ee_client.egg-info/PKG-INFO +1 -1
  3. {ee_client-2.6.2 → ee_client-2.6.3}/ee_client.egg-info/SOURCES.txt +2 -1
  4. {ee_client-2.6.2 → ee_client-2.6.3}/eeclient/__init__.py +1 -1
  5. {ee_client-2.6.2 → ee_client-2.6.3}/eeclient/helpers.py +21 -4
  6. {ee_client-2.6.2 → ee_client-2.6.3}/eeclient/sepal_credential_mixin.py +2 -4
  7. {ee_client-2.6.2 → ee_client-2.6.3}/pyproject.toml +2 -2
  8. ee_client-2.6.3/tests/test_tls_verify.py +51 -0
  9. {ee_client-2.6.2 → ee_client-2.6.3}/LICENSE +0 -0
  10. {ee_client-2.6.2 → ee_client-2.6.3}/README.rst +0 -0
  11. {ee_client-2.6.2 → ee_client-2.6.3}/ee_client.egg-info/dependency_links.txt +0 -0
  12. {ee_client-2.6.2 → ee_client-2.6.3}/ee_client.egg-info/requires.txt +0 -0
  13. {ee_client-2.6.2 → ee_client-2.6.3}/ee_client.egg-info/top_level.txt +0 -0
  14. {ee_client-2.6.2 → ee_client-2.6.3}/eeclient/cache.py +0 -0
  15. {ee_client-2.6.2 → ee_client-2.6.3}/eeclient/client.py +0 -0
  16. {ee_client-2.6.2 → ee_client-2.6.3}/eeclient/data.py +0 -0
  17. {ee_client-2.6.2 → ee_client-2.6.3}/eeclient/exceptions.py +0 -0
  18. {ee_client-2.6.2 → ee_client-2.6.3}/eeclient/export/__init__.py +0 -0
  19. {ee_client-2.6.2 → ee_client-2.6.3}/eeclient/export/image.py +0 -0
  20. {ee_client-2.6.2 → ee_client-2.6.3}/eeclient/export/table.py +0 -0
  21. {ee_client-2.6.2 → ee_client-2.6.3}/eeclient/interfaces/__init__.py +0 -0
  22. {ee_client-2.6.2 → ee_client-2.6.3}/eeclient/interfaces/export.py +0 -0
  23. {ee_client-2.6.2 → ee_client-2.6.3}/eeclient/interfaces/operations.py +0 -0
  24. {ee_client-2.6.2 → ee_client-2.6.3}/eeclient/interfaces/tasks.py +0 -0
  25. {ee_client-2.6.2 → ee_client-2.6.3}/eeclient/models.py +0 -0
  26. {ee_client-2.6.2 → ee_client-2.6.3}/eeclient/oauth_app.py +0 -0
  27. {ee_client-2.6.2 → ee_client-2.6.3}/eeclient/tasks.py +0 -0
  28. {ee_client-2.6.2 → ee_client-2.6.3}/setup.cfg +0 -0
  29. {ee_client-2.6.2 → ee_client-2.6.3}/tests/test_cache.py +0 -0
  30. {ee_client-2.6.2 → ee_client-2.6.3}/tests/test_client.py +0 -0
  31. {ee_client-2.6.2 → ee_client-2.6.3}/tests/test_data.py +0 -0
  32. {ee_client-2.6.2 → ee_client-2.6.3}/tests/test_export_image.py +0 -0
  33. {ee_client-2.6.2 → ee_client-2.6.3}/tests/test_export_table.py +0 -0
  34. {ee_client-2.6.2 → ee_client-2.6.3}/tests/test_integration_get_assets.py +0 -0
  35. {ee_client-2.6.2 → ee_client-2.6.3}/tests/test_models.py +0 -0
  36. {ee_client-2.6.2 → ee_client-2.6.3}/tests/test_tasks.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ee-client
3
- Version: 2.6.2
3
+ Version: 2.6.3
4
4
  Summary: extends the capabilities of the earthengine-api by providing custom session management and client interactions
5
5
  Author-email: Daniel Guerrero <dfgm2006@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/dfguerrerom/ee-client
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ee-client
3
- Version: 2.6.2
3
+ Version: 2.6.3
4
4
  Summary: extends the capabilities of the earthengine-api by providing custom session management and client interactions
5
5
  Author-email: Daniel Guerrero <dfgm2006@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/dfguerrerom/ee-client
@@ -30,4 +30,5 @@ tests/test_export_image.py
30
30
  tests/test_export_table.py
31
31
  tests/test_integration_get_assets.py
32
32
  tests/test_models.py
33
- tests/test_tasks.py
33
+ tests/test_tasks.py
34
+ tests/test_tls_verify.py
@@ -1,6 +1,6 @@
1
1
  __title__ = "eeclient"
2
2
  __summary__ = "A client for Google Earth Engine"
3
- __version__ = "2.6.2"
3
+ __version__ = "2.6.3"
4
4
 
5
5
  __author__ = "Daniel Guerrero"
6
6
  __email__ = "dfgm2006@gmail.com"
@@ -13,6 +13,25 @@ from ee.data import convert_asset_id_to_asset_name # noqa: F401
13
13
 
14
14
  log = logging.getLogger("eeclient")
15
15
 
16
+ # Hosts that legitimately serve self-signed certs in local development.
17
+ # TLS verification is skipped for these (or via EECLIENT_INSECURE_TLS) only —
18
+ # never for arbitrary or production hosts.
19
+ _LOCAL_INSECURE_HOSTS = {"host.docker.internal"}
20
+
21
+
22
+ def should_verify_tls(host: Optional[str] = None) -> bool:
23
+ """Return whether TLS certificates should be verified for ``host``.
24
+
25
+ Secure by default. Verification is skipped only for known local-dev hosts
26
+ that serve self-signed certs, or when the ``EECLIENT_INSECURE_TLS`` env var
27
+ is explicitly truthy. It is never disabled for arbitrary/production hosts.
28
+ """
29
+ if os.getenv("EECLIENT_INSECURE_TLS", "").strip().lower() in {"1", "true", "yes"}:
30
+ return False
31
+ if host and host in _LOCAL_INSECURE_HOSTS:
32
+ return False
33
+ return True
34
+
16
35
 
17
36
  def _get_ee_image(
18
37
  ee_object: Union[Image, ImageCollection, Feature, FeatureCollection],
@@ -77,7 +96,7 @@ def get_sepal_headers_from_auth(
77
96
  )
78
97
 
79
98
  session = requests.Session()
80
- session.verify = False
99
+ session.verify = should_verify_tls(sepal_host)
81
100
 
82
101
  creds_response = session.post(
83
102
  f"https://{sepal_host}/api/user/login",
@@ -91,10 +110,8 @@ def get_sepal_headers_from_auth(
91
110
 
92
111
  creds_response.raise_for_status()
93
112
 
94
- log.debug(f"Authentication successful. Cookies: {session.cookies}")
95
- log.debug(f"Response>>>>>>>>>>: {creds_response.json()}")
96
-
97
113
  sepal_user_obj = SepalUser.model_validate(creds_response.json())
114
+ log.debug("Authentication successful for user '%s'", sepal_user_obj.username)
98
115
 
99
116
  cookies_dict = {cookie.name: cookie.value for cookie in session.cookies}
100
117
 
@@ -4,6 +4,7 @@ from eeclient.exceptions import (
4
4
  CredentialsFileUnknownError,
5
5
  SepalCredentialsUnavailableError,
6
6
  )
7
+ from eeclient.helpers import should_verify_tls
7
8
  import os
8
9
  import logging
9
10
  import json
@@ -50,10 +51,7 @@ class SepalCredentialMixin:
50
51
  f"https://{self.sepal_host}/api/user-files/download/"
51
52
  "?path=%2F.config%2Fearthengine%2Fcredentials"
52
53
  )
53
- self.verify_ssl = not (
54
- self.sepal_host == "host.docker.internal"
55
- or self.sepal_host == "danielg.sepal.io"
56
- )
54
+ self.verify_ssl = should_verify_tls(self.sepal_host)
57
55
 
58
56
  self._google_tokens = self.sepal_user_data.google_tokens
59
57
  if self._google_tokens:
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ee-client"
7
- version = "2.6.2"
7
+ version = "2.6.3"
8
8
  description = "extends the capabilities of the earthengine-api by providing custom session management and client interactions"
9
9
  readme = { file = "README.rst", content-type = "text/x-rst" }
10
10
  authors = [
@@ -66,7 +66,7 @@ branch = true
66
66
  [tool.commitizen]
67
67
  tag_format = "v$major.$minor.$patch$prerelease"
68
68
  update_changelog_on_bump = false
69
- version = "2.6.2"
69
+ version = "2.6.3"
70
70
  version_files = [
71
71
  "pyproject.toml:version",
72
72
  "eeclient/__init__.py:__version__",
@@ -0,0 +1,51 @@
1
+ """TLS verification policy for ee-client.
2
+
3
+ Security regression guard: TLS must be verified by default for every host,
4
+ including the maintainer's former personal dev host. Verification may only be
5
+ skipped for known local-dev hosts (self-signed) or via an explicit opt-in env
6
+ var — never for arbitrary or production hosts.
7
+ """
8
+
9
+ import pytest
10
+
11
+ from eeclient.helpers import should_verify_tls
12
+
13
+ INSECURE_ENV = "EECLIENT_INSECURE_TLS"
14
+
15
+
16
+ @pytest.fixture(autouse=True)
17
+ def _clear_insecure_env(monkeypatch):
18
+ monkeypatch.delenv(INSECURE_ENV, raising=False)
19
+
20
+
21
+ @pytest.mark.parametrize(
22
+ "host",
23
+ [
24
+ "sepal.io",
25
+ "danielg.sepal.io", # former hardcoded insecure host — must now verify
26
+ "danielg.sepal.io.attacker.com", # must not match via substring
27
+ "anything.example.com",
28
+ None, # file-based auth (no host)
29
+ ],
30
+ )
31
+ def test_verifies_by_default(host):
32
+ assert should_verify_tls(host) is True
33
+
34
+
35
+ def test_local_docker_host_is_skipped():
36
+ # Local Docker host serves a self-signed cert and cannot be meaningfully
37
+ # MITM'd; skipping verification there is the one defensible exception.
38
+ assert should_verify_tls("host.docker.internal") is False
39
+
40
+
41
+ @pytest.mark.parametrize("value", ["1", "true", "TRUE", "yes", "Yes"])
42
+ def test_explicit_opt_in_disables_verification(monkeypatch, value):
43
+ monkeypatch.setenv(INSECURE_ENV, value)
44
+ assert should_verify_tls("danielg.sepal.io") is False
45
+ assert should_verify_tls("sepal.io") is False
46
+
47
+
48
+ @pytest.mark.parametrize("value", ["", "0", "false", "no", "off"])
49
+ def test_non_truthy_opt_in_keeps_verification(monkeypatch, value):
50
+ monkeypatch.setenv(INSECURE_ENV, value)
51
+ assert should_verify_tls("sepal.io") is True
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes