网站首页 网站源码
website
站点相关全部源代码,隐藏了一些关于服务器的信息
using System.Collections.Immutable;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Text.Json;
using Dpz.Core.EnumLibrary;
using Dpz.Core.MongodbAccess;
using Dpz.Core.Public.Entity.Auth;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using OpenIddict.Abstractions;

namespace Dpz.Core.Auth.Service;

public sealed class DpzApplicationStore(
    IRepository<DpzApplication> repository,
    ILogger<DpzApplicationStore> logger
) : IOpenIddictApplicationStore<DpzApplication>
{
    public async ValueTask<long> CountAsync(CancellationToken cancellationToken)
    {
        logger.LogInformation("Counting applications");
        return await repository.Collection.CountDocumentsAsync(
            FilterDefinition<DpzApplication>.Empty,
            cancellationToken: cancellationToken
        );
    }

    public async ValueTask<long> CountAsync<TResult>(
        Func<IQueryable<DpzApplication>, IQueryable<TResult>> query,
        CancellationToken cancellationToken
    )
    {
        logger.LogInformation("Counting applications with custom query");
        return await query(repository.MongodbQueryable)
            .LongCountAsync(cancellationToken: cancellationToken);
    }

    public async ValueTask CreateAsync(
        DpzApplication application,
        CancellationToken cancellationToken
    )
    {
        logger.LogInformation(
            "Creating application {ClientId} ({Id})",
            application.ClientId,
            application.Id
        );
        await repository.InsertAsync(application, cancellationToken);
    }

    public async ValueTask DeleteAsync(
        DpzApplication application,
        CancellationToken cancellationToken
    )
    {
        await repository.DeleteAsync(application.Id, cancellationToken);
    }

    public async ValueTask<DpzApplication?> FindByIdAsync(
        string identifier,
        CancellationToken cancellationToken
    )
    {
        if (ObjectId.TryParse(identifier, out var oid))
        {
            return await repository.FindAsync(oid, cancellationToken);
        }

        return null;
    }

    public async ValueTask<DpzApplication?> FindByClientIdAsync(
        string identifier,
        CancellationToken cancellationToken
    )
    {
        var application = await repository
            .SearchFor(x => x.ClientId == identifier)
            .FirstOrDefaultAsync(cancellationToken);
        return application;
    }

    public IAsyncEnumerable<DpzApplication> FindByPostLogoutRedirectUriAsync(
        string uri,
        CancellationToken cancellationToken
    )
    {
        var filter = Builders<DpzApplication>.Filter.Eq(x => x.PostLogoutRedirectUri, uri);
        return repository.SearchForAsync(filter, cancellationToken);
    }

    public IAsyncEnumerable<DpzApplication> FindByRedirectUriAsync(
        string uri,
        CancellationToken cancellationToken
    )
    {
        var filter = Builders<DpzApplication>.Filter.Eq(x => x.RedirectUris, uri);
        return repository.SearchForAsync(filter, cancellationToken);
    }

    public async ValueTask<string?> GetApplicationTypeAsync(
        DpzApplication application,
        CancellationToken cancellationToken
    )
    {
        if (!string.IsNullOrWhiteSpace(application.ApplicationType))
        {
            return application.ApplicationType;
        }

        if (application.Id != default || application.Id != ObjectId.Empty)
        {
            return (
                await FindByIdAsync(application.Id.ToString(), cancellationToken)
            )?.ApplicationType;
        }

        if (!string.IsNullOrWhiteSpace(application.ClientId))
        {
            return (
                await FindByClientIdAsync(application.ClientId, cancellationToken)
            )?.ApplicationType;
        }

        return null;
    }

    public async ValueTask<TResult?> GetAsync<TState, TResult>(
        Func<IQueryable<DpzApplication>, TState, IQueryable<TResult>> query,
        TState state,
        CancellationToken cancellationToken
    )
    {
        return await Task.FromResult(query(repository.MongodbQueryable, state).FirstOrDefault());
    }

    public async ValueTask<string?> GetClientIdAsync(
        DpzApplication application,
        CancellationToken cancellationToken
    )
    {
        return await ValueTask.FromResult(application.ClientId);
    }

    public async ValueTask<string?> GetClientSecretAsync(
        DpzApplication application,
        CancellationToken cancellationToken
    )
    {
        return await ValueTask.FromResult(application.ClientSecret);
    }

    public async ValueTask<string?> GetClientTypeAsync(
        DpzApplication application,
        CancellationToken cancellationToken
    )
    {
        return await ValueTask.FromResult(application.ClientType);
    }

    public ValueTask<string?> GetConsentTypeAsync(
        DpzApplication application,
        CancellationToken cancellationToken
    )
    {
        return ValueTask.FromResult<string?>(string.Empty);
    }

    public ValueTask<string?> GetDisplayNameAsync(
        DpzApplication application,
        CancellationToken cancellationToken
    )
    {
        return ValueTask.FromResult<string?>(application.DisplayName);
    }

    public ValueTask<ImmutableDictionary<CultureInfo, string>> GetDisplayNamesAsync(
        DpzApplication application,
        CancellationToken cancellationToken
    )
    {
        return ValueTask.FromResult(ImmutableDictionary<CultureInfo, string>.Empty);
    }

    public ValueTask<string?> GetIdAsync(
        DpzApplication application,
        CancellationToken cancellationToken
    )
    {
        return ValueTask.FromResult<string?>(application.Id.ToString());
    }

    public ValueTask<JsonWebKeySet?> GetJsonWebKeySetAsync(
        DpzApplication application,
        CancellationToken cancellationToken
    )
    {
        return ValueTask.FromResult<JsonWebKeySet?>(null);
    }

    public async ValueTask<ImmutableArray<string>> GetPermissionsAsync(
        DpzApplication application,
        CancellationToken cancellationToken
    )
    {
        ImmutableArray<string> result = [.. application.Permissions ?? []];
        return await ValueTask.FromResult(result);
    }

    public async ValueTask<ImmutableArray<string>> GetPostLogoutRedirectUrisAsync(
        DpzApplication application,
        CancellationToken cancellationToken
    )
    {
        return await ValueTask.FromResult(
            application
                .PostLogoutRedirectUri?.Split([';'], StringSplitOptions.RemoveEmptyEntries)
                .ToImmutableArray() ?? []
        );
    }

    public ValueTask<ImmutableDictionary<string, JsonElement>> GetPropertiesAsync(
        DpzApplication application,
        CancellationToken cancellationToken
    )
    {
        return ValueTask.FromResult(ImmutableDictionary<string, JsonElement>.Empty);
    }

    public ValueTask<ImmutableArray<string>> GetRedirectUrisAsync(
        DpzApplication application,
        CancellationToken cancellationToken
    )
    {
        return ValueTask.FromResult(
            (
                application.RedirectUris?.Split([';'], StringSplitOptions.RemoveEmptyEntries) ?? []
            ).ToImmutableArray()
        );
    }

    public ValueTask<ImmutableArray<string>> GetRequirementsAsync(
        DpzApplication application,
        CancellationToken cancellationToken
    )
    {
        return ValueTask.FromResult(ImmutableArray<string>.Empty);
    }

    public ValueTask<ImmutableDictionary<string, string>> GetSettingsAsync(
        DpzApplication application,
        CancellationToken cancellationToken
    )
    {
        return ValueTask.FromResult(ImmutableDictionary<string, string>.Empty);
    }

    public ValueTask<DpzApplication> InstantiateAsync(CancellationToken cancellationToken)
    {
        return ValueTask.FromResult(new DpzApplication { Id = ObjectId.GenerateNewId() });
    }

    public IAsyncEnumerable<DpzApplication> ListAsync(
        int? count,
        int? offset,
        CancellationToken cancellationToken
    )
    {
        var options = new FindOptions<DpzApplication>();

        if (offset.HasValue)
        {
            options.Skip = offset.Value;
        }

        if (count.HasValue)
        {
            options.Limit = count.Value;
        }

        return repository.SearchForAsync(
            Builders<DpzApplication>.Filter.Empty,
            options,
            cancellationToken
        );
    }

    public async IAsyncEnumerable<TResult> ListAsync<TState, TResult>(
        Func<IQueryable<DpzApplication>, TState, IQueryable<TResult>> query,
        TState state,
        [EnumeratorCancellation] CancellationToken cancellationToken
    )
    {
        var projected = query(repository.MongodbQueryable, state);
        await foreach (
            var element in projected.ToAsyncEnumerable().WithCancellation(cancellationToken)
        )
        {
            yield return element;
        }
    }

    public ValueTask SetApplicationTypeAsync(
        DpzApplication application,
        string? type,
        CancellationToken cancellationToken
    )
    {
        application.ApplicationType = type;
        return ValueTask.CompletedTask;
    }

    public ValueTask SetClientIdAsync(
        DpzApplication application,
        string? identifier,
        CancellationToken cancellationToken
    )
    {
        application.ClientId = identifier;
        return ValueTask.CompletedTask;
    }

    public ValueTask SetClientSecretAsync(
        DpzApplication application,
        string? secret,
        CancellationToken cancellationToken
    )
    {
        application.ClientSecret = secret;
        return ValueTask.CompletedTask;
    }

    public ValueTask SetClientTypeAsync(
        DpzApplication application,
        string? type,
        CancellationToken cancellationToken
    )
    {
        application.ClientType = type;
        return ValueTask.CompletedTask;
    }

    public ValueTask SetConsentTypeAsync(
        DpzApplication application,
        string? type,
        CancellationToken cancellationToken
    )
    {
        return ValueTask.CompletedTask;
    }

    public ValueTask SetDisplayNameAsync(
        DpzApplication application,
        string? name,
        CancellationToken cancellationToken
    )
    {
        application.DisplayName = name;
        return ValueTask.CompletedTask;
    }

    public ValueTask SetDisplayNamesAsync(
        DpzApplication application,
        ImmutableDictionary<CultureInfo, string> names,
        CancellationToken cancellationToken
    )
    {
        return ValueTask.CompletedTask;
    }

    public ValueTask SetJsonWebKeySetAsync(
        DpzApplication application,
        JsonWebKeySet? set,
        CancellationToken cancellationToken
    )
    {
        return ValueTask.CompletedTask;
    }

    public ValueTask SetPermissionsAsync(
        DpzApplication application,
        ImmutableArray<string> permissions,
        CancellationToken cancellationToken
    )
    {
        application.Permissions = permissions.ToList();
        return ValueTask.CompletedTask;
    }

    public async ValueTask SetPostLogoutRedirectUrisAsync(
        DpzApplication application,
        ImmutableArray<string> uris,
        CancellationToken cancellationToken
    )
    {
        application.PostLogoutRedirectUri = string.Join(';', uris);
        await Task.CompletedTask;
    }

    public ValueTask SetPropertiesAsync(
        DpzApplication application,
        ImmutableDictionary<string, JsonElement> properties,
        CancellationToken cancellationToken
    )
    {
        var bson = BsonDocument.Parse(JsonSerializer.Serialize(properties));

        application.Properties = bson;
        return ValueTask.CompletedTask;
    }

    public ValueTask SetRedirectUrisAsync(
        DpzApplication application,
        ImmutableArray<string> uris,
        CancellationToken cancellationToken
    )
    {
        application.RedirectUris = string.Join(';', uris);
        return ValueTask.CompletedTask;
    }

    public ValueTask SetRequirementsAsync(
        DpzApplication application,
        ImmutableArray<string> requirements,
        CancellationToken cancellationToken
    )
    {
        return ValueTask.CompletedTask;
    }

    public ValueTask SetSettingsAsync(
        DpzApplication application,
        ImmutableDictionary<string, string> settings,
        CancellationToken cancellationToken
    )
    {
        return ValueTask.CompletedTask;
    }

    public async ValueTask UpdateAsync(
        DpzApplication application,
        CancellationToken cancellationToken
    )
    {
        // 不允许修改 id ClientId ClientSecret
        var update = Builders<DpzApplication>
            .Update.Set(x => x.DisplayName, application.DisplayName)
            .Set(x => x.RedirectUris, application.RedirectUris)
            .Set(x => x.PostLogoutRedirectUri, application.PostLogoutRedirectUri)
            .Set(x => x.ApplicationType, application.ApplicationType)
            .Set(x => x.ClientType, application.ClientType)
            .Set(x => x.Permissions, application.Permissions)
            .Set(x => x.Properties, application.Properties);

        await repository.UpdateAsync(x => x.Id == application.Id, update, cancellationToken);
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

上述代码定义了一个名为 DpzApplicationStore 的类,它实现了 IOpenIddictApplicationStore<DpzApplication> 接口。这个类主要用于管理与 OpenIddict 应用程序相关的操作,具体功能如下:

主要功能

  1. 计数操作:

    • CountAsync: 计算存储中的应用程序数量。
    • CountAsync<TResult>: 计算符合自定义查询条件的应用程序数量。
  2. 创建和删除应用程序:

    • CreateAsync: 创建一个新的应用程序并将其插入到存储中。
    • DeleteAsync: 根据应用程序的 ID 删除应用程序。
  3. 查找应用程序:

    • FindByIdAsync: 根据应用程序的 ID 查找应用程序。
    • FindByClientIdAsync: 根据客户端 ID 查找应用程序。
    • FindByPostLogoutRedirectUriAsync: 根据注销后重定向 URI 查找应用程序。
    • FindByRedirectUriAsync: 根据重定向 URI 查找应用程序。
  4. 获取应用程序属性:

    • GetApplicationTypeAsync: 获取应用程序类型。
    • GetClientIdAsync: 获取客户端 ID。
    • GetClientSecretAsync: 获取客户端密钥。
    • GetClientTypeAsync: 获取客户端类型。
    • GetDisplayNameAsync: 获取显示名称。
    • GetRedirectUrisAsync: 获取重定向 URI 列表。
    • GetPostLogoutRedirectUrisAsync: 获取注销后重定向 URI 列表。
    • GetPermissionsAsync: 获取应用程序的权限。
  5. 设置应用程序属性:

    • SetApplicationTypeAsync: 设置应用程序类型。
    • SetClientIdAsync: 设置客户端 ID。
    • SetClientSecretAsync: 设置客户端密钥。
    • SetDisplayNameAsync: 设置显示名称。
    • SetRedirectUrisAsync: 设置重定向 URI 列表。
    • SetPostLogoutRedirectUrisAsync: 设置注销后重定向 URI 列表。
    • SetPermissionsAsync: 设置应用程序的权限。
  6. 更新应用程序:

    • UpdateAsync: 更新应用程序的属性,但不允许修改 ID、客户端 ID 和客户端密钥。
  7. 实例化应用程序:

    • InstantiateAsync: 创建一个新的 DpzApplication 实例,生成一个新的 ID。
  8. 列出应用程序:

    • ListAsync: 列出所有应用程序,支持分页(通过 countoffset 参数)。
    • ListAsync<TState, TResult>: 根据自定义查询列出应用程序。
  9. 获取和设置其他属性:

    • GetJsonWebKeySetAsync: 获取 JSON Web 密钥集(目前返回 null)。
    • GetPropertiesAsync: 获取应用程序的属性(目前返回空字典)。
    • GetRequirementsAsync: 获取应用程序的要求(目前返回空数组)。
    • GetSettingsAsync: 获取应用程序的设置(目前返回空字典)。

设计考虑

  • 异步编程: 该类使用异步方法(asyncawait)来处理数据库操作,以提高性能和响应能力。
  • 日志记录: 使用 ILogger 记录操作信息,便于调试和监控。
  • MongoDB: 该类与 MongoDB 数据库交互,使用 MongoDB 的驱动程序进行 CRUD 操作。
  • 不可变集合: 使用 ImmutableArrayImmutableDictionary 来处理集合,确保数据的不可变性。

总结

DpzApplicationStore 类是一个用于管理 OpenIddict 应用程序的存储类,提供了创建、查找、更新和删除应用程序的功能,并支持异步操作和日志记录。它与 MongoDB 数据库交互,使用了现代 C# 的一些特性,如异步编程和不可变集合。

loading