1
0
mirror of https://github.com/bitwarden/mobile synced 2025-12-24 04:04:34 +00:00

[PM-192] Refactor forwarded email providers (#2579)

* PM-192 Refactor Forwarded email providers to use better patterns and code reuse.

* PM-192 fix format
This commit is contained in:
Federico Maccaroni
2023-06-27 18:49:38 -03:00
committed by GitHub
parent 3506269811
commit 1014563c75
20 changed files with 547 additions and 459 deletions

View File

@@ -4,6 +4,7 @@ using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Bit.Core.Abstractions;
using Bit.Core.Enums;
@@ -763,111 +764,29 @@ namespace Bit.Core.Services
}
}
public async Task<string> GetUsernameFromAsync(ForwardedEmailServiceType service, UsernameGeneratorConfig config)
public async Task<HttpResponseMessage> SendAsync(HttpRequestMessage requestMessage, CancellationToken cancellationToken = default)
{
using (var requestMessage = new HttpRequestMessage())
HttpResponseMessage response;
try
{
requestMessage.Version = new Version(1, 0);
requestMessage.Method = HttpMethod.Post;
requestMessage.RequestUri = new Uri(config.Url);
requestMessage.Headers.Add("Accept", "application/json");
switch (service)
{
case ForwardedEmailServiceType.AnonAddy:
requestMessage.Headers.Add("Authorization", $"Bearer {config.ApiToken}");
requestMessage.Content = new FormUrlEncodedContent(new Dictionary<string, string>
{
["domain"] = config.Domain
});
break;
case ForwardedEmailServiceType.FirefoxRelay:
requestMessage.Headers.Add("Authorization", $"Token {config.ApiToken}");
requestMessage.Content = new StringContent(JsonConvert.SerializeObject(
new
{
enabled = true,
description = "Generated by Bitwarden."
}), Encoding.UTF8, "application/json");
break;
case ForwardedEmailServiceType.SimpleLogin:
requestMessage.Headers.Add("Authentication", config.ApiToken);
break;
case ForwardedEmailServiceType.DuckDuckGo:
requestMessage.Headers.Add("Authorization", $"Bearer {config.ApiToken}");
break;
case ForwardedEmailServiceType.Fastmail:
requestMessage.Headers.Add("Authorization", $"Bearer {config.ApiToken}");
requestMessage.Content = new StringContent(await CreateFastmailRequest(config.ApiToken),
Encoding.UTF8, "application/json");
break;
}
HttpResponseMessage response;
try
{
response = await _httpClient.SendAsync(requestMessage);
}
catch (Exception e)
{
throw new ApiException(HandleWebError(e));
}
if (!response.IsSuccessStatusCode)
{
throw new ApiException(new ErrorResponse
{
StatusCode = response.StatusCode,
Message = $"{service} error: {(int)response.StatusCode} {response.ReasonPhrase}."
});
}
var responseJsonString = await response.Content.ReadAsStringAsync();
var result = JObject.Parse(responseJsonString);
switch (service)
{
case ForwardedEmailServiceType.AnonAddy:
return result["data"]?["email"]?.ToString();
case ForwardedEmailServiceType.FirefoxRelay:
return result["full_address"]?.ToString();
case ForwardedEmailServiceType.SimpleLogin:
return result["alias"]?.ToString();
case ForwardedEmailServiceType.DuckDuckGo:
return $"{result["address"]?.ToString()}@duck.com";
case ForwardedEmailServiceType.Fastmail:
return HandleFastMailResponse(result);
default:
return string.Empty;
}
response = await _httpClient.SendAsync(requestMessage, cancellationToken);
}
catch (Exception e)
{
throw new ApiException(HandleWebError(e));
}
if (!response.IsSuccessStatusCode)
{
throw new ApiException(new ErrorResponse
{
StatusCode = response.StatusCode,
Message = $"{requestMessage.RequestUri} error: {(int)response.StatusCode} {response.ReasonPhrase}."
});
}
return response;
}
private string HandleFastMailResponse(JObject result)
{
if (result["methodResponses"] == null || !result["methodResponses"].HasValues ||
!result["methodResponses"][0].HasValues)
{
throw new Exception("Fastmail error: could not parse response.");
}
if (result["methodResponses"][0][0].ToString() == "MaskedEmail/set")
{
if (result["methodResponses"][0][1]?["created"]?["new-masked-email"] != null)
{
return result["methodResponses"][0][1]?["created"]?["new-masked-email"]?["email"].ToString();
}
if (result["methodResponses"][0][1]?["notCreated"]?["new-masked-email"] != null)
{
throw new Exception("Fastmail error: " +
result["methodResponses"][0][1]?["created"]?["new-masked-email"]?["description"].ToString());
}
}
else if (result["methodResponses"][0][0].ToString() == "error")
{
throw new Exception("Fastmail error: " + result["methodResponses"][0][1]?["description"].ToString());
}
throw new Exception("Fastmail error: could not parse response.");
}
private async Task<string> CreateFastmailRequest(string apiKey)
public async Task<string> GetFastmailAccountIdAsync(string apiKey)
{
using (var httpclient = new HttpClient())
{
@@ -891,36 +810,7 @@ namespace Bit.Core.Services
});
}
var result = JObject.Parse(await response.Content.ReadAsStringAsync());
var accountId = result["primaryAccounts"]?["https://www.fastmail.com/dev/maskedemail"]?.ToString();
var requestJObj = new JObject
{
new JProperty("using",
new JArray { "https://www.fastmail.com/dev/maskedemail", "urn:ietf:params:jmap:core" }),
new JProperty("methodCalls",
new JArray
{
new JArray
{
"MaskedEmail/set",
new JObject
{
["accountId"] = accountId,
["create"] = new JObject
{
["new-masked-email"] = new JObject
{
["state"] = "enabled",
["description"] = "",
["url"] = "",
["emailPrefix"] = ""
}
}
},
"0"
}
})
};
return requestJObj.ToString();
return result["primaryAccounts"]?["https://www.fastmail.com/dev/maskedemail"]?.ToString();
}
}