net-smtp icon indicating copy to clipboard operation
net-smtp copied to clipboard

Use a shared SASL implementation

Open nevans opened this issue 2 years ago • 0 comments

Builds on the following other PRs:

  • #68
    • #63
    • #64
    • #71
      • ~#65~
      • #72
        • #66
      • #73
        • #67

As currently written, this also depends on the following net-imap PRs:

  • ruby/net-imap#183
  • ruby/net-imap#187
  • ruby/net-imap#195

After those PRs are applied, this PR creates an adapter that is compatible with Authenticator and #authenticate and registers it as a generic default for mechanisms that haven't otherwise been added (as subclasses of Authenticator). This adapter then delegates to net-imap's SASL implementation. Every other mechanism supported by net-imap v0.4.1 is added here:

  • ANONYMOUS
  • DIGEST-MD5 (deprecated)
  • EXTERNAL
  • OAUTHBEARER
  • SCRAM-SHA-1 and SCRAM-SHA-256
  • XOAUTH

TODO: Ideally, net-smtp and net-imap should both depend on a shared sasl or net-sasl gem, rather than keep the SASL implementation inside one or the other. See https://github.com/ruby/net-imap/issues/23.

In this PR, the current Net::SMTP::Authenticator implementation is still used by the PLAIN, LOGIN, and CRAM-MD5 mechanisms. PR #70 removes the current authenticators are replaces them with this.

Related issues:

  • Fixes #36
  • Fixes #46

nevans avatar Oct 09 '23 22:10 nevans

Scratch that, let me try and implement this again and see what happens.

rawkode avatar Apr 02 '24 09:04 rawkode

Hi @Byron,

I've updated GitSync to (which Comtrya uses) to use this for clone_repository()

    fn clone_repository(&self) -> Result<(), errors::GitSyncError> {
        info!("Attempting to clone {} to {:?}", self.repo, self.dir,);

        unsafe {
            match gix::interrupt::init_handler(1, || {}) {
                Ok(_) => (),
                Err(error) => {
                    return Err(GitSyncError::GenericError { error });
                }
            };
        }

        if !self.dir.exists() {
            match std::fs::create_dir_all(&self.dir) {
                Ok(_) => {}
                Err(error) => {
                    return Err(GitSyncError::GenericError { error });
                }
            }
        }

        let url = match gix::url::parse(self.repo.as_str().into()) {
            Ok(url) => url,
            Err(error) => {
                return Err(GitSyncError::GixParseError { error });
            }
        };

        let mut prepare_clone = match gix::prepare_clone(url, &self.dir) {
            Ok(prepared_fetch) => prepared_fetch,
            Err(error) => {
                return Err(GitSyncError::GixCloneError { error });
            }
        };

        let (mut prepare_checkout, _) = match prepare_clone
            .fetch_then_checkout(gix::progress::Discard, &gix::interrupt::IS_INTERRUPTED)
        {
            Ok(checkout) => checkout,
            Err(error) => {
                return Err(GitSyncError::GixCloneFetchError { error });
            }
        };

        match prepare_checkout
            .main_worktree(gix::progress::Discard, &gix::interrupt::IS_INTERRUPTED)
        {
            Ok(repository) => repository,
            Err(error) => {
                return Err(GitSyncError::GixCloneCheckoutError { error });
            }
        };

        Ok(())
    }

and this works well.

We also have a sync function, which is using gix::open(); but I can't work out how to fetch_then_checkout on an existing repository.

I've also tried just using clone_repository with the dir being the existing checkout, but it doesn't seem like HEAD is updated.

Any advice?

rawkode avatar Apr 02 '24 11:04 rawkode

Draft PR

https://github.com/rawkode/gitsync/pull/4

rawkode avatar Apr 02 '24 11:04 rawkode

Thanks for trying it out!

and this works well.

Is the question-mark operation ? forbidden in your codebase? I am pretty sure clippy would take offence in not using it -error-handling seems unnecessarily verbose. Since it's an application, I'd recommend anyhow as well.

We also have a sync function, which is using gix::open(); but I can't work out how to fetch_then_checkout on an existing repository.

One cannot yet checkout into an existing repository, and I'd hope it refuses to do so into an existing non-empty directory as it would bluntly overwrite everything. It's only possible to checkout the initial clone.

It will take a while until git reset/checkout are possible, but this PR and it's follow-ups will lead there.

Byron avatar Apr 02 '24 11:04 Byron