Skip to content

Commit cc2665d

Browse files
ShahanaFarooquinepet
authored andcommitted
clnrest: prefixing all rest config options with cln
This will allow users to use clnrest with c-lightning-REST without conflicts. It was required for applications to have enough time for migrating from c-lightning-REST to clnrest. Changelog-Changed: config option `rest-certs` changed to `clnrest-certs` config option `rest-protocol` changed to `clnrest-protocol` config option `rest-host` changed to `clnrest-host` config option `rest-port` changed to `clnrest-port` config option `rest-cors-origins` changed to `clnrest-cors-origins` config option `rest-csp` changed to `clnrest-csp`
1 parent 017581c commit cc2665d

File tree

6 files changed

+69
-68
lines changed

6 files changed

+69
-68
lines changed

doc/developers-guide/app-development/rest.md

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ An online demo for the REST interface is available at [REST API REFERENCE](ref:g
2828
>
2929
> - The `ip` should be configured with your system's public IP address.
3030
>
31-
> - Default `rest-host` is `127.0.0.1` but this testing will require it to be `0.0.0.0`.
31+
> - Default `clnrest-host` is `127.0.0.1` but this testing will require it to be `0.0.0.0`.
3232
>
3333
> Note: This setup is for **testing only**. It is **highly recommended** to test with _non-mainnet_ (regtest/testnet) setup only.
3434
@@ -38,36 +38,37 @@ An online demo for the REST interface is available at [REST API REFERENCE](ref:g
3838
The plugin is built-in with Core Lightning but its python dependencies are not, and must be installed separately.
3939
Install required packages with `pip install -r plugins/clnrest/requirements.txt`.
4040

41-
Note: if you have the older c-lightning-rest plugin, you can configure Core Lightning with `disable-plugin=clnrest.py` option
42-
to avoid any conflict with this one. Of course, you could use this one instead!
41+
Note: if you have the older c-lightning-REST plugin, you can configure Core Lightning with `disable-plugin=clnrest.py`
42+
option to avoid confusion with this one. You can also run both plugins simultaneously till all your applications
43+
are not migrated to `clnrest`.
4344

4445

4546
## Configuration
4647

47-
If `rest-port` is not specified, the plugin will disable itself.
48+
If `clnrest-port` is not specified, the plugin will disable itself.
4849

49-
- --rest-port: Sets the REST server port to listen to (3010 is common)
50+
- --clnrest-port: Sets the REST server port to listen to (3010 is common)
5051

51-
- --rest-protocol: Specifies the REST server protocol. Default is HTTPS.
52+
- --clnrest-protocol: Specifies the REST server protocol. Default is HTTPS.
5253

53-
- --rest-host: Defines the REST server host. Default is 127.0.0.1.
54+
- --clnrest-host: Defines the REST server host. Default is 127.0.0.1.
5455

55-
- --rest-certs: Defines the path for HTTPS cert & key. Default path is same as RPC file path to utilize gRPC's client certificate.
56+
- --clnrest-certs: Defines the path for HTTPS cert & key. Default path is same as RPC file path to utilize gRPC's client certificate.
5657
If it is missing at the configured location, new identity will be generated.
5758

58-
- --rest-csp: Creates a whitelist of trusted content sources that can run on a webpage and helps mitigate the risk of attacks.
59+
- --clnrest-csp: Creates a whitelist of trusted content sources that can run on a webpage and helps mitigate the risk of attacks.
5960
Default CSP:
6061
`default-src 'self'; font-src 'self'; img-src 'self' data:; frame-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline';`
6162
Example CSP:
62-
`rest-csp=default-src 'self'; font-src 'self'; img-src 'self'; frame-src 'self'; style-src 'self'; script-src 'self';`.
63+
`clnrest-csp=default-src 'self'; font-src 'self'; img-src 'self'; frame-src 'self'; style-src 'self'; script-src 'self';`.
6364

64-
- --rest-cors-origins: Define multiple origins which are allowed to share resources on web pages to a domain different from the
65+
- --clnrest-cors-origins: Define multiple origins which are allowed to share resources on web pages to a domain different from the
6566
one that served the web page. Default is `*` which allows all origins. Example to define multiple origins:
6667

6768
```
68-
rest-cors-origins=https://localhost:5500
69-
rest-cors-origins=http://192.168.1.50:3030
70-
rest-cors-origins=https?://127.0.0.1:([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])
69+
clnrest-cors-origins=https://localhost:5500
70+
clnrest-cors-origins=http://192.168.1.50:3030
71+
clnrest-cors-origins=https?://127.0.0.1:([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])
7172
7273
```
7374

doc/lightningd-config.5.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -632,27 +632,27 @@ all DNS lookups, to avoid leaking information.
632632
Set a Tor control password, which may be needed for *autotor:* to
633633
authenticate to the Tor control port.
634634

635-
* **rest-port**=*PORT* [plugin `clnrest.py`]
635+
* **clnrest-port**=*PORT* [plugin `clnrest.py`]
636636

637637
Sets the REST server port to listen to (3010 is common). If this is not specified, the clnrest.py plugin will be disabled.
638638

639-
* **rest-protocol**=*PROTOCOL* [plugin `clnrest.py`]
639+
* **clnrest-protocol**=*PROTOCOL* [plugin `clnrest.py`]
640640

641641
Specifies the REST server protocol. Default is HTTPS.
642642

643-
* **rest-host**=*HOST* [plugin `clnrest.py`]
643+
* **clnrest-host**=*HOST* [plugin `clnrest.py`]
644644

645645
Defines the REST server host. Default is 127.0.0.1.
646646

647-
* **rest-certs**=*PATH* [plugin `clnrest.py`]
647+
* **clnrest-certs**=*PATH* [plugin `clnrest.py`]
648648

649649
Defines the path for HTTPS cert & key. Default path is same as RPC file path to utilize gRPC's client certificate. If it is missing at the configured location, new identity (`client.pem` and `client-key.pem`) will be generated.
650650

651-
* **rest-cors-origins**=*CORSORIGINS* [plugin `clnrest.py`]
651+
* **clnrest-cors-origins**=*CORSORIGINS* [plugin `clnrest.py`]
652652

653653
Define multiple origins which are allowed to share resources on web pages to a domain different from the one that served the web page. Default is `*` which allows all origins.
654654

655-
* **rest-csp**=*CSPOLICY* [plugin `clnrest.py`]
655+
* **clnrest-csp**=*CSPOLICY* [plugin `clnrest.py`]
656656

657657
Creates a whitelist of trusted content sources that can run on a webpage and helps mitigate the risk of attacks. Default CSP is `default-src 'self'; font-src 'self'; img-src 'self' data:; frame-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline';`.
658658

plugins/clnrest/clnrest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ def add_csp_headers(response):
119119
response.headers['Content-Security-Policy'] = REST_CSP.replace('\\', '').replace("[\"", '').replace("\"]", '')
120120
return response
121121
except Exception as err:
122-
plugin.log(f"Error from rest-csp config: {err}", "info")
122+
plugin.log(f"Error from clnrest-csp config: {err}", "info")
123123

124124

125125
def set_application_options(plugin):

plugins/clnrest/utilities/rpc_plugin.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33

44
plugin = Plugin(autopatch=False)
55

6-
plugin.add_option(name="rest-certs", default=os.getcwd(), description="Path for certificates (for https)", opt_type="string", deprecated=False)
7-
plugin.add_option(name="rest-protocol", default="https", description="REST server protocol", opt_type="string", deprecated=False)
8-
plugin.add_option(name="rest-host", default="127.0.0.1", description="REST server host", opt_type="string", deprecated=False)
9-
plugin.add_option(name="rest-port", default=None, description="REST server port to listen", opt_type="int", deprecated=False)
10-
plugin.add_option(name="rest-cors-origins", default="*", description="Cross origin resource sharing origins", opt_type="string", deprecated=False, multi=True)
11-
plugin.add_option(name="rest-csp", default="default-src 'self'; font-src 'self'; img-src 'self' data:; frame-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline';", description="Content security policy (CSP) for the server", opt_type="string", deprecated=False, multi=False)
6+
plugin.add_option(name="clnrest-certs", default=os.getcwd(), description="Path for certificates (for https)", opt_type="string", deprecated=False)
7+
plugin.add_option(name="clnrest-protocol", default="https", description="REST server protocol", opt_type="string", deprecated=False)
8+
plugin.add_option(name="clnrest-host", default="127.0.0.1", description="REST server host", opt_type="string", deprecated=False)
9+
plugin.add_option(name="clnrest-port", default=None, description="REST server port to listen", opt_type="int", deprecated=False)
10+
plugin.add_option(name="clnrest-cors-origins", default="*", description="Cross origin resource sharing origins", opt_type="string", deprecated=False, multi=True)
11+
plugin.add_option(name="clnrest-csp", default="default-src 'self'; font-src 'self'; img-src 'self' data:; frame-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline';", description="Content security policy (CSP) for the server", opt_type="string", deprecated=False, multi=False)

plugins/clnrest/utilities/shared.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,25 +39,25 @@ def validate_port(port):
3939

4040

4141
def set_config(options):
42-
if 'rest-port' not in options:
43-
return "`rest-port` option is not configured"
42+
if 'clnrest-port' not in options:
43+
return "`clnrest-port` option is not configured"
4444
global CERTS_PATH, REST_PROTOCOL, REST_HOST, REST_PORT, REST_CSP, REST_CORS_ORIGINS
4545

46-
REST_PORT = int(options["rest-port"])
46+
REST_PORT = int(options["clnrest-port"])
4747
if validate_port(REST_PORT) is False:
48-
return f"`rest-port` {REST_PORT}, should be a valid available port between 1024 and 65535."
48+
return f"`clnrest-port` {REST_PORT}, should be a valid available port between 1024 and 65535."
4949

50-
REST_HOST = str(options["rest-host"])
50+
REST_HOST = str(options["clnrest-host"])
5151
if REST_HOST != "localhost" and validate_ip4(REST_HOST) is False and validate_ip6(REST_HOST) is False:
52-
return f"`rest-host` should be a valid IP."
52+
return f"`clnrest-host` should be a valid IP."
5353

54-
REST_PROTOCOL = str(options["rest-protocol"])
54+
REST_PROTOCOL = str(options["clnrest-protocol"])
5555
if REST_PROTOCOL != "http" and REST_PROTOCOL != "https":
56-
return f"`rest-protocol` can either be http or https."
56+
return f"`clnrest-protocol` can either be http or https."
5757

58-
CERTS_PATH = str(options["rest-certs"])
59-
REST_CSP = str(options["rest-csp"])
60-
cors_origins = options["rest-cors-origins"]
58+
CERTS_PATH = str(options["clnrest-certs"])
59+
REST_CSP = str(options["clnrest-csp"])
60+
cors_origins = options["clnrest-cors-origins"]
6161
REST_CORS_ORIGINS.clear()
6262
for origin in cors_origins:
6363
REST_CORS_ORIGINS.append(str(origin))

tests/test_clnrest.py

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -24,22 +24,22 @@ def http_session_with_retry():
2424

2525

2626
def test_clnrest_no_auto_start(node_factory):
27-
"""Ensure that we do not start clnrest unless a `rest-port` is configured."""
27+
"""Ensure that we do not start clnrest unless a `clnrest-port` is configured."""
2828
l1 = node_factory.get_node()
2929
# This might happen really early!
3030
l1.daemon.logsearch_start = 0
3131
assert [p for p in l1.rpc.plugin('list')['plugins'] if 'clnrest.py' in p['name']] == []
32-
assert l1.daemon.is_in_log(r'plugin-clnrest.py: Killing plugin: disabled itself at init: `rest-port` option is not configured')
32+
assert l1.daemon.is_in_log(r'plugin-clnrest.py: Killing plugin: disabled itself at init: `clnrest-port` option is not configured')
3333

3434

3535
def test_clnrest_self_signed_certificates(node_factory):
36-
"""Test that self-signed certificates have `rest-host` IP in Subject Alternative Name."""
36+
"""Test that self-signed certificates have `clnrest-host` IP in Subject Alternative Name."""
3737
rest_port = str(reserve())
3838
rest_host = '127.0.0.1'
3939
base_url = f'https://{rest_host}:{rest_port}'
4040
l1 = node_factory.get_node(options={'disable-plugin': 'cln-grpc',
41-
'rest-port': rest_port,
42-
'rest-host': rest_host})
41+
'clnrest-port': rest_port,
42+
'clnrest-host': rest_host})
4343
# This might happen really early!
4444
l1.daemon.logsearch_start = 0
4545
l1.daemon.wait_for_log(r'plugin-clnrest.py: REST server running at ' + base_url)
@@ -54,12 +54,12 @@ def test_clnrest_self_signed_certificates(node_factory):
5454
def test_clnrest_uses_grpc_plugin_certificates(node_factory):
5555
"""Test that clnrest reuses `cln-grpc` plugin certificates if available.
5656
Defaults:
57-
- rest-protocol: https
57+
- clnrest-protocol: https
5858
"""
5959
rest_host = 'localhost'
6060
grpc_port = str(reserve())
6161
rest_port = str(reserve())
62-
l1 = node_factory.get_node(options={'grpc-port': grpc_port, 'rest-host': rest_host, 'rest-port': rest_port})
62+
l1 = node_factory.get_node(options={'grpc-port': grpc_port, 'clnrest-host': rest_host, 'clnrest-port': rest_port})
6363
base_url = f'https://{rest_host}:{rest_port}'
6464
# This might happen really early!
6565
l1.daemon.logsearch_start = 0
@@ -73,21 +73,21 @@ def test_clnrest_uses_grpc_plugin_certificates(node_factory):
7373

7474
def test_clnrest_generate_certificate(node_factory):
7575
"""Test whether we correctly generate the certificates."""
76-
# when `rest-protocol` is `http`, certs are not generated at `rest-certs` path
76+
# when `clnrest-protocol` is `http`, certs are not generated at `clnrest-certs` path
7777
rest_port = str(reserve())
7878
rest_protocol = 'http'
7979
rest_certs = node_factory.directory + '/clnrest-certs'
80-
l1 = node_factory.get_node(options={'rest-port': rest_port,
81-
'rest-protocol': rest_protocol,
82-
'rest-certs': rest_certs})
80+
l1 = node_factory.get_node(options={'clnrest-port': rest_port,
81+
'clnrest-protocol': rest_protocol,
82+
'clnrest-certs': rest_certs})
8383

8484
assert not Path(rest_certs).exists()
8585

8686
# node l1 not started
8787
rest_port = str(reserve())
8888
rest_certs = node_factory.directory + '/clnrest-certs'
89-
l1 = node_factory.get_node(options={'rest-port': rest_port,
90-
'rest-certs': rest_certs}, start=False)
89+
l1 = node_factory.get_node(options={'clnrest-port': rest_port,
90+
'clnrest-certs': rest_certs}, start=False)
9191
rest_certs_path = Path(rest_certs)
9292
files = [rest_certs_path / f for f in [
9393
'ca.pem',
@@ -131,7 +131,7 @@ def start_node_with_clnrest(node_factory):
131131
- the certificate authority path used for the self-signed certificates."""
132132
rest_port = str(reserve())
133133
rest_certs = node_factory.directory + '/clnrest-certs'
134-
l1 = node_factory.get_node(options={'rest-port': rest_port, 'rest-certs': rest_certs})
134+
l1 = node_factory.get_node(options={'clnrest-port': rest_port, 'clnrest-certs': rest_certs})
135135
base_url = 'https://127.0.0.1:' + rest_port
136136
# This might happen really early!
137137
l1.daemon.logsearch_start = 0
@@ -374,49 +374,49 @@ def test_clnrest_websocket_rune_no_listnotifications(node_factory):
374374

375375

376376
def test_clnrest_options(node_factory):
377-
"""Test startup options `rest-host`, `rest-protocol` and `rest-certs`."""
377+
"""Test startup options `clnrest-host`, `clnrest-protocol` and `clnrest-certs`."""
378378
# with invalid port
379379
rest_port = 1000
380-
l1 = node_factory.get_node(options={'rest-port': rest_port})
381-
assert l1.daemon.is_in_log(f'plugin-clnrest.py: Killing plugin: disabled itself at init: `rest-port` {rest_port}, should be a valid available port between 1024 and 65535.')
380+
l1 = node_factory.get_node(options={'clnrest-port': rest_port})
381+
assert l1.daemon.is_in_log(f'plugin-clnrest.py: Killing plugin: disabled itself at init: `clnrest-port` {rest_port}, should be a valid available port between 1024 and 65535.')
382382

383383
# with invalid protocol
384384
rest_port = str(reserve())
385385
rest_protocol = 'htttps'
386-
l1 = node_factory.get_node(options={'rest-port': rest_port,
387-
'rest-protocol': rest_protocol})
388-
assert l1.daemon.is_in_log(r'plugin-clnrest.py: Killing plugin: disabled itself at init: `rest-protocol` can either be http or https.')
386+
l1 = node_factory.get_node(options={'clnrest-port': rest_port,
387+
'clnrest-protocol': rest_protocol})
388+
assert l1.daemon.is_in_log(r'plugin-clnrest.py: Killing plugin: disabled itself at init: `clnrest-protocol` can either be http or https.')
389389

390390
# with invalid host
391391
rest_port = str(reserve())
392392
rest_host = '127.0.0.12.15'
393-
l1 = node_factory.get_node(options={'rest-port': rest_port,
394-
'rest-host': rest_host})
395-
assert l1.daemon.is_in_log(r'plugin-clnrest.py: Killing plugin: disabled itself at init: `rest-host` should be a valid IP.')
393+
l1 = node_factory.get_node(options={'clnrest-port': rest_port,
394+
'clnrest-host': rest_host})
395+
assert l1.daemon.is_in_log(r'plugin-clnrest.py: Killing plugin: disabled itself at init: `clnrest-host` should be a valid IP.')
396396

397397

398398
def test_clnrest_http_headers(node_factory):
399-
"""Test HTTP headers set with `rest-csp` and `rest-cors-origins` options."""
399+
"""Test HTTP headers set with `clnrest-csp` and `clnrest-cors-origins` options."""
400400
# start a node with clnrest
401401
l1, base_url, ca_cert = start_node_with_clnrest(node_factory)
402402
http_session = http_session_with_retry()
403403

404-
# Default values for `rest-csp` and `rest-cors-origins` options
404+
# Default values for `clnrest-csp` and `clnrest-cors-origins` options
405405
response = http_session.get(base_url + '/v1/list-methods', verify=ca_cert)
406406
assert response.headers['Content-Security-Policy'] == "default-src 'self'; font-src 'self'; img-src 'self' data:; frame-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline';"
407407
assert response.headers['Access-Control-Allow-Origin'] == '*'
408408
# This might happen really early!
409409
l1.daemon.logsearch_start = 0
410410
l1.daemon.wait_for_log(f'plugin-clnrest.py: REST server running at {base_url}')
411411

412-
# Custom values for `rest-csp` and `rest-cors-origins` options
412+
# Custom values for `clnrest-csp` and `clnrest-cors-origins` options
413413
rest_port = str(reserve())
414414
rest_certs = node_factory.directory + '/clnrest-certs'
415415
l2 = node_factory.get_node(options={
416-
'rest-port': rest_port,
417-
'rest-certs': rest_certs,
418-
'rest-csp': "default-src 'self'; font-src 'self'; img-src 'self'; frame-src 'self'; style-src 'self'; script-src 'self';",
419-
'rest-cors-origins': ['https://localhost:5500', 'http://192.168.1.30:3030', 'http://192.168.1.10:1010']
416+
'clnrest-port': rest_port,
417+
'clnrest-certs': rest_certs,
418+
'clnrest-csp': "default-src 'self'; font-src 'self'; img-src 'self'; frame-src 'self'; style-src 'self'; script-src 'self';",
419+
'clnrest-cors-origins': ['https://localhost:5500', 'http://192.168.1.30:3030', 'http://192.168.1.10:1010']
420420
})
421421
base_url = 'https://127.0.0.1:' + rest_port
422422
# This might happen really early!

0 commit comments

Comments
 (0)