-
-
Notifications
You must be signed in to change notification settings - Fork 17
Add combined protocol auth helpers for tooling #595
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
Changes from 3 commits
85b97b9
c26a5a0
0c5d243
0614699
876adc1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -76,6 +76,11 @@ public string? PendingMessagesPath { | |
| /// <summary>Credentials used during authentication.</summary> | ||
| public NetworkCredential? Credential { get; private set; } | ||
|
|
||
| /// <summary> | ||
| /// Effective secure socket options used by the active or most recent connection attempt. | ||
| /// </summary> | ||
| public SecureSocketOptions ActiveSecureSocketOptions => _activeSecureSocketOptions; | ||
|
|
||
| /// <summary> | ||
| /// Optional identity hint used to isolate SMTP connection pooling by credentials. | ||
| /// </summary> | ||
|
|
@@ -524,8 +529,15 @@ public SmtpResult Connect(string server, int port, SecureSocketOptions secureSoc | |
| /// <param name="useSsl">Compatibility switch. Overrides | ||
| /// <paramref name="secureSocketOptions"/> only when set to <c>true</c> and the | ||
| /// option is left as <see cref="SecureSocketOptions.Auto"/>.</param> | ||
| /// <param name="cancellationToken">Cancellation token for the connect operation.</param> | ||
| /// <returns></returns> | ||
| public async Task<SmtpResult> ConnectAsync(string server, int port, SecureSocketOptions secureSocketOptions = SecureSocketOptions.Auto, bool useSsl = false) { | ||
| public async Task<SmtpResult> ConnectAsync( | ||
| string server, | ||
| int port, | ||
| SecureSocketOptions secureSocketOptions = SecureSocketOptions.Auto, | ||
| bool useSsl = false, | ||
| CancellationToken cancellationToken = default) { | ||
| cancellationToken.ThrowIfCancellationRequested(); | ||
| var oldServer = Server; | ||
| var oldPort = Port; | ||
| var oldPoolIdentity = _poolIdentity ?? GetConnectionPoolIdentity(); | ||
|
|
@@ -575,11 +587,13 @@ public async Task<SmtpResult> ConnectAsync(string server, int port, SecureSocket | |
| try { | ||
| if (!Client.IsConnected) | ||
| { | ||
| await Client.ConnectAsync(server, port, effectiveOptions); | ||
| await Client.ConnectAsync(server, port, effectiveOptions, cancellationToken).ConfigureAwait(false); | ||
| } | ||
| _poolIdentity = poolIdentity; | ||
| LogVerbose($"Connected to {server} on {port} port using SSL: {effectiveOptions}"); | ||
| return new SmtpResult(true, EmailAction.Connect, SentTo, SentFrom, server, port, Stopwatch.Elapsed, ""); | ||
| } catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) { | ||
| throw; | ||
| } catch (Exception ex) { | ||
| LogWarning($"Send-EmailMessage - Error during connect: {ex.Message}"); | ||
| LogWarning($"Send-EmailMessage - Possible issue: Port? ({port} was used), Using SSL? ({effectiveOptions}, was used). You can also try 'SkipCertificateValidation' or 'SkipCertificateRevocation'."); | ||
|
|
@@ -590,6 +604,69 @@ public async Task<SmtpResult> ConnectAsync(string server, int port, SecureSocket | |
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Connects and authenticates using the provided user name/secret in one step. | ||
| /// </summary> | ||
| /// <param name="server">SMTP server hostname.</param> | ||
| /// <param name="port">SMTP server port.</param> | ||
| /// <param name="userName">SMTP user name.</param> | ||
| /// <param name="secret">SMTP password or OAuth token.</param> | ||
| /// <param name="secureSocketOptions">TLS/SSL options.</param> | ||
| /// <param name="useSsl">Compatibility SSL switch.</param> | ||
| /// <param name="authMode">Authentication mode.</param> | ||
| /// <param name="cancellationToken">Cancellation token.</param> | ||
| /// <returns>Combined connect/auth outcome.</returns> | ||
| public async Task<SmtpConnectAuthenticateResult> ConnectAndAuthenticateAsync( | ||
| string server, | ||
| int port, | ||
| string userName, | ||
| string secret, | ||
| SecureSocketOptions secureSocketOptions = SecureSocketOptions.Auto, | ||
| bool useSsl = false, | ||
| ProtocolAuthMode authMode = ProtocolAuthMode.Basic, | ||
| CancellationToken cancellationToken = default) { | ||
| cancellationToken.ThrowIfCancellationRequested(); | ||
|
|
||
| var connectResult = await ConnectAsync(server, port, secureSocketOptions, useSsl, cancellationToken).ConfigureAwait(false); | ||
|
||
| if (!connectResult.Status) { | ||
| return new SmtpConnectAuthenticateResult { | ||
| IsSuccess = false, | ||
| SecureSocketOptions = ActiveSecureSocketOptions, | ||
| ErrorCode = "connect_failed", | ||
| Error = connectResult.Error ?? "Connect failed.", | ||
| IsTransient = SmtpValidation.TryValidateServer(server, port, out _) | ||
| }; | ||
| } | ||
|
|
||
| if (DryRun) { | ||
| LogVerbose("Send-EmailMessage - DryRun enabled, skipping authentication."); | ||
| Credential = new NetworkCredential(userName?.Trim() ?? string.Empty, secret ?? string.Empty); | ||
| return new SmtpConnectAuthenticateResult { | ||
| IsSuccess = true, | ||
| SecureSocketOptions = ActiveSecureSocketOptions | ||
| }; | ||
| } | ||
|
|
||
| try { | ||
| await ProtocolAuth.AuthenticateSmtpAsync(Client, userName, secret, authMode, cancellationToken).ConfigureAwait(false); | ||
|
||
| Credential = new NetworkCredential(userName?.Trim() ?? string.Empty, secret ?? string.Empty); | ||
| return new SmtpConnectAuthenticateResult { | ||
| IsSuccess = true, | ||
| SecureSocketOptions = ActiveSecureSocketOptions | ||
| }; | ||
| } catch (OperationCanceledException) { | ||
| throw; | ||
| } catch (Exception ex) { | ||
| return new SmtpConnectAuthenticateResult { | ||
PrzemyslawKlys marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| IsSuccess = false, | ||
| SecureSocketOptions = ActiveSecureSocketOptions, | ||
| ErrorCode = "auth_failed", | ||
| Error = ex.Message, | ||
| IsTransient = false | ||
| }; | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Authenticate using the provided credentials. | ||
| /// </summary> | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.