160 lines
6.1 KiB
C#
160 lines
6.1 KiB
C#
using System;
|
|
using Google.Apis.Auth.OAuth2;
|
|
using Google.Apis.Gmail.v1;
|
|
using Google.Apis.Gmail.v1.Data;
|
|
using Google.Apis.Services;
|
|
using Google.Apis.Util.Store;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Linq;
|
|
using System.Text.RegularExpressions;
|
|
using System.Runtime.Remoting.Messaging;
|
|
|
|
|
|
namespace cdrtool
|
|
{
|
|
|
|
class Gmail
|
|
{
|
|
static string[] Scopes = { GmailService.Scope.GmailReadonly };
|
|
static string ApplicationName = "Gmail API .NET Quickstart";
|
|
|
|
|
|
public static async Task<string> GetMail()
|
|
{
|
|
UserCredential credential;
|
|
string mfa_code = "";
|
|
|
|
using (var stream = new FileStream("credentials.json", FileMode.Open, FileAccess.Read))
|
|
{
|
|
string credPath = "token.json";
|
|
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
|
|
GoogleClientSecrets.FromStream(stream).Secrets,
|
|
Scopes,
|
|
"user",
|
|
CancellationToken.None,
|
|
new FileDataStore(credPath, true));
|
|
//Console.WriteLine("Credential file saved to: " + credPath);
|
|
}
|
|
|
|
// Create Gmail API service.
|
|
var service = new GmailService(new BaseClientService.Initializer()
|
|
{
|
|
HttpClientInitializer = credential,
|
|
ApplicationName = ApplicationName,
|
|
});
|
|
|
|
// Define the timestamp after which we want to find emails (in Unix time format).
|
|
DateTime afterTimestamp = new DateTime(2024, 01, 01); // Use this when you cannot generate a new mfs email to test with
|
|
afterTimestamp = DateTime.Now; // We do this to ensure we get the latest auth email, usually 2-3 seconds after this fires
|
|
long afterUnixTimestamp = ((DateTimeOffset)afterTimestamp).ToUnixTimeSeconds();
|
|
|
|
Logger.Log(1,"Awaiting MFA email (max {0}s)", cdrtool.mfa_delay);
|
|
bool repeat = false;
|
|
int count = cdrtool.mfa_delay;
|
|
|
|
do
|
|
{
|
|
// Fetch emails received after the given timestamp
|
|
var request = service.Users.Messages.List("me");
|
|
request.Q = $"after:{afterUnixTimestamp} from:\"Rogers SIP Portal\" "; //refinement added Sep16 2024
|
|
ListMessagesResponse response = await request.ExecuteAsync();
|
|
var messages = response.Messages?.OrderByDescending(m => m.InternalDate).ToList();
|
|
repeat = (messages == null);
|
|
//Console.WriteLine("Messages count: {0}", (messages != null) ? messages.Count : 0 );
|
|
|
|
if (messages != null && messages.Any())
|
|
{
|
|
//Console.WriteLine("Messages count: {0}",messages.Count);
|
|
|
|
var mostRecentMessage = messages.First();
|
|
Message message = await service.Users.Messages.Get("me", mostRecentMessage.Id).ExecuteAsync();
|
|
|
|
try
|
|
{
|
|
Regex word = new Regex(@".*Your Portal.+([0-9]{6})"); // MFA looking for 6 digit code //refinement added Sep16 2024
|
|
Match m = word.Match(message.Snippet); // .Snippet easily grabs enough plain text to find the MFA code
|
|
|
|
if (m.Success)
|
|
{
|
|
Group g = m.Groups[1];
|
|
//Capture c = g.Captures[0];
|
|
Logger.Log(6, "Regex Match {0} / Group Count {1} / Captures Count {2} / result={3}", m.Success, m.Groups.Count, m.Captures.Count, g.Value);
|
|
int code = Convert.ToInt32(g.Value);
|
|
if ((code >= 0) && (code <= 999999))
|
|
Logger.Log(5, "Code found successfully {0}", code);
|
|
|
|
mfa_code = g.Value;
|
|
repeat = false;
|
|
}
|
|
else
|
|
{
|
|
Logger.Log(1, "No code found in email.");
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Logger.Log(0, "Error parsing Gmail. {0}", e.Message);
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
{
|
|
int incr = 1;
|
|
if (count <= (cdrtool.mfa_delay - 5) ) incr = 5;
|
|
count-= incr;
|
|
System.Threading.Thread.Sleep(1000 * incr);
|
|
Logger.Log(1, "No message found for {0}s", cdrtool.mfa_delay - count);
|
|
}
|
|
|
|
}
|
|
while (repeat && (count > 0) );
|
|
|
|
Logger.Log(0, "Emailed MFA Code : {0}", mfa_code);
|
|
return mfa_code;
|
|
|
|
}
|
|
|
|
|
|
static string GetPlainTextFromMessageParts(IList<MessagePart> parts)
|
|
{
|
|
if (parts == null)
|
|
return string.Empty;
|
|
|
|
foreach (var part in parts)
|
|
{
|
|
//Console.WriteLine("email: type:{0}\nbody:\n{1}", part.MimeType, part.Body.Data);
|
|
if (part.MimeType == "text/plain" && part.Body != null && part.Body.Data != null)
|
|
{
|
|
return Base64UrlDecode(part.Body.Data);
|
|
}
|
|
else if (part.Parts != null)
|
|
{
|
|
string text = GetPlainTextFromMessageParts(part.Parts);
|
|
if (!string.IsNullOrEmpty(text))
|
|
return text;
|
|
}
|
|
}
|
|
|
|
return string.Empty;
|
|
}
|
|
|
|
static string Base64UrlDecode(string input)
|
|
{
|
|
string s = input.Replace('-', '+').Replace('_', '/');
|
|
switch (s.Length % 4)
|
|
{
|
|
case 2: s += "=="; break;
|
|
case 3: s += "="; break;
|
|
}
|
|
var bytes = Convert.FromBase64String(s);
|
|
return System.Text.Encoding.UTF8.GetString(bytes);
|
|
}
|
|
}
|
|
|
|
}
|
|
|