public static async Task Run(MinioClient client, string bucketName = "my-bucketname", string objectName = "my-objectname") { // default value for expiration is 2 minutes var expiration = DateTime.UtcNow.AddMinutes(2); var form = new PostPolicy(); form.SetKey(objectName); form.SetBucket(bucketName); form.SetExpires(expiration); var args = new PresignedPostPolicyArgs() .WithBucket(bucketName) .WithObject(objectName) .WithPolicy(form); var tuple = await client.PresignedPostPolicyAsync(form); var curlCommand = "curl -k --insecure -X POST"; foreach (var pair in tuple.Item2) { curlCommand = curlCommand + $" -F {pair.Key}={pair.Value}"; } curlCommand = curlCommand + " -F file=@/etc/issue " + tuple.Item1 + bucketName + "/"; }
public async static Task Run(MinioClient client) { try { PostPolicy form = new PostPolicy(); DateTime expiration = DateTime.UtcNow; form.SetExpires(expiration.AddDays(10)); form.SetKey("my-objectname"); form.SetBucket("my-bucketname"); Tuple <string, Dictionary <string, string> > tuple = await client.PresignedPostPolicyAsync(form); string curlCommand = "curl -X POST "; foreach (KeyValuePair <string, string> pair in tuple.Item2) { curlCommand = curlCommand + String.Format(" -F {0}={1}", pair.Key, pair.Value); } curlCommand = curlCommand + " -F file=@/etc/bashrc " + tuple.Item1; // https://s3.amazonaws.com/my-bucketname"; Console.Out.WriteLine(curlCommand); } catch (Exception e) { Console.Out.WriteLine("Exception ", e.Message); } }
public async Task <AddPolicyResponse> ExecuteAsync(PostPolicy request, string url, string authorizationHeaderValue) { if (request == null) { throw new ArgumentNullException(nameof(request)); } if (string.IsNullOrWhiteSpace(url)) { throw new ArgumentNullException(nameof(url)); } if (string.IsNullOrWhiteSpace(authorizationHeaderValue)) { throw new ArgumentNullException(nameof(authorizationHeaderValue)); } var httpClient = _httpClientFactory.GetHttpClient(); var serializedPostResourceSet = JsonConvert.SerializeObject(request); var body = new StringContent(serializedPostResourceSet, Encoding.UTF8, "application/json"); var httpRequest = new HttpRequestMessage { Content = body, Method = HttpMethod.Post, RequestUri = new Uri(url) }; httpRequest.Headers.Add("Authorization", "Bearer " + authorizationHeaderValue); var httpResult = await httpClient.SendAsync(httpRequest).ConfigureAwait(false); httpResult.EnsureSuccessStatusCode(); var content = await httpResult.Content.ReadAsStringAsync().ConfigureAwait(false); return(JsonConvert.DeserializeObject <AddPolicyResponse>(content)); }
internal SignedPostPolicy(PostPolicy source, string encodedPolicy, string signature, DateTimeOffset expiration, Uri url) { Source = GaxPreconditions.CheckNotNull(source, nameof(source)); PostUrl = GaxPreconditions.CheckNotNull(url, nameof(url)); EncodedPolicy = GaxPreconditions.CheckNotNull(encodedPolicy, nameof(encodedPolicy)); Signature = GaxPreconditions.CheckNotNull(signature, nameof(signature)); Expiration = expiration; }
public SignedPostPolicy Sign(PostPolicy postPolicy, Options options, IBlobSigner blobSigner, IClock clock) { var state = new PostPolicySigningState(new PostPolicy(postPolicy), options, blobSigner, clock); var base64Signature = blobSigner.CreateSignature(state._blobToSign); var rawSignature = Convert.FromBase64String(base64Signature); var hexSignature = FormatHex(rawSignature); return(state.GetResult(hexSignature)); }
internal PostPolicySigningState(PostPolicy policy, Options options, IBlobSigner blobSigner, IClock clock) { string uri = options.UrlStyle switch { UrlStyle.PathStyle => policy.Bucket == null ? StorageHost : $"{StorageHost}/{policy.Bucket}", UrlStyle.VirtualHostedStyle => policy.Bucket == null ? throw new ArgumentNullException(nameof(PostPolicy.Bucket), $"When using {UrlStyle.VirtualHostedStyle} a bucket condition must be set in the policy.") : $"{policy.Bucket}.{StorageHost}", UrlStyle.BucketBoundHostname => options.BucketBoundHostname, _ => throw new ArgumentOutOfRangeException(nameof(options.UrlStyle)) }; uri = $"{options.Scheme}://{uri}/"; options = options.ToExpiration(clock); var now = clock.GetCurrentDateTimeUtc(); int expirySeconds = (int)(options.Expiration.Value - now).TotalSeconds; if (expirySeconds <= 0) { throw new ArgumentOutOfRangeException(nameof(options.Expiration), "Expiration must be at least 1 second."); } if (expirySeconds > MaxExpirySecondsInclusive) { throw new ArgumentOutOfRangeException(nameof(options.Expiration), "Expiration must not be greater than 7 days."); } var datestamp = now.ToString("yyyyMMdd", CultureInfo.InvariantCulture); string credentialScope = $"{datestamp}/{DefaultRegion}/{ScopeSuffix}"; policy.SetField(PolicyCreationDateTime.Element, new DateTimeOffset(now)); policy.SetField(PolicyAlgorithm.Element, Algorithm); policy.SetField(PolicyCredential.Element, $"{blobSigner.Id}/{credentialScope}"); _expiration = options.Expiration.Value; _policy = policy; _url = new Uri(uri); StringBuilder sb = new StringBuilder(); StringWriter sw = new StringWriter(sb); using (JsonWriter writer = new JsonTextWriter(sw)) { writer.StringEscapeHandling = StringEscapeHandling.EscapeNonAscii; writer.WriteStartObject(); policy.WriteTo(writer); writer.WritePropertyName("expiration"); writer.WriteValue(_expiration.UtcDateTime.ToString("yyyy-MM-dd'T'HH:mm:ss'Z'", CultureInfo.InvariantCulture)); writer.WriteEndObject(); } var decodedPolicy = sb.ToString(); _encodedPolicy = Convert.ToBase64String(Encoding.UTF8.GetBytes(decodedPolicy)); _blobToSign = Encoding.UTF8.GetBytes(_encodedPolicy); }
public async Task <SignedPostPolicy> SignAsync(PostPolicy postPolicy, Options options, IBlobSigner blobSigner, IClock clock, CancellationToken cancellationToken) { var state = new PostPolicySigningState(new PostPolicy(postPolicy), options, blobSigner, clock); var base64Signature = await blobSigner.CreateSignatureAsync(state._blobToSign, cancellationToken).ConfigureAwait(false); var rawSignature = Convert.FromBase64String(base64Signature); var hexSignature = FormatHex(rawSignature); return(state.GetResult(hexSignature)); }
public async void Unsupported_SignPostPolicy() { var signer = UrlSigner.FromServiceAccountCredential(CreateFakeServiceAccountCredential()); var options = Options .FromExpiration(DateTimeOffset.UtcNow + TimeSpan.FromDays(1)) .WithSigningVersion(SigningVersion.V2); var postPolicy = PostPolicy.ForBucketAndKey("my-bucket", "my-test-object"); Assert.Throws <NotSupportedException>(() => signer.Sign(postPolicy, options)); await Assert.ThrowsAsync <NotSupportedException>(() => signer.SignAsync(postPolicy, options)); }
public static AddPolicyParameter ToParameter(this PostPolicy postPolicy) { var rules = postPolicy.Rules == null ? new List <AddPolicyRuleParameter>() : postPolicy.Rules.Select(r => r.ToParameter()).ToList(); return(new AddPolicyParameter { Rules = rules, ResourceSetIds = postPolicy.ResourceSetIds }); }
public static AddPolicyParameter ToParameter(this PostPolicy postPolicy) { return(new AddPolicyParameter { Claims = postPolicy.Claims == null ? new List <AddClaimParameter>() : postPolicy.Claims.Select(c => c.ToParameter()).ToList(), IsResourceOwnerConsentNeeded = postPolicy.IsResourceOwnerConsentNeeded, Script = postPolicy.Script, ResourceSetIds = postPolicy.ResourceSetIds, Scopes = postPolicy.Scopes, ClientIdsAllowed = postPolicy.ClientIdsAllowed }); }
public async Task <ActionResult> PostPolicy([FromBody] PostPolicy postPolicy) { if (postPolicy == null) { return(BuildError(ErrorCodes.InvalidRequestCode, "no parameter in body request", HttpStatusCode.BadRequest)); } var policyId = await _policyActions.AddPolicy(postPolicy.ToParameter()); var content = new AddPolicyResponse { PolicyId = policyId }; return(new ObjectResult(content) { StatusCode = (int)HttpStatusCode.Created }); }
public async Task <ActionResult> PostPolicy([FromBody] PostPolicy postPolicy) { if (postPolicy == null) { throw new ArgumentNullException(nameof(postPolicy)); } var policyId = await _policyActions.AddPolicy(postPolicy.ToParameter()); var content = new AddPolicyResponse { PolicyId = policyId }; await _representationManager.AddOrUpdateRepresentationAsync(this, CachingStoreNames.GetPoliciesStoreName, false); return(new ObjectResult(content) { StatusCode = (int)HttpStatusCode.Created }); }
public async Task <string> GetPresignedUploadUrlAsync(DTOs.Uploads.FileInfo fileInfo) { string endpoint = _config["AppSettings:S3Endpoint"]; string apiKey = _config["AppSettings:S3ApiKey"]; string apiSecret = _config["AppSettings:S3ApiSecret"]; string bucketName = _config["AppSettings:S3BucketName"]; PostPolicy policy = new PostPolicy(); DateTime expiredIn = DateTime.UtcNow.AddMinutes(15); policy.SetExpires(expiredIn); policy.SetContentLength(fileInfo.Size); policy.SetcontentType(fileInfo.ContentType); policy.SetKey(fileInfo.Name); policy.SetBucket(bucketName); var minio = new MinioClient(endpoint, apiKey, apiSecret); await minio.PresignedPostPolicyAsync(policy); string presignedUrl = await minio.PresignedPutObjectAsync(bucketName, fileInfo.Name, 15 * 60); return(presignedUrl); }
static int Main() { /// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-bucketname and /// my-objectname are dummy values, please replace them with original values. var client = new MinioClient("s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY"); PostPolicy form = new PostPolicy(); DateTime expiration = DateTime.UtcNow; form.SetExpires(expiration.AddDays(10)); form.SetKey("my-objectname"); form.SetBucket("my-bucketname"); Dictionary <string, string> formData = client.PresignedPostPolicy(form); string curlCommand = "curl "; foreach (KeyValuePair <string, string> pair in formData) { curlCommand = curlCommand + " -F " + pair.Key + "=" + pair.Value; } curlCommand = curlCommand + " -F file=@/etc/bashrc https://s3.amazonaws.com/my-bucketname"; Console.Out.WriteLine(curlCommand); return(0); }
public async static Task Run(MinioClient client, string bucketName = "my-bucketname", string objectName = "my-objectname") { // default value for expiration is 2 minutes DateTime expiration = DateTime.UtcNow.AddMinutes(2); // DefaultPolicy defaultPolicy = delegate (string bucketName, // string objectName, // DateTime expiration) // { PostPolicy form = new PostPolicy(); form.SetKey(objectName); form.SetBucket(bucketName); form.SetExpires(expiration); // return policy; // }; // PostPolicy postPolicy = defaultPolicy(bucketName, // objectName, // expiration); PresignedPostPolicyArgs args = new PresignedPostPolicyArgs() .WithBucket(bucketName) .WithObject(objectName) .WithPolicy(form); var tuple = await client.PresignedPostPolicyAsync(form); string curlCommand = "curl -k --insecure -X POST"; foreach (KeyValuePair <string, string> pair in tuple.Item2) { curlCommand = curlCommand + $" -F {pair.Key}={pair.Value}"; } curlCommand = curlCommand + " -F file=@/etc/issue " + tuple.Item1 + bucketName + "/"; }
static int Main() { /// Note: s3 AccessKey and SecretKey needs to be added in App.config file /// See instructions in README.md on running examples for more information. var client = new MinioClient("s3.amazonaws.com", ConfigurationManager.AppSettings["s3AccessKey"], ConfigurationManager.AppSettings["s3SecretKey"]); PostPolicy form = new PostPolicy(); DateTime expiration = DateTime.UtcNow; form.SetExpires(expiration.AddDays(10)); form.SetKey("my-objectname"); form.SetBucket("my-bucketname"); Dictionary <string, string> formData = client.PresignedPostPolicy(form); string curlCommand = "curl "; foreach (KeyValuePair <string, string> pair in formData) { curlCommand = curlCommand + " -F " + pair.Key + "=" + pair.Value; } curlCommand = curlCommand + " -F file=@/etc/bashrc https://s3.amazonaws.com/my-bucketname"; Console.Out.WriteLine(curlCommand); return(0); }
public void TestPresignedPostPolicy() { DateTime requestDate = new DateTime(2020, 05, 01, 15, 45, 33, DateTimeKind.Utc); var authenticator = new V4Authenticator(false, "my-access-key", "secretkey"); var policy = new PostPolicy(); policy.SetBucket("bucket-name"); policy.SetKey("object-name"); policy.SetAlgorithm("AWS4-HMAC-SHA256"); var region = "mock-location"; policy.SetCredential(authenticator.GetCredentialString(requestDate, region)); policy.SetDate(requestDate); policy.SetSessionToken(null); string policyBase64 = policy.Base64(); string signature = authenticator.PresignPostSignature(region, requestDate, policyBase64); policy.SetPolicy(policyBase64); policy.SetSignature(signature); var headers = new Dictionary <string, string> { { "bucket", "bucket-name" }, { "key", "object-name" }, { "x-amz-algorithm", "AWS4-HMAC-SHA256" }, { "x-amz-credential", "my-access-key/20200501/mock-location/s3/aws4_request" }, { "x-amz-date", "20200501T154533Z" }, { "policy", "eyJleHBpcmF0aW9uIjoiMDAwMS0wMS0wMVQwMDowMDowMC4wMDBaIiwiY29uZGl0aW9ucyI6W1siZXEiLCIkYnVja2V0IiwiYnVja2V0LW5hbWUiXSxbImVxIiwiJGtleSIsIm9iamVjdC1uYW1lIl0sWyJlcSIsIiR4LWFtei1hbGdvcml0aG0iLCJBV1M0LUhNQUMtU0hBMjU2Il0sWyJlcSIsIiR4LWFtei1jcmVkZW50aWFsIiwibXktYWNjZXNzLWtleS8yMDIwMDUwMS9tb2NrLWxvY2F0aW9uL3MzL2F3czRfcmVxdWVzdCJdLFsiZXEiLCIkeC1hbXotZGF0ZSIsIjIwMjAwNTAxVDE1NDUzM1oiXV19" }, { "x-amz-signature", "ec6dad862909ee905cfab3ef87ede0e666eebd6b8f00d28e5df104a8fcbd4027" }, }; CollectionAssert.AreEquivalent(headers, policy.GetFormData()); }
private async static Task PresignedPostPolicy_Test1(MinioClient minio) { Console.Out.WriteLine("Test1: PresignedPostPolicyAsync"); string bucketName = GetRandomName(15); string objectName = GetRandomName(10); string fileName = CreateFile(1 * MB); try { await Setup_Test(minio, bucketName); await minio.PutObjectAsync(bucketName, objectName, fileName); // Generate presigned post policy url PostPolicy form = new PostPolicy(); DateTime expiration = DateTime.UtcNow; form.SetExpires(expiration.AddDays(10)); form.SetKey(objectName); form.SetBucket(bucketName); var pairs = new List <KeyValuePair <string, string> >(); string url = "https://s3.amazonaws.com/" + bucketName; Tuple <string, System.Collections.Generic.Dictionary <string, string> > policyTuple = await minio.PresignedPostPolicyAsync(form); var httpClient = new HttpClient(); using (var stream = File.OpenRead(fileName)) { MultipartFormDataContent multipartContent = new MultipartFormDataContent(); multipartContent.Add(new StreamContent(stream), fileName, objectName); multipartContent.Add(new FormUrlEncodedContent(pairs)); var response = await httpClient.PostAsync(url, multipartContent); response.EnsureSuccessStatusCode(); } // Validate PolicyType policy = await minio.GetPolicyAsync(bucketName, objectName.Substring(5)); Assert.AreEqual(policy.GetType(), PolicyType.READ_ONLY); await minio.RemoveObjectAsync(bucketName, objectName); await TearDown(minio, bucketName); File.Delete(fileName); } catch (Exception e) { Console.Out.WriteLine("Exception ", e.Message); } Console.Out.WriteLine("Test1: PresignedPostPolicyAsync Complete"); await minio.RemoveObjectAsync(bucketName, objectName); await TearDown(minio, bucketName); File.Delete(fileName); Console.Out.WriteLine("Test1: PresignedPostPolicyAsync Complete"); }
public async Task <AddPolicyResult> AddByResolution(PostPolicy request, string url, string token) { var policyEndpoint = await GetPolicyEndPoint(UriHelpers.GetUri(url)).ConfigureAwait(false); return(await Add(request, policyEndpoint, token).ConfigureAwait(false)); }
public void PostPolicyTest(PostPolicyV4Test test) { var timestamp = test.PolicyInput.Timestamp.ToDateTime(); var clock = new FakeClock(timestamp); var signer = UrlSigner .FromServiceAccountCredential(StorageConformanceTestData.TestCredential) .WithClock(clock); var options = Options .FromDuration(TimeSpan.FromSeconds(test.PolicyInput.Expiration)) .WithSigningVersion(SigningVersion.V4) .WithScheme(test.PolicyInput.Scheme); switch (test.PolicyInput.UrlStyle) { case UrlStyle.VirtualHostedStyle: options = options.WithUrlStyle(UrlSigner.UrlStyle.VirtualHostedStyle); break; case UrlStyle.BucketBoundHostname: options = options.WithBucketBoundHostname(test.PolicyInput.BucketBoundHostname); break; default: break; } var postPolicy = PostPolicy.ForBucketAndKey(test.PolicyInput.Bucket, test.PolicyInput.Object, new PostPolicyElementTestComparer()); foreach (var field in test.PolicyInput.Fields) { if (field.Key.StartsWith("x-goog-meta-")) { postPolicy.SetCustomField(PostPolicyCustomElement.GoogleMetadata, field.Key, field.Value); } else { var element = GetStandardElement(field.Key); if (element == PostPolicyStandardElement.SuccessActionStatus) { postPolicy.SetField(element, (HttpStatusCode)int.Parse(field.Value)); } else { postPolicy.SetField(element, field.Value); } } } for (int i = 0; i < test.PolicyInput.Conditions?.StartsWith?.Count; i += 2) { postPolicy.SetStartsWith( GetStandardElement(test.PolicyInput.Conditions.StartsWith[i]), test.PolicyInput.Conditions.StartsWith[i + 1]); } if (test.PolicyInput.Conditions?.ContentLengthRange?.Count > 0) { postPolicy.SetRange(PostPolicyStandardElement.ContentLength, test.PolicyInput.Conditions.ContentLengthRange[0], test.PolicyInput.Conditions.ContentLengthRange[1]); } var signedPostPolicy = signer.Sign(postPolicy, options); Assert.Equal(test.PolicyOutput.Url, signedPostPolicy.PostUrl.ToString()); Assert.Equal(test.PolicyOutput.Fields.Count, signedPostPolicy.Fields.Count); foreach (var field in test.PolicyOutput.Fields) { Assert.True(signedPostPolicy.Fields.TryGetValue(field.Key, out object value)); Assert.Equal(field.Value, value.ToString()); } PostPolicyStandardElement GetStandardElement(string name) => name switch { "acl" => PostPolicyStandardElement.Acl, "$acl" => PostPolicyStandardElement.Acl, "cache-control" => PostPolicyStandardElement.CacheControl, "$cache-control" => PostPolicyStandardElement.CacheControl, "success_action_status" => PostPolicyStandardElement.SuccessActionStatus, "$success_action_status" => PostPolicyStandardElement.SuccessActionStatus, "success_action_redirect" => PostPolicyStandardElement.SuccessActionRedirect, "$success_action_redirect" => PostPolicyStandardElement.SuccessActionRedirect, "content-disposition" => PostPolicyStandardElement.ContentDisposition, "$content-disposition" => PostPolicyStandardElement.ContentDisposition, "content-encoding" => PostPolicyStandardElement.ContentEncoding, "$content-encoding" => PostPolicyStandardElement.ContentEncoding, "content-type" => PostPolicyStandardElement.ContentType, _ => throw new NotImplementedException($"{name} missing from {nameof(GetStandardElement)}.") }; }
internal PostPolicy(PostPolicy other) =>
public Task <SignedPostPolicy> SignAsync(PostPolicy postPolicy, Options options, IBlobSigner blobSigner, IClock clock, CancellationToken cancellationToken) => throw new NotSupportedException($"Post policy signing is not supported by {nameof(SigningVersion)}.{SigningVersion.V2}.");
/// <summary> /// Signs the given post policy. The result can be used to make form posting requests matching the conditions /// set in the post policy. /// </summary> /// <remarks> /// <para> /// Signing post policies is not supported by <see cref="SigningVersion.V2"/>. A <see cref="NotSupportedException"/> /// will be thrown if an attempt is made to sign a post policy using <see cref="SigningVersion.V2"/>. /// </para> /// <para> /// When a <see cref="UrlSigner"/> is created with a service account credential, the signing can be performed /// with no network access. When it is created with an implementation of <see cref="IBlobSigner"/>, that may require /// network access or other IO. In that case, one of the asynchronous methods should be used when the caller is /// in a context that should not block. /// </para> /// <para> /// See https://cloud.google.com/storage/docs/xml-api/post-object for more information on signed post policies. /// </para> /// </remarks> /// <param name="postPolicy">The post policy to signed and that will be enforced when making the post request. /// Most not be null.</param> /// <param name="options">The options used to generate the signed post policy. Must not be null.</param> /// <param name="cancellationToken">The token to monitor for cancellation requests.</param> /// <returns>The signed post policy, which contains all the fields that should be including in the form to post.</returns> public Task <SignedPostPolicy> SignAsync(PostPolicy postPolicy, Options options, CancellationToken cancellationToken = default) => GetEffectiveSigner(GaxPreconditions.CheckNotNull(options, nameof(options)).SigningVersion).SignAsync( GaxPreconditions.CheckNotNull(postPolicy, nameof(postPolicy)), options, _blobSigner, _clock, cancellationToken);
/// <summary> /// Signs the given post policy. The result can be used to make form posting requests matching the conditions /// set in the post policy. /// </summary> /// <remarks> /// <para> /// Signing post policies is not supported by <see cref="SigningVersion.V2"/>. A <see cref="NotSupportedException"/> /// will be thrown if an attempt is made to sign a post policy using <see cref="SigningVersion.V2"/>. /// </para> /// <para> /// When a <see cref="UrlSigner"/> is created with a service account credential, the signing can be performed /// with no network access. When it is created with an implementation of <see cref="IBlobSigner"/>, that may require /// network access or other IO. In that case, one of the asynchronous methods should be used when the caller is /// in a context that should not block. /// </para> /// <para> /// See https://cloud.google.com/storage/docs/xml-api/post-object for more information on signed post policies. /// </para> /// </remarks> /// <param name="postPolicy">The post policy to signed and that will be enforced when making the post request. /// Must not be null.</param> /// <param name="options">The options used to generate the signed post policy. Must not be null.</param> /// <returns>The signed post policy, which contains all the fields that should be including in the form to post.</returns> public SignedPostPolicy Sign(PostPolicy postPolicy, Options options) => GetEffectiveSigner(GaxPreconditions.CheckNotNull(options, nameof(options)).SigningVersion).Sign( GaxPreconditions.CheckNotNull(postPolicy, nameof(postPolicy)), options, _blobSigner, _clock);
public Task <AddPolicyResponse> Add(PostPolicy request, string url, string token) { return(_addPolicyOperation.ExecuteAsync(request, url, token)); }
public async Task <AddPolicyResponse> AddByResolution(PostPolicy request, string url, string token) { var policyEndpoint = await GetPolicyEndPoint(UriHelpers.GetUri(url)); return(await Add(request, policyEndpoint, token)); }
public SignedPostPolicy Sign(PostPolicy postPolicy, Options options, IBlobSigner blobSigner, IClock clock) => throw new NotSupportedException($"Post policy signing is not supported by {nameof(SigningVersion)}.{SigningVersion.V2}.");