Support Android emulator API access
Enable CORS in all environments and disable HTTPS redirect in dev. Seed the database after migrations. Make the API base URL configurable, defaulting to the Android emulator host, and use per-config Android manifests.
This commit is contained in:
89
SlipItIn.Server/Data/DbSeeder.cs
Normal file
89
SlipItIn.Server/Data/DbSeeder.cs
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using SlipItIn.Shared.Models;
|
||||||
|
|
||||||
|
namespace SlipItIn.Server.Data;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Befüllt die Datenbank mit Testdaten (2 Testuser, einige Dutzend Phrasen),
|
||||||
|
/// wenn sie leer ist. Dient der Erleichterung manueller Tests.
|
||||||
|
/// </summary>
|
||||||
|
public static class DbSeeder
|
||||||
|
{
|
||||||
|
public static async Task SeedAsync(SlipItInDbContext context)
|
||||||
|
{
|
||||||
|
// Nur seeden, wenn die Datenbank leer ist
|
||||||
|
if (await context.Users.AnyAsync() || await context.Phrases.AnyAsync())
|
||||||
|
return;
|
||||||
|
|
||||||
|
var alice = new User
|
||||||
|
{
|
||||||
|
Username = "alice",
|
||||||
|
Email = "alice@test.local",
|
||||||
|
PasswordHash = BCrypt.Net.BCrypt.HashPassword("Test123!")
|
||||||
|
};
|
||||||
|
|
||||||
|
var bob = new User
|
||||||
|
{
|
||||||
|
Username = "bob",
|
||||||
|
Email = "bob@test.local",
|
||||||
|
PasswordHash = BCrypt.Net.BCrypt.HashPassword("Test123!")
|
||||||
|
};
|
||||||
|
|
||||||
|
context.Users.AddRange(alice, bob);
|
||||||
|
await context.SaveChangesAsync();
|
||||||
|
|
||||||
|
var phrases = new[]
|
||||||
|
{
|
||||||
|
"Das hat mir meine Oma schon immer gesagt.",
|
||||||
|
"Ich hab da mal eine Doku gesehen.",
|
||||||
|
"Das ist wie damals in der Grundschule.",
|
||||||
|
"Das muss man sich mal auf der Zunge zergehen lassen.",
|
||||||
|
"Da kommt mir direkt ein Lied in den Sinn.",
|
||||||
|
"Das ist wie beim Autofahren: Bremsen kann man immer noch.",
|
||||||
|
"Ich habe das Gefühl, wir reden aneinander vorbei.",
|
||||||
|
"Das würde ich an deiner Stelle nochmal überdenken.",
|
||||||
|
"Ich glaube, da steckt mehr dahinter.",
|
||||||
|
"Also ich finde, das riecht verdächtig nach Montag.",
|
||||||
|
"Das schmeckt nach mehr.",
|
||||||
|
"Da ist der Wurm drin.",
|
||||||
|
"Das hat hand und Fuß.",
|
||||||
|
"Das ist ein zweischneidiges Schwert.",
|
||||||
|
"Da liegt der Hase im Pfeffer.",
|
||||||
|
"Das ist wie ein guter Wein – wird mit den Jahren besser.",
|
||||||
|
"Ich würde sagen: Glück im Unglück.",
|
||||||
|
"Das ist schon fast eine Wissenschaft für sich.",
|
||||||
|
"Man muss das Kind beim Namen nennen.",
|
||||||
|
"Das ist wie Weihnachten und Geburtstag zusammen.",
|
||||||
|
"Da geht mir das Herz auf.",
|
||||||
|
"Ich würde das jetzt nicht überbewerten.",
|
||||||
|
"Das kommt mir spanisch vor.",
|
||||||
|
"Das ist das Beste seit geschnittenem Brot.",
|
||||||
|
"Da bleibt kein Auge trocken.",
|
||||||
|
"Das ist wie Nägel mit Köpfen machen.",
|
||||||
|
"Ich habe da so eine Vermutung.",
|
||||||
|
"Das ist wie ein roter Faden.",
|
||||||
|
"Da platzt mir gleich der Kragen.",
|
||||||
|
"Ich bin da ganz bei dir.",
|
||||||
|
"Das muss man erstmal sacken lassen.",
|
||||||
|
"Das ist wie ein offenes Buch.",
|
||||||
|
"Da würde ich nicht drauf wetten.",
|
||||||
|
"Das ist wie eine Achterbahn der Gefühle.",
|
||||||
|
"Ich hab da ein ganz mieses Gefühl bei.",
|
||||||
|
"Das ist wie ein Dorn im Auge."
|
||||||
|
};
|
||||||
|
|
||||||
|
var random = new Random(42);
|
||||||
|
var creators = new[] { alice, bob };
|
||||||
|
|
||||||
|
foreach (var text in phrases)
|
||||||
|
{
|
||||||
|
context.Phrases.Add(new Phrase
|
||||||
|
{
|
||||||
|
Text = text,
|
||||||
|
CreatorId = creators[random.Next(creators.Length)].Id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -98,21 +98,28 @@ var app = builder.Build();
|
|||||||
// Aspire Default Endpoints (Health Checks)
|
// Aspire Default Endpoints (Health Checks)
|
||||||
app.MapDefaultEndpoints();
|
app.MapDefaultEndpoints();
|
||||||
|
|
||||||
// Migrations anwenden
|
// Migrations anwenden und Testdaten seeden (nur wenn die Datenbank leer ist)
|
||||||
using (var scope = app.Services.CreateScope())
|
using (var scope = app.Services.CreateScope())
|
||||||
{
|
{
|
||||||
var db = scope.ServiceProvider.GetRequiredService<SlipItInDbContext>();
|
var db = scope.ServiceProvider.GetRequiredService<SlipItInDbContext>();
|
||||||
db.Database.Migrate();
|
db.Database.Migrate();
|
||||||
|
await DbSeeder.SeedAsync(db);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure the HTTP request pipeline.
|
// Configure the HTTP request pipeline.
|
||||||
if (app.Environment.IsDevelopment())
|
if (app.Environment.IsDevelopment())
|
||||||
{
|
{
|
||||||
app.MapOpenApi();
|
app.MapOpenApi();
|
||||||
app.UseCors("AllowAll");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
app.UseHttpsRedirection();
|
app.UseCors("AllowAll");
|
||||||
|
|
||||||
|
// Beim Emulator/geräteübergreifenden Zugriff würde die HTTPS-Umleitung
|
||||||
|
// den Client auf eine nicht vertrauenswürdige Dev-Zertifikats-URL schicken.
|
||||||
|
if (!app.Environment.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.UseHttpsRedirection();
|
||||||
|
}
|
||||||
app.UseAuthentication();
|
app.UseAuthentication();
|
||||||
app.UseAuthorization();
|
app.UseAuthorization();
|
||||||
|
|
||||||
|
|||||||
11
SlipItIn/Platforms/Android/AndroidManifest.Debug.xml
Normal file
11
SlipItIn/Platforms/Android/AndroidManifest.Debug.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="de.krampitz.slipitin">
|
||||||
|
<application
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:icon="@mipmap/appicon"
|
||||||
|
android:supportsRtl="true"
|
||||||
|
android:label="Slip It In"
|
||||||
|
android:usesCleartextTraffic="true" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
</manifest>
|
||||||
11
SlipItIn/Platforms/Android/AndroidManifest.Release.xml
Normal file
11
SlipItIn/Platforms/Android/AndroidManifest.Release.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="de.krampitz.slipitin">
|
||||||
|
<application
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:icon="@mipmap/appicon"
|
||||||
|
android:supportsRtl="true"
|
||||||
|
android:label="Slip It In">
|
||||||
|
</application>
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
</manifest>
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="de.krampitz.slipitin">
|
|
||||||
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:supportsRtl="true" android:label="Slip It In"></application>
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
|
||||||
</manifest>
|
|
||||||
@@ -4,9 +4,20 @@ namespace SlipItIn.Services;
|
|||||||
|
|
||||||
public class AppConfigurationService : IAppConfigurationService
|
public class AppConfigurationService : IAppConfigurationService
|
||||||
{
|
{
|
||||||
|
private const string ApiBaseUrlPreferenceKey = "api_base_url";
|
||||||
private const string DefaultApiBaseUrl = "https://localhost:7274";
|
private const string DefaultApiBaseUrl = "https://localhost:7274";
|
||||||
|
private const string AndroidEmulatorApiBaseUrl = "http://10.0.2.2:5234";
|
||||||
|
|
||||||
public string ApiBaseUrl => DefaultApiBaseUrl;
|
public string ApiBaseUrl => Preferences.Default
|
||||||
|
.Get(ApiBaseUrlPreferenceKey, GetPlatformDefaultApiBaseUrl())
|
||||||
|
.TrimEnd('/');
|
||||||
|
|
||||||
public string HubUrl => $"{DefaultApiBaseUrl.TrimEnd('/')}/hubs/game";
|
public string HubUrl => $"{ApiBaseUrl}/hubs/game";
|
||||||
|
|
||||||
|
private static string GetPlatformDefaultApiBaseUrl()
|
||||||
|
{
|
||||||
|
return DeviceInfo.Platform == DevicePlatform.Android
|
||||||
|
? AndroidEmulatorApiBaseUrl
|
||||||
|
: DefaultApiBaseUrl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,4 +124,12 @@
|
|||||||
</MauiXaml>
|
</MauiXaml>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)'=='Debug|net10.0-android'">
|
||||||
|
<AndroidManifest>Platforms\Android\AndroidManifest.Debug.xml</AndroidManifest>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)'=='Release|net10.0-android'">
|
||||||
|
<AndroidManifest>Platforms\Android\AndroidManifest.Release.xml</AndroidManifest>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
Reference in New Issue
Block a user