mirror of https://github.com/abpframework/abp.git
committed by
GitHub
71 changed files with 1882 additions and 126 deletions
@ -0,0 +1,3 @@ |
|||||
|
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
||||
|
<ConfigureAwait ContinueOnCapturedContext="false" /> |
||||
|
</Weavers> |
||||
@ -0,0 +1,30 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
||||
|
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
||||
|
<xs:element name="Weavers"> |
||||
|
<xs:complexType> |
||||
|
<xs:all> |
||||
|
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
||||
|
<xs:complexType> |
||||
|
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:all> |
||||
|
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:schema> |
||||
@ -0,0 +1,23 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\..\configureawait.props" /> |
||||
|
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFrameworks>netstandard2.0;netstandard2.1;net8.0</TargetFrameworks> |
||||
|
<Nullable>enable</Nullable> |
||||
|
<WarningsAsErrors>Nullable</WarningsAsErrors> |
||||
|
<AssemblyName>Volo.Abp.AspNetCore.Abstractions</AssemblyName> |
||||
|
<PackageId>Volo.Abp.AspNetCore.Abstractions</PackageId> |
||||
|
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
||||
|
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
||||
|
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
||||
|
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
||||
|
<RootNamespace /> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\Volo.Abp.Core\Volo.Abp.Core.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,15 @@ |
|||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Volo.Abp.AspNetCore.VirtualFileSystem; |
||||
|
using Volo.Abp.AspNetCore.WebClientInfo; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore; |
||||
|
|
||||
|
public class AbpAspNetCoreAbstractionsModule : AbpModule |
||||
|
{ |
||||
|
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
context.Services.AddSingleton<IWebContentFileProvider, NullWebContentFileProvider>(); |
||||
|
context.Services.AddSingleton<IWebClientInfoProvider, NullWebClientInfoProvider>();; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
using Microsoft.Extensions.FileProviders; |
||||
|
using Microsoft.Extensions.Primitives; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.VirtualFileSystem; |
||||
|
|
||||
|
public class NullWebContentFileProvider : IWebContentFileProvider |
||||
|
{ |
||||
|
public virtual IFileInfo GetFileInfo(string subpath) |
||||
|
{ |
||||
|
return new NotFoundFileInfo(subpath); |
||||
|
} |
||||
|
|
||||
|
public virtual IDirectoryContents GetDirectoryContents(string subpath) |
||||
|
{ |
||||
|
return new NotFoundDirectoryContents(); |
||||
|
} |
||||
|
|
||||
|
public virtual IChangeToken Watch(string filter) |
||||
|
{ |
||||
|
return NullChangeToken.Singleton; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
namespace Volo.Abp.AspNetCore.WebClientInfo; |
||||
|
|
||||
|
public class NullWebClientInfoProvider : IWebClientInfoProvider |
||||
|
{ |
||||
|
public virtual string? BrowserInfo { get; } |
||||
|
|
||||
|
public virtual string? ClientIpAddress { get; } |
||||
|
|
||||
|
public virtual string? DeviceInfo { get; } |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using Volo.Abp.Security.Claims; |
||||
|
|
||||
|
namespace Volo.Abp.Identity.AspNetCore; |
||||
|
|
||||
|
public class AbpRefreshingPrincipalOptions |
||||
|
{ |
||||
|
public List<string> CurrentPrincipalKeepClaimTypes { get; set; } |
||||
|
|
||||
|
public AbpRefreshingPrincipalOptions() |
||||
|
{ |
||||
|
CurrentPrincipalKeepClaimTypes = new List<string> |
||||
|
{ |
||||
|
AbpClaimTypes.SessionId |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
namespace Volo.Abp.Identity; |
||||
|
|
||||
|
public class IdentitySessionConsts |
||||
|
{ |
||||
|
public static int MaxSessionIdLength { get; set; } = 128; |
||||
|
|
||||
|
public static int MaxDeviceLength { get; set; } = 64; |
||||
|
|
||||
|
public static int MaxDeviceInfoLength { get; set; } = 64; |
||||
|
|
||||
|
public static int MaxClientIdLength { get; set; } = 64; |
||||
|
|
||||
|
public static int MaxIpAddressesLength { get; set; } = 256; |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
namespace Volo.Abp.Identity; |
||||
|
|
||||
|
public static class IdentitySessionDevices |
||||
|
{ |
||||
|
public const string Web = "Web"; |
||||
|
|
||||
|
public const string OAuth = "OAuth"; |
||||
|
|
||||
|
public const string Mobile = "Mobile"; |
||||
|
} |
||||
@ -0,0 +1,35 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Domain.Repositories; |
||||
|
|
||||
|
namespace Volo.Abp.Identity; |
||||
|
|
||||
|
public interface IIdentitySessionRepository : IBasicRepository<IdentitySession, Guid> |
||||
|
{ |
||||
|
Task<IdentitySession> FindAsync(string sessionId, CancellationToken cancellationToken = default); |
||||
|
|
||||
|
Task<IdentitySession> GetAsync(string sessionId, CancellationToken cancellationToken = default); |
||||
|
|
||||
|
Task<List<IdentitySession>> GetListAsync( |
||||
|
string sorting = null, |
||||
|
int maxResultCount = int.MaxValue, |
||||
|
int skipCount = 0, |
||||
|
Guid? userId = null, |
||||
|
string device = null, |
||||
|
string clientId = null, |
||||
|
CancellationToken cancellationToken = default); |
||||
|
|
||||
|
Task<long> GetCountAsync( |
||||
|
Guid? userId = null, |
||||
|
string device = null, |
||||
|
string clientId = null, |
||||
|
CancellationToken cancellationToken = default); |
||||
|
|
||||
|
Task DeleteAllAsync(Guid userId, Guid? exceptSessionId = null, CancellationToken cancellationToken = default); |
||||
|
|
||||
|
Task DeleteAllAsync(Guid userId, string device, Guid? exceptSessionId = null, CancellationToken cancellationToken = default); |
||||
|
|
||||
|
Task DeleteAllAsync(TimeSpan inactiveTimeSpan, CancellationToken cancellationToken = default); |
||||
|
} |
||||
@ -0,0 +1,90 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using Volo.Abp.Domain.Entities; |
||||
|
using Volo.Abp.MultiTenancy; |
||||
|
|
||||
|
namespace Volo.Abp.Identity; |
||||
|
|
||||
|
public class IdentitySession : BasicAggregateRoot<Guid>, IMultiTenant |
||||
|
{ |
||||
|
public virtual string SessionId { get; protected set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Web, Mobile ...
|
||||
|
/// </summary>
|
||||
|
public virtual string Device { get; protected set; } |
||||
|
|
||||
|
public virtual string DeviceInfo { get; protected set; } |
||||
|
|
||||
|
public virtual Guid? TenantId { get; protected set; } |
||||
|
|
||||
|
public virtual Guid UserId { get; protected set; } |
||||
|
|
||||
|
public virtual string ClientId { get; set; } |
||||
|
|
||||
|
public virtual string IpAddresses { get; protected set; } |
||||
|
|
||||
|
public virtual DateTime SignedIn { get; protected set; } |
||||
|
|
||||
|
public virtual DateTime? LastAccessed { get; protected set; } |
||||
|
|
||||
|
protected IdentitySession() |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public IdentitySession( |
||||
|
Guid id, |
||||
|
string sessionId, |
||||
|
string device, |
||||
|
string deviceInfo, |
||||
|
Guid userId, |
||||
|
Guid? tenantId, |
||||
|
string clientId, |
||||
|
string ipAddresses, |
||||
|
DateTime signedIn, |
||||
|
DateTime? lastAccessed = null) |
||||
|
{ |
||||
|
Id = id; |
||||
|
SessionId = sessionId; |
||||
|
Device = device; |
||||
|
DeviceInfo = deviceInfo; |
||||
|
UserId = userId; |
||||
|
TenantId = tenantId; |
||||
|
ClientId = clientId; |
||||
|
IpAddresses = ipAddresses; |
||||
|
SignedIn = signedIn; |
||||
|
LastAccessed = lastAccessed; |
||||
|
} |
||||
|
|
||||
|
public void SetSignedInTime(DateTime signedIn) |
||||
|
{ |
||||
|
SignedIn = signedIn; |
||||
|
} |
||||
|
|
||||
|
public void UpdateLastAccessedTime(DateTime? lastAccessed) |
||||
|
{ |
||||
|
LastAccessed = lastAccessed; |
||||
|
} |
||||
|
|
||||
|
public void SetIpAddresses(IEnumerable<string> ipAddresses) |
||||
|
{ |
||||
|
IpAddresses = JoinAsString(ipAddresses); |
||||
|
} |
||||
|
|
||||
|
public IEnumerable<string> GetIpAddresses() |
||||
|
{ |
||||
|
return GetArrayFromString(IpAddresses); |
||||
|
} |
||||
|
|
||||
|
private static string JoinAsString(IEnumerable<string> list) |
||||
|
{ |
||||
|
var serialized = string.Join(",", list); |
||||
|
return serialized.IsNullOrWhiteSpace() ? null : serialized; |
||||
|
} |
||||
|
|
||||
|
private string[] GetArrayFromString(string str) |
||||
|
{ |
||||
|
return str?.Split(",", StringSplitOptions.RemoveEmptyEntries) ?? Array.Empty<string>(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,85 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Linq.Dynamic.Core; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.EntityFrameworkCore; |
||||
|
using Volo.Abp.Domain.Entities; |
||||
|
using Volo.Abp.Domain.Repositories.EntityFrameworkCore; |
||||
|
using Volo.Abp.EntityFrameworkCore; |
||||
|
using Volo.Abp.Timing; |
||||
|
|
||||
|
namespace Volo.Abp.Identity.EntityFrameworkCore; |
||||
|
|
||||
|
public class EfCoreIdentitySessionRepository : EfCoreRepository<IIdentityDbContext, IdentitySession, Guid>, IIdentitySessionRepository |
||||
|
{ |
||||
|
public EfCoreIdentitySessionRepository(IDbContextProvider<IIdentityDbContext> dbContextProvider) |
||||
|
: base(dbContextProvider) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public virtual async Task<IdentitySession> FindAsync(string sessionId, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
return await (await GetDbSetAsync()).FirstOrDefaultAsync(x => x.SessionId == sessionId, GetCancellationToken(cancellationToken)); |
||||
|
} |
||||
|
|
||||
|
public virtual async Task<IdentitySession> GetAsync(string sessionId, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
var session = await FindAsync(sessionId, cancellationToken); |
||||
|
if (session == null) |
||||
|
{ |
||||
|
throw new EntityNotFoundException(typeof(IdentitySession)); |
||||
|
} |
||||
|
|
||||
|
return session; |
||||
|
} |
||||
|
|
||||
|
public virtual async Task<List<IdentitySession>> GetListAsync( |
||||
|
string sorting = null, |
||||
|
int maxResultCount = int.MaxValue, |
||||
|
int skipCount = 0, |
||||
|
Guid? userId = null, |
||||
|
string device = null, |
||||
|
string clientId = null, |
||||
|
CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
return await (await GetDbSetAsync()) |
||||
|
.WhereIf(userId.HasValue, x => x.UserId == userId) |
||||
|
.WhereIf(!device.IsNullOrWhiteSpace(), x => x.Device == device) |
||||
|
.WhereIf(!clientId.IsNullOrWhiteSpace(), x => x.ClientId == clientId) |
||||
|
.OrderBy(sorting.IsNullOrWhiteSpace() ? $"{nameof(IdentitySession.LastAccessed)} desc" : sorting) |
||||
|
.PageBy(skipCount, maxResultCount) |
||||
|
.ToListAsync(GetCancellationToken(cancellationToken)); |
||||
|
} |
||||
|
|
||||
|
public virtual async Task<long> GetCountAsync( |
||||
|
Guid? userId = null, |
||||
|
string device = null, |
||||
|
string clientId = null, |
||||
|
CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
return await (await GetDbSetAsync()) |
||||
|
.WhereIf(userId.HasValue, x => x.UserId == userId) |
||||
|
.WhereIf(!device.IsNullOrWhiteSpace(), x => x.Device == device) |
||||
|
.WhereIf(!clientId.IsNullOrWhiteSpace(), x => x.ClientId == clientId) |
||||
|
.LongCountAsync(GetCancellationToken(cancellationToken)); |
||||
|
} |
||||
|
|
||||
|
public virtual async Task DeleteAllAsync(Guid userId, Guid? exceptSessionId = null, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
await DeleteAsync(x => x.UserId == userId && x.Id != exceptSessionId, cancellationToken: cancellationToken); |
||||
|
} |
||||
|
|
||||
|
public virtual async Task DeleteAllAsync(Guid userId, string device, Guid? exceptSessionId = null, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
await DeleteAsync(x => x.UserId == userId && x.Device == device && x.Id != exceptSessionId, cancellationToken: cancellationToken); |
||||
|
} |
||||
|
|
||||
|
public virtual async Task DeleteAllAsync(TimeSpan inactiveTimeSpan, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
var now = LazyServiceProvider.LazyGetRequiredService<IClock>().Now; |
||||
|
await DeleteDirectAsync(x => x.LastAccessed == null || x.LastAccessed < now.Subtract(inactiveTimeSpan), cancellationToken: cancellationToken); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,90 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Linq.Dynamic.Core; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using MongoDB.Driver; |
||||
|
using MongoDB.Driver.Linq; |
||||
|
using Volo.Abp.Domain.Entities; |
||||
|
using Volo.Abp.Domain.Repositories.MongoDB; |
||||
|
using Volo.Abp.MongoDB; |
||||
|
using Volo.Abp.Timing; |
||||
|
|
||||
|
namespace Volo.Abp.Identity.MongoDB; |
||||
|
|
||||
|
public class MongoIdentitySessionRepository : MongoDbRepository<IAbpIdentityMongoDbContext, IdentitySession, Guid>, IIdentitySessionRepository |
||||
|
{ |
||||
|
public MongoIdentitySessionRepository(IMongoDbContextProvider<IAbpIdentityMongoDbContext> dbContextProvider) |
||||
|
: base(dbContextProvider) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public virtual async Task<IdentitySession> FindAsync(string sessionId, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
return await (await GetMongoQueryableAsync(GetCancellationToken(cancellationToken))) |
||||
|
.As<IMongoQueryable<IdentitySession>>() |
||||
|
.FirstOrDefaultAsync(x => x.SessionId == sessionId, GetCancellationToken(cancellationToken)); |
||||
|
} |
||||
|
|
||||
|
public virtual async Task<IdentitySession> GetAsync(string sessionId, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
var session = await FindAsync(sessionId, cancellationToken); |
||||
|
if (session == null) |
||||
|
{ |
||||
|
throw new EntityNotFoundException(typeof(IdentitySession)); |
||||
|
} |
||||
|
|
||||
|
return session; |
||||
|
} |
||||
|
|
||||
|
public virtual async Task<List<IdentitySession>> GetListAsync( |
||||
|
string sorting = null, |
||||
|
int maxResultCount = int.MaxValue, |
||||
|
int skipCount = 0, |
||||
|
Guid? userId = null, |
||||
|
string device = null, |
||||
|
string clientId = null, |
||||
|
CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
return await (await GetMongoQueryableAsync(GetCancellationToken(cancellationToken))) |
||||
|
.WhereIf(userId.HasValue, x => x.UserId == userId) |
||||
|
.WhereIf(!device.IsNullOrWhiteSpace(), x => x.Device == device) |
||||
|
.WhereIf(!clientId.IsNullOrWhiteSpace(), x => x.ClientId == clientId) |
||||
|
.OrderBy(sorting.IsNullOrWhiteSpace() ? $"{nameof(IdentitySession.LastAccessed)} desc" : sorting) |
||||
|
.PageBy(skipCount, maxResultCount) |
||||
|
.As<IMongoQueryable<IdentitySession>>() |
||||
|
.ToListAsync(GetCancellationToken(cancellationToken)); |
||||
|
} |
||||
|
|
||||
|
public virtual async Task<long> GetCountAsync( |
||||
|
Guid? userId = null, |
||||
|
string device = null, |
||||
|
string clientId = null, |
||||
|
CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
return await (await GetMongoQueryableAsync(GetCancellationToken(cancellationToken))) |
||||
|
.WhereIf(userId.HasValue, x => x.UserId == userId) |
||||
|
.WhereIf(!device.IsNullOrWhiteSpace(), x => x.Device == device) |
||||
|
.WhereIf(!clientId.IsNullOrWhiteSpace(), x => x.ClientId == clientId) |
||||
|
.As<IMongoQueryable<IdentitySession>>() |
||||
|
.LongCountAsync(GetCancellationToken(cancellationToken)); |
||||
|
} |
||||
|
|
||||
|
public virtual async Task DeleteAllAsync(Guid userId, Guid? exceptSessionId = null, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
await DeleteAsync(x => x.UserId == userId && x.Id != exceptSessionId, cancellationToken: cancellationToken); |
||||
|
} |
||||
|
|
||||
|
public virtual async Task DeleteAllAsync(Guid userId, string device, Guid? exceptSessionId = null, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
await DeleteAsync(x => x.UserId == userId && x.Device == device && x.Id != exceptSessionId, cancellationToken: cancellationToken); |
||||
|
} |
||||
|
|
||||
|
public virtual async Task DeleteAllAsync(TimeSpan inactiveTimeSpan, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
var now = LazyServiceProvider.LazyGetRequiredService<IClock>().Now; |
||||
|
await DeleteDirectAsync(x => x.LastAccessed == null || x.LastAccessed < now.Subtract(inactiveTimeSpan), cancellationToken: cancellationToken); |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue