Example #1
0
        public static async Task SaveFileAsync(ITusFile file, IHostingEnvironment env)
        {
            CancellationTokenSource source = new CancellationTokenSource();
            CancellationToken       token  = source.Token;

            var metadata = await file.GetMetadataAsync(token);

            var fileName = Path.GetRandomFileName();

            if (metadata.ContainsKey("filename"))
            {
                fileName = metadata["filename"].GetString(Encoding.UTF8);
            }

            var filePath = Path.Combine(env.ContentRootPath, "arquivos", fileName);

            CreateDirectory(Path.Combine(env.ContentRootPath, "arquivos"));

            using (var stream = await file.GetContentAsync(token))
            {
                using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
                {
                    stream.CopyTo(fileStream);
                }
            }
        }
Example #2
0
        /// <summary>
        /// Persist the uploaded file data to db
        /// </summary>
        private async Task <gFileItem> PersistMetaData(FileCompleteContext ctx)
        {
            var gUserResponse = await _fileMngClient.GetUserAsync(new gUserRequest());

            if (gUserResponse == null)
            {
                _logger.LogError("Unknown error occured while requesting user info");
                ctx.HttpContext.Response.StatusCode = 400;
                return(null);
            }
            if (gUserResponse.Status.Status != Protos.RequestStatus.Success)
            {
                _logger.LogError(gUserResponse.Status.Message);
                ctx.HttpContext.Response.StatusCode = 400;
                return(null);
            }

            ITusFile file     = await((ITusReadableStore)ctx.Store).GetFileAsync(ctx.FileId, ctx.CancellationToken);
            var      metadata = await file.GetMetadataAsync(ctx.CancellationToken);

            gFileItem fileitem = new gFileItem()
            {
                Id       = Helpers.GenerateUniqueId(),
                TusId    = ctx.FileId,
                UserId   = gUserResponse.User.Id,
                Size     = uint.Parse(new FileInfo(Path.Combine(_uploadOpts.CurrentValue.UploadPath, file.Id)).Length.ToString()),
                Name     = metadata["name"].GetString(Encoding.UTF8),
                MimeType = metadata["contentType"].GetString(Encoding.UTF8),
                // file with no folderid is placed in the virtual root folder
                FolderId = metadata["folderId"].GetString(Encoding.UTF8) == "root"
                                                                                ? null
                                                                                : metadata["folderId"].GetString(Encoding.UTF8),
                Extension       = Helpers.GetFileExtension(metadata["contentType"].GetString(Encoding.UTF8)) ?? string.Empty,
                StorageServerId = metadata["serverId"].GetString(Encoding.UTF8),
                CreatedAt       = Timestamp.FromDateTime(DateTime.SpecifyKind(DateTime.UtcNow, DateTimeKind.Utc)),
                LastModified    = Timestamp.FromDateTime(DateTime.SpecifyKind(DateTime.UtcNow, DateTimeKind.Utc)),
                Status          = Protos.ItemStatus.Visible
            };

            // send the uploaded file info to the main app
            gFileItemResponse response = await _fileMngClient.SaveFileAsync(new gFileItemRequest()
            {
                FileItem = fileitem
            });

            if (response == null)
            {
                _logger.LogError("No response has been received from the server.", ErrorOrigin.Server);
                return(null);
            }
            if (response.Status.Status != Protos.RequestStatus.Success)
            {
                _logger.LogError("An error has been returned from server call: " + response.Status.Message);
                return(null);
            }
            return(response.FileItem);
        }
Example #3
0
        /// <summary>
        /// Check if the <see cref="ITusFile"/> has been completely uploaded.
        /// </summary>
        /// <param name="file">The file to check</param>
        /// <param name="store">The store responsible for handling the file</param>
        /// <param name="cancellationToken">The cancellation token to use when cancelling</param>
        /// <returns>True if the file is completed, otherwise false</returns>
        public static async Task <bool> IsCompleteAsync(this ITusFile file, ITusStore store, CancellationToken cancellationToken)
        {
            var length = store.GetUploadLengthAsync(file.Id, cancellationToken);
            var offset = store.GetUploadOffsetAsync(file.Id, cancellationToken);

            await Task.WhenAll(length, offset);

            return(length.Result == offset.Result);
        }
Example #4
0
        private async Task DoSomeProcessing(ITusFile file, Dictionary <string, tusdotnet.Models.Metadata> metadata)
        {
            var guid = Guid.ParseExact(file.Id, "N");

            _logger.LogInformation($"Publish message with: FileId = {file.Id}, Name = {metadata.GetValueOrDefault("filename", null)?.GetString(Encoding.UTF8)}, Type = {metadata.GetValueOrDefault("filetype", null)?.GetString(Encoding.UTF8)}");
            await _messageQueue.Publish <IVideoUploadedEvent>(new VideoUploadedEvent
            {
                FileId = guid,
                Name   = metadata.GetValueOrDefault("filename", null)?.GetString(Encoding.UTF8),
                Type   = metadata.GetValueOrDefault("filetype", null)?.GetString(Encoding.UTF8)
            });

            await _messageQueue.Publish <IVideoUploadedForCatalogEvent>(new VideoUploadedForCatalogEvent
            {
                FileId = guid,
                Name   = metadata.GetValueOrDefault("filename", null)?.GetString(Encoding.UTF8),
                Type   = metadata.GetValueOrDefault("filetype", null)?.GetString(Encoding.UTF8)
            });
        }
Example #5
0
        public async Task OnFileCompleteAsync(FileCompleteContext context)
        {
            ITusFile file = await context.GetFileAsync();

            _logger.LogInformation($"Fileupload completed: ${file.Id}");
            var metadata = await file.GetMetadataAsync(context.CancellationToken);

            var metadataInString = "";

            foreach (var item in metadata)
            {
                if (metadataInString.Length != 0)
                {
                    metadataInString += ", ";
                }
                metadataInString += $"\"{item.Key}:{item.Value.GetString(Encoding.UTF8)}\"";
            }
            _logger.LogInformation($"Fileupload completed: {metadataInString}");
            await DoSomeProcessing(file, metadata);

            await Task.CompletedTask;
        }
        public static async Task HandleRoute(HttpContext context)
        {
            DefaultTusConfiguration config = context.RequestServices.GetRequiredService <DefaultTusConfiguration>();

            if (!(config.Store is ITusReadableStore store))
            {
                return;
            }

            string   fileId = (string)context.Request.RouteValues["fileId"];
            ITusFile file   = await store.GetFileAsync(fileId, context.RequestAborted);

            if (file == null)
            {
                context.Response.StatusCode = 404;
                await context.Response.WriteAsync($"File with id {fileId} was not found.", context.RequestAborted);

                return;
            }

            System.IO.Stream fileStream = await file.GetContentAsync(context.RequestAborted);

            Dictionary <string, Metadata> metadata = await file.GetMetadataAsync(context.RequestAborted);

            context.Response.ContentType   = GetContentTypeOrDefault(metadata);
            context.Response.ContentLength = fileStream.Length;

            if (metadata.TryGetValue("name", out var nameMeta))
            {
                context.Response.Headers.Add("Content-Disposition",
                                             new[] { $"attachment; filename=\"{nameMeta.GetString(Encoding.UTF8)}\"" });
            }

            using (fileStream)
                await fileStream.CopyToAsync(context.Response.Body, 81920, context.RequestAborted);
        }
Example #7
0
        // Generates thumbnail from an image and returns its relative path
        private async Task <string> GenerateImageThumbnailAsync(
            ITusFile file,
            string fileExtension,
            string storePath,
            string userName,
            CancellationToken ct,
            int height = 400,
            int width  = 400)
        {
            var thumbnailDirectory = Path.Combine(storePath, "thumbnails");
            var thumbnailFilePath  = Path.Combine(storePath, "thumbnails", $"{file.Id}_{width}x{height}_thumbnail{fileExtension}");

            // Creates directory if it does not exist...
            Directory.CreateDirectory(thumbnailDirectory);

            using (Image image = Image.Load(await file.GetContentAsync(ct)))
            {
                image.Mutate(x => x.Resize(width, height));

                image.Save(thumbnailFilePath);

                return(thumbnailFilePath);
            }
        }
Example #8
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            //app.UseCors(options => options.WithOrigins("https://*****:*****@"C:\Users\chunc\Documents\RuneLaboratory\Freelance\FileUploadService\StoredFiles\"),
                // On what url should we listen for uploads?
                UrlPath = "/tusUpload",
                Events  = new Events
                {
                    OnAuthorizeAsync = eventContext =>
                    {
                        // if (!eventContext.HttpContext.User.Identity.IsAuthenticated)
                        // {
                        //     System.Console.WriteLine("DEBUG XXX 2");
                        //     eventContext.FailRequest(HttpStatusCode.Unauthorized);
                        //     return Task.CompletedTask;
                        // }

                        // Do other verification on the user; claims, roles, etc. In this case, check the username.
                        // if (eventContext.HttpContext.User.Identity.Name != "test")
                        // {
                        //     System.Console.WriteLine("DEBUG XXX 3 Identity name = " + eventContext.HttpContext.User.Identity.Name);
                        //     eventContext.FailRequest(HttpStatusCode.Forbidden, "'test' is the only allowed user");
                        //     return Task.CompletedTask;
                        // }

                        // Verify different things depending on the intent of the request.
                        // E.g.:
                        //   Does the file about to be written belong to this user?
                        //   Is the current user allowed to create new files or have they reached their quota?
                        //   etc etc
                        switch (eventContext.Intent)
                        {
                        case IntentType.CreateFile:
                            System.Console.WriteLine("This is Create File API");
                            break;

                        case IntentType.ConcatenateFiles:
                            System.Console.WriteLine("This is Concatenate Files API");
                            break;

                        case IntentType.WriteFile:
                            System.Console.WriteLine("This is Write Files API");
                            break;

                        case IntentType.DeleteFile:
                            System.Console.WriteLine("This is Delete File API");
                            break;

                        case IntentType.GetFileInfo:
                            System.Console.WriteLine("This is Get File Info API");
                            break;

                        case IntentType.GetOptions:
                            System.Console.WriteLine("This is Get Options Files API");
                            break;

                        default:
                            break;
                        }

                        return(Task.CompletedTask);
                    },
                    OnFileCompleteAsync = async eventContext =>
                    {
                        // eventContext.FileId is the id of the file that was uploaded.
                        // eventContext.Store is the data store that was used (in this case an instance of the TusDiskStore)

                        // A normal use case here would be to read the file and do some processing on it.
                        ITusFile file = await eventContext.GetFileAsync();
                        var result    = await DoSomeProcessing(file, eventContext.CancellationToken);
                        System.Console.WriteLine("Tus File upload complete YEah l " + file.Id);

                        async Task <string> DoSomeProcessing(ITusFile file, CancellationToken eventContext)
                        {
                            System.Console.WriteLine();
                            System.Console.WriteLine("Tus File upload complete YEah :" + file.Id);
                            return("success");
                        }

                        if (result != "success")
                        {
                            //throw new MyProcessingException("Something went wrong during processing");
                        }
                    }
                }
            });
Example #9
0
        private async Task <bool> TusIsFileTypeVerifiedAsync(ITusFile file, string fileName, CancellationToken cancellationToken)
        {
            // If you require a check on specific characters in the IsValidFileExtensionAndSignature
            // method, supply the characters in the _allowedChars field.
            byte[] _allowedChars = { };

            var ext = Path.GetExtension(fileName).ToLowerInvariant();

            if (string.IsNullOrEmpty(ext))
            {
                return(false);
            }

            // For more file signatures, see the File Signatures Database (https://www.filesignatures.net/)
            // and the official specifications for the file types you wish to add.
            Dictionary <string, List <byte[]> > _fileSignature = new Dictionary <string, List <byte[]> >
            {
                { ".gif", new List <byte[]> {
                      new byte[] { 0x47, 0x49, 0x46, 0x38 }
                  } },
                { ".bmp", new List <byte[]> {
                      new byte[] { 0x42, 0x4D }
                  } },
                { ".png", new List <byte[]> {
                      new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }
                  } },
                { ".jpeg", new List <byte[]>
                  {
                      new byte[] { 0xFF, 0xD8, 0xFF, 0xE0 },
                      new byte[] { 0xFF, 0xD8, 0xFF, 0xE2 },
                      new byte[] { 0xFF, 0xD8, 0xFF, 0xE3 },
                  } },
                { ".jpg", new List <byte[]>
                  {
                      new byte[] { 0xFF, 0xD8, 0xFF, 0xE0 },
                      new byte[] { 0xFF, 0xD8, 0xFF, 0xE1 },
                      new byte[] { 0xFF, 0xD8, 0xFF, 0xE8 },
                  } },

                { ".3gp", new List <byte[]>
                  {
                      new byte[] { 0x00, 0x00, 0x00, 0x14, 0x66, 0x74, 0x79, 0x70 },
                      new byte[] { 0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70 },
                  } },
                { ".avi", new List <byte[]> {
                      new byte[] { 0x52, 0x49, 0x46, 0x46 }
                  } },
                { ".flv", new List <byte[]> {
                      new byte[] { 0x46, 0x4C, 0x56 }
                  } },
                { ".wmv", new List <byte[]> {
                      new byte[] { 0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11 }
                  } },
                { ".mpg", new List <byte[]>
                  {
                      new byte[] { 0x00, 0x00, 0x01, 0xBA },
                      new byte[] { 0x00, 0x00, 0x01, 0xB3 },
                  } },
                { ".mp4", new List <byte[]>
                  {
                      new byte[] { 0x00, 0x00, 0x00, 0x14, 0x66, 0x74, 0x79, 0x70, 0x69, 0x73, 0x6F, 0x6D },
                      new byte[] { 0x00, 0x00, 0x00, 0x14, 0x66, 0x74, 0x79, 0x70, 0x4D, 0x53, 0x4E, 0x56 },
                      new byte[] { 0x00, 0x00, 0x00, 0x18, 0x66, 0x74, 0x79, 0x70, 0x69, 0x73, 0x6F, 0x6D },
                      new byte[] { 0x00, 0x00, 0x00, 0x18, 0x66, 0x74, 0x79, 0x70, 0x4D, 0x53, 0x4E, 0x56 },
                      new byte[] { 0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70, 0x69, 0x73, 0x6F, 0x6D },
                      new byte[] { 0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70, 0x4D, 0x53, 0x4E, 0x56 },
                  } },
                { ".mkv", new List <byte[]> {
                      new byte[] { 0x1A, 0x45, 0xDF, 0xA3, 0x93, 0x42, 0x82, 0x88 }
                  } },

                { ".wma", new List <byte[]> {
                      new byte[] { 0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11 }
                  } },
                { ".mp3", new List <byte[]> {
                      new byte[] { 0x49, 0x44, 0x33 }
                  } },

                { ".pdf", new List <byte[]> {
                      new byte[] { 0x25, 0x50, 0x44, 0x46 }
                  } },

                { ".rtf", new List <byte[]> {
                      new byte[] { 0x7B, 0x5C, 0x72, 0x74, 0x66, 0x31 }
                  } },
                { ".doc", new List <byte[]>
                  {
                      new byte[] { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 },
                      new byte[] { 0x0D, 0x44, 0x4F, 0x43 },
                      new byte[] { 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1, 0x00 },
                      new byte[] { 0xDB, 0xA5, 0x2D, 0x00 },
                      new byte[] { 0xEC, 0xA5, 0xC1, 0x00 },
                  } },
                { ".docx", new List <byte[]>
                  {
                      new byte[] { 0x50, 0x4B, 0x03, 0x04 },
                      new byte[] { 0x50, 0x4B, 0x03, 0x04, 0x14, 0x00, 0x06, 0x00 },
                  } },
                { ".xls", new List <byte[]>
                  {
                      new byte[] { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 },
                      new byte[] { 0x09, 0x08, 0x10, 0x00, 0x00, 0x06, 0x05, 0x00 },
                      new byte[] { 0xFD, 0xFF, 0xFF, 0xFF, 0x10 },
                      new byte[] { 0xFD, 0xFF, 0xFF, 0xFF, 0x1F },
                      new byte[] { 0xFD, 0xFF, 0xFF, 0xFF, 0x22 },
                      new byte[] { 0xFD, 0xFF, 0xFF, 0xFF, 0x23 },
                      new byte[] { 0xFD, 0xFF, 0xFF, 0xFF, 0x28 },
                      new byte[] { 0xFD, 0xFF, 0xFF, 0xFF, 0x29 },
                  } },
                { ".xlsx", new List <byte[]>
                  {
                      new byte[] { 0x50, 0x4B, 0x03, 0x04 },
                      new byte[] { 0x50, 0x4B, 0x03, 0x04, 0x14, 0x00, 0x06, 0x00 },
                  } },

                { ".zip", new List <byte[]>
                  {
                      new byte[] { 0x50, 0x4B, 0x03, 0x04 },
                      new byte[] { 0x50, 0x4B, 0x4C, 0x49, 0x54, 0x45 },
                      new byte[] { 0x50, 0x4B, 0x53, 0x70, 0x58 },
                      new byte[] { 0x50, 0x4B, 0x05, 0x06 },
                      new byte[] { 0x50, 0x4B, 0x07, 0x08 },
                      new byte[] { 0x57, 0x69, 0x6E, 0x5A, 0x69, 0x70 },
                  } },
                { ".rar", new List <byte[]> {
                      new byte[] { 0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0x00 }
                  } },
                { ".7z", new List <byte[]> {
                      new byte[] { 0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C }
                  } },
            };

            using (var stream = await file.GetContentAsync(cancellationToken))
                using (var reader = new BinaryReader(stream))
                {
                    if (ext.Equals(".txt") || ext.Equals(".csv") || ext.Equals(".prn") || ext.Equals(".svg"))
                    {
                        if (_allowedChars.Length == 0)
                        {
                            // Limits characters to ASCII encoding.
                            for (var i = 0; i < stream.Length; i++)
                            {
                                if (reader.ReadByte() > sbyte.MaxValue)
                                {
                                    return(false);
                                }
                            }
                        }
                        else
                        {
                            // Limits characters to ASCII encoding and
                            // values of the _allowedChars array.
                            for (var i = 0; i < stream.Length; i++)
                            {
                                var b = reader.ReadByte();
                                if (b > sbyte.MaxValue ||
                                    !_allowedChars.Contains(b))
                                {
                                    return(false);
                                }
                            }
                        }

                        return(true);
                    }

                    // Uncomment the following code block if you must permit
                    // files whose signature isn't provided in the _fileSignature
                    // dictionary. We recommend that you add file signatures
                    // for files (when possible) for all file types you intend
                    // to allow on the system and perform the file signature
                    // check.

                    /*
                     * if (!_fileSignature.ContainsKey(ext))
                     * {
                     *  return true;
                     * }
                     */

                    // File signature check
                    // --------------------
                    // With the file signatures provided in the _fileSignature
                    // dictionary, the following code tests the input content's
                    // file signature.
                    List <byte[]> signatures = _fileSignature.TryGetValue(ext, out signatures) ? _fileSignature[ext] : null;
                    if (signatures == null)
                    {
                        return(false);
                    }

                    var headerBytes = reader.ReadBytes(signatures.Max(m => m.Length));
                    return(signatures.Any(signature =>
                                          headerBytes.Take(signature.Length).SequenceEqual(signature)));
                }
        }
Example #10
0
        public async Task SaveTusFileInfoAsync(ITusFile file, SiteTypeEnum siteType, string refreshToken, UploadLocationEnum location, UploadLinkAccessibilityEnum linkAccessibility, CancellationToken cancellationToken)
        {
            var metadata = await file.GetMetadataAsync(cancellationToken);

            string name = metadata["name"].GetString(Encoding.UTF8);
            string type = metadata["type"].GetString(Encoding.UTF8);


            using (var scope = Services.CreateScope())
            {
                var httpContextAccessor =
                    scope.ServiceProvider
                    .GetRequiredService <IHttpContextAccessor>();

                var context =
                    scope.ServiceProvider
                    .GetRequiredService <DataContext>();

                var logger =
                    scope.ServiceProvider
                    .GetRequiredService <IActivityLogger>();

                var token = context.Tokens.SingleOrDefault(x => x.RefreshToken == refreshToken);
                var user  = token.CreatedBy;

                var    storePath         = Path.Combine(UploadFolderName, user.UserName);
                var    extension         = Path.GetExtension(name);
                var    fileName          = file.Id;
                var    filePublicName    = name;
                var    mimeType          = type;
                var    fileRelativePath  = Path.Combine(storePath, fileName);
                long   size              = 0;
                string fileThumbnailPath = "";
                var    fileType          = TusCheckFileType(type);

                if (location == UploadLocationEnum.LocalHost)
                {
                    size = new FileInfo(Path.Combine(UploadFolderName, user.UserName, fileName)).Length;
                    fileThumbnailPath = fileType == AttachmentTypeEnum.Photo ? await GenerateImageThumbnailAsync(file, extension, storePath, user.UserName, cancellationToken) : "";
                }
                if (location == UploadLocationEnum.FtpServer)
                {
                    // create an FTP client
                    FtpClient client = new FtpClient(_baseUri, _port, _username, _password);
                    // begin connecting to the server
                    await client.ConnectAsync();

                    size = await client.GetFileSizeAsync($"{storePath}/{fileName}");

                    //
                    await client.DisconnectAsync();
                }

                var site = await context.Sites.SingleOrDefaultAsync(x => x.SiteType == siteType);

                user.CreatedAttachments.Add(new Attachment
                {
                    SiteId            = site.Id,
                    UploadLocation    = location,
                    Type              = fileType,
                    RelativePath      = fileRelativePath,
                    ThumbnailPath     = fileThumbnailPath,
                    MimeType          = mimeType,
                    FileName          = fileName,
                    PublicFileName    = filePublicName,
                    FileExtension     = extension,
                    FileSize          = size,
                    LinkAccessibility = linkAccessibility
                });

                var success = await context.SaveChangesAsync() > 0;

                if (success)
                {
                    await logger.LogActivity(
                        site.Id,
                        ActivityCodeEnum.AttachmentAdd,
                        ActivitySeverityEnum.Medium,
                        ActivityObjectEnum.Attachemnt,
                        $"The {fileType} file with the name {fileName} has been uploaded");
                }
                else
                {
                    throw new Exception("Problem saving file information in database!");
                }
            }
        }
Example #11
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHttpContextAccessor httpContextAccessor, ILogger <Startup> logger, ITusUploadUtils tusUploadUtils, IOptions <FtpServerSettings> config)
        {
            if (env.IsDevelopment())
            {
                app.UseWhen(ctx => ctx.Request.Path.StartsWithSegments("/api", StringComparison.InvariantCultureIgnoreCase),
                            appBuilder =>
                {
                    // Custom API Error handler
                    appBuilder.UseMiddleware <APIErrorHandlingMiddleware>();
                }
                            );

                app.UseWhen(ctx => !ctx.Request.Path.StartsWithSegments("/api", StringComparison.InvariantCultureIgnoreCase),
                            appBuilder =>
                {
                    // Default mvc error handler
                    appBuilder.UseDeveloperExceptionPage();
                }
                            );
            }
            else
            {
                app.UseWhen(ctx => ctx.Request.Path.StartsWithSegments("/api", StringComparison.InvariantCultureIgnoreCase),
                            appBuilder =>
                {
                    // Custom API Error handler
                    appBuilder.UseMiddleware <APIErrorHandlingMiddleware>();
                }
                            );

                app.UseWhen(ctx => !ctx.Request.Path.StartsWithSegments("/api", StringComparison.InvariantCultureIgnoreCase),
                            appBuilder =>
                {
                    // Default mvc error handler
                    appBuilder.UseExceptionHandler("/Home/Error");
                }
                            );
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            //app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseCors("CorsPolicy");

            app.UseAuthentication();
            app.UseAuthorization();

            // To use FTPServer as the storage you must use TusDiskStore instead of CustomTusDiskStore
            // if you want to use localhost as the storage without config param
            var uploadLocation = UploadLocationEnum.LocalHost;

            app.UseTus(httpContext => new DefaultTusConfiguration
            {
                // Use TusDiskStore instead of CustomTusDiskStore if you want to use localhost as the storage without config param
                Store = new TusDiskStore(tusUploadUtils.GetStorePath("uploads", uploadLocation), true, new TusDiskBufferSize(1024 * 1024 * 5, 1024 * 1024 * 5)),
                // On what url should we listen for uploads?
                UrlPath = "/api/v1/attachments/add-private-media",
                Events  = new Events
                {
                    OnAuthorizeAsync = eventContext =>
                    {
                        var refreshToken = httpContextAccessor.HttpContext.Request.Cookies["refreshToken"];

                        if (refreshToken == null)
                        {
                            eventContext.FailRequest(HttpStatusCode.Unauthorized);
                            return(Task.CompletedTask);
                        }
                        // Do other verification on the user; claims, roles, etc. In this case, check the username.
                        // if (eventContext.HttpContext.User.Identity.Name != "test")
                        // {
                        //     eventContext.FailRequest(HttpStatusCode.Forbidden, "'test' is the only allowed user");
                        //     return Task.CompletedTask;
                        // }

                        // Verify different things depending on the intent of the request.
                        // E.g.:
                        //   Does the file about to be written belong to this user?
                        //   Is the current user allowed to create new files or have they reached their quota?
                        //   etc etc
                        switch (eventContext.Intent)
                        {
                        case IntentType.CreateFile:
                            break;

                        case IntentType.ConcatenateFiles:
                            break;

                        case IntentType.WriteFile:
                            break;

                        case IntentType.DeleteFile:
                            break;

                        case IntentType.GetFileInfo:
                            break;

                        case IntentType.GetOptions:
                            break;

                        default:
                            break;
                        }

                        return(Task.CompletedTask);
                    },

                    OnBeforeCreateAsync = async ctx =>
                    {
                        var storePath = tusUploadUtils.GetStorePath("uploads", uploadLocation);
                        // If localhost is the storage
                        if (uploadLocation == UploadLocationEnum.LocalHost)
                        {
                            // Create temp directory if it does not exist...
                            Directory.CreateDirectory(storePath);
                        }

                        // If FTP server is the storage
                        if (uploadLocation == UploadLocationEnum.FtpServer)
                        {
                            // create an FTP client
                            FtpClient client = new FtpClient(config.Value.ServerUri, config.Value.ServerPort, config.Value.ServerUsername, config.Value.ServerPassword);
                            // Connecting to the server
                            await client.ConnectAsync();

                            // check if a folder doesn't exist
                            if (!await client.DirectoryExistsAsync(storePath))
                            {
                                await client.CreateDirectoryAsync(storePath);
                            }
                        }

                        if (!ctx.Metadata.ContainsKey("name"))
                        {
                            ctx.FailRequest("name metadata must be specified. ");
                        }

                        if (!ctx.Metadata.ContainsKey("type"))
                        {
                            ctx.FailRequest("filetype metadata must be specified. ");
                        }

                        if (!await tusUploadUtils.IsFileTypeAllowed(ctx.Metadata["type"].GetString(Encoding.UTF8), SiteTypeEnum.Blog))
                        {
                            ctx.FailRequest("Filetype is not allowed!");
                        }
                    },

                    OnFileCompleteAsync = async eventContext =>
                    {
                        ITusFile file = await eventContext.GetFileAsync();

                        var refreshToken = httpContextAccessor.HttpContext.Request.Cookies["refreshToken"];

                        // Saving file information into database
                        await tusUploadUtils.SaveTusFileInfoAsync(file, SiteTypeEnum.Blog, refreshToken, uploadLocation, UploadLinkAccessibilityEnum.Private, eventContext.CancellationToken);

                        // If FTP server is the storage
                        if (uploadLocation == UploadLocationEnum.FtpServer)
                        {
                            // create an FTP client
                            FtpClient client = new FtpClient(config.Value.ServerUri, config.Value.ServerPort, config.Value.ServerUsername, config.Value.ServerPassword);
                            // Connecting to the server
                            await client.DisconnectAsync();
                        }
                    },
                }
            });

            app.UseTus(httpContext => new DefaultTusConfiguration
            {
                // Use TusDiskStore instead of CustomTusDiskStore if you want to use localhost as the storage without config param
                Store = new TusDiskStore(
                    tusUploadUtils.GetStorePath("uploads",
                                                uploadLocation, UploadLinkAccessibilityEnum.Private),
                    true,
                    new TusDiskBufferSize(1024 * 1024 * 5, 1024 * 1024 * 5)),

                // On what url should we listen for uploads?
                UrlPath = "/api/v1/attachments/add-public-media",
                Events  = new Events
                {
                    OnAuthorizeAsync = eventContext =>
                    {
                        var refreshToken = httpContextAccessor.HttpContext.Request.Cookies["refreshToken"];

                        if (refreshToken == null)
                        {
                            eventContext.FailRequest(HttpStatusCode.Unauthorized);
                            return(Task.CompletedTask);
                        }
                        // Do other verification on the user; claims, roles, etc. In this case, check the username.
                        // if (eventContext.HttpContext.User.Identity.Name != "test")
                        // {
                        //     eventContext.FailRequest(HttpStatusCode.Forbidden, "'test' is the only allowed user");
                        //     return Task.CompletedTask;
                        // }

                        // Verify different things depending on the intent of the request.
                        // E.g.:
                        //   Does the file about to be written belong to this user?
                        //   Is the current user allowed to create new files or have they reached their quota?
                        //   etc etc
                        switch (eventContext.Intent)
                        {
                        case IntentType.CreateFile:
                            break;

                        case IntentType.ConcatenateFiles:
                            break;

                        case IntentType.WriteFile:
                            break;

                        case IntentType.DeleteFile:
                            break;

                        case IntentType.GetFileInfo:
                            break;

                        case IntentType.GetOptions:
                            break;

                        default:
                            break;
                        }

                        return(Task.CompletedTask);
                    },

                    OnBeforeCreateAsync = async ctx =>
                    {
                        var storePath = tusUploadUtils.GetStorePath(
                            "uploads",
                            uploadLocation,
                            UploadLinkAccessibilityEnum.Private);
                        // If localhost is the storage
                        if (uploadLocation == UploadLocationEnum.LocalHost)
                        {
                            // Create temp directory if it does not exist...
                            Directory.CreateDirectory(storePath);
                        }

                        // If FTP server is the storage
                        if (uploadLocation == UploadLocationEnum.FtpServer)
                        {
                            // create an FTP client
                            FtpClient client = new FtpClient(config.Value.ServerUri, config.Value.ServerPort, config.Value.ServerUsername, config.Value.ServerPassword);
                            // Connecting to the server
                            await client.ConnectAsync();

                            // check if a folder doesn't exist
                            if (!await client.DirectoryExistsAsync(storePath))
                            {
                                await client.CreateDirectoryAsync(storePath);
                            }
                        }

                        if (!ctx.Metadata.ContainsKey("name"))
                        {
                            ctx.FailRequest("name metadata must be specified. ");
                        }

                        if (!ctx.Metadata.ContainsKey("type"))
                        {
                            ctx.FailRequest("filetype metadata must be specified. ");
                        }

                        if (!await tusUploadUtils.IsFileTypeAllowed(ctx.Metadata["type"].GetString(Encoding.UTF8), SiteTypeEnum.Blog))
                        {
                            ctx.FailRequest("Filetype is not allowed!");
                        }
                    },

                    OnFileCompleteAsync = async eventContext =>
                    {
                        ITusFile file = await eventContext.GetFileAsync();

                        var refreshToken = httpContextAccessor.HttpContext.Request.Cookies["refreshToken"];

                        // Saving file information into database
                        await tusUploadUtils.SaveTusFileInfoAsync(file, SiteTypeEnum.Blog, refreshToken, uploadLocation, UploadLinkAccessibilityEnum.Public, eventContext.CancellationToken);

                        // If FTP server is the storage
                        if (uploadLocation == UploadLocationEnum.FtpServer)
                        {
                            // create an FTP client
                            FtpClient client = new FtpClient(config.Value.ServerUri, config.Value.ServerPort, config.Value.ServerUsername, config.Value.ServerPassword);
                            // Connecting to the server
                            await client.DisconnectAsync();
                        }
                    },
                }
            });


            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }