public void Authenticate(ImapClient client, NetworkCredential credential, Account account) { if (!client.ServerCapability.Items.Contains("AUTH=XOAUTH")) { return; } if (string.IsNullOrEmpty(account.XOAuthKey)) { // in this case the username is the email address; var email = credential.UserName; var token = new OAuthRequest().WithAnonymousConsumer().WithEndpoint("https://www.google.com/accounts/OAuthGetRequestToken").WithParameter("scope", "https://mail.google.com/") // gmail specific .WithParameter(OAuthParameters.OAuthCallback, "oob").WithParameter("xoauth_displayname", "Crystalbyte Equinox") // xoauth protocol specific .WithSignatureMethod(OAuthSignatureMethods.HmacSha1).Sign().RequestToken(); var authUrl = new OAuthRequest().WithEndpoint("https://www.google.com/accounts/OAuthAuthorizeToken").WithToken(token).GetAuthorizationUri(); Process.Start(authUrl.AbsoluteUri); string verificationCode; using (var form = new OAuthVerificationForm()) { var result = form.ShowDialog(); if (result == DialogResult.Cancel) { return; } verificationCode = form.VerificationCode; } var accessToken = new OAuthRequest().WithAnonymousConsumer().WithEndpoint("https://www.google.com/accounts/OAuthGetAccessToken").WithParameter(OAuthParameters.OAuthVerifier, verificationCode).WithSignatureMethod(OAuthSignatureMethods.HmacSha1).WithToken(token).Sign().RequestToken(); var xOUrl = string.Format("https://mail.google.com/mail/b/{0}/imap/", email); account.XOAuthKey = new OAuthRequest().WithAnonymousConsumer().WithEndpoint(xOUrl).WithSignatureMethod(OAuthSignatureMethods.HmacSha1).WithToken(accessToken).Sign().CreateXOAuthKey(); } client.AuthenticateXOAuth(account.XOAuthKey); }
// needed as a callback if IMAP uses OAuth (not necessary if username/pwd will be provided) public void OAuthHandler(ImapClient client, NetworkCredential credential, ImapAccountInfo account) { if (!client.ServerCapability.Items.Contains("AUTH=XOAUTH")) { return; } if (string.IsNullOrEmpty(account.XOAuthKey)) { // in this case the username is the email address; var email = credential.UserName; var token = new OAuthRequest(). WithAnonymousConsumer(). WithEndpoint(XOAuthRequestTokenEndPoint). WithParameter("scope", XOAuthRequestScope). WithParameter(OAuthParameters.OAuthCallback, "oob"). WithParameter("xoauth_displayname", account.XOAuthAppDisplayName). WithSignatureMethod(OAuthSignatureMethods.HmacSha1). Sign(). RequestToken(); var authUrl = new OAuthRequest(). WithEndpoint(XOAuthAuthTokenEndPoint). WithToken(token). GetAuthorizationUri(); // TODO: change this to (a) redirect the user to the authUri, // (b) get back the verification code in a callback from the authUri // // Probably means we have to break this method into at least two different methods // with some sort of flow between them. // account.XOAuthSecret = GetXOAuthSecret(authUrl); var accessToken = new OAuthRequest(). WithAnonymousConsumer(). WithEndpoint(XOAuthAccessTokenEndPoint). WithParameter(OAuthParameters.OAuthVerifier, account.XOAuthSecret). WithSignatureMethod(OAuthSignatureMethods.HmacSha1). WithToken(token). Sign(). RequestToken(); var authUri = String.Format(XOAuthUrlFormat, email); account.XOAuthKey = new OAuthRequest(). WithAnonymousConsumer(). WithEndpoint(authUri). WithSignatureMethod(OAuthSignatureMethods.HmacSha1). WithToken(accessToken). Sign(). CreateXOAuthKey(); } client.AuthenticateXOAuth(account.XOAuthKey); }