예제 #1
0
        protected async Task <TModel> ReloadSelfAsync()
        {
            Model = await LoadModelAsync();
            await UpdateSubscribersAsync(Model);

            return(Model);
        }
예제 #2
0
        public async Task <ILive <TModel>?> Import(ArchiveReader archive, bool lowPriority = false, CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested();

            TModel?model = null;

            try
            {
                model = CreateModel(archive);

                if (model == null)
                {
                    return(null);
                }
            }
            catch (TaskCanceledException)
            {
                throw;
            }
            catch (Exception e)
            {
                LogForModel(model, @$ "Model creation of {archive.Name} failed.", e);
                return(null);
            }

            var scheduledImport = Task.Factory.StartNew(async() => await Import(model, archive, lowPriority, cancellationToken).ConfigureAwait(false),
                                                        cancellationToken, TaskCreationOptions.HideScheduler, lowPriority ? import_scheduler_low_priority : import_scheduler).Unwrap();

            return(await scheduledImport.ConfigureAwait(false));
        }
예제 #3
0
        private async Task <SetupVM> GetVM <TModel>(TModel?model = null, string?errorMessage = null) where TModel : class
        {
            var externalProviders = await SignInManager.GetExternalProvidersAsync();

            var request = HttpContext.Request;

            var result = new SetupVM
            {
                BaseUrlConfigured      = urlGenerator.BuildUrl(),
                BaseUrlCurrent         = $"{request.Scheme}://{request.Host}",
                ErrorMessage           = errorMessage,
                EverybodyCanCreateApps = !uiOptions.OnlyAdminsCanCreateApps,
                IsValidHttps           = HttpContext.Request.IsHttps,
                IsAssetStoreFile       = assetStore is FolderAssetStore,
                IsAssetStoreFtp        = assetStore is FTPAssetStore,
                HasExternalLogin       = externalProviders.Any(),
                HasPasswordAuth        = identityOptions.AllowPasswordAuth
            };

            if (model != null)
            {
                SimpleMapper.Map(model, result);
            }

            return(result);
        }
예제 #4
0
        protected async Task <TModel> SetModelAsync(TModel newModel)
        {
            Model = newModel;
            await UpdateSubscribersAsync(Model);

            return(Model);
        }
예제 #5
0
        /// <summary>
        /// Create and import a model based off the provided <see cref="ArchiveReader"/>.
        /// </summary>
        /// <remarks>
        /// This method also handled queueing the import task on a relevant import thread pool.
        /// </remarks>
        /// <param name="archive">The archive to be imported.</param>
        /// <param name="batchImport">Whether this import is part of a larger batch.</param>
        /// <param name="cancellationToken">An optional cancellation token.</param>
        private async Task <Live <TModel>?> importFromArchive(ArchiveReader archive, bool batchImport = false, CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested();

            TModel?model = null;

            try
            {
                model = CreateModel(archive);

                if (model == null)
                {
                    return(null);
                }
            }
            catch (TaskCanceledException)
            {
                throw;
            }
            catch (Exception e)
            {
                LogForModel(model, @$ "Model creation of {archive.Name} failed.", e);
                return(null);
            }

            var scheduledImport = Task.Factory.StartNew(() => ImportModel(model, archive, batchImport, cancellationToken),
                                                        cancellationToken,
                                                        TaskCreationOptions.HideScheduler,
                                                        batchImport ? import_scheduler_batch : import_scheduler);

            return(await scheduledImport.ConfigureAwait(false));
        }
예제 #6
0
        protected async Task <TModel> UpdateModelAsync(Func <TModel, TModel> modelUpdater)
        {
            var model = await GetOrLoadModelAsync();

            Model = modelUpdater.Invoke(model);
            await UpdateSubscribersAsync(Model);

            return(Model);
        }
        public async Task <HttpStatusCode> UpsertAsync(TModel?model)
        {
            if (model == null)
            {
                throw new ArgumentNullException(nameof(model));
            }

            return(await Repository.UpsertAsync(model).ConfigureAwait(false));
        }
예제 #8
0
        /// <summary>
        /// Map to source.
        /// </summary>
        private T?MapToSrce(TModel?model)
        {
            if (model == null)
            {
                return(null);
            }

            return(Args.Mapper.Map <TModel, T>(model, Mapper.OperationTypes.Get) !);
        }
예제 #9
0
        public async Task <HttpStatusCode> UpdateAsync(TModel?upsertDocumentModel)
        {
            if (upsertDocumentModel == null)
            {
                return(HttpStatusCode.BadRequest);
            }

            var existingDocument = await contentPageService.GetByIdAsync(upsertDocumentModel.Id).ConfigureAwait(false);

            if (existingDocument == null)
            {
                return(HttpStatusCode.NotFound);
            }

            var beforePageLocationUpdate = JsonConvert.SerializeObject(upsertDocumentModel);

            upsertDocumentModel.PageLocation = ExtractPageLocation(upsertDocumentModel);

            if (string.IsNullOrEmpty(upsertDocumentModel.PageLocation) || string.IsNullOrEmpty(upsertDocumentModel.PartitionKey))
            {
                logger.LogError(
                    "PageLocation ({PageLocation}) and/or PartitionKey ({PartitionKey}) is empty or null. Document before = {SerialisedDocumentBefore}. Document = {SerialisedDocument}",
                    upsertDocumentModel.PageLocation,
                    upsertDocumentModel.PartitionKey,
                    beforePageLocationUpdate,
                    JsonConvert.SerializeObject(upsertDocumentModel));

                return(HttpStatusCode.BadRequest);
            }

            if (existingDocument.PartitionKey?.Equals(upsertDocumentModel.PartitionKey, StringComparison.OrdinalIgnoreCase) == true)
            {
                upsertDocumentModel.Etag = existingDocument.Etag;
            }
            else
            {
                var deleted = await contentPageService.DeleteAsync(existingDocument.Id).ConfigureAwait(false);

                if (deleted)
                {
                    logger.LogInformation($"{nameof(UpdateAsync)} has deleted content for: {existingDocument.CanonicalName} due to partition key change: {existingDocument.PartitionKey} -> {upsertDocumentModel.PartitionKey}");
                }
                else
                {
                    logger.LogWarning($"{nameof(UpdateAsync)} failed to delete content for: {existingDocument.CanonicalName} due to partition key change: {existingDocument.PartitionKey} -> {upsertDocumentModel.PartitionKey}");
                    return(HttpStatusCode.BadRequest);
                }
            }

            var response = await contentPageService.UpsertAsync(upsertDocumentModel).ConfigureAwait(false);

            logger.LogInformation($"{nameof(UpdateAsync)} has upserted content for: {upsertDocumentModel.CanonicalName} with response code {response}");

            return(response);
        }
        private TModel?AddToApiCache <TModel>(string key, TModel?model)
            where TModel : class, IBaseContentItemModel
        {
            if (model == null)
            {
                return(null);
            }

            apiCacheService.AddOrUpdate(key, model);
            return(model);
        }
예제 #11
0
    public virtual TDbEntity?ToEntity(TModel?source)
    {
        if (source == null)
        {
            return(null);
        }
        var dbEntity = NewEntity();

        UpdateEntity(source, dbEntity);
        return(dbEntity);
    }
예제 #12
0
        public ViewViewComponentResult View <TModel>(string?viewName, TModel?model)
        {
            var viewData = new ViewDataDictionary <TModel?>(ViewData, model);

            return(new ViewViewComponentResult
            {
                ViewEngine = ViewEngine,
                ViewName = viewName,
                ViewData = viewData
            });
        }
예제 #13
0
 /// <summary>
 /// 执行过滤
 /// </summary>
 /// <typeparam name="TModel"></typeparam>
 /// <param name="data"></param>
 /// <param name="newTypeName"></param>
 /// <returns></returns>
 public object?Filter <TModel>(TModel?data, string?newTypeName = default)
     where TModel : class
 {
     newTypeName ??= DefaultName(typeof(TModel).FullName ?? string.Empty);
     if (Config.GetOrCreateNewType(typeof(TModel), newTypeName, DataAdapter).MapFunc is Func <TModel, object> func)
     {
         if (data != default)
         {
             return(func.Invoke(data));
         }
     }
     return(data);
 }
        public static void Sanitize <TModel>(TModel?model)
            where TModel : class
        {
            _ = model ?? throw new ArgumentNullException(nameof(model));

            var type = model.GetType();

            foreach (var propertyInfo in type.GetProperties().Where(w => Type.GetTypeCode(w.PropertyType) == TypeCode.String))
            {
                var value = propertyInfo.GetValue(model, null) as string;
                value = SanitizeString(value);
                propertyInfo.SetValue(model, value);
            }
        }
예제 #15
0
        public string?ExtractPageLocation(TModel?model)
        {
            string?result           = null;
            var    contentPageModel = model as ContentPageModel;

            if (contentPageModel?.PageLocations != null && contentPageModel.PageLocations.Any())
            {
                var pageLocations = ExtractPageLocationItem(contentPageModel.PageLocations);

                pageLocations.RemoveAll(r => string.IsNullOrWhiteSpace(r));
                pageLocations.RemoveAll(r => r.Equals("/", StringComparison.Ordinal));

                pageLocations.Reverse();

                result = "/" + string.Join("/", pageLocations);
            }

            return(result);
        }
예제 #16
0
        public async Task <T> DeserializeAsync <TModel>(string filePath)
            where TModel : T, new()
        {
            try
            {
                using var reader = File.OpenRead(filePath);
                TModel?t = await JsonSerializer.DeserializeAsync <TModel>(reader).ConfigureAwait(false);

                if (t is null)
                {
                    return(new TModel());
                }
                return(t);
            }
            catch (JsonException)
            {
                return(await new ValueTask <TModel>(new TModel()).ConfigureAwait(false));
            }
        }
예제 #17
0
        public bool TryValidateModel <TModel>(TModel?model)
            where TModel : class, ICachedModel
        {
            _ = model ?? throw new ArgumentNullException(nameof(model));

            var validationContext = new ValidationContext(model, null, null);
            var validationResults = new List <ValidationResult>();
            var isValid           = Validator.TryValidateObject(model, validationContext, validationResults, true);

            if (!isValid && validationResults.Any())
            {
                foreach (var validationResult in validationResults)
                {
                    logger.LogError($"Error validating {model.Title} - {model.Url}: {string.Join(",", validationResult.MemberNames)} - {validationResult.ErrorMessage}");
                }
            }

            return(isValid);
        }
        public async Task <HttpStatusCode> CreateAsync(TModel?upsertDocumentModel)
        {
            if (upsertDocumentModel == null)
            {
                return(HttpStatusCode.BadRequest);
            }

            var existingDocument = await _documentService.GetByIdAsync(upsertDocumentModel.Id).ConfigureAwait(false);

            if (existingDocument != null)
            {
                return(HttpStatusCode.AlreadyReported);
            }

            var response = await _documentService.UpsertAsync(upsertDocumentModel).ConfigureAwait(false);

            logger.LogInformation($"{nameof(CreateAsync)} has upserted content for: {upsertDocumentModel.Title} with response code {response}");

            return(response);
        }
예제 #19
0
        public async Task <HttpStatusCode> UpdateAsync(TModel?upsertDocumentModel)
        {
            if (upsertDocumentModel == null)
            {
                return(HttpStatusCode.BadRequest);
            }

            var existingDocument = await contentPageService.GetByIdAsync(upsertDocumentModel.Id).ConfigureAwait(false);

            if (existingDocument == null)
            {
                return(HttpStatusCode.NotFound);
            }

            upsertDocumentModel.PageLocation = ExtractPageLocation(upsertDocumentModel);

            if (existingDocument.PartitionKey != null && existingDocument.PartitionKey.Equals(upsertDocumentModel.PartitionKey, StringComparison.Ordinal))
            {
                upsertDocumentModel.Etag = existingDocument.Etag;
            }
            else
            {
                var deleted = await contentPageService.DeleteAsync(existingDocument.Id).ConfigureAwait(false);

                if (deleted)
                {
                    logger.LogInformation($"{nameof(UpdateAsync)} has deleted content for: {existingDocument.CanonicalName} due to partition key change: {existingDocument.PartitionKey} -> {upsertDocumentModel.PartitionKey}");
                }
                else
                {
                    logger.LogWarning($"{nameof(UpdateAsync)} failed to delete content for: {existingDocument.CanonicalName} due to partition key change: {existingDocument.PartitionKey} -> {upsertDocumentModel.PartitionKey}");
                    return(HttpStatusCode.BadRequest);
                }
            }

            var response = await contentPageService.UpsertAsync(upsertDocumentModel).ConfigureAwait(false);

            logger.LogInformation($"{nameof(UpdateAsync)} has upserted content for: {upsertDocumentModel.CanonicalName} with response code {response}");

            return(response);
        }
        public async Task Run(CancellationToken stoppingToken)
        {
            while (true)
            {
                CancellationTokenSource refreshLockCancellationTokenSource = new();
                TModel?dataToProcess = null;
                try
                {
                    dataToProcess = await AcquireDataToProcess(stoppingToken);

                    if (dataToProcess == null || stoppingToken.IsCancellationRequested)
                    {
                        return;
                    }

#pragma warning disable 4014
                    Task.Run(() => RefreshLock(dataToProcess, refreshLockCancellationTokenSource.Token),
                             refreshLockCancellationTokenSource.Token);
#pragma warning restore 4014

                    stoppingToken.ThrowIfCancellationRequested();

                    await Process(dataToProcess);

                    await SaveDoneStatus(dataToProcess.Id);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "{ServiceName} failed", GetType().FullName);
                    if (dataToProcess != null)
                    {
                        await SaveFailedStatus(dataToProcess.Id, ex);
                    }
                }
                finally
                {
                    refreshLockCancellationTokenSource.Cancel();
                }
            }
        }
예제 #21
0
        private async Task <TModel> ConvertDtoToEntity <TModel, TDto>(TDto dto, TModel?entity = null)
            where TModel : BacklogItem, new()
            where TDto : BacklogItemAddUpdRequestBase
        {
            entity ??= new TModel();

            entity.Title    = dto.Title;
            entity.Tags     = dto.Tags;
            entity.Assignee = dto.AssigneeId != null ? await _userResolver.GetReferenceById(dto.AssigneeId) : null;

            entity.AddHistoryRecord(
                await _userResolver.GetCurrentUserReference(),
                entity.ModifiedBy.Any() ? "Modified" : "Created"                        // TODO: Provide more informative description in case of modifications
                );

            if (dto.CustomFields != null)
            {
                var verifiedCustomFieldIds = await _customFieldQueryService.GetFullIdsOfExistingItems(
                    dto.CustomFields.Where(pair => pair.Value != null).Select(pair => pair.Key)
                    );

                entity.CustomFields = verifiedCustomFieldIds.ToDictionary(x => x.Value, x => dto.CustomFields[x.Key] !);
            }
            else
            {
                entity.CustomFields = null;
            }

            entity.RelatedItems = dto.RelatedItems != null ? await ResolveRelatedItems(dto.RelatedItems) : null;

            // entity.CustomProperties = dto.CustomProperties;	TODO: De-serialise custom properties

            if (dto is BugAddUpdRequest bugDto && entity is BacklogItemBug bugEntity)
            {
                bugEntity.Severity           = bugDto.Severity;
                bugEntity.Priority           = bugDto.Priority;
                bugEntity.StepsToReproduce   = bugDto.StepsToReproduce;
                bugEntity.AcceptanceCriteria = bugDto.AcceptanceCriteria;
            }
예제 #22
0
        public string?ExtractPageLocation(TModel?model)
        {
            var contentPageModel = model as ContentPageModel;

            if (contentPageModel?.PageLocations?.Any() != true)
            {
                logger.LogInformation(
                    "{MethodName} returns null. Is ContentPageModel = {ContentPageModelCastable}. {PageLocationCount} page locations",
                    nameof(ExtractPageLocation),
                    contentPageModel != null,
                    contentPageModel?.PageLocations?.Count);

                return(null);
            }

            var pageLocations = ExtractPageLocationItem(contentPageModel.PageLocations);

            pageLocations.RemoveAll(r => string.IsNullOrWhiteSpace(r));
            pageLocations.RemoveAll(r => r.Equals("/", StringComparison.Ordinal));
            pageLocations.Reverse();

            return($"/{string.Join("/", pageLocations)}");
        }
예제 #23
0
        private async Task <ProfileVM> GetProfileVM <TModel>(IUser?user, TModel?model = null, string?errorMessage = null, string?successMessage = null) where TModel : class
        {
            if (user == null)
            {
                throw new DomainException(T.Get("users.userNotFound"));
            }

            var(providers, hasPassword, logins) = await AsyncHelper.WhenAll(
                signInManager.GetExternalProvidersAsync(),
                userService.HasPasswordAsync(user),
                userService.GetLoginsAsync(user));

            var result = new ProfileVM
            {
                Id                = user.Id,
                ClientSecret      = user.Claims.ClientSecret() !,
                Email             = user.Email,
                ErrorMessage      = errorMessage,
                ExternalLogins    = logins,
                ExternalProviders = providers,
                DisplayName       = user.Claims.DisplayName() !,
                HasPassword       = hasPassword,
                HasPasswordAuth   = identityOptions.AllowPasswordAuth,
                IsHidden          = user.Claims.IsHidden(),
                SuccessMessage    = successMessage
            };

            if (model != null)
            {
                SimpleMapper.Map(model, result);
            }

            result.Properties ??= user.Claims.GetCustomProperties().Select(UserProperty.FromTuple).ToList();

            return(result);
        }
    }
예제 #24
0
        public async Task <HttpStatusCode> CreateAsync(TModel?upsertDocumentModel)
        {
            if (upsertDocumentModel == null)
            {
                return(HttpStatusCode.BadRequest);
            }

            var existingDocument = await contentPageService.GetByIdAsync(upsertDocumentModel.Id).ConfigureAwait(false);

            if (existingDocument != null)
            {
                return(HttpStatusCode.AlreadyReported);
            }

            var beforePageLocationUpdate = JsonConvert.SerializeObject(upsertDocumentModel);

            upsertDocumentModel.PageLocation = ExtractPageLocation(upsertDocumentModel);

            if (string.IsNullOrEmpty(upsertDocumentModel.PageLocation))
            {
                logger.LogError(
                    "PageLocation ({PageLocation}) and/or PartitionKey ({PartitionKey}) is empty or null. Document before = {SerialisedDocumentBefore}. Document = {SerialisedDocument}",
                    upsertDocumentModel.PageLocation,
                    upsertDocumentModel.PartitionKey,
                    beforePageLocationUpdate,
                    JsonConvert.SerializeObject(upsertDocumentModel));

                return(HttpStatusCode.BadRequest);
            }

            var response = await contentPageService.UpsertAsync(upsertDocumentModel).ConfigureAwait(false);

            logger.LogInformation($"{nameof(CreateAsync)} has upserted content for: {upsertDocumentModel.CanonicalName} with response code {response}");

            return(response);
        }
예제 #25
0
        internal static void LogForModel(TModel?model, string message, Exception?e = null)
        {
            string trimmedHash;

            if (model == null || !model.IsValid || string.IsNullOrEmpty(model.Hash))
            {
                trimmedHash = "?????";
            }
            else
            {
                trimmedHash = model.Hash.Substring(0, 5);
            }

            string prefix = $"[{trimmedHash}]";

            if (e != null)
            {
                Logger.Error(e, $"{prefix} {message}", LoggingTarget.Database);
            }
            else
            {
                Logger.Log($"{prefix} {message}", LoggingTarget.Database);
            }
        }
        private static EventGridEvent[] BuildValidEventGridEvent <TModel>(string eventType, TModel?data)
            where TModel : class
        {
            var models = new EventGridEvent[]
            {
                new EventGridEvent
                {
                    Id          = Guid.NewGuid().ToString(),
                    Subject     = "a-subject",
                    Data        = data,
                    EventType   = eventType,
                    EventTime   = DateTime.Now,
                    DataVersion = "1.0",
                },
            };

            return(models);
        }
 /// <summary>
 ///
 /// </summary>
 /// <returns></returns>
 public Task EditAsync(object model)
 {
     Model = model as TModel;
     return(Task.CompletedTask);
 }
 /// <summary>
 ///
 /// </summary>
 /// <param name="model"></param>
 /// <returns></returns>
 public override Task <bool> AddAsync(TModel model)
 {
     Model = model;
     return(base.AddAsync(model));
 }
예제 #29
0
 public ViewViewComponentResult View <TModel>(TModel?model)
 {
     return(View(viewName: null, model: model));
 }
예제 #30
0
        private async Task <IActionResult> MakeChangeAsync <TModel>(Func <string, Task> action, string successMessage, TModel?model = null) where TModel : class
        {
            var user = await userService.GetAsync(User);

            if (user == null)
            {
                return(NotFound());
            }

            if (!ModelState.IsValid)
            {
                return(View(nameof(Profile), await GetProfileVM(user, model)));
            }

            string errorMessage;

            try
            {
                await action(user.Id);

                await signInManager.SignInAsync((IdentityUser)user.Identity, true);

                return(RedirectToAction(nameof(Profile), new { successMessage }));
            }
            catch (ValidationException ex)
            {
                errorMessage = ex.Message;
            }
            catch (Exception)
            {
                errorMessage = T.Get("users.errorHappened");
            }

            return(View(nameof(Profile), await GetProfileVM(user, model, errorMessage)));
        }