EF: AccountLinker

This commit is contained in:
pavelbannov 2019-12-04 14:40:42 +03:00
parent a047332f9c
commit cb8d7ed191
3 changed files with 108 additions and 29 deletions

View File

@ -0,0 +1,30 @@
using ASC.Core.Common.EF.Model;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
namespace ASC.Core.Common.EF.Context
{
public class AccountLinkContext : BaseDbContext
{
public DbSet<AccountLinks> AccountLinks { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.AddAccountLinks();
}
}
public static class AccountLinkContextExtension
{
public static IServiceCollection AddAccountLinkContextService(this IServiceCollection services)
{
services.TryAddScoped<DbContextManager<AccountLinkContext>>();
services.TryAddScoped<IConfigureOptions<AccountLinkContext>, ConfigureDbContext>();
services.TryAddScoped<AccountLinkContext>();
return services;
}
}
}

View File

@ -0,0 +1,25 @@
using System;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;
namespace ASC.Core.Common.EF.Model
{
[Table("account_links")]
public class AccountLinks : BaseDbContext
{
public string Id { get; set; }
public string UId { get; set; }
public string Provider { get; set; }
public string Profile { get; set; }
public DateTime Linked { get; set; }
}
public static class AccountLinksExtension
{
public static void AddAccountLinks(this ModelBuilder modelBuilder)
{
modelBuilder.Entity<AccountLinks>()
.HasKey(c => new { c.Id, c.UId });
}
}
}

View File

@ -29,11 +29,13 @@ using System.Collections.Generic;
using System.Linq;
using ASC.Common.Caching;
using ASC.Common.Data;
using ASC.Common.Data.Sql;
using ASC.Common.Data.Sql.Expressions;
using ASC.Common.Utils;
using ASC.Core.Common.EF;
using ASC.Core.Common.EF.Context;
using ASC.Core.Common.EF.Model;
using ASC.FederatedLogin.Profile;
using ASC.Security.Cryptography;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
@ -70,24 +72,28 @@ namespace ASC.FederatedLogin
{
public Signature Signature { get; }
public InstanceCrypto InstanceCrypto { get; }
public DbOptionsManager DbOptions { get; }
public AccountLinkerStorage AccountLinkerStorage { get; }
public DbContextManager<AccountLinkContext> DbContextManager { get; }
public ConfigureAccountLinker(Signature signature, InstanceCrypto instanceCrypto, DbOptionsManager dbOptions, AccountLinkerStorage accountLinkerStorage)
public ConfigureAccountLinker(
Signature signature,
InstanceCrypto instanceCrypto,
AccountLinkerStorage accountLinkerStorage,
DbContextManager<AccountLinkContext> dbContextManager)
{
Signature = signature;
InstanceCrypto = instanceCrypto;
DbOptions = dbOptions;
AccountLinkerStorage = accountLinkerStorage;
DbContextManager = dbContextManager;
}
public void Configure(string name, AccountLinker options)
{
options.DbId = name;
options.AccountLinkerStorage = AccountLinkerStorage;
options.DbOptions = DbOptions;
options.InstanceCrypto = InstanceCrypto;
options.Signature = Signature;
options.AccountLinkContext = DbContextManager;
}
public void Configure(AccountLinker options)
@ -101,8 +107,16 @@ namespace ASC.FederatedLogin
public string DbId { get; set; }
public Signature Signature { get; set; }
public InstanceCrypto InstanceCrypto { get; set; }
public DbOptionsManager DbOptions { get; set; }
public AccountLinkerStorage AccountLinkerStorage { get; set; }
public DbContextManager<AccountLinkContext> AccountLinkContext { get; set; }
public DbSet<AccountLinks> AccountLinks
{
get
{
return AccountLinkContext.Get(DbId).AccountLinks;
}
}
public IEnumerable<string> GetLinkedObjects(string id, string provider)
{
@ -116,10 +130,11 @@ namespace ASC.FederatedLogin
public IEnumerable<string> GetLinkedObjectsByHashId(string hashid)
{
var db = DbOptions.Get(DbId);
var query = new SqlQuery("account_links")
.Select("id").Where("uid", hashid).Where(!Exp.Eq("provider", string.Empty));
return db.ExecuteList(query).ConvertAll(x => (string)x[0]);
return AccountLinks
.Where(r => r.UId == hashid)
.Where(r => r.Provider != string.Empty)
.Select(r => r.Id)
.ToList();
}
public IEnumerable<LoginProfile> GetLinkedProfiles(string obj, string provider)
@ -135,23 +150,27 @@ namespace ASC.FederatedLogin
private List<LoginProfile> GetLinkedProfilesFromDB(string obj)
{
//Retrieve by uinque id
var db = DbOptions.Get(DbId);
var query = new SqlQuery("account_links")
.Select("profile").Where("id", obj);
return db.ExecuteList(query).ConvertAll(x => LoginProfile.CreateFromSerializedString(Signature, InstanceCrypto, (string)x[0]));
return AccountLinks
.Where(r => r.Id == obj)
.Select(r => r.Profile)
.ToList()
.ConvertAll(x => LoginProfile.CreateFromSerializedString(Signature, InstanceCrypto, x));
}
public void AddLink(string obj, LoginProfile profile)
{
var db = DbOptions.Get(DbId);
db.ExecuteScalar<int>(
new SqlInsert("account_links", true)
.InColumnValue("id", obj)
.InColumnValue("uid", profile.HashId)
.InColumnValue("provider", profile.Provider)
.InColumnValue("profile", profile.ToSerializedString())
.InColumnValue("linked", DateTime.UtcNow)
);
var accountLink = new AccountLinks
{
Id = obj,
UId = profile.HashId,
Provider = profile.Provider,
Profile = profile.ToSerializedString(),
Linked = DateTime.UtcNow
};
AccountLinks.Add(accountLink);
AccountLinkContext.Get(DbId).SaveChanges();
AccountLinkerStorage.RemoveFromCache(obj);
}
@ -172,14 +191,18 @@ namespace ASC.FederatedLogin
public void RemoveProvider(string obj, string provider = null, string hashId = null)
{
var sql = new SqlDelete("account_links").Where("id", obj);
using var tr = AccountLinkContext.Get(DbId).Database.BeginTransaction();
if (!string.IsNullOrEmpty(provider)) sql.Where("provider", provider);
if (!string.IsNullOrEmpty(hashId)) sql.Where("uid", hashId);
var accountLinkQuery = AccountLinks
.Where(r => r.Id == obj);
var db = DbOptions.Get(DbId);
db.ExecuteScalar<int>(sql);
if (!string.IsNullOrEmpty(provider)) accountLinkQuery = accountLinkQuery.Where(r => r.Provider == provider);
if (!string.IsNullOrEmpty(hashId)) accountLinkQuery = accountLinkQuery.Where(r => r.UId == hashId);
var accountLink = accountLinkQuery.FirstOrDefault();
AccountLinks.Remove(accountLink);
tr.Commit();
AccountLinkerStorage.RemoveFromCache(obj);
}
}
@ -203,6 +226,7 @@ namespace ASC.FederatedLogin
services.TryAddScoped<IConfigureOptions<AccountLinker>, ConfigureAccountLinker>();
return services
.AddAccountLinkContextService()
.AddSignatureService()
.AddInstanceCryptoService()
.AddDbManagerService()