diff options
| author | ivarlovlie <git@ivarlovlie.no> | 2022-01-30 01:30:58 +0100 |
|---|---|---|
| committer | ivarlovlie <git@ivarlovlie.no> | 2022-01-30 01:30:58 +0100 |
| commit | bda1e81c87a34bc0e6d2ce805f706a726087e957 (patch) | |
| tree | 124ebf09d1289900e0d67d8723528b96bfbb6a7e | |
| parent | 253c8479b9ae0ba6853a70728d3f6e904e1ac2ba (diff) | |
| download | bookmark-thing-bda1e81c87a34bc0e6d2ce805f706a726087e957.tar.xz bookmark-thing-bda1e81c87a34bc0e6d2ce805f706a726087e957.zip | |
feat: WIP: Map github logins
When github is used for login, we want to create
a mapping to a regular user in our database.
This is mainly so that we don't have to change the PK in our database or add a column to it.
| -rw-r--r-- | src/server/Api/Internal/Account/GetClaimsRoute.cs | 16 | ||||
| -rw-r--r-- | src/server/Api/Internal/Account/GetProfileDataRoute.cs | 35 | ||||
| -rw-r--r-- | src/server/Api/Internal/BaseInternalRoute.cs | 3 | ||||
| -rw-r--r-- | src/server/Api/Internal/LoggedInInternalUser.cs | 2 | ||||
| -rw-r--r-- | src/server/Api/Internal/OAuthCallbackRoute.cs | 1 | ||||
| -rw-r--r-- | src/server/Api/V1/BaseV1Route.cs | 5 | ||||
| -rw-r--r-- | src/server/IOL.BookmarkThing.Server.csproj | 4 | ||||
| -rw-r--r-- | src/server/Migrations/20220125180758_GithubUserMappings.Designer.cs | 179 | ||||
| -rw-r--r-- | src/server/Migrations/20220125180758_GithubUserMappings.cs | 43 | ||||
| -rw-r--r-- | src/server/Migrations/AppDbContextModelSnapshot.cs | 38 | ||||
| -rw-r--r-- | src/server/Models/Database/AppDbContext.cs | 5 | ||||
| -rw-r--r-- | src/server/Models/Database/GithubUserMapping.cs | 7 | ||||
| -rw-r--r-- | src/server/Models/Database/User.cs | 10 | ||||
| -rw-r--r-- | src/server/Startup.cs | 30 | ||||
| -rw-r--r-- | src/server/StaticData/AppClaims.cs | 8 | ||||
| -rw-r--r-- | src/server/Utilities/ConnectionStrings.cs | 22 | ||||
| -rw-r--r-- | src/server/Utilities/HandleGithubCreatingTicket.cs | 30 |
17 files changed, 402 insertions, 36 deletions
diff --git a/src/server/Api/Internal/Account/GetClaimsRoute.cs b/src/server/Api/Internal/Account/GetClaimsRoute.cs new file mode 100644 index 0000000..fde8887 --- /dev/null +++ b/src/server/Api/Internal/Account/GetClaimsRoute.cs @@ -0,0 +1,16 @@ +namespace IOL.BookmarkThing.Server.Api.Internal.Account; + +public class GetClaimsRoute : RouteBaseInternalSync.WithoutRequest.WithActionResult +{ + [HttpGet("~/v{apiVersion:apiVersion}/account/claims")] + public override ActionResult Handle() { + if (HttpContext.Request.Query.ContainsKey("download")) { + var serializerOptions = new JsonSerializerOptions() { + ReferenceHandler = ReferenceHandler.IgnoreCycles + }; + return File(JsonSerializer.SerializeToUtf8Bytes(User.Claims, serializerOptions), "application/json", "claims_" + User.Identity?.Name + ".json"); + } + + return Ok(User.Claims); + } +} diff --git a/src/server/Api/Internal/Account/GetProfileDataRoute.cs b/src/server/Api/Internal/Account/GetProfileDataRoute.cs index adf1cba..c68f295 100644 --- a/src/server/Api/Internal/Account/GetProfileDataRoute.cs +++ b/src/server/Api/Internal/Account/GetProfileDataRoute.cs @@ -2,10 +2,45 @@ namespace IOL.BookmarkThing.Server.Api.Internal.Account; public class GetProfileDataRoute : RouteBaseInternalSync.WithoutRequest.WithActionResult<LoggedInInternalUser> { + private readonly AppDbContext _context; + private readonly ILogger<GetProfileDataRoute> _logger; + + public GetProfileDataRoute(ILogger<GetProfileDataRoute> logger, AppDbContext context) { + _logger = logger; + _context = context; + } + [ApiVersionNeutral] [ApiExplorerSettings(IgnoreApi = true)] [HttpGet("~/v{version:apiVersion}/account/profile-data")] public override ActionResult<LoggedInInternalUser> Handle() { + // if (!Guid.TryParse(User.FindFirstValue(ClaimTypes.NameIdentifier), out var _)) { + // var github_id = User.FindFirstValue(AppClaims.GITHUB_ID); + // if (github_id.HasValue()) { + // var existing_mapping = _context.GithubUserMappings.Include(c => c.User).SingleOrDefault(c => c.GithubId == github_id); + // var id = new ClaimsIdentity(); + // if (existing_mapping != default) { + // id.AddClaims(existing_mapping.User.DefaultClaims()); + // User.AddIdentity(id); + // } else { + // var name = User.FindFirstValue(ClaimTypes.Name); + // var user = new User(name) { + // Id = Guid.NewGuid() + // }; + // var mapping = new GithubUserMapping { + // GithubId = github_id, + // User = user + // }; + // _context.GithubUserMappings.Add(mapping); + // _context.SaveChanges(); + // id.AddClaims(mapping.User.DefaultClaims()); + // User.AddIdentity(id); + // } + // + // _logger.LogInformation("Added user mapping for github user"); + // } + // } + return Ok(LoggedInUser); } } diff --git a/src/server/Api/Internal/BaseInternalRoute.cs b/src/server/Api/Internal/BaseInternalRoute.cs index 2f92c8e..6c0a2d9 100644 --- a/src/server/Api/Internal/BaseInternalRoute.cs +++ b/src/server/Api/Internal/BaseInternalRoute.cs @@ -5,11 +5,12 @@ namespace IOL.BookmarkThing.Server.Api.Internal; [ApiController] public class BaseInternalRoute : ControllerBase { + /// <summary> /// User data for the currently logged on user. /// </summary> protected LoggedInInternalUser LoggedInUser => new() { + Id = User.FindFirstValue(ClaimTypes.NameIdentifier).ToGuid(), Username = User.Identity?.Name, - Id = User.Claims.SingleOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value.ToGuid() ?? default }; } diff --git a/src/server/Api/Internal/LoggedInInternalUser.cs b/src/server/Api/Internal/LoggedInInternalUser.cs index e08dd51..36906ca 100644 --- a/src/server/Api/Internal/LoggedInInternalUser.cs +++ b/src/server/Api/Internal/LoggedInInternalUser.cs @@ -2,6 +2,6 @@ namespace IOL.BookmarkThing.Server.Api.Internal; public class LoggedInInternalUser { - public Guid Id { get; set; } + public Guid? Id { get; set; } public string Username { get; set; } } diff --git a/src/server/Api/Internal/OAuthCallbackRoute.cs b/src/server/Api/Internal/OAuthCallbackRoute.cs index 156ff11..d2823c4 100644 --- a/src/server/Api/Internal/OAuthCallbackRoute.cs +++ b/src/server/Api/Internal/OAuthCallbackRoute.cs @@ -13,6 +13,7 @@ public class OAuthCallbackRoute : RouteBaseInternalSync.WithoutRequest.WithActio [ApiExplorerSettings(IgnoreApi = true)] [HttpGet("~/oauth-cb")] public override ActionResult Handle() { + Console.WriteLine(JsonSerializer.Serialize(HttpContext.User)); return Redirect(_configuration.GetValue<string>("FRONTEND_CANONICAL_URL")); } } diff --git a/src/server/Api/V1/BaseV1Route.cs b/src/server/Api/V1/BaseV1Route.cs index 21c8128..9322bf9 100644 --- a/src/server/Api/V1/BaseV1Route.cs +++ b/src/server/Api/V1/BaseV1Route.cs @@ -13,8 +13,8 @@ public class BaseV1Route : ControllerBase /// User data for the currently logged on user. /// </summary> protected LoggedInV1User LoggedInUser => new() { + Id = User.FindFirstValue(ClaimTypes.NameIdentifier).ToGuid(), Username = User.Identity?.Name, - Id = User.Claims.SingleOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value.ToGuid() ?? default }; protected bool IsApiCall() { @@ -22,8 +22,7 @@ public class BaseV1Route : ControllerBase try { var authHeader = AuthenticationHeaderValue.Parse(Request.Headers["Authorization"]); if (authHeader.Parameter == null) return false; - } catch (Exception e) { - Console.WriteLine(e); + } catch { return false; } diff --git a/src/server/IOL.BookmarkThing.Server.csproj b/src/server/IOL.BookmarkThing.Server.csproj index da78675..73e1c38 100644 --- a/src/server/IOL.BookmarkThing.Server.csproj +++ b/src/server/IOL.BookmarkThing.Server.csproj @@ -20,14 +20,14 @@ <PackageReference Include="AspNet.Security.OAuth.GitHub" Version="6.0.3" /> <PackageReference Include="EFCore.NamingConventions" Version="6.0.0" /> <PackageReference Include="HtmlAgilityPack" Version="1.11.40" /> - <PackageReference Include="IOL.Helpers" Version="1.2.0" /> + <PackageReference Include="IOL.Helpers" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="5.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer" Version="5.0.0" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.1"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> - <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.2" /> + <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.3" /> <PackageReference Include="Quartz.Extensions.Hosting" Version="3.3.3" /> <PackageReference Include="Serilog.AspNetCore" Version="4.1.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" /> diff --git a/src/server/Migrations/20220125180758_GithubUserMappings.Designer.cs b/src/server/Migrations/20220125180758_GithubUserMappings.Designer.cs new file mode 100644 index 0000000..c568013 --- /dev/null +++ b/src/server/Migrations/20220125180758_GithubUserMappings.Designer.cs @@ -0,0 +1,179 @@ +// <auto-generated /> +using System; +using IOL.BookmarkThing.Server.Models.Database; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace IOL.BookmarkThing.Server.Migrations +{ + [DbContext(typeof(AppDbContext))] + [Migration("20220125180758_GithubUserMappings")] + partial class GithubUserMappings + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.1") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("IOL.BookmarkThing.Server.Models.Database.AccessToken", b => + { + b.Property<Guid>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property<bool>("AllowCreate") + .HasColumnType("boolean") + .HasColumnName("allow_create"); + + b.Property<bool>("AllowDelete") + .HasColumnType("boolean") + .HasColumnName("allow_delete"); + + b.Property<bool>("AllowRead") + .HasColumnType("boolean") + .HasColumnName("allow_read"); + + b.Property<bool>("AllowUpdate") + .HasColumnType("boolean") + .HasColumnName("allow_update"); + + b.Property<DateTime>("Created") + .HasColumnType("timestamp with time zone") + .HasColumnName("created"); + + b.Property<DateTime>("ExpiryDate") + .HasColumnType("timestamp with time zone") + .HasColumnName("expiry_date"); + + b.Property<Guid?>("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_access_tokens"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_access_tokens_user_id"); + + b.ToTable("access_tokens", (string)null); + }); + + modelBuilder.Entity("IOL.BookmarkThing.Server.Models.Database.Entry", b => + { + b.Property<Guid>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property<DateTime>("Created") + .HasColumnType("timestamp with time zone") + .HasColumnName("created"); + + b.Property<string>("Description") + .HasColumnType("text") + .HasColumnName("description"); + + b.Property<string>("Tags") + .HasColumnType("text") + .HasColumnName("tags"); + + b.Property<string>("Url") + .HasColumnType("text") + .HasColumnName("url"); + + b.Property<Guid>("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_entries"); + + b.ToTable("entries", (string)null); + }); + + modelBuilder.Entity("IOL.BookmarkThing.Server.Models.Database.GithubUserMapping", b => + { + b.Property<Guid>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property<DateTime>("Created") + .HasColumnType("timestamp with time zone") + .HasColumnName("created"); + + b.Property<string>("GithubId") + .HasColumnType("text") + .HasColumnName("github_id"); + + b.Property<Guid?>("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_github_user_mappings"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_github_user_mappings_user_id"); + + b.ToTable("github_user_mappings", (string)null); + }); + + modelBuilder.Entity("IOL.BookmarkThing.Server.Models.Database.User", b => + { + b.Property<Guid>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property<DateTime>("Created") + .HasColumnType("timestamp with time zone") + .HasColumnName("created"); + + b.Property<string>("Password") + .HasColumnType("text") + .HasColumnName("password"); + + b.Property<string>("Username") + .HasColumnType("text") + .HasColumnName("username"); + + b.HasKey("Id") + .HasName("pk_users"); + + b.ToTable("users", (string)null); + }); + + modelBuilder.Entity("IOL.BookmarkThing.Server.Models.Database.AccessToken", b => + { + b.HasOne("IOL.BookmarkThing.Server.Models.Database.User", "User") + .WithMany() + .HasForeignKey("UserId") + .HasConstraintName("fk_access_tokens_users_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("IOL.BookmarkThing.Server.Models.Database.GithubUserMapping", b => + { + b.HasOne("IOL.BookmarkThing.Server.Models.Database.User", "User") + .WithMany() + .HasForeignKey("UserId") + .HasConstraintName("fk_github_user_mappings_users_user_id"); + + b.Navigation("User"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/server/Migrations/20220125180758_GithubUserMappings.cs b/src/server/Migrations/20220125180758_GithubUserMappings.cs new file mode 100644 index 0000000..24f5cc4 --- /dev/null +++ b/src/server/Migrations/20220125180758_GithubUserMappings.cs @@ -0,0 +1,43 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace IOL.BookmarkThing.Server.Migrations +{ + public partial class GithubUserMappings : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "github_user_mappings", + columns: table => new + { + id = table.Column<Guid>(type: "uuid", nullable: false), + user_id = table.Column<Guid>(type: "uuid", nullable: true), + github_id = table.Column<string>(type: "text", nullable: true), + created = table.Column<DateTime>(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("pk_github_user_mappings", x => x.id); + table.ForeignKey( + name: "fk_github_user_mappings_users_user_id", + column: x => x.user_id, + principalTable: "users", + principalColumn: "id"); + }); + + migrationBuilder.CreateIndex( + name: "ix_github_user_mappings_user_id", + table: "github_user_mappings", + column: "user_id"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "github_user_mappings"); + } + } +} diff --git a/src/server/Migrations/AppDbContextModelSnapshot.cs b/src/server/Migrations/AppDbContextModelSnapshot.cs index c48f478..8e55e15 100644 --- a/src/server/Migrations/AppDbContextModelSnapshot.cs +++ b/src/server/Migrations/AppDbContextModelSnapshot.cs @@ -99,6 +99,34 @@ namespace IOL.BookmarkThing.Server.Migrations b.ToTable("entries", (string)null); }); + modelBuilder.Entity("IOL.BookmarkThing.Server.Models.Database.GithubUserMapping", b => + { + b.Property<Guid>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property<DateTime>("Created") + .HasColumnType("timestamp with time zone") + .HasColumnName("created"); + + b.Property<string>("GithubId") + .HasColumnType("text") + .HasColumnName("github_id"); + + b.Property<Guid?>("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_github_user_mappings"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_github_user_mappings_user_id"); + + b.ToTable("github_user_mappings", (string)null); + }); + modelBuilder.Entity("IOL.BookmarkThing.Server.Models.Database.User", b => { b.Property<Guid>("Id") @@ -133,6 +161,16 @@ namespace IOL.BookmarkThing.Server.Migrations b.Navigation("User"); }); + + modelBuilder.Entity("IOL.BookmarkThing.Server.Models.Database.GithubUserMapping", b => + { + b.HasOne("IOL.BookmarkThing.Server.Models.Database.User", "User") + .WithMany() + .HasForeignKey("UserId") + .HasConstraintName("fk_github_user_mappings_users_user_id"); + + b.Navigation("User"); + }); #pragma warning restore 612, 618 } } diff --git a/src/server/Models/Database/AppDbContext.cs b/src/server/Models/Database/AppDbContext.cs index ae1f45b..4961f0e 100644 --- a/src/server/Models/Database/AppDbContext.cs +++ b/src/server/Models/Database/AppDbContext.cs @@ -6,6 +6,7 @@ public class AppDbContext : DbContext public DbSet<User> Users { get; set; } public DbSet<Entry> Entries { get; set; } public DbSet<AccessToken> AccessTokens { get; set; } + public DbSet<GithubUserMapping> GithubUserMappings { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<User>(e => { @@ -20,6 +21,10 @@ public class AppDbContext : DbContext e.ToTable("access_tokens"); }); + modelBuilder.Entity<GithubUserMapping>(e => { + e.ToTable("github_user_mappings"); + }); + base.OnModelCreating(modelBuilder); } } diff --git a/src/server/Models/Database/GithubUserMapping.cs b/src/server/Models/Database/GithubUserMapping.cs new file mode 100644 index 0000000..440360d --- /dev/null +++ b/src/server/Models/Database/GithubUserMapping.cs @@ -0,0 +1,7 @@ +namespace IOL.BookmarkThing.Server.Models.Database; + +public class GithubUserMapping : Base +{ + public User User { get; set; } + public string GithubId { get; set; } +} diff --git a/src/server/Models/Database/User.cs b/src/server/Models/Database/User.cs index 1215f4e..e034665 100644 --- a/src/server/Models/Database/User.cs +++ b/src/server/Models/Database/User.cs @@ -2,10 +2,10 @@ namespace IOL.BookmarkThing.Server.Models.Database; public class User : Base { - public User(string username) => Username = username; + public User(string username = "") => Username = username; - public string Username { get; set; } - public string Password { get; set; } + public string Username { get; } + public string Password { get; private set; } public void HashAndSetPassword(string password) { Password = PasswordHelper.HashPassword(password); @@ -17,8 +17,8 @@ public class User : Base public IEnumerable<Claim> DefaultClaims() { return new Claim[] { - new(ClaimTypes.NameIdentifier, Id.ToString()), - new(ClaimTypes.Name, Username), + new(AppClaims.USER_ID, Id.ToString()), + new(AppClaims.NAME, Username), }; } } diff --git a/src/server/Startup.cs b/src/server/Startup.cs index 4ad70fc..aa07f33 100644 --- a/src/server/Startup.cs +++ b/src/server/Startup.cs @@ -12,25 +12,6 @@ public class Startup private IWebHostEnvironment WebHostEnvironment { get; } private IConfiguration Configuration { get; } - private string AppDatabaseConnectionString() { - var host = Configuration.GetValue<string>("DB_HOST"); - var port = Configuration.GetValue<string>("DB_PORT"); - var database = Configuration.GetValue<string>("DB_NAME"); - var user = Configuration.GetValue<string>("DB_USER"); - var password = Configuration.GetValue<string>("DB_PASSWORD"); - return $"Server={host};Port={port};Database={database};User Id={user};Password={password}"; - } - - public string QuartzDatabaseConnectionString() { - var host = Configuration.GetValue<string>("QUARTZ_DB_HOST"); - var port = Configuration.GetValue<string>("QUARTZ_DB_PORT"); - var database = Configuration.GetValue<string>("QUARTZ_DB_NAME"); - var user = Configuration.GetValue<string>("QUARTZ_DB_USER"); - var password = Configuration.GetValue<string>("QUARTZ_DB_PASSWORD"); - return $"Server={host};Port={port};Database={database};User Id={user};Password={password}"; - } - - // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddDataProtection() @@ -45,7 +26,7 @@ public class Startup services.Configure(AppJsonSettings.Default); services.AddDbContext<AppDbContext>(options => { - options.UseNpgsql(AppDatabaseConnectionString(), + options.UseNpgsql(ConnectionStrings.AppDatabaseConnectionString(Configuration), builder => { builder.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery); builder.EnableRetryOnFailure(5, TimeSpan.FromSeconds(10), default); @@ -58,7 +39,7 @@ public class Startup services.AddQuartz(options => { options.UsePersistentStore(o => { - o.UsePostgres(QuartzDatabaseConnectionString()); + o.UsePostgres(ConnectionStrings.QuartzDatabaseConnectionString(Configuration)); o.UseSerializer<QuartzJsonSerializer>(); }); options.UseMicrosoftDependencyInjectionJobFactory(); @@ -83,20 +64,21 @@ public class Startup options.Events.OnRedirectToAccessDenied = options.Events.OnRedirectToLogin = c => { c.Response.StatusCode = StatusCodes.Status401Unauthorized; - return Task.FromResult<object>(null); + return Task.FromResult<CookieAuthenticationOptions>(default); }; }) - // TODO: Handle github claims, current behaviour creates entries with user_id set to default guid :D .AddGitHub(options => { options.ClientSecret = Configuration.GetValue<string>("GH_CLIENT_SECRET"); options.ClientId = Configuration.GetValue<string>("GH_CLIENT_ID"); options.SaveTokens = true; + options.ClaimActions.MapJsonKey(AppClaims.GITHUB_ID, "id"); options.CorrelationCookie = new CookieBuilder { - Name = "gh_corr", + Name = "gh_correlation", SameSite = SameSiteMode.Lax, SecurePolicy = CookieSecurePolicy.Always, HttpOnly = true, }; + options.Events.OnCreatingTicket = context => HandleGithubCreatingTicket.Handle(context, Configuration); }) .AddScheme<AuthenticationSchemeOptions, BasicAuthenticationHandler>(Constants.BASIC_AUTH_SCHEME, default); diff --git a/src/server/StaticData/AppClaims.cs b/src/server/StaticData/AppClaims.cs new file mode 100644 index 0000000..86437d4 --- /dev/null +++ b/src/server/StaticData/AppClaims.cs @@ -0,0 +1,8 @@ +namespace IOL.BookmarkThing.Server.StaticData; + +public static class AppClaims +{ + public const string GITHUB_ID = "gh_id"; + public const string USER_ID = "user_id"; + public const string NAME = "name"; +} diff --git a/src/server/Utilities/ConnectionStrings.cs b/src/server/Utilities/ConnectionStrings.cs new file mode 100644 index 0000000..8ea8f70 --- /dev/null +++ b/src/server/Utilities/ConnectionStrings.cs @@ -0,0 +1,22 @@ +namespace IOL.BookmarkThing.Server.Utilities; + +public static class ConnectionStrings +{ + public static string AppDatabaseConnectionString(IConfiguration Configuration) { + var host = Configuration.GetValue<string>("DB_HOST"); + var port = Configuration.GetValue<string>("DB_PORT"); + var database = Configuration.GetValue<string>("DB_NAME"); + var user = Configuration.GetValue<string>("DB_USER"); + var password = Configuration.GetValue<string>("DB_PASSWORD"); + return $"Server={host};Port={port};Database={database};User Id={user};Password={password}"; + } + + public static string QuartzDatabaseConnectionString(IConfiguration Configuration) { + var host = Configuration.GetValue<string>("QUARTZ_DB_HOST"); + var port = Configuration.GetValue<string>("QUARTZ_DB_PORT"); + var database = Configuration.GetValue<string>("QUARTZ_DB_NAME"); + var user = Configuration.GetValue<string>("QUARTZ_DB_USER"); + var password = Configuration.GetValue<string>("QUARTZ_DB_PASSWORD"); + return $"Server={host};Port={port};Database={database};User Id={user};Password={password}"; + } +} diff --git a/src/server/Utilities/HandleGithubCreatingTicket.cs b/src/server/Utilities/HandleGithubCreatingTicket.cs new file mode 100644 index 0000000..3ead322 --- /dev/null +++ b/src/server/Utilities/HandleGithubCreatingTicket.cs @@ -0,0 +1,30 @@ +using Microsoft.AspNetCore.Authentication.OAuth; +using Npgsql; + +namespace IOL.BookmarkThing.Server.Utilities; + +public static class HandleGithubCreatingTicket +{ + public static Task Handle(OAuthCreatingTicketContext context, IConfiguration configuration) { + var ghid = context.Identity?.FindFirst(p => p.Type == AppClaims.GITHUB_ID); + if (ghid == default) { + return default; + } + + var connstring = ConnectionStrings.AppDatabaseConnectionString(configuration); + var connection = new NpgsqlConnection(connstring); + connection.Open(); + var query = new NpgsqlCommand(@$"SELECT user_id FROM github_user_mappings WHERE github_id='{ghid}'", connection); + var x = query.ExecuteReader(); + foreach (var row in x) { + Console.WriteLine(JsonSerializer.Serialize(row)); + } + + // var claims = context.Identity.Claims.ToList(); + // foreach (var claim in claims) { + // context.Identity.RemoveClaim(claim); + // } + + return Task.CompletedTask; + } +} |
