set messagettl of a message in Azure Queue using python - python-3.x

I'm trying to post a message to azure queue service using python3 by making a POST request and specifying messagettl to -1 which indicates the message does not expire. In the doc https://learn.microsoft.com/en-us/rest/api/storageservices/put-message I have to specify the Authorization key and Date which indicates the time at which the response was initiated (both parameters are required), and the body must be an XML, here what I did:
url = "https://MyStorageAccountName.queue.core.windows.net/MyQueueName?messagettl=-1"
xml = """<?xml version='1.0' encoding='utf-8'?>
<QueueMessage>
<MessageText>First message</MessageText>
</QueueMessage> """
headers = {'Content-Type': 'application/xml',
'Authorization' : 'SharedKey MyStorageAccountName:MyKey1....==',
'Date' : str(datetime.utcnow())}
print(requests.post(url, data=xml, headers=headers).text)
And the response is an error:
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>AuthenticationFailed</Code>
<Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:44d1fd4c-c003-001d-215...000
Time:2020-11-20T15:39:10.9730253Z</Message>
<AuthenticationErrorDetail>The Date header in the request is incorrect.</AuthenticationErrorDetail>
</Error>
which piece of the puzzle I am missing?
UPDATE:
In headers I fixed the issue by replacing str(datetime.utcnow()) with format_date_time(mktime(datetime.now().timetuple())) and fixed the related date error, but I have a new error and don't know how to sign my key:
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>AuthenticationFailed</Code>
<Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:359305a5-a003-0034...
Time:2020-11-20T15:59:12.4611176Z</Message>
<AuthenticationErrorDetail>The MAC signature found in the HTTP request 'HACSNj/4PwH...MyKey...YJQ==' is not the same as any computed signature. Server used following string to sign: 'POST
application/xml
Fri, 20 Nov 2020 15:59:09 GMT
/MystorageAccount/MyQueueName'.</AuthenticationErrorDetail>
</Error>

I think using python SDK to do this is much easier, just try the code below:
from azure.storage.queue import QueueClient
connectionString = "<storage account connection string>"
queueName = "<queue name>"
queueClient = QueueClient.from_connection_string(connectionString, queueName)
queueClient.send_message(content = 'hello sdk', time_to_live=-1)
Result:
For info about python queue client sdk, just refer to this doc.

Related

Howto register a webhook with AuthType=HttpHeader using "Dynamics 365 Web API"

To register a webhook on Dynamics 365 there is a tool called Plug-in Registration (https://learn.microsoft.com/en-us/powerapps/developer/data-platform/register-web-hook).
However, I would like to automate the webhook registration process and thus would like to use the Web API endpoint for webhook registration:
/api/data/v9.2/serviceendpoints
The problem I have is the setting of the value for the parameter authvalue in the JSON request body, because I want to use Http Header authtype:
{
"name": "Test Webhook",
"url": "https://myendpoint",
"contract": 8,
"authtype": 5,
"authvalue": "<========= ??? what comes here ???"
}
Assuming I want to have this header be sent to my webhook endpoint:
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
What would be the value of authvalue in the JSON above ?
The value should be a string according to the data type of authvalue, but how that should be formatted?
If I use the value Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ= as is for authvalue,
when the webhook is fired, I got the following error in System Job:
Plugin Trace:
[Microsoft.Crm.ServiceBus: Microsoft.Crm.ServiceBus.WebhookPlugin]
[ad9a4124-ab57-ec11-8f8f-6045bd8aed3b: Test for Step Creation]
Error Message:
System.ServiceModel.FaultException`1[Microsoft.Xrm.Sdk.OrganizationServiceFault]:
The webhook call failed because of invalid http headers in authValue.
Check if the authValue format, header names and values are valid for
your Service Endpoint entity. (Fault Detail is equal to Exception
details: ErrorCode: 0x80050203 Message: The webhook call failed
because of invalid http headers in authValue. Check if the authValue
format, header names and values are valid for your Service Endpoint
entity. TimeStamp: 2021-12-08T10:15:26.8637496Z
-- Exception details: ErrorCode: 0x80040216 Message: Received exception when adding custom http headers: for
OrgId:xxxxxx-925f-4958-9aee-xxxxxxxxxxxx, serviceEndpointId:
c099d16c-a057-ec11-8f8f-6045bd8aed3b, name: Test Webhook,
exception:System.Xml.XmlException: Data at the root level is invalid.
Line 1, position 1. at System.Xml.XmlTextReaderImpl.Throw(Exception
e) at System.Xml.XmlTextReaderImpl.ParseRootLevelWhitespace() at
System.Xml.XmlTextReaderImpl.ParseDocumentContent() at
System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean
preserveWhitespace) at System.Xml.XmlDocument.Load(XmlReader
reader) at System.Xml.XmlDocument.LoadXml(String xml) at
Microsoft.Crm.ServiceBus.WebhookClient.ExtractKe...).
For HtppHeader authentication type the key value pair for AuthValue must be set in the following xml format:
<settings><setting name="Authorization" value="Basic dXNlcm5hbWU6cGFzc3dvcmQ=" /></settings>

How to upload files into Azure Blob Storage with Postman?

I am trying to upload base64 string as image file to Azure Blob Storage. Using https://learn.microsoft.com/en-us/rest/api/storageservices/put-blob documentation tried to create blob.
Request Syntax:
PUT https://myaccount.blob.core.windows.net/mycontainer/myblockblob HTTP/1.1
Request Headers:
x-ms-version: 2015-02-21
x-ms-date: <date>
Content-Type: text/plain; charset=UTF-8
x-ms-blob-content-disposition: attachment; filename="fname.ext"
x-ms-blob-type: BlockBlob
x-ms-meta-m1: v1
x-ms-meta-m2: v2
Authorization: SharedKey myaccount:YhuFJjN4fAR8/AmBrqBz7MG2uFinQ4rkh4dscbj598g=
Content-Length: 11
Request Body:
hello world
I am getting response as below,
<?xml
version="1.0" encoding="utf-8"?>
<Error>
<Code>AuthenticationFailed</Code>
<Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:a5d32623-f01e-0040-4275-c1880d000000
Time:2020-11-23T08:45:49.6994297Z</Message>
<AuthenticationErrorDetail>The MAC signature found in the HTTP request 'YhuFJjN4fAR8/AmBrqBz7MG2uFinQ4rkh4dscbj598g=' is not the same as any computed signature. Server used following string to sign: 'PUT
11
text/plain; charset=UTF-8
x-ms-blob-content-disposition:attachment; filename="demo.txt"
x-ms-blob-type:BlockBlob
x-ms-date:Mon, 23 Nov 2020 13:08:11 GMT
x-ms-encryption-key:YhuFJjN4fAR8/AmBrqBz7MG2uFinQ4rkh4dscbj598g=
x-ms-meta-m1:v1
x-ms-meta-m2:v2
x-ms-version:2015-02-21
/<myaccount>/<mycontainer>/<myblob>'.</AuthenticationErrorDetail>
</Error>
How to resolve this issue?
A simple way to upload a blob is to use the sas token.
Nav to azure portal -> your storage account -> Shared access signature, then select the following options in the screenshot -> then click the Generate SAS and connection string button. The screenshot is as below:
Then copy the SAS token, and append it to the url. Then the new url looks like this: https://myaccount.blob.core.windows.net/mycontainer/myblockblob?sv=2019-12-12&ss=b&srt=coxxxxx
Next, in the postman, paste the new url. And in the Headers, you can remove Authorization field.
The test result is as below:
#sathishKumar
If you look closely in this article Authorize with Shared Key
The syntax is as below :
Authorization="[SharedKey|SharedKeyLite] <AccountName>:<Signature>"
It is the signature that is passed along and not the Account key.
Signature is a Hash-based Message Authentication Code (HMAC) constructed from the request and computed by using the SHA256 algorithm, and then encoded by using Base64 encoding.
There are detailed steps how to construct the same mentioned on the above document.
Also, came across the post which talks about a PowerShell script which creates an Signature string through the Powershell that could be useful for you.
Sample Powershell Script
C# Implementation :
internal static AuthenticationHeaderValue GetAuthorizationHeader(
string storageAccountName, string storageAccountKey, DateTime now,
HttpRequestMessage httpRequestMessage, string ifMatch = "", string md5 = "")
{
// This is the raw representation of the message signature.
HttpMethod method = httpRequestMessage.Method;
String MessageSignature = String.Format("{0}\n\n\n{1}\n{5}\n\n\n\n{2}\n\n\n\n{3}{4}",
method.ToString(),
(method == HttpMethod.Get || method == HttpMethod.Head) ? String.Empty
: httpRequestMessage.Content.Headers.ContentLength.ToString(),
ifMatch,
GetCanonicalizedHeaders(httpRequestMessage),
GetCanonicalizedResource(httpRequestMessage.RequestUri, storageAccountName),
md5);
// Now turn it into a byte array.
byte[] SignatureBytes = Encoding.UTF8.GetBytes(MessageSignature);
// Create the HMACSHA256 version of the storage key.
HMACSHA256 SHA256 = new HMACSHA256(Convert.FromBase64String(storageAccountKey));
// Compute the hash of the SignatureBytes and convert it to a base64 string.
string signature = Convert.ToBase64String(SHA256.ComputeHash(SignatureBytes));
// This is the actual header that will be added to the list of request headers.
AuthenticationHeaderValue authHV = new AuthenticationHeaderValue("SharedKey",
storageAccountName + ":" + signature);
return authHV;
}

Azure Text to Speech started returning "400 Bad Request" all the sudden

I was using Azure Text-to-Speech API succesfully for months with this format:
<speak version='1.0' xmlns='w3.org/2001/10/synthesis' xml:lang='en-US'><voice name='Microsoft Server Speech Text to Speech Voice (fi-FI, HeidiRUS)'>My text</voice></speak>
But suddenly this request started returning:
HTTP/1.1 400 Bad request
We were using the same request successfully for months (with different phrase of course) but just some weeks ago the same request started returning this error. I don't get any additional information so I don't know where to look. Azure documentation says:
A required parameter is missing, empty, or null. Or, the value passed
to either a required or optional parameter is invalid. A common issue
is a header that is too long.
I also tried making the request more specific by adding gender and language and replacing single quotes with double quotes, but no use:
<speak version="1.0" xmlns="w3.org/2001/10/synthesis" xml:lang="fi-FI" xml:gender="Female"><voice name="Microsoft Server Speech Text to Speech Voice (fi-FI, HeidiRUS)">Text.</voice></speak>
Did something change in the API? Or what is missing in my request?
I got a 200 OK with the right content when I send the following payload:
<speak version='1.0' xmlns='http://www.w3.org/2001/10/synthesis' xml:lang='en-US'><voice name='Microsoft Server Speech Text to Speech Voice (fi-FI, HeidiRUS)'>This is my test</voice></speak>
Here is my C# code to send this:
// Generate request
string body = $#"<speak version='1.0' xmlns='http://www.w3.org/2001/10/synthesis' xml:lang='{voiceLang}'><voice name='{voiceName}'>{text}</voice></speak>";
using (var client = new HttpClient())
{
using (var request = new HttpRequestMessage())
{
// Set the HTTP method
request.Method = HttpMethod.Post;
// Construct the URI
request.RequestUri = new Uri(ttsHostUri);
// Set the content type header
request.Content = new StringContent(body, Encoding.UTF8, "application/ssml+xml");
// Set additional header, such as Authorization and User-Agent
request.Headers.Add("Authorization", "Bearer " + accessToken);
request.Headers.Add("Connection", "Keep-Alive");
// Update your resource name
request.Headers.Add("User-Agent", "YOUR_RESOURCE_NAME");
request.Headers.Add("X-Microsoft-OutputFormat", "riff-24khz-16bit-mono-pcm");
// Create a request
using (var response = await client.SendAsync(request).ConfigureAwait(false))
{
response.EnsureSuccessStatusCode();
// Asynchronously read the response
using (var dataStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
{
// ... Process your audio here
}
}
}
}
The only difference that I can see on our payloads is the xmlns value where I have a full url (with http://) whereas yours doesn't get it.
The error may be elsewhere: are you sure you are authenticating yourself when querying the endpoint?
We also suddenly got the 400 error and in our case we had missed to encapsulate the text for the XML request with
<![CDATA[ your text here ]]>
after we did that in our code we got no more reported 400 errors by the users.

Cannot create an Integrator Key Docusign

I kept getting the following error when using Docusign python API
The specified Integrator Key was not found or is disabled. An Integrator key was not specified
Exception when calling DocuSign API: (401)
Reason: Unauthorized
HTTP response headers: HTTPHeaderDict({'Cache-Control': 'no-cache', 'Content-Length': '165', 'Content-Type': 'application/json; charset=utf-8', 'X-DocuSign-TraceToken': '2818f346-79f7-4c81-a1e1-b8da0f5556a6', 'Date': 'Thu, 17 Jan 2019 17:52:40 GMT', 'Vary': 'Accept-Encoding', 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains'})
HTTP response body: b'{\r\n "errorCode": "PARTNER_AUTHENTICATION_FAILED",\r\n "message": "The specified Integrator Key was not found or is disabled. An Integrator key was not specified."\r\n}'
So I tried creating new Integrator keys, not really knowing what the callback URI should be or much about what I am doing.
I noticed that everytime I created a key, if I refreshed browser, status would go to 'Error' - anybody know how I can generate an Integrator Key that stays in status 'Demo' and that i can use to make API calls
Here is an example of how I am setting up integrator key:
EDIT
I created a new sandbox of my own, when I create an API key in there it doesn't go to Error, stays in status 'Demo'
API key config looks like
and code to call looks like
integrator_key = MY_KEY_FROM_SCREENSHOT
base_url = "https://demo.docusign.net/restapi"
oauth_base_url = 'account-d.docusign.com'
redirect_uri = 'http://localhost:8000'
user_id = MY_EMAIL
#NOTHING HERE REALLY
private_key_filename = os.path.join(BASE_DIR, "keys/docusign_private_key.txt")
oauth_login_url = api_client.get_jwt_uri(integrator_key, redirect_uri, oauth_base_url)
# configure the ApiClient to asynchronously get an access token and store it
#api_client.configure_jwt_authorization_flow(private_key_filename, oauth_base_url, integrator_key, user_id, 3600)
docusign.configuration.api_client = api_client
auth_api = AuthenticationApi()
try:
login_info = auth_api.login(api_password='true', include_account_id_guid='true')
Hmmm I don't know why the Integration Key's status is changing to "Error."
A couple of ideas:
When adding a Redirect URI, include http:// or https:// at the start of the URI. Eg, enter http://127.0.0.1:8000/tools/ds_api
Don't click the Review Transactions option of the Actions drop down. That should only be done when you are ready for the Go-Live test.

Docusign : One or both of Username and Password are invalid

I was testing Docusign PHP API and trying the following code:
$envelopeId = '3e979aac-1d8d-4ab9-rand-envelopid';
$api = new APIService();
$api->setCredentials('devaccountemail', 'devaccountpassword');
$userName = 'Test Signer';
$userEmail = 'random#randor.com';
$userId = '457';
$RequestRecipientTokenParams = new RequestRecipientToken();
$RequestRecipientTokenParams->EnvelopeID = $envelopeId;
$RequestRecipientTokenParams->Username = $userName;
$RequestRecipientTokenParams->Email = $userEmail;
$RequestRecipientTokenParams->ClientUserID = $userId;
$RequestRecipientTokenParams->AuthenticationAssertion->AssertionID = rand(0, 999);
$RequestRecipientTokenParams->AuthenticationAssertion->AuthenticationInstant = date("Y")."-".date("m")."-".date("d")."T00:00:00.00";
$RequestRecipientTokenParams->AuthenticationAssertion->AuthenticationMethod = RequestRecipientTokenAuthenticationAssertionAuthenticationMethod::Email;
$RequestRecipientTokenParams->AuthenticationAssertion->SecurityDomain = "local IP Address";
$RequestRecipientTokenParams->ClientURLs->OnAccessCodeFailed = "https://YourApp.com/DocuSignCallback.html?envelopeId=YourEnvelopeId&event=OnAccessCodeFailed";
$RequestRecipientTokenParams->ClientURLs->OnCancel = "https://YourApp.com/DocuSignCallback.html?envelopeId=YourEnvelopeId&event=OnCancel";
$RequestRecipientTokenParams->ClientURLs->OnDecline = "https://YourApp.com/DocuSignCallback.html?envelopeId=YourEnvelopeId&event=OnDecline";
$RequestRecipientTokenParams->ClientURLs->OnException = "https://YourApp.com/DocuSignCallback.html?envelopeId=YourEnvelopeId&event=OnException";
$RequestRecipientTokenParams->ClientURLs->OnFaxPending = "https://YourApp.com/DocuSignCallback.html?envelopeId=YourEnvelopeId&event=OnFaxPending";
$RequestRecipientTokenParams->ClientURLs->OnIdCheckFailed = "https://YourApp.com/DocuSignCallback.html?envelopeId=YourEnvelopeId&event=OnIdCheckFailed";
$RequestRecipientTokenParams->ClientURLs->OnSessionTimeout ="https://YourApp.com/DocuSignCallback.html?envelopeId=YourEnvelopeId&event=OnSessionTimeout";
$RequestRecipientTokenParams->ClientURLs->OnSigningComplete = "https://YourApp.com/DocuSignCallback.html?envelopeId=YourEnvelopeId&event=OnSigningComplete";
$RequestRecipientTokenParams->ClientURLs->OnTTLExpired = "https://YourApp.com/DocuSignCallback.html?envelopeId=YourEnvelopeId&event=OnTTLExpired";
$RequestRecipientTokenParams->ClientURLs->OnViewingComplete = "https://YourApp.com/DocuSignCallback.html?envelopeId=YourEnvelopeId&event=OnViewingComplete";
$RequestRecipientTokenResponse = $api->RequestRecipientToken($RequestRecipientTokenParams);
I got the following Error:
SoapFault : One or both of Username and Password are invalid.
The credentials provided by me are valid and I can login to demo.docusign.net account with these credentials. I'm not sure where I'm doing it wrong.
Here is the SOAP request that is being generated:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-
ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.docusign.net/API/3.0"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing">
<SOAP-ENV:Header>
<wsa:Action>http://www.docusign.net/API/3.0/RequestRecipientToken</wsa:Action>
<wsa:To>https://www.docusign.net/API/3.0/api.asmx</wsa:To>
<wsa:MessageID>uudi:638fd49c-2516-12a9-8159-17a9c602975e</wsa:MessageID>
<wsa:ReplyTo>
<wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address>
</wsa:ReplyTo>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" SOAP-ENV:mustUnderstand="1">
<wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsu:Created>2013-09-18T12:30:20Z</wsu:Created>
<wsu:Expires>2013-09-18T12:35:20Z</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken>
<wsse:Username>bhargav.bonu#somedomain.com</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-
token-profile-1.0#PasswordText">mypassword</wsse:Password>
<wsse:Nonce>0PZkAUVbHHiyjV8KZrN6x2x0S6cQ5WbAjTH4yn8dnc4=</wsse:Nonce>
<wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-
utility-1.0.xsd">2013-09-18T12:29:18Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns1:RequestRecipientToken>
<ns1:EnvelopeID>3e979aac-1d8d-4ab9-a45c-randElem</ns1:EnvelopeID>
<ns1:Username>Test Signer</ns1:Username>
<ns1:Email>Guest</ns1:Email>
<ns1:AuthenticationAssertion>
<ns1:AssertionID>175</ns1:AssertionID>
<ns1:AuthenticationInstant>2013-09-18T00:00:00.00</ns1:AuthenticationInstant>
<ns1:AuthenticationMethod>Email</ns1:AuthenticationMethod>
<ns1:SecurityDomain>192.168.0.43</ns1:SecurityDomain></ns1:AuthenticationAssertion>
<ns1:ClientURLs>
<ns1:OnSigningComplete>https://YourApp.com/DocuSignCallback.html?envelopeId=YourEnvelopeId&event=OnSigningComplete</ns1:OnSigningComplete>
<ns1:OnViewingComplete>https://YourApp.com/DocuSignCallback.html?
envelopeId=YourEnvelopeId&event=OnViewingComplete</ns1:OnViewingComplete>
<ns1:OnCancel>https://YourApp.com/DocuSignCallback.html?envelopeId=YourEnvelopeId&event=OnCancel</ns1:OnCancel>
<ns1:OnDecline>https://YourApp.com/DocuSignCallback.html?envelopeId=YourEnvelopeId&event=OnDecline</ns1:OnDecline>
<ns1:OnSessionTimeout>https://YourApp.com/DocuSignCallback.html?envelopeId=YourEnvelopeId&event=OnSessionTimeout</ns1:OnSessionTimeout>
<ns1:OnTTLExpired>https://YourApp.com/DocuSignCallback.html?envelopeId=YourEnvelopeId&event=OnTTLExpired</ns1:OnTTLExpired>
<ns1:OnException>https://YourApp.com/DocuSignCallback.html?envelopeId=YourEnvelopeId&event=OnException</ns1:OnException>
<ns1:OnAccessCodeFailed>https://YourApp.com/DocuSignCallback.html?envelopeId=YourEnvelopeId&event=OnAccessCodeFailed</ns1:OnAccessCodeFailed>
<ns1:OnIdCheckFailed>https://YourApp.com/DocuSignCallback.html?envelopeId=YourEnvelopeId&event=OnIdCheckFailed</ns1:OnIdCheckFailed>
<ns1:OnFaxPending>https://YourApp.com/DocuSignCallback.html?envelopeId=YourEnvelopeId&event=OnFaxPending</ns1:OnFaxPending>
</ns1:ClientURLs>
</ns1:RequestRecipientToken>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
That error indicates that the DocuSign user credentials you're providing in the request to authenticate the API call are not valid. The code you included in this post is irrelevant, really, as any API call would result in this error if either the username or password you're providing to authenticate the request is invalid.
If you haven't already done so, I'd suggest that you produce a trace of the full XML Request (i.e., including headers) to closely examine the authentication credentials that you're providing in the request. The best way to troubleshoot issues like this is to examine what's going over the wire (rather than trying to troubleshoot code that's producing what's going over the wire) -- once the issue in the XML is identified, it should be easy to fix in the code.
Regarding the "username or password invalid" error -- it might be caused by the fact that your not including your Integrator Key within Username. From page 18 of the DocuSign SOAP API Guide (http://www.docusign.com/sites/default/files/DocuSignAPI_Guide.pdf):
The integrator key must be placed in front of the user ID that is in the Username node of the UsernameToken. The integrator key must be wrapped with brackets, “[ and ]”. Example format:
<wsse:Username>[Integrator Key]2988541c-4ec7-4245-b520-f2d324062ca3</wsse:Username>
The Integrator Key must be included in all API requests, as DocuSign requires it in order to identify the integrating application.

Resources