Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test/rpc whitelistdefault test #29858

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

naiyoma
Copy link
Contributor

@naiyoma naiyoma commented Apr 11, 2024

This PR adds tests for rpcwhitelistdefault. The implementation is a continuation of this PR.

Applied suggestions to include the tests in rpc_whitelist.py and to use a single node.

@DrahtBot
Copy link
Contributor

DrahtBot commented Apr 11, 2024

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Code Coverage

For detailed information about the code coverage, see the test coverage report.

Reviews

See the guideline for information on the review process.

Type Reviewers
Concept ACK tdb3, rkrux

If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

Copy link
Contributor

@tdb3 tdb3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for picking this up. Enhancing testing for of the whitelist capability is important to notice regressions associated with this security-minded feature.

Concept ACK. Looks like there could be opportunities to enhance the existing approach taken. Some inline comments were left.

Built and ran all functional tests (all passed).

Checked that the following comments were addressed from PR #17805.

  • The additional tests appear to be integrated into rpc_whitelist.py
  • Tests were organized into different methods
  • num_nodes used is 1
  • Trailing comma included in test_framework.util imports
  • nit: Looks like the original comment @jonatack to include explicit self.setup_clean_chain = False could be added in
    class RPCWhitelistTest(BitcoinTestFramework):
    def set_test_params(self):
  • specififed typo fixed
  • nit: Seems like @jonatack's original comment to create constants for HTTP codes (e.g. HTTP_FORBIDDEN instead of 403) could increase readability, but I'm not particularly partial either way. If it's decided to factor response codes into constants, there probably should be a follow up PR to refactor response codes used in lines in this file predating this PR. Changing the previous instances of 200/403 in this PR would seem to be combining two separate goals (adding new tests, refactoring).

test/functional/rpc_whitelist.py Show resolved Hide resolved
test/functional/rpc_whitelist.py Outdated Show resolved Hide resolved
url = urllib.parse.urlparse(node.url)
headers = {"Authorization": "Basic " + str_to_b64str('{}:{}'.format(user[0], user[3]))}
if password is not None:
auth_value = str_to_b64str('{}:{}'.format(user, password))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be using the argument user as either a string or a list depending on whether or not password was provided, which seems less straightforward than using a consistent type. Unless I'm missing something, the password argument might not be needed at all, since the user list contains the plaintext password. See:

# 0 => Username
# 1 => Password (Hashed)
# 2 => Permissions
# 3 => Password Plaintext
self.users = [
["user1", "50358aa884c841648e0700b073c32b2e$b73e95fff0748cc0b517859d2ca47d9bac1aa78231f3e48fa9222b612bd2083e", "getbestblockhash,getblockcount,", "12345"],

self.log.info("Testing rpcwhitelistdefault=0 with no specified permissions")
with open(os.path.join(get_datadir_path(self.options.tmpdir, 0), "bitcoin.conf"), 'a', encoding='utf8') as f:
f.write("rpcwhitelistdefault=0\n")
f.write("rpcauth=user3:50358aa884c841648e0700b073c32b2e$b73e95fff0748cc0b517859d2ca47d9bac1aa78231f3e48fa9222b612bd2083e\n")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of hardcoding these new rpcauth lines, it might be better to expand the existing users list. This would apply to adjacent methods as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tdb3 I've pushed an update. Adding the users to the existing list is a better approach. However, some tests are now failing because users are whitelisted in the run_test function, while the new tests are designed to test instances when a user is not whitelisted.

I thought clearing the bitcoin.conf file before writing the new test would solve this issue, but it doesn't. Below is a sample output for the bitcoin.conf file in the test_rpcwhitelist_default_0_without_whitelist function:

rpcwhitelistdefault=0
rpcauth=user1:50358aa884c841............................................................
rpcauth=user2:8650ba41296f6..........................................
rpcauth=user3:50358aa8..................................................

Despite having new permissions, users are still whitelisted, and thus this assertion would fail:

assert_equal(200, rpccall(self.nodes[0], user[0], "getbestblockhash", user[3]).status)
Why would this happen? The new tests are still reading permissions from therun_testfunction and not the new bitcoin.conf

@naiyoma
Copy link
Contributor Author

naiyoma commented Apr 17, 2024

Thank you for picking this up. Enhancing testing for of the whitelist capability is important to notice regressions associated with this security-minded feature.

Concept ACK. Looks like there could be opportunities to enhance the existing approach taken. Some inline comments were left.

Built and ran all functional tests (all passed).

Checked that the following comments were addressed from PR #17805.

  • The additional tests appear to be integrated into rpc_whitelist.py
  • Tests were organized into different methods
  • num_nodes used is 1
  • Trailing comma included in test_framework.util imports
  • nit: Looks like the original comment @jonatack to include explicit self.setup_clean_chain = False could be added in
    class RPCWhitelistTest(BitcoinTestFramework):
    def set_test_params(self):
  • specififed typo fixed
  • nit: Seems like @jonatack's original comment to create constants for HTTP codes (e.g. HTTP_FORBIDDEN instead of 403) could increase readability, but I'm not particularly partial either way. If it's decided to factor response codes into constants, there probably should be a follow up PR to refactor response codes used in lines in this file predating this PR. Changing the previous instances of 200/403 in this PR would seem to be combining two separate goals (adding new tests, refactoring).

Thanks a lot for the review,
I didn't implement the requested format for HTTP codes because I wanted to maintain consistency with the already existing tests. However, for readability, I agree with your suggestion. I think the right approach would be to address this in a follow-up PR and also refactor these codes for some of the other tests files as well.

@naiyoma naiyoma force-pushed the test/rpc-whitelistdefault-test branch from 94836b3 to c9358db Compare April 18, 2024 11:48
@DrahtBot
Copy link
Contributor

DrahtBot commented May 3, 2024

🚧 At least one of the CI tasks failed. Make sure to run all tests locally, according to the
documentation.

Possibly this is due to a silent merge conflict (the changes in this pull request being
incompatible with the current code in the target branch). If so, make sure to rebase on the latest
commit of the target branch.

Leave a comment here, if you need help tracking down a confusing failure.

Debug: https://github.com/bitcoin/bitcoin/runs/24559741310

Copy link

@rkrux rkrux left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding these tests, concept ACK.

Seems like this is in progress because there is test failure and a debugger is added.
Added few suggestions for now, will review again when the tests pass.



def test_whitelistdefault_1_with_specified_permission(self):
self.log.info("Testing rpcwhitelistdefault=1 with specified permissions")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with specified
Extra space between

test/functional/rpc_whitelist.py Outdated Show resolved Hide resolved
Comment on lines 102 to 101
self.log.info("Strange test 5")
assert_equal(200, rpccall(self.nodes[0], self.strange_users[4], "getblockcount").status)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: The above test ending here can be put in a separate function so that there are mostly other test functions calls inside run_test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if I should do this in this PR, since the main scope of this one is to cover the whitelistdefault test case.

Comment on lines 181 to 186
permissions = user[2].replace(" ", "").split(",")
i = 0
while i < len(permissions):
if permissions[i] == '':
permissions.pop(i)
i += 1
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This piece of code is duplicated in every test, good candidate for extracting out in a getPermissions(user) function.

test/functional/rpc_whitelist.py Outdated Show resolved Hide resolved

def test_rpcwhitelist_default_0_without_whitelist(self):
self.log.info("Testing rpcwhitelistdefault=0 with no specified permissions")
with open(os.path.join(self.nodes[0].cwd, "bitcoin.conf"), "w", encoding="utf8") as f:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this path different than in other tests below?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea here was to create a separate path for testing whitelisted users and a different path for testing users with no whitelist. The issue is that once a user is whitelisted, clearing the bitcoin.conf and writing new permissions still shows the user as whitelisted. I've provided a detailed explanation here.

@DrahtBot DrahtBot marked this pull request as draft May 13, 2024 07:39
@DrahtBot
Copy link
Contributor

Converted to draft for now. If this is no longer a WIP, you can move it out of draft.

@naiyoma naiyoma force-pushed the test/rpc-whitelistdefault-test branch from e02af85 to c9358db Compare May 14, 2024 21:55
@naiyoma
Copy link
Contributor Author

naiyoma commented May 14, 2024

Thanks for adding these tests, concept ACK.

Seems like this is in progress because there is test failure and a debugger is added. Added few suggestions for now, will review again when the tests pass.

Thanks for the review! The initial tests passed successfully. But I pushed an update that implements the suggested alternative approach from this discussion

Unfortunately, the tests are currently failing with this new approach, as explained here.

While I'm still working on refining the suggested approach, I've decided to revert the PR to its original state (with passing tests) for now. To keep things functional while I continue working on the alternative approach in a separate branch on my fork

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants