public static OpenIddictApplicationModel ToModel(this OpenIddictApplication entity)
    {
        if (entity == null)
        {
            return(null);
        }

        var model = new OpenIddictApplicationModel
        {
            Id                     = entity.Id,
            ClientId               = entity.ClientId,
            ClientSecret           = entity.ClientSecret,
            ConsentType            = entity.ConsentType,
            DisplayName            = entity.DisplayName,
            DisplayNames           = entity.DisplayNames,
            Permissions            = entity.Permissions,
            PostLogoutRedirectUris = entity.PostLogoutRedirectUris,
            Properties             = entity.Properties,
            RedirectUris           = entity.RedirectUris,
            Requirements           = entity.Requirements,
            Type                   = entity.Type,
            ClientUri              = entity.ClientUri,
            LogoUri                = entity.LogoUri
        };

        foreach (var extraProperty in entity.ExtraProperties)
        {
            model.ExtraProperties.Add(extraProperty.Key, extraProperty.Value);
        }

        return(model);
    }
    public ValueTask <ImmutableArray <string> > GetRequirementsAsync(OpenIddictApplicationModel application, CancellationToken cancellationToken)
    {
        Check.NotNull(application, nameof(application));

        if (string.IsNullOrEmpty(application.Requirements))
        {
            return(new ValueTask <ImmutableArray <string> >(ImmutableArray.Create <string>()));
        }

        using (var document = JsonDocument.Parse(application.Requirements))
        {
            var builder = ImmutableArray.CreateBuilder <string>(document.RootElement.GetArrayLength());

            foreach (var element in document.RootElement.EnumerateArray())
            {
                var value = element.GetString();
                if (string.IsNullOrEmpty(value))
                {
                    continue;
                }

                builder.Add(value);
            }

            return(new ValueTask <ImmutableArray <string> >(builder.ToImmutable()));
        }
    }
    public static OpenIddictApplication ToEntity(this OpenIddictApplicationModel model)
    {
        Check.NotNull(model, nameof(model));

        var entity = new OpenIddictApplication(model.Id)
        {
            ClientId               = model.ClientId,
            ClientSecret           = model.ClientSecret,
            ConsentType            = model.ConsentType,
            DisplayName            = model.DisplayName,
            DisplayNames           = model.DisplayNames,
            Permissions            = model.Permissions,
            PostLogoutRedirectUris = model.PostLogoutRedirectUris,
            Properties             = model.Properties,
            RedirectUris           = model.RedirectUris,
            Requirements           = model.Requirements,
            Type      = model.Type,
            ClientUri = model.ClientUri,
            LogoUri   = model.LogoUri
        };

        foreach (var extraProperty in model.ExtraProperties)
        {
            entity.ExtraProperties.Add(extraProperty.Key, extraProperty.Value);
        }

        return(entity);
    }
    public static OpenIddictApplication ToEntity(this OpenIddictApplicationModel model, OpenIddictApplication entity)
    {
        Check.NotNull(model, nameof(model));
        Check.NotNull(entity, nameof(entity));

        entity.ClientId               = model.ClientId;
        entity.ClientSecret           = model.ClientSecret;
        entity.ConsentType            = model.ConsentType;
        entity.DisplayName            = model.DisplayName;
        entity.DisplayNames           = model.DisplayNames;
        entity.Permissions            = model.Permissions;
        entity.PostLogoutRedirectUris = model.PostLogoutRedirectUris;
        entity.Properties             = model.Properties;
        entity.RedirectUris           = model.RedirectUris;
        entity.Requirements           = model.Requirements;
        entity.Type      = model.Type;
        entity.ClientUri = model.ClientUri;
        entity.LogoUri   = model.LogoUri;

        foreach (var extraProperty in model.ExtraProperties)
        {
            entity.ExtraProperties.Remove(extraProperty.Key);
            entity.ExtraProperties.Add(extraProperty.Key, extraProperty.Value);
        }

        return(entity);
    }
    public async ValueTask CreateAsync(OpenIddictApplicationModel application, CancellationToken cancellationToken)
    {
        Check.NotNull(application, nameof(application));

        await Repository.InsertAsync(application.ToEntity(), autoSave : true, cancellationToken : cancellationToken);

        application = (await Repository.FindAsync(application.Id, cancellationToken: cancellationToken)).ToModel();
    }
    public async ValueTask DeleteAsync(OpenIddictApplicationModel application, CancellationToken cancellationToken)
    {
        Check.NotNull(application, nameof(application));

        using (var uow = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: true, isolationLevel: IsolationLevel.RepeatableRead))
        {
            await TokenRepository.DeleteManyByApplicationIdAsync(application.Id, cancellationToken : cancellationToken);

            await Repository.DeleteAsync(application.Id, cancellationToken : cancellationToken);

            await uow.CompleteAsync(cancellationToken);
        }
    }
    public ValueTask <ImmutableDictionary <string, JsonElement> > GetPropertiesAsync(OpenIddictApplicationModel application, CancellationToken cancellationToken)
    {
        Check.NotNull(application, nameof(application));

        if (string.IsNullOrEmpty(application.Properties))
        {
            return(new ValueTask <ImmutableDictionary <string, JsonElement> >(ImmutableDictionary.Create <string, JsonElement>()));
        }

        using (var document = JsonDocument.Parse(application.Properties))
        {
            var builder = ImmutableDictionary.CreateBuilder <string, JsonElement>();

            foreach (var property in document.RootElement.EnumerateObject())
            {
                builder[property.Name] = property.Value.Clone();
            }
            return(new ValueTask <ImmutableDictionary <string, JsonElement> >(builder.ToImmutable()));
        }
    }
    public virtual ValueTask SetClientIdAsync(OpenIddictApplicationModel application, string identifier, CancellationToken cancellationToken)
    {
        Check.NotNull(application, nameof(application));

        application.ClientId = identifier;
        return(default);
    public ValueTask <string> GetIdAsync(OpenIddictApplicationModel application, CancellationToken cancellationToken)
    {
        Check.NotNull(application, nameof(application));

        return(new ValueTask <string>(ConvertIdentifierToString(application.Id)));
    }
    public ValueTask <ImmutableDictionary <CultureInfo, string> > GetDisplayNamesAsync(OpenIddictApplicationModel application, CancellationToken cancellationToken)
    {
        Check.NotNull(application, nameof(application));

        if (string.IsNullOrEmpty(application.DisplayNames))
        {
            return(new ValueTask <ImmutableDictionary <CultureInfo, string> >(ImmutableDictionary.Create <CultureInfo, string>()));
        }

        using (var document = JsonDocument.Parse(application.DisplayNames))
        {
            var builder = ImmutableDictionary.CreateBuilder <CultureInfo, string>();

            foreach (var property in document.RootElement.EnumerateObject())
            {
                var value = property.Value.GetString();
                if (string.IsNullOrEmpty(value))
                {
                    continue;
                }

                builder[CultureInfo.GetCultureInfo(property.Name)] = value;
            }

            return(new ValueTask <ImmutableDictionary <CultureInfo, string> >(builder.ToImmutable()));
        }
    }
    public ValueTask <string> GetDisplayNameAsync(OpenIddictApplicationModel application, CancellationToken cancellationToken)
    {
        Check.NotNull(application, nameof(application));

        return(new ValueTask <string>(application.DisplayName));
    }
    public ValueTask <string> GetClientSecretAsync(OpenIddictApplicationModel application, CancellationToken cancellationToken)
    {
        Check.NotNull(application, nameof(application));

        return(new ValueTask <string>(application.ClientSecret));
    }