Skip to content

Commit

Permalink
Merge branch 'main' into feature/Android_Support_For_Aspire_Project
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesmontemagno authored May 30, 2024
2 parents 28ee2ae + 909ee34 commit b57504d
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 40 deletions.
48 changes: 44 additions & 4 deletions src/ClientApp/MauiProgram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
using eShop.ClientApp.Services.Settings;
using eShop.ClientApp.Services.Theme;
using eShop.ClientApp.Views;

using IdentityModel.OidcClient;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using IBrowser = IdentityModel.OidcClient.Browser.IBrowser;

namespace eShop.ClientApp;
Expand Down Expand Up @@ -63,9 +65,20 @@ public static MauiAppBuilder RegisterAppServices(this MauiAppBuilder mauiAppBuil
mauiAppBuilder.Services.AddSingleton<INavigationService, MauiNavigationService>();
mauiAppBuilder.Services.AddSingleton<IDialogService, DialogService>();
mauiAppBuilder.Services.AddSingleton<IOpenUrlService, OpenUrlService>();
mauiAppBuilder.Services.AddSingleton<IHttpsClientHandlerService, HttpsClientHandlerService>();
mauiAppBuilder.Services.AddSingleton<IRequestProvider, RequestProvider>();
mauiAppBuilder.Services.AddSingleton<IIdentityService, IdentityService>();
mauiAppBuilder.Services.AddSingleton<IRequestProvider>(
sp =>
{
var debugHttpHandler = sp.GetKeyedService<HttpMessageHandler>("DebugHttpMessageHandler");
return new RequestProvider(debugHttpHandler);
});
mauiAppBuilder.Services.AddSingleton<IIdentityService, IdentityService>(
sp =>
{
var browser = sp.GetRequiredService<IBrowser>();
var settingsService = sp.GetRequiredService<ISettingsService>();
var debugHttpHandler = sp.GetKeyedService<HttpMessageHandler>("DebugHttpMessageHandler");
return new IdentityService(browser, settingsService, debugHttpHandler);
});
mauiAppBuilder.Services.AddSingleton<IFixUriService, FixUriService>();
mauiAppBuilder.Services.AddSingleton<ILocationService, LocationService>();

Expand Down Expand Up @@ -93,6 +106,33 @@ public static MauiAppBuilder RegisterAppServices(this MauiAppBuilder mauiAppBuil
mauiAppBuilder.Services.AddTransient<IBrowser, MauiAuthenticationBrowser>();

#if DEBUG
mauiAppBuilder.Services.AddKeyedSingleton<HttpMessageHandler>(
"DebugHttpMessageHandler",
(sp, key) =>
{
#if ANDROID
var handler = new Xamarin.Android.Net.AndroidMessageHandler();
handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) =>
{
if (cert != null && cert.Issuer.Equals("CN=localhost", StringComparison.OrdinalIgnoreCase))
{
return true;
}

return errors == System.Net.Security.SslPolicyErrors.None;
};
return handler;
#elif IOS || MACCATALYST
var handler = new NSUrlSessionHandler
{
TrustOverrideForUrl = (sender, url, trust) => url.StartsWith("https://localhost", StringComparison.OrdinalIgnoreCase),
};
return handler;
#else
return null;
#endif
});

mauiAppBuilder.Logging.AddDebug();
#endif

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">10.0.2.2</domain>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
using Android.App;
using Android.Content;
using Android.Content.PM;

namespace eShop.ClientApp;

[Activity(NoHistory = true, LaunchMode = LaunchMode.SingleTop, Exported = true)]
[IntentFilter(new[] { Android.Content.Intent.ActionView },
Categories = new[] { Android.Content.Intent.CategoryDefault, Android.Content.Intent.CategoryBrowsable },
DataScheme = "maui",
DataHost = "authcallback")]
Categories = new[] { Android.Content.Intent.CategoryDefault, Android.Content.Intent.CategoryBrowsable },
DataScheme = "maui",
DataHost = "authcallback")]
public class WebAuthenticationCallbackActivity : Microsoft.Maui.Authentication.WebAuthenticatorCallbackActivity
{

Expand Down
1 change: 1 addition & 0 deletions src/ClientApp/Services/Catalog/CatalogService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public class CatalogService : ICatalogService
{
private const string ApiUrlBase = "api/catalog";
private const string ApiVersion = "api-version=1.0";

private readonly IFixUriService _fixUriService;
private readonly IRequestProvider _requestProvider;
private readonly ISettingsService _settingsService;
Expand Down
4 changes: 3 additions & 1 deletion src/ClientApp/Services/FixUri/FixUriService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ namespace eShop.ClientApp.Services.FixUri;

public class FixUriService : IFixUriService
{
private const string ApiVersion = "api-version=1.0";

private readonly ISettingsService _settingsService;

private readonly Regex IpRegex = new(@"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b");
Expand All @@ -31,7 +33,7 @@ public void FixCatalogItemPictureUri(IEnumerable<CatalogItem> catalogItems)
{
foreach (var catalogItem in catalogItems)
{
catalogItem.PictureUri = Path.Combine(_settingsService.GatewayCatalogEndpointBase, $"api/catalog/items/{catalogItem.Id}/pic?api-version=1.0");
catalogItem.PictureUri = Path.Combine(_settingsService.GatewayCatalogEndpointBase, $"api/catalog/items/{catalogItem.Id}/pic?{ApiVersion}");
}
}
}
Expand Down
19 changes: 10 additions & 9 deletions src/ClientApp/Services/Identity/IdentityService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ public class IdentityService : IIdentityService
{
private readonly IBrowser _browser;
private readonly ISettingsService _settingsService;
private readonly IHttpsClientHandlerService _httpsClientHandlerService;

public IdentityService(IBrowser browser, ISettingsService settingsService, IHttpsClientHandlerService httpsClientHandlerService)
private readonly HttpMessageHandler _httpMessageHandler;

public IdentityService(IBrowser browser, ISettingsService settingsService, HttpMessageHandler httpMessageHandler)
{
_browser = browser;
_settingsService = settingsService;
_httpsClientHandlerService = httpsClientHandlerService;
_httpMessageHandler = httpMessageHandler;
}

public async Task<bool> SignInAsync()
Expand Down Expand Up @@ -140,14 +141,14 @@ private OidcClient GetClient()
Scope = "openid profile basket orders offline_access",
RedirectUri = _settingsService.CallbackUri,
PostLogoutRedirectUri = _settingsService.CallbackUri,
Browser = _browser
Browser = _browser,
};

#if DEBUG
var platformMessageHandler = _httpsClientHandlerService.GetPlatformMessageHandler();
options.BackchannelHandler = platformMessageHandler;
#endif

if (_httpMessageHandler is not null)
{
options.BackchannelHandler = _httpMessageHandler;
}
return new OidcClient(options);
}
}
11 changes: 7 additions & 4 deletions src/ClientApp/Services/Order/OrderService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public class OrderService : IOrderService
{
private const string ApiUrlBase = "api/orders";
private const string ApiVersion = "api-version=1.0";

private readonly IIdentityService _identityService;
private readonly IRequestProvider _requestProvider;
private readonly ISettingsService _settingsService;
Expand All @@ -33,7 +34,8 @@ public async Task CreateOrderAsync(Models.Orders.Order newOrder)
return;
}

var uri = UriHelper.CombineUri(_settingsService.GatewayOrdersEndpointBase, $"{ApiUrlBase}?{ApiVersion}");

var uri = $"{UriHelper.CombineUri(_settingsService.GatewayOrdersEndpointBase, ApiUrlBase)}?{ApiVersion}";

var success = await _requestProvider.PostAsync(uri, newOrder, authToken, "x-requestid").ConfigureAwait(false);
}
Expand All @@ -47,7 +49,7 @@ public async Task CreateOrderAsync(Models.Orders.Order newOrder)
return Enumerable.Empty<Models.Orders.Order>();
}

var uri = UriHelper.CombineUri(_settingsService.GatewayOrdersEndpointBase, $"{ApiUrlBase}?{ApiVersion}");
var uri = $"{UriHelper.CombineUri(_settingsService.GatewayOrdersEndpointBase, ApiUrlBase)}?{ApiVersion}";

var orders =
await _requestProvider.GetAsync<IEnumerable<Models.Orders.Order>>(uri, authToken).ConfigureAwait(false);
Expand All @@ -66,7 +68,8 @@ public async Task CreateOrderAsync(Models.Orders.Order newOrder)

try
{
var uri = UriHelper.CombineUri(_settingsService.GatewayOrdersEndpointBase, $"{ApiUrlBase}/{orderId}?{ApiVersion}");

var uri = $"{UriHelper.CombineUri(_settingsService.GatewayOrdersEndpointBase, $"{ApiUrlBase}/{orderId}")}?{ApiVersion}";

var order =
await _requestProvider.GetAsync<Models.Orders.Order>(uri, authToken).ConfigureAwait(false);
Expand All @@ -88,7 +91,7 @@ public async Task<bool> CancelOrderAsync(int orderId)
return false;
}

var uri = UriHelper.CombineUri(_settingsService.GatewayOrdersEndpointBase, $"{ApiUrlBase}/cancel?{ApiVersion}");
var uri = $"{UriHelper.CombineUri(_settingsService.GatewayOrdersEndpointBase, $"{ApiUrlBase}/cancel")}?{ApiVersion}";

var cancelOrderCommand = new CancelOrderCommand(orderId);

Expand Down
14 changes: 7 additions & 7 deletions src/ClientApp/Services/RequestProvider/RequestProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,23 @@

namespace eShop.ClientApp.Services.RequestProvider;

public class RequestProvider(IHttpsClientHandlerService _httpsClientHandlerService) : IRequestProvider
public class RequestProvider(HttpMessageHandler _messageHandler) : IRequestProvider
{
private readonly Lazy<HttpClient> _httpClient =
new(() =>
{
#if DEBUG
var httpClient = new HttpClient(_httpsClientHandlerService.GetPlatformMessageHandler());
#else
var httpClient = new HttpClient();
#endif
var httpClient = _messageHandler is not null ? new HttpClient(_messageHandler) : new HttpClient();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
return httpClient;
},
LazyThreadSafetyMode.ExecutionAndPublication);

private readonly JsonSerializerOptions _jsonSerializerContext =
new() { PropertyNameCaseInsensitive = true, NumberHandling = JsonNumberHandling.AllowReadingFromString };
new()
{
PropertyNameCaseInsensitive = true,
NumberHandling = JsonNumberHandling.AllowReadingFromString,
};

public async Task<TResult> GetAsync<TResult>(string uri, string token = "")
{
Expand Down
13 changes: 7 additions & 6 deletions src/ClientApp/ViewModels/SettingsViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ namespace eShop.ClientApp.ViewModels;

public class SettingsViewModel : ViewModelBase
{
//Needed if using Android Emulator Locally. See https://learn.microsoft.com/en-us/dotnet/maui/data-cloud/local-web-services?view=net-maui-8.0#android
private static string _baseAddress = DeviceInfo.Platform == DevicePlatform.Android ? "10.0.2.2" : "localhost";

private readonly IAppEnvironmentService _appEnvironmentService;
private readonly ILocationService _locationService;
private readonly ISettingsService _settingsService;
Expand All @@ -27,8 +30,6 @@ public class SettingsViewModel : ViewModelBase
private bool _useAzureServices;
private bool _useFakeLocation;

static string BaseAddress = DeviceInfo.Platform == DevicePlatform.Android ? "10.0.2.2" : "localhost";

public SettingsViewModel(
ILocationService locationService, IAppEnvironmentService appEnvironmentService,
INavigationService navigationService, ISettingsService settingsService)
Expand All @@ -49,22 +50,22 @@ public SettingsViewModel(
IdentityEndpoint =
!string.IsNullOrEmpty(_settingsService.IdentityEndpointBase)
? _settingsService.IdentityEndpointBase
: $"https://{BaseAddress}:5243";
: $"https://{_baseAddress}:5243";

GatewayCatalogEndpoint =
!string.IsNullOrEmpty(_settingsService.GatewayCatalogEndpointBase)
? _settingsService.GatewayCatalogEndpointBase
: $"http://{BaseAddress}:11632";
: $"http://{_baseAddress}:11632";

GatewayBasketEndpoint =
!string.IsNullOrEmpty(_settingsService.GatewayBasketEndpointBase)
? _settingsService.GatewayBasketEndpointBase
: $"http://{BaseAddress}:5221";
: $"http://{_baseAddress}:5221";

GatewayOrdersEndpoint =
!string.IsNullOrEmpty(_settingsService.GatewayOrdersEndpointBase)
? _settingsService.GatewayOrdersEndpointBase
: $"http://{BaseAddress}:11632";
: $"http://{_baseAddress}:11632";

ToggleMockServicesCommand = new RelayCommand(ToggleMockServices);

Expand Down
9 changes: 5 additions & 4 deletions src/eShop.ServiceDefaults/AuthenticationExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,14 @@ public static IServiceCollection AddDefaultAuthentication(this IHostApplicationB

options.Authority = identityUrl;
options.RequireHttpsMetadata = false;
options.Audience = audience;
#if DEBUG
options.Audience = audience;
#if DEBUG
//Needed if using Android Emulator Locally. See https://learn.microsoft.com/en-us/dotnet/maui/data-cloud/local-web-services?view=net-maui-8.0#android
options.TokenValidationParameters.ValidIssuers = [identityUrl, "https://10.0.2.2:5243"];
#else
#else
options.TokenValidationParameters.ValidIssuers = [identityUrl];
#endif
#endif

options.TokenValidationParameters.ValidateAudience = false;
});

Expand Down

0 comments on commit b57504d

Please sign in to comment.