This is my bucket policy
{
"Version" : "2012-10-17",
"ID" : "************",
"Statement" : [
{
"Sid" : "************",
"Effect" : "Allow",
"Principar" : "*",
"Action" : [
"s3:PutObject",
"s3:PutObjectAcl",
"s3:GetObject",
"s3:GetObjectAcl"
],
"Resource" : "************************"
}
]
}
{
"Version" : "2012-10-17",
"ID" : "",
"Statement" : [
{
"Sid" : "",
"Effect" : "Allow",
"Principar" : "",
"Action" : [
"s3:PutObject",
"s3:PutObjectAcl",
"s3:GetObject",
"s3:GetObjectAcl"
],
"Resource" : "***********************"
}
]
}
and here's the code I used to upload image:
[HttpPost]
public bool UploadFile(string file)
{
var s3Client = new AmazonS3Client(accesskey, secretkey, RegionEndpoint.APSoutheast1);
var fileTransferUtility = new TransferUtility(s3Client);
if (file.Length > 0)
{
var filePath = file;
var fileTransferUtilityRequest = new TransferUtilityUploadRequest
{
BucketName = bucketName,
FilePath = filePath,
StorageClass = S3StorageClass.StandardInfrequentAccess,
PartSize = 6291456, // 6 MB.
Key = keyName,
CannedACL = S3CannedACL.PublicRead
};
fileTransferUtilityRequest.Metadata.Add("param1", "Value1");
fileTransferUtilityRequest.Metadata.Add("param2", "Value2");
fileTransferUtility.Upload(fileTransferUtilityRequest);
fileTransferUtility.Dispose();
}
return true;
}
and getting "The bucket does not allow ACLs" even setting it to "ACLs enabled" in object ownership
#Rutger 's answer is correct, and now it's 2022, aws console has changed ( not a lot ,but some what ), so let me show the images:
1.assume you have created the s3 bucket, in the list page,
2.don't toggle the "block" options
3.find the ownership, then click edit.
4.edit the object owner ship (ACLs enabled)
5.now the edit button for ACL is clickable.
6.toggle the permissions you want and save changes.
it's done, now you can upload images to s3 via commandline and then visit them in your browser:
You should be able to go to the AWS S3 console and navigate to the bucket details for the bucket you try to write objects to. You'll see a tab called 'Permissions'. There you have the option to change the "Object Ownership" at a block with te same title.
Once there, you can choose the option "ACLs enabled".
After applying those changes, you should be able to write objects with ACL options.
Related
Iam using third part called tyntec to deal with whatsApp messages ,
my Api deals with tyntec to send a file to specific number :-
and this is the part in my repository which has responsability to talk with tyntec :-
public async Task<SendingMessageRespons> SendRequestAsync(object requestBody)
{
var serializedRequest = "";
try
{
serializedRequest = JsonSerializer.Serialize(requestBody, new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
IgnoreNullValues = true
});
var requestContent = new StringContent(serializedRequest, Encoding.UTF8, "application/json");
var client = new HttpClient();
client.DefaultRequestHeaders.Add("apikey", _config.APIkey);
var response = await client.PostAsync(_config.APIUrl, requestContent);
var content = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
var message = JsonSerializer.Deserialize<Message>(content);
return SendingMessageRespons.Create(response.StatusCode, serializedRequest, content, message.messageId);
}
else
{
return SendingMessageRespons.Create(response.StatusCode, serializedRequest, content, string.Empty);
}
}
catch (Exception ex)
{
return SendingMessageRespons.Create(HttpStatusCode.ExpectationFailed, serializedRequest, ex.Message, null);
}
}
and it's configuration:-
my problem is when I send the pdf to any android user ... it works fine and the name of pdf shows like this :-
but when I send the same pdf to IOS user the name becomes "Untitled" Like this
and when I open the pdf it's name shows
Am trying to guess where is the problem but I can't figure out
I found the answer
the problem was in parameter of the body request :-
My old Json
{
"to": "201119959346",
"channels": ["whatsapp"],
"whatsapp": {
"from" : "201000081092",
"media" : {
"type" : "document"
,
"url" : "https://www.tyntec.com/sites/default/files/uploads/1608_tyntec_CorporateBackground.pdf",
"caption" : "hady125 corporate background"
},
"contentType":"media"
}
}
The new one :-
{
"to": "201119959346",
"channels": ["whatsapp"],
"whatsapp": {
"from" : "201000081092",
"media" : {
"type" : "document"
,
"filename":"hady corporate background" // the new param
,
"url" : "https://www.tyntec.com/sites/default/files/uploads/1608_tyntec_CorporateBackground.pdf",
"caption" : "hady125 corporate background"
},
"contentType":"media"
}
}
notice :- you should keep the two params Caption and filename to work in IOS and Android
I am trying to write a lambda to run FFMPEG in an AWS lambda. I have done this before at another workplace so I know that it is possible.
The log shows that I make a Temporary URL to read the file in, it processes with FFMPEG, I pipe the output to a byte[] which is showing data in it, and then I try to do an S3 PutObjectRequest, which always fails with this message:
The request signature we calculated does not match the signature you provided. Check your key and signing method.
The S3 client is the same credentials that I use automated all the time to upload files to S3 from different servers at different locations of our company. I have tried a couple different IAMs to no effect.
I am not trying to do any sort of signature whatsoever. I am simply doing this:
var putRequest = new PutObjectRequest
{
BucketName = m.Groups["bucket"].Value,
Key = m.Groups["key"].Value,
InputStream = new MemoryStream(Encoding.UTF8.GetBytes(data ?? "")),
CannedACL = S3CannedACL.PublicRead,
ContentType = MimeTypes.GetMimeType(Path.GetExtension(m.Groups["key"].Value)),
DisablePayloadSigning = true,
};
putRequest.Headers.ContentLength = data.Length;
_context.Logger.LogLine($"Saving file to bucket '{putRequest.BucketName}' and key '{putRequest.Key}' and content type '{putRequest.ContentType}' and content length {putRequest.Headers.ContentLength}");
try
{
await _s3Client.PutObjectAsync(putRequest);
}
catch (AmazonS3Exception s3x)
{
_context.Logger.LogLine($"S3 Exception: {s3x.Message}");
}
I have checked bucket and key and they are correct. Data.length is greater than 0. Content type is "audio/mpeg", which is correct for .mp3. The data is there to be written.
My lambda is running under AWSLambda_Full_Access with the following additional rights granted:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:ListStorageLensConfigurations",
"s3:ListAccessPointsForObjectLambda",
"s3:GetAccessPoint",
"s3:PutAccountPublicAccessBlock",
"s3:GetAccountPublicAccessBlock",
"s3:ListAllMyBuckets",
"s3:*",
"s3:ListAccessPoints",
"s3:ListJobs",
"s3:PutStorageLensConfiguration",
"s3:ListMultiRegionAccessPoints",
"s3:CreateJob"
],
"Resource": "*"
}
]
}
Does anyone have any ideas what else I could be missing? I have been stuck on this one problem for over 3 days now and have tried everything I can think of, so it must be something I'm not thinking of.
Thanks.
We have a front-end flutter application, which should send file to our backend (ASP.NET Core Web API).
The question is: how should controller be constructed? I believe that it should be a POST-method, but how to get this file on the backend.
P.S. All requests come to our API in JSON format.
In dotnet core controller you can use IFormFile Interface to get files,
[HttpPost("upload-file")]
public async Task<IActionResult> UploadFile([FromQuery] IFormFile file){
if(file.Length > 0){
// Do whatever you want with your file here
// e.g.: upload it to somewhere like Azure blob or AWS S3
}
//TODO: Save file description and image URL etc to database.
}
In Flutter you need to send a Multipart POST request to include files with binary content (images, various documents, etc.), in addition to the regular text values.
import 'package:http/http.dart' as http;
Future<String> uploadImage(filename, url) async {
var request = http.MultipartRequest('POST', Uri.parse(url));
request.files.add(
http.MultipartFile.fromBytes(
'file',
File(filename).readAsBytesSync(),
filename: filename.split("/").last
)
);
var res = await request.send();
return res;
}
F# file upload took few hours to figure out giraffe and HTML when some other data need to be added + drag-drop
Here is code:
script [ _type "text/javascript"; _src "https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" ] [];
script [ _type "text/javascript"] [ rawText "
$(function() { $('#uploadForm').submit(function() {
if(!$('form input[type=file]').val()) {
alert('You must select a file!');
return false;
};});}); "];
form [_method "POST"; _action "/upload";
_enctype "multipart/form-data"; _id "uploadForm"; _name "uploadForm"]
h2 [] [ Text "Drop or select file to upload" ];
[ input [ _type "file"; _name "fileName"; _id "file"; ];
input [ _type "text"; _name "Title";];
button [ _type "submit"] [ str "Uppload" ];
];
and
let fileUploadHandler = fun (next : HttpFunc) (ctx : HttpContext) -> task {
return!
(match ctx.Request.HasFormContentType with
| false -> RequestErrors.BAD_REQUEST ("Bad file uppload request")
| true ->
let title = (ctx.Request.Form.Item("Title").ToString()) in
let file = ctx.Request.Form.Files |> Seq.head in
let fileName = file.FileName in
let stream = new MemoryStream() in
file.CopyTo( stream);
let content = Encoding.UTF8.GetString(stream.ToArray()) in
let db_ctx = mssql.GetDataContext() in
let row = db_ctx.Dbo.File.Create(content, fileName, title) in
db_ctx.SubmitUpdates();
htmlView indexView
)
next ctx
}
POST >=> route "/upload" >=> fileUploadHandler;
I currently have an Azure Function that I would like to have update a QnaMaker Knowledge Base every day or so. Currently everything is connected and working fine, however I can only send Qna Objects (qna pairs) and not urls to files on a website of mine. So in the example I provided below, while it should populate the KB with 2 questions and the file from the url, it only populates the questions.
Currently this is not giving me any kind of error, in fact the response code from my call to the KB comes back as 204. So it it getting through, but still not adding the file to the KB as it should.
NOTE: The file being imported in this example (alice-I.html) is a random one for this demonstration (not mine, for security), but the issue is the same. If I directly add this file to the QnaMaker from the KB site itself it works fine, but it won't update from the Azure Function Code.
Any insights into what is happening would be great.
Content Being Sent To Knowledge Base
string replace_kb = #"{
'qnaList': [
{
'id': 0,
'answer': 'A-1',
'source': 'Custom Editorial',
'questions': [
'Q-1'
],
'metadata': []
},
{
'id': 1,
'answer': 'A-2',
'source': 'Custom Editorial',
'questions': [
'Q-2'
],
'metadata': [
{
'name': 'category',
'value': 'api'
}
]
}
],
'files': [
{
'fileName': 'alice-I.html',
'fileUri': 'https://www.cs.cmu.edu/~rgs/alice-I.html'
}
]
}";
Code Sending Content To Knowledge Base
using (var clientF = new HttpClient())
using (var requestF = new HttpRequestMessage())
{
requestF.Method = HttpMethod.Put;
requestF.RequestUri = new Uri(<your-uri>);
requestF.Content = new StringContent(replace_kb, Encoding.UTF8, "application/json");
requestF.Headers.Add("Ocp-Apim-Subscription-Key", <your-key>);
var responseF = await clientF.SendAsync(requestF);
if (responseF.IsSuccessStatusCode)
{
log.LogInformation("{'result' : 'Success.'}");
log.LogInformation($"------------>{responseF}");
}
else
{
await responseF.Content.ReadAsStringAsync();
log.LogInformation($"------------>{responseF}");
}
}
So I still don't know how to get the above working, but I got it to work a different way. Basically I used the UpdateKbOperationDTO Class listed here: class
This still isn't the perfect solution, but it allows me to update my KB with files using code instead of the interface.
Below is my new code:
QnAMakerClient qnaC = new QnAMakerClient(new ApiKeyServiceClientCredentials(<subscription-key>)) { Endpoint = "https://<your-custom-domain>.cognitiveservices.azure.com"};
log.LogInformation("Delete-->Start");
List<string> toDelete = new List<string>();
toDelete.Add("<my-file>");
var updateDelete = await qnaC.Knowledgebase.UpdateAsync(kbId, new UpdateKbOperationDTO
{
// Create JSON of changes ///
Add = null,
Update = null,
Delete = new UpdateKbOperationDTODelete(null, toDelete)
});
log.LogInformation("Delete-->Done");
log.LogInformation("Add-->Start");
List<FileDTO> toAdd = new List<FileDTO>();
toAdd.Add(new FileDTO("<my-file>", "<url-to-file>"));
var updateAdd = await qnaC.Knowledgebase.UpdateAsync(kbId, new UpdateKbOperationDTO
{
// Create JSON of changes ///
Add = new UpdateKbOperationDTOAdd(null, null, toAdd),
Update = null,
Delete = null
});
log.LogInformation("Add-->Done");
I'am using the Microsoft Bot Framework to send a file card to a channel or user,
but it looks like the file card has not the correct format... It is not possible to click on the filecard or open the file...
How I generate the card:
FileInfoCard card = new FileInfoCard()
{
FileType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
UniqueId = driveItemUniqueId,
};
Attachment att = card.ToAttachment();
att.ContentUrl = fileLocation;
att.Name = fileName;
replyToConversation.Attachments.Add(att);
return replyToConversation;
And the json code which will be send to teams is the following:
[{
"contentType": "application/vnd.microsoft.teams.card.file.info",
"contentUrl": "https://fileLocation.com/xyz",
"content": {
"uniqueId": "jfölasjflasjföiu289u9o2or2jor2l1ö1l3jrlö12j4l",
"fileType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"etag": null
},
"name": "Meeting Minutes - testmeeting 2 fso - 26-1-2019.docx",
"thumbnailUrl": null
}]
The Microsoft ressource to this topic:
https://learn.microsoft.com/en-us/microsoftteams/platform/concepts/bots/bots-files
with the following example:
{
"attachments": [{
"contentType": "application/vnd.microsoft.teams.card.file.info",
"contentUrl": "https://contoso.sharepoint.com/personal/johnadams_contoso_com/Documents/Applications/file_example.txt",
"name": "file_example.txt",
"content": {
"uniqueId": "1150D938-8870-4044-9F2C-5BBDEBA70C8C",
"fileType": "txt",
}
}]
}
EDIT: Additional information.
I'm not sure if the uniqueId is correct. The word file is uploaded to a SharePoint site. This UniqueId looks not like the unique GUID in the example... on the Team iOS App I can click on the link but there will be a message that it is not possible to access this file.
EDIT: Unique ID fixed but the problem still occurs on MS Teams Desktop client.
I have replaced the unique id with the GUID in the Ctag from the file which I get from the Graph API. On the iOs App it's working now but on the desktop client, there is still the red triangle.
Button on Iphone:
Please set the FileType to docx instead as given below:
FileInfoCard card = new FileInfoCard()
{
FileType = "docx",
UniqueId = Guid.NewGuid().ToString() // unique id.
};
Attachment att = card.ToAttachment();
att.ContentUrl = contentUrl;
att.Name = name;