1
0
mirror of https://github.com/bitwarden/server.git synced 2025-07-01 08:02:49 -05:00

attachment apis and azure storage service

This commit is contained in:
Kyle Spearrin
2017-06-15 15:34:12 -04:00
parent 94be5bc1dd
commit 06ca566be1
9 changed files with 232 additions and 0 deletions

View File

@ -0,0 +1,30 @@
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using System;
using System.Linq;
namespace Bit.Api.Utilities
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class DisableFormValueModelBindingAttribute : Attribute, IResourceFilter
{
public void OnResourceExecuting(ResourceExecutingContext context)
{
var formValue = context.ValueProviderFactories.OfType<FormValueProviderFactory>().FirstOrDefault();
if(formValue != null)
{
context.ValueProviderFactories.Remove(formValue);
}
var jqFormValue = context.ValueProviderFactories.OfType<JQueryFormValueProviderFactory>().FirstOrDefault();
if(jqFormValue != null)
{
context.ValueProviderFactories.Remove(jqFormValue);
}
}
public void OnResourceExecuted(ResourceExecutedContext context)
{
}
}
}

View File

@ -0,0 +1,58 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Net.Http.Headers;
using System;
using System.IO;
using System.Threading.Tasks;
namespace Bit.Api.Utilities
{
public static class MultipartFormDataHelper
{
private static readonly FormOptions _defaultFormOptions = new FormOptions();
public static async Task GetFilesAsync(this HttpRequest request, Func<Stream, string, Task> callback)
{
var boundary = GetBoundary(MediaTypeHeaderValue.Parse(request.ContentType),
_defaultFormOptions.MultipartBoundaryLengthLimit);
var reader = new MultipartReader(boundary, request.Body);
var section = await reader.ReadNextSectionAsync();
while(section != null)
{
ContentDispositionHeaderValue content;
if(ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out content) &&
HasFileContentDisposition(content))
{
await callback(section.Body, HeaderUtilities.RemoveQuotes(content.FileName));
}
section = await reader.ReadNextSectionAsync();
}
}
private static string GetBoundary(MediaTypeHeaderValue contentType, int lengthLimit)
{
var boundary = HeaderUtilities.RemoveQuotes(contentType.Boundary);
if(string.IsNullOrWhiteSpace(boundary))
{
throw new InvalidDataException("Missing content-type boundary.");
}
if(boundary.Length > lengthLimit)
{
throw new InvalidDataException($"Multipart boundary length limit {lengthLimit} exceeded.");
}
return boundary;
}
private static bool HasFileContentDisposition(ContentDispositionHeaderValue content)
{
// Content-Disposition: form-data; name="myfile1"; filename="Misc 002.jpg"
return content != null && content.DispositionType.Equals("form-data") &&
(!string.IsNullOrEmpty(content.FileName) || !string.IsNullOrEmpty(content.FileNameStar));
}
}
}