checkrune: make nodeid and method optional.

nodeid is only useful when we know the peer we're talking to (e.g. commando).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
No-schema-diff-check: We're simply making optional, not deprecating!
This commit is contained in:
Rusty Russell
2023-09-12 10:22:44 +09:30
parent bbb3459d5e
commit bb38f83b88
4 changed files with 60 additions and 13 deletions

View File

@@ -4,7 +4,7 @@ lightning-checkrune -- Command to Validate Rune
SYNOPSIS
--------
**checkrune** *rune* *nodeid* *method* [*params*]
**checkrune** *rune* [*nodeid*] [*method*] [*params*]
DESCRIPTION
-----------

View File

@@ -3,9 +3,7 @@
"type": "object",
"additionalProperties": false,
"required": [
"nodeid",
"rune",
"method"
"rune"
],
"added": "v23.08",
"properties": {
@@ -15,11 +13,11 @@
},
"nodeid": {
"type": "string",
"description": "node id of your node"
"description": "node id of requesting node *(required until v23.11)*"
},
"method": {
"type": "string",
"description": "method for which rune needs to be validated"
"description": "method for which rune needs to be validated *(required until v23.11)*"
},
"params": {
"oneOf": [

View File

@@ -674,11 +674,17 @@ static const char *check_condition(const tal_t *ctx,
if (streq(alt->fieldname, "time")) {
return rune_alt_single_int(ctx, alt, time_now().ts.tv_sec);
} else if (streq(alt->fieldname, "id")) {
const char *id = node_id_to_hexstr(tmpctx, cinfo->peer);
return rune_alt_single_str(ctx, alt, id, strlen(id));
if (cinfo->peer) {
const char *id = node_id_to_hexstr(tmpctx, cinfo->peer);
return rune_alt_single_str(ctx, alt, id, strlen(id));
}
return rune_alt_single_missing(ctx, alt);
} else if (streq(alt->fieldname, "method")) {
return rune_alt_single_str(ctx, alt,
cinfo->method, strlen(cinfo->method));
if (cinfo->method) {
return rune_alt_single_str(ctx, alt,
cinfo->method, strlen(cinfo->method));
}
return rune_alt_single_missing(ctx, alt);
} else if (streq(alt->fieldname, "pnum")) {
return rune_alt_single_int(ctx, alt, (cinfo && cinfo->params) ? cinfo->params->size : 0);
} else if (streq(alt->fieldname, "rate")) {
@@ -748,8 +754,8 @@ static struct command_result *json_checkrune(struct command *cmd,
if (!param(cmd, buffer, params,
p_req("rune", param_rune, &ras),
p_req("nodeid", param_node_id, &nodeid),
p_req("method", param_string, &method),
p_opt("nodeid", param_node_id, &nodeid),
p_opt("method", param_string, &method),
p_opt("params", param_params, &methodparams),
NULL))
return command_param_failed();
@@ -793,6 +799,6 @@ static const struct json_command checkrune_command = {
"checkrune",
"utility",
json_checkrune,
"Checks rune for validity with required {nodeid}, {rune}, {method} and optional {params} and returns {valid: true} or error message"
"Checks rune for validity with required {rune} and optional {nodeid}, {method}, {params} and returns {valid: true} or error message"
};
AUTODATA(json_command, &checkrune_command);

View File

@@ -471,6 +471,49 @@ def test_commando_blacklist_migration(node_factory):
{'start': 9, 'end': 9}]}
def test_missing_method_or_nodeid(node_factory):
"""For v23.11 we realized that nodeid should not be required for checkrune, which means method (which followed it) could not be require either"""
l1 = node_factory.get_node()
rune1 = l1.rpc.createrune(restrictions=[["method=getinfo"]])['rune']
rune2 = l1.rpc.createrune(restrictions=[["id={}".format(l1.info['id'])]])['rune']
rune3 = l1.rpc.createrune(restrictions=[["method!"]])['rune']
rune4 = l1.rpc.createrune(restrictions=[["id!"]])['rune']
# Simple cases with nodeid and method
assert l1.rpc.checkrune(rune=rune1,
nodeid=l1.info['id'],
method='getinfo')['valid'] is True
assert l1.rpc.checkrune(rune=rune2,
nodeid=l1.info['id'],
method='getinfo')['valid'] is True
# No nodeid works for rune1
assert l1.rpc.checkrune(rune=rune1,
method='getinfo')['valid'] is True
# No method works for rune2
assert l1.rpc.checkrune(rune=rune2,
nodeid=l1.info['id'])['valid'] is True
# No method works for rune3
assert l1.rpc.checkrune(rune=rune3,
nodeid=l1.info['id'])['valid'] is True
# No id works for rune4
assert l1.rpc.checkrune(rune=rune4,
method='getinfo')['valid'] is True
# This fails, as method is missing
with pytest.raises(RpcError, match='Not permitted: method not present'):
l1.rpc.checkrune(rune=rune1)
# This fails, as id is missing
with pytest.raises(RpcError, match='Not permitted: id not present'):
l1.rpc.checkrune(rune=rune2)
# This fails, as method is present
with pytest.raises(RpcError, match='Not permitted: method is present'):
l1.rpc.checkrune(rune=rune3, method='getinfo')
# This fails, as id is present
with pytest.raises(RpcError, match='Not permitted: id is present'):
l1.rpc.checkrune(rune=rune4, nodeid=l1.info['id'])
def test_showrune_id(node_factory):
l1 = node_factory.get_node()