Repository: CS-SI/eodag

Issue:
Support geodes provider

Support geodes provider : https://geodes.cnes.fr/migration-de-peps-vers-geodes/ 


Deprecate peps provider
Add geodes provider


Discussion:
github-actions[bot]: ## Test Results
    2 files   -     2      2 suites   - 2   2m 49s :stopwatch: - 2m 51s
  568 tests ±    0    561 :white_check_mark:  -     4  3 :zzz: ± 0  4 :x: +4 
1 136 runs   - 1 136  1 126 :white_check_mark:  - 1 050  6 :zzz:  - 90  4 :x: +4 

For more details on these failures, see [this check](https://github.com/CS-SI/eodag/runs/31737278239).

Results for commit 64d35774. ± Comparison against base commit 4785e8a1.

[test-results]:data:application/gzip;base64,H4sIALZvEmcC/03MSw6DIBSF4a0Yxh1wkYd0Mw0CJqQqDY9R0733ais6/L+TnDeZwuwzuXfs1pFcQ2nhajIlxBUTpEbAqWyjkMNRj1yt3QlOeoYXUt9gMmFG4A18SjGhUJRU1+0ToJf/Oj4B2Em/z9aXy72vjzYuSygYRHLXC6U4ZVJYypmQTo+DNkY7bj13RqCMCsjnC5a5EUAHAQAA

github-actions[bot]: ![badge](https://raw.githubusercontent.com/CS-SI/eodag/_xml_coverage_reports/data/geodes/./badge.svg)


## Code Coverage (Ubuntu)

<details>


```
Filename                                     Stmts    Miss  Cover    Missing
-----------------------------------------  -------  ------  -------  ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
__init__.py                                      8       0  100.00%
cli.py                                         314      59  81.21%   657-716, 818-869, 873
config.py                                      396      27  93.18%   83-85, 94, 102, 106-108, 179, 190, 608-610, 723-726, 769-770, 779-780, 885, 948-953, 955
crunch.py                                        5       5  0.00%    20-24
api/__init__.py                                  0       0  100.00%
api/core.py                                    767      69  91.00%   374, 664, 708-711, 749, 793, 827, 872-877, 903, 994, 1062, 1200, 1285-1297, 1333, 1335, 1363, 1367-1378, 1391-1397, 1480-1483, 1516-1536, 1588, 1605-1609, 1621-1624, 1980, 2004-2010, 2261, 2265-2269, 2278-2280, 2312
api/search_result.py                            58       4  93.10%   92, 101, 108, 122
api/product/__init__.py                          6       0  100.00%
api/product/_assets.py                          48       5  89.58%   75, 147, 155, 158-162
api/product/_product.py                        187      20  89.30%   70-72, 237-238, 313, 342, 399, 413-416, 429, 453-456, 499-505
api/product/metadata_mapping.py                680      68  90.00%   130-132, 227, 259-260, 306-307, 317-329, 331, 342, 348-360, 405-406, 443, 464-467, 490, 498-499, 575-576, 600-601, 607-610, 625-626, 775, 821, 992-997, 1124, 1138-1158, 1178, 1183, 1312, 1326, 1397, 1449, 1489-1493, 1508
api/product/drivers/__init__.py                  6       0  100.00%
api/product/drivers/base.py                      6       1  83.33%   38
plugins/__init__.py                              0       0  100.00%
plugins/base.py                                 21       2  90.48%   48, 55
plugins/manager.py                             172      15  91.28%   116-121, 171, 209, 231, 235, 259, 281, 399-402, 414-415
plugins/apis/__init__.py                         0       0  100.00%
plugins/apis/base.py                             4       0  100.00%
plugins/apis/ecmwf.py                           91       8  91.21%   149-151, 198-199, 225-227
plugins/apis/usgs.py                           180      31  82.78%   132, 234, 268, 303-305, 310, 336-337, 342, 372-379, 390-395, 417-423, 425-431, 454
plugins/authentication/__init__.py               6       1  83.33%   31
plugins/authentication/aws_auth.py              19       0  100.00%
plugins/authentication/base.py                  17       2  88.24%   43, 56
plugins/authentication/generic.py               14       2  85.71%   40, 50
plugins/authentication/header.py                19       0  100.00%
plugins/authentication/keycloak.py              48       4  91.67%   134, 160-165
plugins/authentication/oauth.py                 13       7  46.15%   32-34, 38-41
plugins/authentication/openid_connect.py       187      17  90.91%   114, 128-154, 162, 316-319, 345
plugins/authentication/qsauth.py                34       1  97.06%   83
plugins/authentication/sas_auth.py              47       1  97.87%   76
plugins/authentication/token.py                 89      16  82.02%   79, 108, 110, 133-146, 202-206
plugins/authentication/token_exchange.py        36      20  44.44%   74-80, 92-122
plugins/crunch/__init__.py                       0       0  100.00%
plugins/crunch/base.py                          10       1  90.00%   40
plugins/crunch/filter_date.py                   59      14  76.27%   49-54, 66, 75, 84, 87, 99-101, 110-112, 119
plugins/crunch/filter_latest_intersect.py       47       8  82.98%   51-52, 68, 77-80, 82, 89-92
plugins/crunch/filter_latest_tpl_name.py        31       1  96.77%   83
plugins/crunch/filter_overlap.py                66      18  72.73%   28-30, 68-71, 78-81, 87, 95, 106-122
plugins/crunch/filter_property.py               30       7  76.67%   54-59, 62-63, 79-83
plugins/download/__init__.py                     0       0  100.00%
plugins/download/aws.py                        491     163  66.80%   266, 279, 346-349, 363-367, 409-411, 415, 447-448, 454-458, 487, 519, 523, 530, 560-568, 572, 604-612, 623-625, 656-730, 748-808, 819-824, 836-849, 874, 889-891, 894, 904-912, 920-933, 943-974, 981-993, 1031, 1057, 1102-1104, 1324
plugins/download/base.py                       253      51  79.84%   136, 164, 296-297, 314-320, 351-355, 361-362, 404, 407-421, 433, 437, 501-505, 535-536, 544-561, 568-576, 578-582, 625, 647, 669, 677
plugins/download/creodias_s3.py                 17       9  47.06%   44-58
plugins/download/http.py                       534     120  77.53%   204, 300-303, 305-306, 313-318, 336-351, 368-370, 382, 430, 437-443, 461, 475, 489, 497-499, 515-520, 531, 549, 591-595, 617, 657, 702, 716-722, 751-815, 833, 863-872, 894-895, 924-929, 935, 938, 955, 972-973, 1003-1004, 1011, 1072-1078, 1133-1134, 1140, 1150, 1186, 1222, 1240-1253, 1279-1281
plugins/download/s3rest.py                     116      24  79.31%   113, 149, 156, 191, 218-225, 228-230, 234, 245-251, 259-260, 263-267, 290, 311-314
plugins/search/__init__.py                      22       0  100.00%
plugins/search/base.py                         132      13  90.15%   100, 104, 115, 274, 294, 350-351, 371, 374-382
plugins/search/build_search_result.py          188      24  87.23%   105, 146-147, 153, 164, 298-301, 330, 365-382, 431, 460, 463, 473, 490, 518, 520
plugins/search/cop_marine.py                   236      50  78.81%   55, 63-65, 75-76, 81, 86-87, 103, 105, 108, 143-145, 157-158, 200, 206, 210, 214, 227, 238-239, 247, 275, 279, 294, 298, 302, 306, 310-314, 320-323, 326-340, 357, 406-410, 415, 427
plugins/search/creodias_s3.py                   55       3  94.55%   58, 76, 110
plugins/search/csw.py                          105      81  22.86%   58-59, 63-64, 72-120, 126-139, 147-179, 197-238
plugins/search/data_request_search.py          202      69  65.84%   90-93, 109, 120, 124-125, 136, 141, 146, 153, 166-169, 223-224, 228, 238-244, 249, 275-278, 286-297, 314, 316, 323-326, 328-329, 347-351, 384, 394, 405, 418, 424-439, 444
plugins/search/qssearch.py                     742     107  85.58%   371, 381-410, 440, 444-450, 461-462, 572-584, 628, 644, 654, 673-688, 725-728, 799-800, 848, 867, 874, 886, 943, 964, 967-968, 977-978, 987-988, 997-998, 1025, 1096-1101, 1105-1114, 1148, 1170, 1230, 1279, 1343, 1346-1347, 1429-1433, 1495, 1498, 1504-1505, 1526, 1553-1565, 1572, 1604-1606, 1616-1622, 1652, 1675, 1690, 1706, 1781-1784, 1789-1792, 1819-1820, 1835
plugins/search/static_stac_search.py            72      10  86.11%   98-125, 141, 154
rest/__init__.py                                 4       2  50.00%   21-22
rest/cache.py                                   33       7  78.79%   35-37, 53-55, 59, 68
rest/config.py                                  25       0  100.00%
rest/constants.py                                6       0  100.00%
rest/core.py                                   251      63  74.90%   216-217, 273, 281, 299-316, 331-369, 460, 502-533, 680, 687-735
rest/errors.py                                  69       5  92.75%   106, 116, 127, 143-144
rest/server.py                                 188      24  87.23%   89, 112-114, 277-282, 310, 495-497, 514-519, 548, 550, 554-555, 559-560
rest/stac.py                                   319      63  80.25%   306, 328, 380-383, 410-437, 468-470, 493, 525-526, 608-648, 670-686, 778-782, 789, 843-844, 905, 995-997
rest/types/__init__.py                           0       0  100.00%
rest/types/collections_search.py                13      13  0.00%    18-44
rest/types/eodag_search.py                     176       5  97.16%   225-229, 282, 285, 353
rest/types/queryables.py                        55       1  98.18%   163
rest/types/stac_search.py                      125       7  94.40%   138, 184, 199-201, 209, 213
rest/utils/__init__.py                          93      12  87.10%   108-109, 128-130, 182, 192-206
rest/utils/cql_evaluate.py                      48       5  89.58%   69, 76, 90, 97, 105
rest/utils/rfc3339.py                           23       3  86.96%   48, 60, 62
types/__init__.py                              114      14  87.72%   65, 82, 141-144, 211, 225-234, 244, 265, 278
types/bbox.py                                   43      19  55.81%   46-61, 72-74, 85-87, 99-101, 113-115, 123
types/download_args.py                           9       0  100.00%
types/queryables.py                             80       0  100.00%
types/search_args.py                            70      18  74.29%   60-64, 71-88, 103
types/whoosh.py                                 15       0  100.00%
utils/__init__.py                              499      36  92.79%   85, 189-190, 199-226, 229, 243, 323-327, 401-405, 424-426, 505, 520, 556-557, 921-924, 932-933, 971-972, 1143
utils/constraints.py                           119      38  68.07%   62, 89-98, 139, 144, 148, 159, 182-184, 194, 208-224, 233-244
utils/exceptions.py                             41       0  100.00%
utils/import_system.py                          28      19  32.14%   64-78, 89-99
utils/logging.py                                28       1  96.43%   41
utils/notebook.py                               44      23  47.73%   25-29, 36-41, 58-62, 72-78, 83-87
utils/repr.py                                   30       8  73.33%   36, 38, 42, 76, 94-101
utils/requests.py                               55      11  80.00%   64, 86, 88, 90, 92, 94, 110, 118-120, 128
utils/rest.py                                   36       1  97.22%   55
utils/stac_reader.py                           111      45  59.46%   56-57, 63-85, 95-97, 101, 137, 153-156, 203-212, 222-252
TOTAL                                         9636    1601  83.39%
```

</details>


### Diff against develop

```
Filename                      Stmts    Miss  Cover
--------------------------  -------  ------  -------
config.py                       +12       0  +0.21%
plugins/download/http.py         +1       0  +0.04%
plugins/search/qssearch.py      +24     +13  -1.33%
TOTAL                           +37     +13  -0.07%
```


Results for commit: 64d357740265c04256d9b89aa9d4ce4da556db71


_Minimum allowed coverage is `70%`_


:recycle: This comment has been updated with latest results


<!-- Sticky Pull Request Commentartifacts/unit-test-results-python3.13-ubuntu-latest/coverage.xml -->
github-actions[bot]: ![badge](https://raw.githubusercontent.com/CS-SI/eodag/_xml_coverage_reports_win/data/geodes/./badge.svg)


## Code Coverage (Windows)

<details>


```
Filename                                     Stmts    Miss  Cover    Missing
-----------------------------------------  -------  ------  -------  ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
__init__.py                                      8       0  100.00%
cli.py                                         314      59  81.21%   657-716, 818-869, 873
config.py                                      425      28  93.41%   83-85, 94, 102, 106-108, 179, 190, 684-686, 799-802, 845-846, 855-856, 961, 992, 1024-1029, 1031
crunch.py                                        5       5  0.00%    20-24
api/__init__.py                                  0       0  100.00%
api/core.py                                    767      69  91.00%   374, 664, 708-711, 749, 793, 827, 872-877, 903, 994, 1062, 1200, 1285-1297, 1333, 1335, 1363, 1367-1378, 1391-1397, 1480-1483, 1516-1536, 1588, 1605-1609, 1621-1624, 1980, 2004-2010, 2261, 2265-2269, 2278-2280, 2312
api/search_result.py                            58       4  93.10%   92, 101, 108, 122
api/product/__init__.py                          6       0  100.00%
api/product/_assets.py                          48       5  89.58%   75, 147, 155, 158-162
api/product/_product.py                        187      20  89.30%   70-72, 237-238, 313, 342, 399, 413-416, 429, 453-456, 499-505
api/product/metadata_mapping.py                680      68  90.00%   130-132, 227, 259-260, 306-307, 317-329, 331, 342, 348-360, 405-406, 443, 464-467, 490, 498-499, 575-576, 600-601, 607-610, 625-626, 775, 821, 992-997, 1124, 1138-1158, 1178, 1183, 1312, 1326, 1397, 1449, 1489-1493, 1508
api/product/drivers/__init__.py                  6       0  100.00%
api/product/drivers/base.py                      6       1  83.33%   38
plugins/__init__.py                              0       0  100.00%
plugins/base.py                                 21       3  85.71%   48, 55, 68
plugins/manager.py                             172      15  91.28%   116-121, 171, 209, 231, 235, 259, 281, 399-402, 414-415
plugins/apis/__init__.py                         0       0  100.00%
plugins/apis/base.py                             4       0  100.00%
plugins/apis/ecmwf.py                           91       8  91.21%   159-161, 208-209, 235-237
plugins/apis/usgs.py                           180      31  82.78%   155, 257, 291, 326-328, 333, 359-360, 365, 395-402, 413-418, 440-446, 448-454, 477
plugins/authentication/__init__.py               6       1  83.33%   31
plugins/authentication/aws_auth.py              19       0  100.00%
plugins/authentication/base.py                  17       2  88.24%   43, 56
plugins/authentication/generic.py               14       2  85.71%   51, 61
plugins/authentication/header.py                19       0  100.00%
plugins/authentication/keycloak.py              48       4  91.67%   153, 179-184
plugins/authentication/oauth.py                 13       7  46.15%   42-44, 48-51
plugins/authentication/openid_connect.py       187      17  90.91%   118, 132-158, 166, 300-303, 329
plugins/authentication/qsauth.py                34       1  97.06%   91
plugins/authentication/sas_auth.py              47       1  97.87%   76
plugins/authentication/token.py                 89      16  82.02%   101, 130, 132, 155-168, 224-228
plugins/authentication/token_exchange.py        36      20  44.44%   72-78, 90-120
plugins/crunch/__init__.py                       0       0  100.00%
plugins/crunch/base.py                          10       1  90.00%   43
plugins/crunch/filter_date.py                   59      14  76.27%   52-57, 69, 78, 87, 90, 102-104, 113-115, 122
plugins/crunch/filter_latest_intersect.py       47      33  29.79%   49-54, 67-112
plugins/crunch/filter_latest_tpl_name.py        31       1  96.77%   83
plugins/crunch/filter_overlap.py                66      18  72.73%   28-30, 66-69, 76-79, 85, 93, 104-120
plugins/crunch/filter_property.py               30       7  76.67%   55-60, 63-64, 80-84
plugins/download/__init__.py                     0       0  100.00%
plugins/download/aws.py                        491     163  66.80%   282, 295, 362-365, 379-383, 425-427, 431, 463-464, 470-474, 503, 535, 539, 546, 576-584, 588, 620-628, 639-641, 672-746, 764-824, 835-840, 852-865, 890, 905-907, 910, 920-928, 936-949, 959-990, 997-1009, 1047, 1073, 1118-1120, 1340
plugins/download/base.py                       253      53  79.05%   136, 164, 231-233, 296-297, 314-320, 351-355, 361-362, 404, 407-421, 433, 437, 501-505, 535-536, 544-561, 568-576, 578-582, 625, 647, 669, 677
plugins/download/creodias_s3.py                 17       9  47.06%   53-67
plugins/download/http.py                       534     121  77.34%   234, 330-333, 335-336, 343-348, 366-381, 398-400, 412, 460, 467-473, 491, 505, 519, 527-529, 545-550, 561, 579, 621-625, 647, 687, 732, 746-752, 781-845, 863, 893-902, 924-925, 954-959, 965, 968, 985, 1002-1003, 1016, 1033-1034, 1041, 1102-1108, 1163-1164, 1170, 1180, 1216, 1252, 1270-1283, 1309-1311
plugins/download/s3rest.py                     116      24  79.31%   118, 154, 161, 196, 223-230, 233-235, 239, 250-256, 264-265, 268-272, 295, 316-319
plugins/search/__init__.py                      22       0  100.00%
plugins/search/base.py                         132      14  89.39%   100, 104, 115, 274, 294, 350-351, 371, 374-382, 384
plugins/search/build_search_result.py          188      31  83.51%   100, 141-142, 148, 159, 292-295, 324, 359-376, 425, 454, 457, 467, 484, 504-519
plugins/search/cop_marine.py                   236      50  78.81%   55, 63-65, 75-76, 81, 86-87, 103, 105, 108, 155-157, 169-170, 212, 218, 222, 226, 239, 250-251, 259, 287, 291, 306, 310, 314, 318, 322-326, 332-335, 338-352, 369, 418-422, 427, 439
plugins/search/creodias_s3.py                   55       3  94.55%   58, 76, 110
plugins/search/csw.py                          105      81  22.86%   98-99, 103-104, 112-160, 166-179, 187-219, 237-278
plugins/search/data_request_search.py          202      69  65.84%   188-191, 207, 218, 222-223, 234, 239, 244, 251, 264-267, 321-322, 326, 336-342, 347, 373-376, 384-395, 412, 414, 421-424, 426-427, 445-449, 482, 492, 503, 516, 522-537, 542
plugins/search/qssearch.py                     756     145  80.82%   444, 454-483, 502, 516, 520-526, 537-538, 554-558, 650-662, 706, 709, 722, 732, 751-766, 803-806, 877-878, 926, 945, 952, 964, 1021, 1042, 1045-1046, 1055-1056, 1065-1066, 1075-1076, 1103, 1174-1179, 1183-1192, 1226, 1248, 1308, 1398, 1485, 1488-1489, 1571-1575, 1637, 1640, 1646-1647, 1668, 1695-1707, 1714, 1746-1748, 1758-1764, 1794, 1817, 1832, 1848, 1916-2022
plugins/search/static_stac_search.py            75      13  82.67%   98-124, 140, 153
rest/__init__.py                                 4       2  50.00%   21-22
rest/cache.py                                   33      22  33.33%   35-37, 44-70
rest/config.py                                  25       1  96.00%   35
rest/constants.py                                6       0  100.00%
rest/core.py                                   251     139  44.62%   162, 164, 166, 169-170, 184-194, 206-207, 209-210, 216-217, 220, 223, 264-318, 331-369, 400-434, 449-465, 481-490, 502-533, 550, 592-641, 680, 687-735
rest/errors.py                                  69      49  28.99%   60, 65-100, 105-108, 115-118, 126-147, 155-160, 175-181
rest/server.py                                 188     188  0.00%    18-573
rest/stac.py                                   319      68  78.68%   240, 306, 328, 380-383, 410-437, 468-470, 493, 525-526, 608-648, 670-686, 713, 778-782, 789, 843-844, 850, 905, 943, 976, 995-997
rest/types/__init__.py                           0       0  100.00%
rest/types/collections_search.py                13      13  0.00%    18-44
rest/types/eodag_search.py                     176      16  90.91%   225-229, 262-264, 282, 285, 291, 295, 353, 370-380
rest/types/queryables.py                        55      13  76.36%   50-51, 58-59, 66-67, 93-98, 107-108, 163
rest/types/stac_search.py                      125      11  91.20%   136-138, 184, 199-201, 209, 213, 261, 264
rest/utils/__init__.py                          93      30  67.74%   79-85, 105, 108-109, 128-130, 143, 150, 175-183, 190-211
rest/utils/cql_evaluate.py                      48       5  89.58%   69, 76, 90, 97, 105
rest/utils/rfc3339.py                           23       5  78.26%   43-44, 48, 60, 62
types/__init__.py                              114      39  65.79%   65, 78-82, 93-105, 132-134, 141-144, 184, 211, 221-237, 242, 244, 265, 270, 278, 288
types/bbox.py                                   43      19  55.81%   46-61, 72-74, 85-87, 99-101, 113-115, 123
types/download_args.py                           9       0  100.00%
types/queryables.py                             80       0  100.00%
types/search_args.py                            70      18  74.29%   60-64, 71-88, 103
types/whoosh.py                                 15       0  100.00%
utils/__init__.py                              499      36  92.79%   85, 189-190, 199-226, 229, 244, 324-328, 401-405, 424-426, 505, 520, 560-561, 925-928, 936-937, 975-976, 1147
utils/constraints.py                           119      38  68.07%   62, 89-98, 139, 144, 148, 159, 182-184, 194, 208-224, 233-244
utils/exceptions.py                             41       0  100.00%
utils/import_system.py                          28      19  32.14%   64-78, 89-99
utils/logging.py                                28       1  96.43%   41
utils/notebook.py                               44      23  47.73%   25-29, 36-41, 58-62, 72-78, 83-87
utils/repr.py                                   30       8  73.33%   36, 38, 42, 76, 94-101
utils/requests.py                               55      11  80.00%   64, 86, 88, 90, 92, 94, 110, 118-120, 128
utils/rest.py                                   36       1  97.22%   55
utils/stac_reader.py                           111      45  59.46%   56-57, 63-85, 95-97, 101, 137, 153-156, 203-212, 222-252
TOTAL                                         9682    2057  78.75%
```

</details>


### Diff against develop

```
Filename                      Stmts    Miss  Cover
--------------------------  -------  ------  -------
config.py                        +4       0  +0.06%
plugins/download/http.py         +1       0  +0.04%
plugins/search/qssearch.py      +25     +13  -1.12%
TOTAL                           +30     +13  -0.07%
```


Results for commit: fb85752aeb6503e88b6a9db0923356cb354f59ba


_Minimum allowed coverage is `70%`_


:recycle: This comment has been updated with latest results


<!-- Sticky Pull Request Commentartifacts/unit-test-results-python3.13-windows-latest/coverage.xml -->

Patch:
diff --git a/docs/getting_started_guide/providers.rst b/docs/getting_started_guide/providers.rst
index 55b28631..d3bc844e 100644
--- a/docs/getting_started_guide/providers.rst
+++ b/docs/getting_started_guide/providers.rst
@@ -23,6 +23,7 @@ Products from the following providers are made avaiable through ``eodag``:
   Storage download
 * `ecmwf <https://www.ecmwf.int/>`_: European Centre for Medium-Range Weather Forecasts
 * `eumetsat_ds <https://data.eumetsat.int>`_: EUMETSAT Data Store (European Organisation for the Exploitation of Meteorological Satellites)
+* `geodes <https://geodes.cnes.fr>`_: French National Space Agency (CNES) Earth Observation portal
 * `hydroweb_next <https://hydroweb.next.theia-land.fr>`_: hydroweb.next thematic hub for hydrology data access
 * `meteoblue <https://content.meteoblue.com/en/business-solutions/weather-apis/dataset-api>`_: Meteoblue forecast
 * `onda <https://www.onda-dias.eu/cms/>`_: Serco DIAS
diff --git a/docs/getting_started_guide/register.rst b/docs/getting_started_guide/register.rst
index cf7a3810..03317eac 100644
--- a/docs/getting_started_guide/register.rst
+++ b/docs/getting_started_guide/register.rst
@@ -145,6 +145,12 @@ Create an account `here <https://eoportal.eumetsat.int/userMgmt/register.faces>`
 Then use the consumer key as `username` and the consumer secret as `password` from `here
 <https://api.eumetsat.int/api-key/>`__ in eodag credentials.
 
+``geodes``
+^^^^^^^^^^
+Go to `https://geodes-portal.cnes.fr <https://https://geodes-portal.cnes.fr>`_, then login or create an account by
+clicking on ``Log in`` in the top-right corner. Once logged-in, create an API key in the user settings page, and used it
+as *apikey* in EODAG provider auth credentials.
+
 ``hydroweb_next``
 ^^^^^^^^^^^^^^^^^
 Go to `https://hydroweb.next.theia-land.fr <https://hydroweb.next.theia-land.fr>`_, then login or create an account by
diff --git a/docs/index.rst b/docs/index.rst
index 64a6969c..68e9ecc5 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -27,31 +27,32 @@ types (Sentinel 1, Sentinel 2, Sentinel 3, Landsat, etc.) that can be searched a
 
     [Growing list of] supported providers
       `astraea_eod <https://eod-catalog-svc-prod.astraea.earth/api.html>`_,
-      `aws_eos <https://eos.com/>`_,
+      `aws_eos <https://eos.com>`_,
       `cop_ads <https://ads.atmosphere.copernicus.eu>`_,
       `cop_cds <https://cds.climate.copernicus.eu>`_,
-      `cop_dataspace <https://dataspace.copernicus.eu/>`_,
+      `cop_dataspace <https://dataspace.copernicus.eu>`_,
       `cop_marine <https://marine.copernicus.eu>`_,
-      `creodias <https://creodias.eu/>`_,
-      `creodias_s3 <https://creodias.eu/>`_,
+      `creodias <https://creodias.eu>`_,
+      `creodias_s3 <https://creodias.eu>`_,
       `dedl <https://hda.data.destination-earth.eu/ui>`_,
       `dedt_lumi <https://polytope.lumi.apps.dte.destination-earth.eu/openapi>`_,
       `earth_search <https://www.element84.com/earth-search/>`_,
       `earth_search_gcs <https://cloud.google.com/storage/docs/public-datasets>`_,
-      `ecmwf <https://www.ecmwf.int/>`_,
+      `ecmwf <https://www.ecmwf.int>`_,
+      `geodes <https://data.eumetsat.int>`_,
       `eumetsat_ds <https://data.eumetsat.int>`_,
       `hydroweb_next <https://hydroweb.next.theia-land.fr>`_,
       `meteoblue <https://content.meteoblue.com/en/business-solutions/weather-apis/dataset-api>`_,
-      `onda <https://www.onda-dias.eu/cms/>`_,
+      `onda <https://www.onda-dias.eu/cms>`_,
       `peps <https://peps.cnes.fr/rocket/#/home>`_,
-      `planetary_computer <https://planetarycomputer.microsoft.com/>`_,
+      `planetary_computer <https://planetarycomputer.microsoft.com>`_,
       `sara <https://copernicus.nci.org.au>`_,
-      `theia <https://theia.cnes.fr/atdistrib/rocket/>`_,
-      `usgs <https://earthexplorer.usgs.gov/>`_,
-      `usgs_satapi_aws <https://landsatlook.usgs.gov/sat-api/>`_,
+      `theia <https://theia.cnes.fr/atdistrib/rocket>`_,
+      `usgs <https://earthexplorer.usgs.gov>`_,
+      `usgs_satapi_aws <https://geodes.cnes.fr>`_,
       `wekeo_cmems <https://www.wekeo.eu>`_,
-      `wekeo_ecmwf <https://www.wekeo.eu/>`_,
-      `wekeo_main <https://www.wekeo.eu/>`_
+      `wekeo_ecmwf <https://www.wekeo.eu>`_,
+      `wekeo_main <https://www.wekeo.eu>`_
 
 EODAG has the following primary features:
 
diff --git a/docs/notebooks/api_user_guide/1_overview.ipynb b/docs/notebooks/api_user_guide/1_overview.ipynb
index b1c4eca4..def0b7b9 100644
--- a/docs/notebooks/api_user_guide/1_overview.ipynb
+++ b/docs/notebooks/api_user_guide/1_overview.ipynb
@@ -120,8 +120,8 @@
      "name": "stderr",
      "output_type": "stream",
      "text": [
-      "2023-10-17 16:51:54,405 eodag.config                     [INFO    ] Loading user configuration from: /home/anesson/.config/eodag/eodag.yml\n",
-      "2023-10-17 16:51:54,592 eodag.core                       [INFO    ] Locations configuration loaded from /home/anesson/.config/eodag/locations.yml\n"
+      "2024-10-22 14:50:41,809 eodag.config                     [INFO    ] Loading user configuration from: /home/sylvain/.config/eodag/eodag.yml\n",
+      "2024-10-22 14:50:41,859 eodag.core                       [INFO    ] Locations configuration loaded from /home/sylvain/.config/eodag/locations.yml\n"
      ]
     }
    ],
@@ -145,7 +145,7 @@
     {
      "data": {
       "text/plain": [
-       "['S1_SAR_GRD', 'S1_SAR_OCN', 'S1_SAR_SLC', 'S2_MSI_L1C', 'S2_MSI_L2A']"
+       "['S1_SAR_GRD', 'S1_SAR_OCN', 'S1_SAR_SLC', 'S2_MSI_L1C']"
       ]
      },
      "execution_count": 5,
@@ -172,17 +172,20 @@
     {
      "data": {
       "text/plain": [
-       "['astraea_eod',\n",
+       "['peps',\n",
+       " 'astraea_eod',\n",
        " 'aws_eos',\n",
        " 'cop_dataspace',\n",
        " 'creodias',\n",
+       " 'creodias_s3',\n",
+       " 'dedl',\n",
        " 'earth_search',\n",
        " 'earth_search_gcs',\n",
+       " 'geodes',\n",
        " 'onda',\n",
-       " 'peps',\n",
        " 'sara',\n",
        " 'usgs',\n",
-       " 'wekeo']"
+       " 'wekeo_main']"
       ]
      },
      "execution_count": 6,
diff --git a/docs/notebooks/api_user_guide/2_providers_products_available.ipynb b/docs/notebooks/api_user_guide/2_providers_products_available.ipynb
index 64896afc..696ff46d 100644
--- a/docs/notebooks/api_user_guide/2_providers_products_available.ipynb
+++ b/docs/notebooks/api_user_guide/2_providers_products_available.ipynb
@@ -18,17 +18,8 @@
      "name": "stderr",
      "output_type": "stream",
      "text": [
-      "2024-08-09 09:14:18,559 eodag.config                     [INFO    ] Loading user configuration from: /home/sylvain/workspace/eodag/eodag/resources/user_conf_template.yml\n",
-      "2024-08-09 09:14:18,611 eodag.core                       [INFO    ] usgs: provider needing auth for search has been pruned because no credentials could be found\n",
-      "2024-08-09 09:14:18,613 eodag.core                       [INFO    ] aws_eos: provider needing auth for search has been pruned because no credentials could be found\n",
-      "2024-08-09 09:14:18,614 eodag.core                       [INFO    ] meteoblue: provider needing auth for search has been pruned because no credentials could be found\n",
-      "2024-08-09 09:14:18,615 eodag.core                       [INFO    ] hydroweb_next: provider needing auth for search has been pruned because no credentials could be found\n",
-      "2024-08-09 09:14:18,618 eodag.core                       [INFO    ] wekeo_main: provider needing auth for search has been pruned because no credentials could be found\n",
-      "2024-08-09 09:14:18,619 eodag.core                       [INFO    ] wekeo_ecmwf: provider needing auth for search has been pruned because no credentials could be found\n",
-      "2024-08-09 09:14:18,621 eodag.core                       [INFO    ] wekeo_cmems: provider needing auth for search has been pruned because no credentials could be found\n",
-      "2024-08-09 09:14:18,622 eodag.core                       [INFO    ] creodias_s3: provider needing auth for search has been pruned because no credentials could be found\n",
-      "2024-08-09 09:14:18,624 eodag.core                       [INFO    ] dedl: provider needing auth for search has been pruned because no credentials could be found\n",
-      "2024-08-09 09:14:18,658 eodag.core                       [INFO    ] Locations configuration loaded from /home/sylvain/.config/eodag/locations.yml\n"
+      "2024-10-22 14:59:44,334 eodag.config                     [INFO    ] Loading user configuration from: /home/sylvain/.config/eodag/eodag.yml\n",
+      "2024-10-22 14:59:44,377 eodag.core                       [INFO    ] Locations configuration loaded from /home/sylvain/.config/eodag/locations.yml\n"
      ]
     }
    ],
@@ -63,22 +54,32 @@
       "text/plain": [
        "['peps',\n",
        " 'astraea_eod',\n",
+       " 'aws_eos',\n",
        " 'cop_ads',\n",
        " 'cop_cds',\n",
        " 'cop_dataspace',\n",
        " 'cop_marine',\n",
        " 'creodias',\n",
+       " 'creodias_s3',\n",
+       " 'dedl',\n",
        " 'dedt_lumi',\n",
        " 'earth_search',\n",
        " 'earth_search_cog',\n",
        " 'earth_search_gcs',\n",
        " 'ecmwf',\n",
        " 'eumetsat_ds',\n",
+       " 'geodes',\n",
+       " 'hydroweb_next',\n",
+       " 'meteoblue',\n",
        " 'onda',\n",
        " 'planetary_computer',\n",
        " 'sara',\n",
        " 'theia',\n",
-       " 'usgs_satapi_aws']"
+       " 'usgs',\n",
+       " 'usgs_satapi_aws',\n",
+       " 'wekeo_cmems',\n",
+       " 'wekeo_ecmwf',\n",
+       " 'wekeo_main']"
       ]
      },
      "execution_count": 2,
@@ -100,7 +101,7 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "eodag has 18 providers already configured.\n"
+      "eodag has 28 providers already configured.\n"
      ]
     }
    ],
@@ -125,12 +126,18 @@
       "text/plain": [
        "['peps',\n",
        " 'astraea_eod',\n",
+       " 'aws_eos',\n",
        " 'cop_dataspace',\n",
        " 'creodias',\n",
+       " 'creodias_s3',\n",
+       " 'dedl',\n",
        " 'earth_search',\n",
        " 'earth_search_gcs',\n",
+       " 'geodes',\n",
        " 'onda',\n",
-       " 'sara']"
+       " 'sara',\n",
+       " 'usgs',\n",
+       " 'wekeo_main']"
       ]
      },
      "execution_count": 4,
@@ -178,7 +185,7 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "EODAG has 216 product types stored in its internal catalog.\n"
+      "EODAG has 248 product types stored in its internal catalog.\n"
      ]
     }
    ],
diff --git a/docs/notebooks/api_user_guide/3_configuration.ipynb b/docs/notebooks/api_user_guide/3_configuration.ipynb
index 9b64e66b..34b4a300 100644
--- a/docs/notebooks/api_user_guide/3_configuration.ipynb
+++ b/docs/notebooks/api_user_guide/3_configuration.ipynb
@@ -46,25 +46,26 @@
        " 'cop_dataspace',\n",
        " 'cop_marine',\n",
        " 'creodias',\n",
+       " 'creodias_s3',\n",
+       " 'dedl',\n",
        " 'dedt_lumi',\n",
        " 'earth_search',\n",
        " 'earth_search_cog',\n",
        " 'earth_search_gcs',\n",
        " 'ecmwf',\n",
        " 'eumetsat_ds',\n",
+       " 'geodes',\n",
        " 'hydroweb_next',\n",
        " 'meteoblue',\n",
        " 'onda',\n",
        " 'planetary_computer',\n",
        " 'sara',\n",
        " 'theia',\n",
+       " 'usgs',\n",
        " 'usgs_satapi_aws',\n",
        " 'wekeo_cmems',\n",
        " 'wekeo_ecmwf',\n",
-       " 'wekeo_main',\n",
-       " 'creodias_s3',\n",
-       " 'dedl',\n",
-       " 'usgs']"
+       " 'wekeo_main']"
       ]
      },
      "execution_count": 2,
@@ -279,7 +280,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.8.10"
+   "version": "3.10.12"
   },
   "nbsphinx": {
    "execute": "always"
diff --git a/docs/plugins.rst b/docs/plugins.rst
index 52abea5e..d7aceaf4 100644
--- a/docs/plugins.rst
+++ b/docs/plugins.rst
@@ -60,6 +60,8 @@ The providers are implemented with a triplet of *Search/Authentication/Download*
 +------------------------+------------------------------------+---------------------------------+------------------+
 | ``eumetsat_ds``        | |QueryStringSearch|                | |TokenAuth|                     | |HTTPDownload|   |
 +------------------------+------------------------------------+---------------------------------+------------------+
+| ``geodes``             | |StacSearch|                       | |HTTPHeaderAuth|                | |HTTPDownload|   |
++------------------------+------------------------------------+---------------------------------+------------------+
 | ``hydroweb_next``      | |StacSearch|                       | |HTTPHeaderAuth|                | |HTTPDownload|   |
 +------------------------+------------------------------------+---------------------------------+------------------+
 | ``meteoblue``          | |BuildPostSearchResult|            | |HttpQueryStringAuth|           | |HTTPDownload|   |
diff --git a/docs/stac.rst b/docs/stac.rst
index 35517f32..f840b015 100644
--- a/docs/stac.rst
+++ b/docs/stac.rst
@@ -11,9 +11,9 @@ STAC client
 -----------
 
 STAC API providers can be configured to be used for `search` and `download` using EODAG.
-Some providers (*astraea_eod*, *earth_search*, *usgs_satapi_aws*) are already implemented
-and new providers can be dynamically added by the user. Static catalogs can also be
-fetched by EODAG.
+Some providers (*astraea_eod*, *dedl*, *earth_search*, *geodes*, *hydroweb_next*, *planetary_computer*,
+*usgs_satapi_aws*) are already implemented and new providers can be dynamically added by the user.
+Static catalogs can also be fetched by EODAG.
 
 STAC server
 -----------
diff --git a/eodag/api/core.py b/eodag/api/core.py
index fa4b1505..c9918fb3 100644
--- a/eodag/api/core.py
+++ b/eodag/api/core.py
@@ -1561,7 +1561,7 @@ class EODataAccessGateway:
             try:
                 product_type = self.get_product_type_from_alias(product_type)
             except NoMatchingProductType:
-                logger.warning("product type %s not found", product_type)
+                logger.debug("product type %s not found", product_type)
         get_search_plugins_kwargs = dict(provider=provider, product_type=product_type)
         search_plugins = self._plugins_manager.get_search_plugins(
             **get_search_plugins_kwargs
@@ -1929,7 +1929,7 @@ class EODataAccessGateway:
                             eo_product.product_type
                         )
                 except NoMatchingProductType:
-                    logger.warning("product type %s not found", eo_product.product_type)
+                    logger.debug("product type %s not found", eo_product.product_type)
 
                 if eo_product.search_intersection is not None:
                     download_plugin = self._plugins_manager.get_download_plugin(
diff --git a/eodag/config.py b/eodag/config.py
index f3fd1c82..b0a8b662 100644
--- a/eodag/config.py
+++ b/eodag/config.py
@@ -268,6 +268,14 @@ class PluginConfig(yaml.YAMLObject):
 
         #: URL from which the product types can be fetched
         fetch_url: Optional[str]
+        #: HTTP method used to fetch product types
+        fetch_method: str
+        #: Request body to fetch product types using POST method
+        fetch_body: Dict[str, Any]
+        #: The f-string template for pagination requests.
+        next_page_url_tpl: str
+        #: Index of the starting page for pagination requests.
+        start_page: int
         #: Type of the provider result
         result_type: str
         #: JsonPath to the list of product types
diff --git a/eodag/plugins/download/http.py b/eodag/plugins/download/http.py
index 3337db49..72b52cad 100644
--- a/eodag/plugins/download/http.py
+++ b/eodag/plugins/download/http.py
@@ -924,6 +924,8 @@ class HTTPDownload(Download):
             logger.info("Progress bar unavailable, please call product.download()")
             progress_callback = ProgressCallback(disable=True)
 
+        ssl_verify = getattr(self.config, "ssl_verify", True)
+
         ordered_message = ""
         if (
             "orderLink" in product.properties
@@ -974,6 +976,7 @@ class HTTPDownload(Download):
             params=params,
             headers=USER_AGENT,
             timeout=DEFAULT_STREAM_REQUESTS_TIMEOUT,
+            verify=ssl_verify,
             **req_kwargs,
         ) as self.stream:
             try:
diff --git a/eodag/plugins/search/qssearch.py b/eodag/plugins/search/qssearch.py
index a3b93f86..15f4b404 100644
--- a/eodag/plugins/search/qssearch.py
+++ b/eodag/plugins/search/qssearch.py
@@ -437,15 +437,70 @@ class QueryStringSearch(Search):
     def discover_product_types(self, **kwargs: Any) -> Optional[Dict[str, Any]]:
         """Fetch product types list from provider using `discover_product_types` conf
 
+        :returns: configuration dict containing fetched product types information
+        """
+        unpaginated_fetch_url = self.config.discover_product_types.get("fetch_url")
+        if not unpaginated_fetch_url:
+            return None
+
+        # product types pagination
+        next_page_url_tpl = self.config.discover_product_types.get("next_page_url_tpl")
+        page = self.config.discover_product_types.get("start_page", 1)
+
+        if not next_page_url_tpl:
+            # no pagination
+            return self.discover_product_types_per_page(**kwargs)
+
+        conf_update_dict: Dict[str, Any] = {
+            "providers_config": {},
+            "product_types_config": {},
+        }
+
+        while True:
+            fetch_url = next_page_url_tpl.format(url=unpaginated_fetch_url, page=page)
+
+            conf_update_dict_per_page = self.discover_product_types_per_page(
+                fetch_url=fetch_url, **kwargs
+            )
+
+            if (
+                not conf_update_dict_per_page
+                or not conf_update_dict_per_page.get("providers_config")
+                or conf_update_dict_per_page.items() <= conf_update_dict.items()
+            ):
+                # conf_update_dict_per_page is empty or a subset on existing conf
+                break
+            else:
+                conf_update_dict["providers_config"].update(
+                    conf_update_dict_per_page["providers_config"]
+                )
+                conf_update_dict["product_types_config"].update(
+                    conf_update_dict_per_page["product_types_config"]
+                )
+
+            page += 1
+
+        return conf_update_dict
+
+    def discover_product_types_per_page(
+        self, **kwargs: Any
+    ) -> Optional[Dict[str, Any]]:
+        """Fetch product types list from provider using `discover_product_types` conf
+        using paginated ``kwargs["fetch_url"]``
+
         :returns: configuration dict containing fetched product types information
         """
         try:
             prep = PreparedSearch()
 
-            fetch_url = self.config.discover_product_types.get("fetch_url")
+            # url from discover_product_types() or conf
+            fetch_url: Optional[str] = kwargs.get("fetch_url")
             if fetch_url is None:
-                return None
-            prep.url = fetch_url.format(**self.config.__dict__)
+                if fetch_url := self.config.discover_product_types.get("fetch_url"):
+                    fetch_url = fetch_url.format(**self.config.__dict__)
+                else:
+                    return None
+            prep.url = fetch_url
 
             # get auth if available
             if "auth" in kwargs:
@@ -475,7 +530,14 @@ class QueryStringSearch(Search):
                 "Skipping error while fetching product types for " "{} {} instance:"
             ).format(self.provider, self.__class__.__name__)
 
-            response = QueryStringSearch._request(self, prep)
+            # Query using appropriate method
+            fetch_method = self.config.discover_product_types.get("fetch_method", "GET")
+            fetch_body = self.config.discover_product_types.get("fetch_body", {})
+            if fetch_method == "POST" and isinstance(self, PostJsonSearch):
+                prep.query_params = fetch_body
+                response = self._request(prep)
+            else:
+                response = QueryStringSearch._request(self, prep)
         except (RequestError, KeyError, AttributeError):
             return None
         else:
diff --git a/eodag/resources/providers.yml b/eodag/resources/providers.yml
index 19ca0c3e..f939c869 100644
--- a/eodag/resources/providers.yml
+++ b/eodag/resources/providers.yml
@@ -7425,3 +7425,130 @@
     matching_url: s3://
     matching_conf:
       s3_endpoint: https://s3.waw3-1.cloudferro.com
+
+---
+!provider # MARK: geodes
+  name: geodes
+  priority: 0
+  roles:
+    - host
+  description: French National Space Agency (CNES) Earth Observation portal
+  url: https://geodes.cnes.fr
+  search: !plugin
+    type: StacSearch
+    api_endpoint: https://geodes-portal.cnes.fr/api/stac/search
+    need_auth: false
+    ssl_verify: false
+    discover_queryables:
+      fetch_url: null
+      product_type_fetch_url: null
+    discover_product_types:
+      fetch_url: https://geodes-portal.cnes.fr/api/stac/collections
+      fetch_method: POST
+      fetch_body:
+        limit: 10000
+    pagination:
+      total_items_nb_key_path: '$.context.matched'
+      # 1000 is ok and 2000 fails
+      max_items_per_page: 1000
+    sort:
+      sort_by_tpl: '{{"sortBy": [ {{"field": "{sort_param}", "direction": "{sort_order}" }} ] }}'
+      sort_by_default:
+        - !!python/tuple [startTimeFromAscendingNode, ASC]
+      sort_param_mapping:
+        id: spaceborne:s2TakeId
+        startTimeFromAscendingNode: temporal:startDate
+        completionTimeFromAscendingNode: temporal:endDate
+        platformSerialIdentifier: spaceborne:satellitePlatform
+        cloudCover: spaceborne:cloudCover
+    metadata_mapping:
+      uid: '$.id'
+      # OpenSearch Parameters for Collection Search (Table 3)
+      productType:
+        - '{{"query":{{"dataType":{{"eq":"{productType}"}}}}}}'
+        - '$.properties."dataType"'
+      processingLevel:
+        - '{{"query":{{"spaceborne:productLevel":{{"eq":"{processingLevel}"}}}}}}'
+        - '$.properties."spaceborne:productLevel"'
+      platformSerialIdentifier:
+        - '{{"query":{{"spaceborne:satellitePlatform":{{"eq":"{platformSerialIdentifier}"}}}}}}'
+        - '$.properties."spaceborne:satellitePlatform"'
+      instrument:
+        - '{{"query":{{"spaceborne:satelliteSensor":{{"eq":"{instrument}"}}}}}}'
+        - '$.properties."spaceborne:satelliteSensor"'
+      # INSPIRE obligated OpenSearch Parameters for Collection Search (Table 4)
+      title: '{$.properties."accessService:endpointURL"#replace_str(r"^.*\/(\w+)\.zip$",r"\1")}'
+      keyword: '$.properties."spaceborne:keywords"'
+      # OpenSearch Parameters for Product Search (Table 5)
+      orbitNumber:
+        - '{{"query":{{"spaceborne:absoluteOrbitID":{{"eq":"{orbitNumber}"}}}}}}'
+        - '$.properties."spaceborne:absoluteOrbitID"'
+      orbitDirection:
+        - '{{"query":{{"spaceborne:orbitDirection":{{"eq":"{orbitDirection}"}}}}}}'
+        - '$.properties."spaceborne:orbitDirection"'
+      swathIdentifier:
+        - '{{"query":{{"spaceborne:swath":{{"eq":"{swathIdentifier}"}}}}}}'
+        - '$.properties."spaceborne:swath"'
+      cloudCover:
+        - '{{"query":{{"spaceborne:cloudCover":{{"lte":"{cloudCover}"}}}}}}'
+        - '$.properties."spaceborne:cloudCover"'
+      sensorMode:
+        - '{{"query":{{"spaceborne:sensorMode":{{"eq":"{sensorMode}"}}}}}}'
+        - '$.properties."spaceborne:sensorMode"'
+      # OpenSearch Parameters for Acquistion Parameters Search (Table 6)
+      startTimeFromAscendingNode:
+        - '{{"query":{{"temporal:endDate":{{"lte":"{startTimeFromAscendingNode#to_iso_utc_datetime}"}}}}}}'
+        - '$.properties."temporal:startDate"'
+      completionTimeFromAscendingNode:
+        - '{{"query":{{"temporal:startDate":{{"gte":"{completionTimeFromAscendingNode#to_iso_utc_datetime}"}}}}}}'
+        - '$.properties."temporal:endDate"'
+      polarizationChannels:
+        - '{{"query":{{"spaceborne:polarization":{{"eq":"{polarizationChannels}"}}}}}}'
+        - '$.properties."spaceborne:polarization"'
+      # Custom parameters (not defined in the base document referenced above)
+      id:
+        - '{{"query":{{"accessService:endpointURL":{{"contains":"{id}"}}}}}}'
+        - '{$.properties."accessService:endpointURL"#replace_str(r"^.*\/(\w+)\.zip$",r"\1")}'
+      geometry:
+        - '{{"intersects":{geometry#to_geojson}}}'
+        - '($.geometry.`str()`.`sub(/^None$/, POLYGON((180 -90, 180 90, -180 90, -180 -90, 180 -90)))`)|($.geometry[*])'
+      providerProductType:
+        - '{{"query":{{"spaceborne:productType":{{"eq":"{providerProductType}"}}}}}}'
+        - '$.null'
+      downloadLink: '$.assets[?(@.roles[0] == "data")].href'
+      quicklook: '$.assets[?(@.roles[0] == "overview")].href'
+      thumbnail: '$.assets[?(@.roles[0] == "overview")].href'
+      # storageStatus set to ONLINE for consistency between providers
+      storageStatus: '{$.null#replace_str("Not Available","ONLINE")}'
+  products:
+    S1_SAR_OCN:
+      providerProductType: OCN
+      productType: PEPS_S1_L2
+      metadata_mapping:
+        cloudCover: '$.null'
+    S1_SAR_GRD:
+      providerProductType: GRD
+      productType: PEPS_S1_L1
+      metadata_mapping:
+        cloudCover: '$.null'
+    S1_SAR_SLC:
+      providerProductType: SLC
+      productType: PEPS_S1_L1
+      metadata_mapping:
+        cloudCover: '$.null'
+    S2_MSI_L1C:
+      productType: PEPS_S2_L1C
+    S2_MSI_L2A_MAJA:
+      productType: MUSCATE_SENTINEL2_SENTINEL2_L2A
+    GENERIC_PRODUCT_TYPE:
+      productType: '{productType}'
+  download: !plugin
+    type: HTTPDownload
+    ssl_verify: false
+    ignore_assets: true
+    archive_depth: 2
+  auth: !plugin
+    type: HTTPHeaderAuth
+    matching_url: https://geodes-portal.cnes.fr
+    headers:
+      X-API-Key: "{apikey}"
diff --git a/eodag/resources/user_conf_template.yml b/eodag/resources/user_conf_template.yml
index 3ae98246..e9729747 100644
--- a/eodag/resources/user_conf_template.yml
+++ b/eodag/resources/user_conf_template.yml
@@ -15,42 +15,19 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
-peps:
-    priority: # Lower value means lower priority (Default: 1)
-    search:  # Search parameters configuration
-    download:
-        extract:  # whether to extract the downloaded products, only applies to archived products (true or false, Default: true).
-        output_dir: # where to store downloaded products, as an absolute file path (Default: local temporary directory)
-        dl_url_params:  # additional parameters to pass over to the download url as an url parameter
-        delete_archive: # whether to delete the downloaded archives (true or false, Default: true).
-    auth:
-        credentials:
-            username:
-            password:
-theia:
+astraea_eod:
     priority: # Lower value means lower priority (Default: 0)
-    search:   # Search parameters configuration
-    download:
-        extract:
-        output_dir:
-        dl_url_params:
+    search: # Search parameters configuration
     auth:
         credentials:
-            ident:
-            pass:
-usgs:
-    priority: # Lower value means lower priority (Default: 0)
-    api:
-        extract:
+            aws_access_key_id:
+            aws_secret_access_key:
+            aws_profile:
+    download:
         output_dir:
-        dl_url_params:
-        product_location_scheme:
-        credentials:
-            username:
-            password:
 aws_eos:
     priority: # Lower value means lower priority (Default: 0)
-    search:   # Search parameters configuration
+    search: # Search parameters configuration
     search_auth:
         credentials:
             api_key:
@@ -61,9 +38,27 @@ aws_eos:
             aws_profile:
     download:
         output_dir:
-creodias:
+cop_ads:
+    priority: # Lower value means lower priority (Default: 0)
+    search: # Search parameters configuration
+    download:
+        extract:
+        output_dir:
+    auth:
+        credentials:
+            apikey:
+cop_cds:
     priority: # Lower value means lower priority (Default: 0)
-    search:   # Search parameters configuration
+    search: # Search parameters configuration
+    download:
+        extract:
+        output_dir:
+    auth:
+        credentials:
+            apikey:
+cop_dataspace:
+    priority: # Lower value means lower priority (Default: 0)
+    search: # Search parameters configuration
     download:
         extract:
         output_dir:
@@ -71,10 +66,15 @@ creodias:
         credentials:
             username:
             password:
-            totp: # set totp dynamically, see https://eodag.readthedocs.io/en/latest/getting_started_guide/configure.html#authenticate-using-an-otp-one-time-password-two-factor-authentication
-onda:
+cop_marine:
     priority: # Lower value means lower priority (Default: 0)
-    search:   # Search parameters configuration
+    search: # Search parameters configuration
+    download:
+        extract:
+        output_dir:
+creodias:
+    priority: # Lower value means lower priority (Default: 0)
+    search: # Search parameters configuration
     download:
         extract:
         output_dir:
@@ -82,29 +82,37 @@ onda:
         credentials:
             username:
             password:
-astraea_eod:
+            totp: # set totp dynamically, see https://eodag.readthedocs.io/en/latest/getting_started_guide/configure.html#authenticate-using-an-otp-one-time-password-two-factor-authentication
+creodias_s3:
     priority: # Lower value means lower priority (Default: 0)
-    search:   # Search parameters configuration
+    search: # Search parameters configuration
+    download:
+        output_dir:
     auth:
         credentials:
             aws_access_key_id:
             aws_secret_access_key:
-            aws_profile:
+dedl:
+    priority: # Lower value means lower priority (Default: 0)
+    search: # Search parameters configuration
     download:
         output_dir:
-usgs_satapi_aws:
-    priority: # Lower value means lower priority (Default: 0)
-    search:   # Search parameters configuration
     auth:
         credentials:
-            aws_access_key_id:
-            aws_secret_access_key:
-            aws_profile:
+            username:
+            password:
+dedt_lumi:
+    priority: # Lower value means lower priority (Default: 0)
+    search:
     download:
         output_dir:
+    auth:
+        credentials:
+            username:
+            password:
 earth_search:
     priority: # Lower value means lower priority (Default: 0)
-    search:   # Search parameters configuration
+    search: # Search parameters configuration
     auth:
         credentials:
             aws_access_key_id:
@@ -114,12 +122,12 @@ earth_search:
         output_dir:
 earth_search_cog:
     priority: # Lower value means lower priority (Default: 0)
-    search:   # Search parameters configuration
+    search: # Search parameters configuration
     download:
         output_dir:
 earth_search_gcs:
     priority: # Lower value means lower priority (Default: 0)
-    search:   # Search parameters configuration
+    search: # Search parameters configuration
     auth:
         credentials:
             aws_access_key_id:
@@ -133,46 +141,44 @@ ecmwf:
         credentials:
             username:
             password:
-cop_ads:
+eumetsat_ds:
     priority: # Lower value means lower priority (Default: 0)
-    search:   # Search parameters configuration
-    download:
-        extract:
+    search: # Search parameters configuration
         output_dir:
     auth:
-      credentials:
-        apikey:
-cop_cds:
-    priority: # Lower value means lower priority (Default: 0)
-    search:   # Search parameters configuration
+        credentials:
+            username:
+            password:
     download:
-        extract:
         output_dir:
+geodes:
+    priority: # Lower value means lower priority (Default: 0)
+    search: # Search parameters configuration
     auth:
         credentials:
             apikey:
-sara:
-    priority: # Lower value means lower priority (Default: 0)
-    search:  # Search parameters configuration
     download:
         extract:
         output_dir:
-        delete_archive:
+hydroweb_next:
+    priority: # Lower value means lower priority (Default: 0)
+    search: # Search parameters configuration
     auth:
         credentials:
-            username:
-            password:
+            apikey:
+    download:
+        output_dir:
 meteoblue:
     priority: # Lower value means lower priority (Default: 0)
-    search:   # Search parameters configuration
+    search: # Search parameters configuration
     auth:
         credentials:
             apikey:
     download:
         output_dir:
-cop_dataspace:
+onda:
     priority: # Lower value means lower priority (Default: 0)
-    search:   # Search parameters configuration
+    search: # Search parameters configuration
     download:
         extract:
         output_dir:
@@ -180,59 +186,69 @@ cop_dataspace:
         credentials:
             username:
             password:
-planetary_computer:
-    priority: # Lower value means lower priority (Default: 0)
-    search:   # Search parameters configuration
+peps:
+    priority: # Lower value means lower priority (Default: 1)
+    search: # Search parameters configuration
+    download:
+        extract: # whether to extract the downloaded products, only applies to archived products (true or false, Default: true).
+        output_dir: # where to store downloaded products, as an absolute file path (Default: local temporary directory)
+        dl_url_params: # additional parameters to pass over to the download url as an url parameter
+        delete_archive: # whether to delete the downloaded archives (true or false, Default: true).
     auth:
         credentials:
-            apikey:
-    download:
-        output_dir:
-hydroweb_next:
+            username:
+            password:
+planetary_computer:
     priority: # Lower value means lower priority (Default: 0)
-    search:   # Search parameters configuration
+    search: # Search parameters configuration
     auth:
         credentials:
             apikey:
     download:
         output_dir:
-wekeo_main:
+sara:
     priority: # Lower value means lower priority (Default: 0)
-    search:   # Search parameters configuration
+    search: # Search parameters configuration
     download:
+        extract:
         output_dir:
+        delete_archive:
     auth:
         credentials:
             username:
             password:
-wekeo_ecmwf:
+theia:
     priority: # Lower value means lower priority (Default: 0)
-    search:   # Search parameters configuration
+    search: # Search parameters configuration
     download:
+        extract:
         output_dir:
+        dl_url_params:
     auth:
         credentials:
-            username:
-            password:
-wekeo_cmems:
+            ident:
+            pass:
+usgs:
     priority: # Lower value means lower priority (Default: 0)
-    search:
-    download:
+    api:
+        extract:
         output_dir:
-    auth:
+        dl_url_params:
+        product_location_scheme:
         credentials:
             username:
             password:
-creodias_s3:
+usgs_satapi_aws:
     priority: # Lower value means lower priority (Default: 0)
-    search:   # Search parameters configuration
-    download:
-        output_dir:
+    search: # Search parameters configuration
     auth:
         credentials:
-          aws_access_key_id:
-          aws_secret_access_key:
-dedt_lumi:
+            aws_access_key_id:
+            aws_secret_access_key:
+            aws_profile:
+    download:
+        output_dir:
+wekeo_cmems:
     priority: # Lower value means lower priority (Default: 0)
     search:
     download:
@@ -241,28 +257,21 @@ dedt_lumi:
         credentials:
             username:
             password:
-dedl:
+wekeo_ecmwf:
     priority: # Lower value means lower priority (Default: 0)
-    search:   # Search parameters configuration
+    search: # Search parameters configuration
     download:
         output_dir:
-    auth:
-      credentials:
-        username:
-        password:
-eumetsat_ds:
-    priority: # Lower value means lower priority (Default: 0)
-    search:   # Search parameters configuration
-        output_dir:
     auth:
         credentials:
             username:
             password:
-    download:
-        output_dir:
-cop_marine:
+wekeo_main:
     priority: # Lower value means lower priority (Default: 0)
-    search:   # Search parameters configuration
+    search: # Search parameters configuration
     download:
-        extract:
         output_dir:
+    auth:
+        credentials:
+            username:
+            password:


Test patch:
diff --git a/tests/integration/test_core_search.py b/tests/integration/test_core_search.py
index 46b83844..69d20246 100644
--- a/tests/integration/test_core_search.py
+++ b/tests/integration/test_core_search.py
@@ -237,6 +237,7 @@ class TestCoreSearch(unittest.TestCase):
                 "peps",
                 "cop_dataspace",
                 "creodias",
+                "geodes",
                 "onda",
                 "sara",
                 "wekeo_main",
@@ -272,6 +273,7 @@ class TestCoreSearch(unittest.TestCase):
                 "peps",
                 "cop_dataspace",
                 "creodias",
+                "geodes",
                 "onda",
                 "sara",
                 "wekeo_main",
@@ -306,6 +308,7 @@ class TestCoreSearch(unittest.TestCase):
                 "peps",
                 "cop_dataspace",
                 "creodias",
+                "geodes",
                 "onda",
                 "sara",
                 "wekeo_main",
@@ -362,6 +365,7 @@ class TestCoreSearch(unittest.TestCase):
                 "peps",
                 "cop_dataspace",
                 "creodias",
+                "geodes",
                 "onda",
                 "sara",
                 "wekeo_main",
@@ -404,6 +408,7 @@ class TestCoreSearch(unittest.TestCase):
                 "peps",
                 "cop_dataspace",
                 "creodias",
+                "geodes",
                 "onda",
                 "sara",
                 "wekeo_main",
@@ -438,6 +443,7 @@ class TestCoreSearch(unittest.TestCase):
                 "peps",
                 "cop_dataspace",
                 "creodias",
+                "geodes",
                 "onda",
                 "sara",
                 "wekeo_main",
diff --git a/tests/units/test_core.py b/tests/units/test_core.py
index 282ec539..0670b1c3 100644
--- a/tests/units/test_core.py
+++ b/tests/units/test_core.py
@@ -261,6 +261,7 @@ class TestCore(TestCoreBase):
             "creodias_s3",
             "dedl",
             "earth_search",
+            "geodes",
             "onda",
             "peps",
             "planetary_computer",
@@ -272,6 +273,7 @@ class TestCore(TestCoreBase):
             "cop_dataspace",
             "creodias",
             "creodias_s3",
+            "geodes",
             "onda",
             "peps",
             "sara",
@@ -289,6 +291,7 @@ class TestCore(TestCoreBase):
             "creodias",
             "creodias_s3",
             "dedl",
+            "geodes",
             "onda",
             "peps",
             "sara",
@@ -303,6 +306,7 @@ class TestCore(TestCoreBase):
             "dedl",
             "earth_search",
             "earth_search_gcs",
+            "geodes",
             "onda",
             "peps",
             "sara",
@@ -323,7 +327,7 @@ class TestCore(TestCoreBase):
         ],
         "S2_MSI_L2AP": ["wekeo_main"],
         "S2_MSI_L2A_COG": ["earth_search_cog"],
-        "S2_MSI_L2A_MAJA": ["theia"],
+        "S2_MSI_L2A_MAJA": ["geodes", "theia"],
         "S2_MSI_L2B_MAJA_SNOW": ["theia"],
         "S2_MSI_L2B_MAJA_WATER": ["theia"],
         "S2_MSI_L3A_WASP": ["theia"],
@@ -592,6 +596,7 @@ class TestCore(TestCoreBase):
         "earth_search_gcs",
         "ecmwf",
         "eumetsat_ds",
+        "geodes",
         "hydroweb_next",
         "meteoblue",
         "onda",
@@ -1596,6 +1601,16 @@ class TestCore(TestCoreBase):
                 "max_sort_params": 1,
             },
             "cop_marine": None,
+            "geodes": {
+                "max_sort_params": None,
+                "sortables": [
+                    "id",
+                    "startTimeFromAscendingNode",
+                    "completionTimeFromAscendingNode",
+                    "platformSerialIdentifier",
+                    "cloudCover",
+                ],
+            },
             "hydroweb_next": {
                 "sortables": [
                     "id",
diff --git a/tests/units/test_download_plugins.py b/tests/units/test_download_plugins.py
index d51f3454..1e005058 100644
--- a/tests/units/test_download_plugins.py
+++ b/tests/units/test_download_plugins.py
@@ -316,6 +316,7 @@ class TestDownloadPluginHttp(BaseDownloadPluginTest):
             params={},
             headers=USER_AGENT,
             timeout=DEFAULT_STREAM_REQUESTS_TIMEOUT,
+            verify=True,
         )
 
     @mock.patch("eodag.plugins.download.http.requests.Session.request", autospec=True)
@@ -401,6 +402,7 @@ class TestDownloadPluginHttp(BaseDownloadPluginTest):
             params={},
             headers=USER_AGENT,
             timeout=DEFAULT_STREAM_REQUESTS_TIMEOUT,
+            verify=True,
         )
 
     @mock.patch(
diff --git a/tests/units/test_search_plugins.py b/tests/units/test_search_plugins.py
index c40fb27b..3d18d8b0 100644
--- a/tests/units/test_search_plugins.py
+++ b/tests/units/test_search_plugins.py
@@ -445,6 +445,109 @@ class TestSearchPluginQueryStringSearch(BaseSearchPluginTest):
         # restore configuration
         search_plugin.config.discover_product_types["results_entry"] = results_entry
 
+    def test_plugins_search_querystringsearch_discover_product_types_paginated(self):
+        """QueryStringSearch.discover_product_types must handle pagination"""
+        # One of the providers that has a QueryStringSearch Search plugin and discover_product_types configured
+        provider = "astraea_eod"
+        search_plugin = self.get_search_plugin(self.product_type, provider)
+
+        # change onfiguration for this test to filter out some collections
+        discover_product_types_conf = search_plugin.config.discover_product_types
+        search_plugin.config.discover_product_types[
+            "fetch_url"
+        ] = "https://foo.bar/collections"
+        search_plugin.config.discover_product_types[
+            "next_page_url_tpl"
+        ] = "{url}?page={page}"
+        search_plugin.config.discover_product_types["start_page"] = 0
+
+        with responses.RequestsMock(
+            assert_all_requests_are_fired=True
+        ) as mock_requests_post:
+            mock_requests_post.add(
+                responses.GET,
+                "https://foo.bar/collections?page=0",
+                json={
+                    "collections": [
+                        {
+                            "id": "foo_collection",
+                            "title": "The FOO collection",
+                            "billing": "free",
+                        }
+                    ]
+                },
+            )
+            mock_requests_post.add(
+                responses.GET,
+                "https://foo.bar/collections?page=1",
+                json={
+                    "collections": [
+                        {
+                            "id": "bar_collection",
+                            "title": "The BAR non-free collection",
+                            "billing": "non-free",
+                        },
+                    ]
+                },
+            )
+            mock_requests_post.add(
+                responses.GET,
+                "https://foo.bar/collections?page=2",
+                json={"collections": []},
+            )
+            conf_update_dict = search_plugin.discover_product_types()
+            self.assertIn("foo_collection", conf_update_dict["providers_config"])
+            self.assertIn("foo_collection", conf_update_dict["product_types_config"])
+            self.assertIn("bar_collection", conf_update_dict["providers_config"])
+            self.assertIn("bar_collection", conf_update_dict["product_types_config"])
+            self.assertEqual(
+                conf_update_dict["providers_config"]["foo_collection"]["productType"],
+                "foo_collection",
+            )
+            self.assertEqual(
+                conf_update_dict["product_types_config"]["foo_collection"]["title"],
+                "The FOO collection",
+            )
+
+        # restore configuration
+        search_plugin.config.discover_product_types = discover_product_types_conf
+
+    @mock.patch("eodag.plugins.search.qssearch.PostJsonSearch._request", autospec=True)
+    def test_plugins_search_querystringsearch_discover_product_types_post(
+        self, mock__request
+    ):
+        """QueryStringSearch.discover_product_types must be able to query using POST requests"""
+        # One of the providers that has a QueryStringSearch.discover_product_types configured with POST requests
+        provider = "geodes"
+        search_plugin = self.get_search_plugin(self.product_type, provider)
+
+        mock__request.return_value = mock.Mock()
+        mock__request.return_value.json.return_value = {
+            "collections": [
+                {
+                    "id": "foo_collection",
+                    "title": "The FOO collection",
+                },
+                {
+                    "id": "bar_collection",
+                    "title": "The BAR collection",
+                },
+            ]
+        }
+        conf_update_dict = search_plugin.discover_product_types()
+        self.assertIn("foo_collection", conf_update_dict["providers_config"])
+        self.assertIn("foo_collection", conf_update_dict["product_types_config"])
+        self.assertIn("bar_collection", conf_update_dict["providers_config"])
+        self.assertIn("bar_collection", conf_update_dict["product_types_config"])
+        self.assertEqual(
+            conf_update_dict["providers_config"]["foo_collection"]["productType"],
+            "foo_collection",
+        )
+        self.assertEqual(
+            conf_update_dict["product_types_config"]["foo_collection"]["title"],
+            "The FOO collection",
+        )
+
     @mock.patch("eodag.plugins.search.qssearch.requests.get", autospec=True)
     def test_plugins_search_querystringsearch_discover_product_types_with_query_param(
         self, mock__request