mirror of https://github.com/abpframework/abp.git
108 changed files with 2085 additions and 230 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); |
||||
|
} |
||||
|
} |
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue