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

feat: initial work on supporting dbus-daemon XML configuration files #146

Closed
wants to merge 6 commits into from

Conversation

jokeyrhyme
Copy link
Contributor

@jokeyrhyme jokeyrhyme commented Oct 6, 2024

Howdie

I figured I knew just enough Rust to work on this whilst learning how to handle XML in Rust, and thought it'd be just tedious enough that nobody else had started this

Then I realised someone has indeed started this over in #23 , haha!

Anyhow, this uses quick-xml, too, but this PR version models just a little bit more in serde, so it ends up being roughly equivalent with ~20% fewer lines of code (but probably takes slightly longer to compile), but the other PR does do a bit more modeling of what's possible in the <listen /> elements

I do have an integration test in this PR that runs the XML deserializer against all the real XML configuration files that are found, and it does pass on my system which is promising (although the hard-coded test cases in the other PR are probably the better bet in the long term)

You probably won't end up using this, but perhaps if the other folks take a look there's something salvageable from this attempt

If you do like the look of this, just let me know what blockers I need to fix up to get it into a merge-worthy state

<3

src/configuration.rs Outdated Show resolved Hide resolved
src/configuration.rs Outdated Show resolved Hide resolved
@zeenix
Copy link
Collaborator

zeenix commented Oct 7, 2024

Anyhow, this uses quick-xml, too, but this PR version models just a little bit more in serde, so it ends up being roughly equivalent with ~20% fewer lines of code (but probably takes slightly longer to compile), but the other PR does do a bit more modeling of what's possible in the <listen /> elements

We probably want to mix combine the best of both. In terms of tests, I like the approach in #23, so the tests are very standalone and cross-platform even. @elmarco any chance, you can take parts from this PR to yours when you rebase and revive it?


@jokeyrhyme btw in anticipation of future contributions from you, I'd like to refer to you our contribution guidelines. The emojis are optional for flyby commits but please keep the commits atomic (in the sense that they bring one specific logical change, regardless of the size and when you wrote the code). #23 was done before we started using emoji prefixes in commits but atomic commits rule is something me and @elmarco have followed for almost 2 decades now. :)


#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
#[serde(default)]
pub(super) struct RawConfiguration {
Copy link
Collaborator

Choose a reason for hiding this comment

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

It's under raw mod, so Raw prefixes in the names are unnecessary. If your'e coming from a C background, I know from my personal experience, that this is one habit that's hard to get rid of. :)

Copy link
Collaborator

@zeenix zeenix Oct 7, 2024

Choose a reason for hiding this comment

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

Some more stuff:

  • Instead of pub(super) everywhere, you can just have them pub` and then from the supermodule, you keep the mod private and that achieves the same.
  • It would be good to have some docs for each item ideally but one thing that definitely need some docs is what the raw API is all about (through a module-level documentation comment).

@zeenix
Copy link
Collaborator

zeenix commented Oct 7, 2024

  • It would be good to have some docs for each item ideally but one thing that definitely need some docs is what the raw API is all about (through a module-level documentation comment).

I'm actually confused by this raw separation. I think we should only need 1 representation and (de)serialization should make it happen. One can always manually impl serde::{Serialize, Deserialize} where needed.

@elmarco
Copy link
Contributor

elmarco commented Oct 7, 2024

@zeenix & @jokeyrhyme I plan to review this MR when I get to rebase #23. Thanks for the work!

@zeenix
Copy link
Collaborator

zeenix commented Oct 7, 2024

@zeenix & @jokeyrhyme I plan to review this MR when I get to rebase #23. Thanks for the work!

Great, thanks!

Btw, please keep in mind the description of the policy issue (#79) here. We should ignore (perhaps with a warning) any xml fragments that we don't want to implement and not create any types/code for parsing those bits. Apart from the example in #79, we should also not bother with limit elements. We should just hardcode their values in the code. I've not even known anyone to modify those values in config.

On the bright side, this also makes this task easier.

@zeenix
Copy link
Collaborator

zeenix commented Oct 7, 2024

Apart from the example in #79, we should also not bother with limit elements. We should just hardcode their values in the code. I've not even known anyone to modify those values in config.

I created #148 for these.

@jokeyrhyme
Copy link
Contributor Author

jokeyrhyme commented Oct 7, 2024

I'm actually confused by this raw separation.

This is my first time playing with XML and serde, and it seemed necessary to have extra structs in a few places: https://docs.rs/quick-xml/latest/quick_xml/de/index.html#element-lists

So, the Raw stuff had these extra structs in place to guide serde as necessary, and then the main Configuration was a more convenient abstraction for the server code to work with

But yeah, I guess a custom Deserializer would be a more idiomatic way to implement this

@zeenix
Copy link
Collaborator

zeenix commented Oct 7, 2024

@jokeyrhyme Thanks for explaining.

But yeah, I guess a custom Deserializer would be a more idiomatic way to implement this

Right. Also as the docs you pointed to say, you might be able to make use of serde-query.

@jokeyrhyme
Copy link
Contributor Author

I did mean to revisit this PR this weekend but I've been on baby duty :)

I'll carefully review your contribution guidelines, and maybe start a new PR that starts with git cherry-pick-ing XML work from the other PR

If @zeenix and @elmarco are still okay with me taking this on

@jokeyrhyme
Copy link
Contributor Author

Regarding features we don't want, I also noticed that dbus-broker will warn that it doesn't implement eavesdrop policies, so maybe one planning/research exercise could be to run every option described in the dbus-daemon documentation through dbus-broker to see such warnings (or just read its code)

I'm guessing we'd probably want the parser to return these warnings as data rather than eprintln!() them out directly?

@jokeyrhyme
Copy link
Contributor Author

https://github.com/search?q=repo%3Abus1%2Fdbus-broker%20deprecated&type=code

                if (cnode->type == CONFIG_NODE_DENY && cnode->allow_deny.send_requested_reply == UTIL_TRISTATE_YES)
                        fprintf(stderr, "Policy to deny expected replies in %s +%lu: Explicit policies on replies and errors are deprecated and ignored\n",
                                cnode->file, cnode->lineno);
                else if (cnode->type == CONFIG_NODE_ALLOW && cnode->allow_deny.send_requested_reply == UTIL_TRISTATE_NO)
                        fprintf(stderr, "Policy to allow unexpected replies in %s +%lu: Explicit policies on replies and errors are deprecated and ignored\n",
                                cnode->file, cnode->lineno);
        if (cnode->allow_deny.eavesdrop == UTIL_TRISTATE_YES) {
                if (cnode->type == CONFIG_NODE_ALLOW)
                        /* Ignore the attribute, but keep the rule, it also applies when not eavesdropping. */
                        fprintf(stderr, "Policy to allow eavesdropping in %s +%lu: Eavesdropping is deprecated and ignored\n",
                                cnode->file, cnode->lineno);
                else if (cnode->type == CONFIG_NODE_DENY)
                        /* The rule applies only when eavesdropping, drop it. */
                        return 0;
        }
                if (cnode->type == CONFIG_NODE_DENY && cnode->allow_deny.recv_requested_reply == UTIL_TRISTATE_YES)
                        fprintf(stderr, "Policy to deny expected replies in %s +%lu: Explicit policies on replies and errors are deprecated and ignored\n",
                                cnode->file, cnode->lineno);
                else if (cnode->type == CONFIG_NODE_ALLOW && cnode->allow_deny.recv_requested_reply == UTIL_TRISTATE_NO)
                        fprintf(stderr, "Policy to allow unexpected replies in %s +%lu: Explicit policies on replies and errors are deprecated and ignored\n",
                                cnode->file, cnode->lineno);
        if (cnode->allow_deny.eavesdrop == UTIL_TRISTATE_YES) {
                if (cnode->type == CONFIG_NODE_ALLOW)
                        /* Ignore the attribute, but keep the rule, it also applies when not eavesdropping. */
                        fprintf(stderr, "Policy to allow eavesdropping in %s +%lu: Eavesdropping is deprecated and ignored\n",
                                cnode->file, cnode->lineno);
                else if (cnode->type == CONFIG_NODE_DENY)
                        /* The rule applies only when eavesdropping, drop it. */
                        return 0;
        }
                if (i_cnode->type == CONFIG_NODE_POLICY &&
                    i_cnode->policy.context  == CONFIG_POLICY_AT_CONSOLE) {
                        fprintf(stderr, "Deprecated policy context in %s +%lu. The 'at_console' context is deprecated and will be ignored in the future.\n",
                                i_cnode->file, i_cnode->lineno);
                }

@jokeyrhyme
Copy link
Contributor Author

Hmmm, my free time this weekend seems to have evaporated

I'm going to close this to signal clearly that I probably won't continue this in the foreseeable future, but if I get a good overlap of inspiration and free time soon I can always start that fresh branch, or even pick up some other feature that isn't already being tackled :)

@jokeyrhyme jokeyrhyme closed this Oct 13, 2024
@zeenix
Copy link
Collaborator

zeenix commented Oct 15, 2024

I can always start that fresh branch

Sure but then you can force to the same branch here and reuse the PR. Creating multiple PRs to achieve the same, only creates unnecessary noise in the GitHub records IMO.

So please do that, if you manage to get back to this. 🙏

@jokeyrhyme
Copy link
Contributor Author

Hmmm, I've force-pushed to the same branch in my fork, and now the "Reopen and comment" button is disabled with "The branch was force-pushed or recreated" :S

@zeenix
Copy link
Collaborator

zeenix commented Oct 21, 2024

I've force-pushed to the same branch in my fork, and now the "Reopen and comment" button is disabled with "The branch was force-pushed or recreated" :S

Ughh.. It's probably because you closed the PR. The Reopen and comment is disabled button is disabled for me too now. It's ok, create a new PR this time but please don't close PRs in the future. I can do that when/if needed. :)

@jokeyrhyme jokeyrhyme mentioned this pull request Oct 27, 2024
41 tasks
jokeyrhyme added a commit to jokeyrhyme/busd that referenced this pull request Nov 12, 2024
jokeyrhyme added a commit to jokeyrhyme/busd that referenced this pull request Nov 19, 2024
jokeyrhyme added a commit to jokeyrhyme/busd that referenced this pull request Nov 19, 2024
jokeyrhyme added a commit to jokeyrhyme/busd that referenced this pull request Nov 27, 2024
zeenix pushed a commit to jokeyrhyme/busd that referenced this pull request Nov 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants