I'm trying to create a python script which installs a default signature for a Mac Mail account. So far, my script successfully installs the signature by manipulating ubiquitous_AllSignatures.plist and creating a corresponding ubiquitous_<SignatureId>.mailsignature. Both of these files are at ~/Library/Mobile Documents/com~apple~mail/Data/V3/MailData/Signatures/. The problem is the installed signature is not recognized by Mail as the default signature, and in order to use the signature you have to manually select it in the signature dropdown while composing an email.
I've searched the file system long and hard to find a relevant plist which dictates the 'default' signature behavior for a given account. I have grep'd for the Signature ID and the only place I can see it other than the places mentioned above is in the sqlite files in ~/Library/Application Support/CloudDocs/session/db/. I don't think this is a good sign for the feasibility of my default signature install.
I understand this is a very specialized/weird/hacky problem, but I'm looking for some insight into the underlying mechanism controlling the default signature for an account in Mac Mail, or at least confirmation of my suspicions that it's impossible to do this without the consent of Mail. Any feedback is much appreciated.
Ok I realize this is incredibly obscure, but because I have been helped greatly by self-answers to obscure questions I'm gonna try to help anyone who may face this problem in the future.
The 'default' signature is indeed set in a plist. This plist is ~/Library/Containers/com.apple.mail/Data/Library/Preferences/com.apple.mail.plist. Be weary, this is a binary plist, which is different and much less readable than an xml plist. But fear not, you can transform back and forth b/w binary and xml with the plutil utility. You can access this utility in python with biplist, hooray! Now it's just a matter of manipulating the SignaturesSelected dictionary within the plist by adding the signature id (string) for the account id (key). And you will have set your default signature!
Related
I have a Node project that's bundled and added to Github as releases. At the moment, it checks my Github for a new release via the API and lets the user download it. The user must then stop the Node server, unzip the release.zip to the folder and overwrite everything to update the project.
What I'm trying to do is write a Python script that I can execute in Node by spawning a new process. This will then kill the Node server using PM2, and then Python script will then check the Github API, grab the download url, downloads it, unzips the contents to the current folder, deletes the zip and then starts up the Node server again.
What I'm struggling with though is checking the Github API and downloading the latest release file. Can anyone point me in the right direction? I've read that wget shouldn't be used in Python, and instead use urlopen
If you are asking for ways to get data from a web server, the two main libraries are:
Requests
Urllib
Personally, I prefer requests. They both have good documentation.
With requests, getting JSON data is as simple as:
r = requests.get("example.com")
r = r.json()
You can add headers and other information easily, though keep in mind that while it supports HTTP, it doesn't support HTTPS.
You need to map out your workflow and dataflow better. You can do it in words or pictures. If you can express your problem clearly and completely in words step by step in list format in words, then translate it to pseudocode. Python is great because you can go almost immediately from a good written description, to pseudocode, to a working implementation. Then at least you have something that works, and you can optimize performance, simplify functionality or usability from there. This is the process of translating a problem into a solution.
When asking questions on SO, you need to show your current thinking, what you've already tried, preferably with your code that doesn't yet work, or work the way you need it to work. People can vote you down and give you negative reputation points if you ask a question with just a vague description, a question that is an obvious cry for help with homework (yours is not that), or a muse or a vague question with not even an attempt at a solution, because it does not contribute back to the community in any way.
Do you have any code or detailed pseudocode steps for checking the GitHub API and checking for the "latest release" of file(s) you are trying to update?
I have a project to send, where basically I have to send an email using python.
My code is complete so I was about to send it.
Because of the fact the module smtplib needs my email log in, I compiled my code so people could no see my email and password, however, even compiled, when we look at the hex code, we can still see my email and password (and some print)
Is there a way to compile so we have no information left after?
Thank you very much for your help and time !
Generally it is a bad idea to hold sensitive information in the code. There is no uniformly the best way to do it, but common practices to store credentials include:
in a separate code file not in your code base (local_settings.py, added to .gitignore)
in a separate config file outside of the project (e.g. json or yml)
environment variables (read using os.environ)
command line parameters
request as user input
a combination of all above
I am trying to generate the same signature from http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html using python,
DateKey = hmac.new(b'AWS4wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY', b'20151229', hashlib.sha256).digest()
DateRegionKey = hmac.new(DateKey, b'us-east-1', hashlib.sha256).digest()
DateRegionServiceKey = hmac.new(DateRegionKey, b's3', hashlib.sha256).digest()
SigningKey = hmac.new(DateRegionServiceKey, b'aws4_request', hashlib.sha256).digest()
signature = hmac.new(other_policy, SigningKey, hashlib.sha256).hexdigest()
But my signature is cb0b0ec487fd5e01382c9c3b6b6a6dfa170da312ddab58a4b18869e7413951be and expected signature is 46503978d3596de22955b4b18d6dfb1d54e8c5958727d5bdcd02cc1119c60fc9
Where am I doing wrong ?
Note
other_policy = b'''eyAiZXhwaXJhdGlvbiI6ICIyMDE1LTEyLTMwVDEyOjAwOjAwLjAwMFoiLA0KICAiY29uZGl0aW9ucyI6IFsNCiAgICB7ImJ1Y2tldCI6ICJzaWd2NGV4YW1wbGVidWNrZXQifSwNCiAgICBbInN0YXJ0cy13aXRoIiwgIiRrZXkiLCAidXNlci91c2VyMS8iXSwNCiAgICB7ImFjbCI6ICJwdWJsaWMtcmVhZCJ9LA0KICAgIHsic3VjY2Vzc19hY3Rpb25fcmVkaXJlY3QiOiAiaHR0cDovL3NpZ3Y0ZXhhbXBsZWJ1Y2tldC5zMy5hbWF6b25hd3MuY29tL3N1Y2Nlc3NmdWxfdXBsb2FkLmh0bWwifSwNCiAgICBbInN0YXJ0cy13aXRoIiwgIiRDb250ZW50LVR5cGUiLCAiaW1hZ2UvIl0sDQogICAgeyJ4LWFtei1tZXRhLXV1aWQiOiAiMTQzNjUxMjM2NTEyNzQifSwNCiAgICB7IngtYW16LXNlcnZlci1zaWRlLWVuY3J5cHRpb24iOiAiQUVTMjU2In0sDQogICAgWyJzdGFydHMtd2l0aCIsICIkeC1hbXotbWV0YS10YWciLCAiIl0sDQoNCiAgICB7IngtYW16LWNyZWRlbnRpYWwiOiAiQUtJQUlPU0ZPRE5ON0VYQU1QTEUvMjAxNTEyMjkvdXMtZWFzdC0xL3MzL2F3czRfcmVxdWVzdCJ9LA0KICAgIHsieC1hbXotYWxnb3JpdGhtIjogIkFXUzQtSE1BQy1TSEEyNTYifSwNCiAgICB7IngtYW16LWRhdGUiOiAiMjAxNTEyMjlUMDAwMDAwWiIgfQ0KICBdDQp9'''
from the http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html
Bug in the code
Your code to generate the signing key looks fine. However, when you generate the signature, the parameters are switched around. The pseudocode is:
Hex(HMAC-SHA256(SigningKey, StringToSign))
So instead of
signature = hmac.new(other_policy, SigningKey, hashlib.sha256).hexdigest()
you should have
signature = hmac.new(SigningKey, other_policy, hashlib.sha256).hexdigest()
Still wrong?
This produces the following signature, which despite the Amazon documentation, I believe is correct for the provided base64 string to sign:
8afdbf4008c03f22c2cd3cdb72e4afbb1f6a588f3255ac628749a66d7f09699e
So why does Amazon say the signature should be 465039...c60fc9???
I'm sorry to say I have no idea. I suspect the documentation may actually be inaccurate, either with respect to the signature value or with respect to the input parameter values used to generate it (secret key, date, region, service, string to sign).
I do feel like I'm going out on a limb a bit suggesting such a thing, but at the same time, I know from experience that not every piece of technical documentation online is 100% accurate (even when produced by a reputable source).
I couldn't reproduce this signature no matter what I tried. I'd love to see an answer that successfully produces this hash.
Evidence
There are really only two things going on here:
Calculate a signing key.
Pass it along with the "string to sign" to a hashing function, to generate the signature.
Your code produces the expected signing key using the parameters in the example under "Deriving the Signing Key with Other Languages" here. This suggests you're calculating the signing key correctly. Python code here.
Your code also produces the expected signature when using the parameters from this example. This suggests you're both calculating the correct signing key and the correct signature. Python code here.
Running the parameters from your question through some existing Python code that I know to work with several services (based on this) also produces the same 8afdb...9699e signature.
I also threw the java signing code into an existing spring boot application, and it also produces the same 8afdb...9699e signature for your input parameters.
What to try?
I suggest you assume your signing code is good, and the AWS documentation on this particular page is mistaken. After all, your code works fine with at least two other AWS examples.
Sign a real request, using your credentials, your bucket policy, your region, the current date, etc.
Then post the sample form and see if it works. If it doesn't work, you could update the question with the error you get from the form POST.
Update (7/15/2018)
AWS has updated their documentation, and this page now contains the correct signature. The incorrect version can be viewed here, for historical purposes.
Interestingly, the wayback machine suggests that the page was correct until at least June 23, 2017. By July 14 it had changed to the wrong signature, and it stayed incorrect at least until December 19, 2017 (over 5 months!).
I have never been able to get Rest APIs to completely work with AWS. The error messages I have seen have been about the time not being correct or the command not being recognized (e.g., list-users). I have verified the "version" was appropriate for the command with AWS's website documentation.
I am trying to use curl with Linux to list the users or instances in my AWS account. I have a problem when I run it. My current error, that I would like to focus on, is "request signatures calculated does not match the signature provided." I went through the process of creating a signature carefully. It wasn't that surprising that it did not work given the hours of trouble and the seemingly many potential pitfalls in the tedious task of creating a signature.
I used this link to generate the hexadecimal string for the signature:
http://docs.aws.amazon.com/general/latest/gr/signature-v4-examples.html#signature-v4-examples-python
I analyzed the output of the signatureKey using a modification of the Python code in the above link. The result is not hexadecimal nor alphanumeric. The result is a combination of special non-alphabet, non-numeric symbols and alphabet letters. I tried to work around this problem by using import binascii and binascii.hexlify. I was able to get a hexadecimal string from otherwise strictly adhering to the sample of Python code from the above link. I tend to think my signatureKey is not right because of this binascii work that I had to do. But what did I do wrong? How is that Python code supposed to calculate a signature?
Alternatively, are there thorough directions not written by Amazon to create a signature key? The process is not simple and seemingly error prone. I could start over with creating a signature if someone cannot clearly tell me how to create a signature. Amazon's forums have few postings related to this topic. I'd prefer to create the signature with Python. If someone recommends Ruby (an accessible language for me), I could try something like that.
I'm exploring many technologies, but I would like your input on which web framework would make this the easiest/ most possible. I'm currently looking to JSP/JSF/Primefaces, but I'm not sure if that is capable of this app.
Here's a basic description of the app:
Users log in with their username and password (maybe I can somehow incorporate OPENID)?
With a really nice UI, they will be presented a large list of questions specific to a certain category, for example, "Cooking". (I will manually compile this list and make it available.)
When they click on any of these questions, a little input box opens up below it to allow the user to put in a link/URL.
If the link they enter has the same question on that webpage the URL points to, they will be awarded one point. This question then disappears and gets added to a different page that has a list of all correctly linked questions.
On the right side of the screen, there will be a leaderboard with the usernames of the people with the top ten points.
The idea is relatively simple - to be able to compile links to external websites for specific questions by allowing many people to contribute.
I know I can build the UI easily with Primefaces. [B]What I'm not sure is if JSP/JSF gives the ability to parse HTML at a certain URL to see if it contains words.[/B] I can do this with python easily by using urllib, but I can't use python for web GUI building (it is very difficult). What is the best approach?
Any help would be appreciated!!! Thanks!
The best approach is whatever is best for you. If Python isn't your strength but Java is, then use Java. If you're a Python expert and know little Java, use Python.
There are so many resources on the Internet supporting so many platforms that the decision really comes down to what works best for you.
For starters, forget about JSP/JSF. This is an old combination that had many problems. Please consider Facelets/JSF. Facelets is the default templating language in the current version of JSF, while JSP is there only for backwards compatibility.
What I'm not sure is if JSP/JSF gives the ability to parse HTML at a certain URL to see if it contains words.
Yes it does, although the actual fetching of data and parsing of its content will be done by plain Java code. This itself has nothing to do with the JSF APIs.
With JSF you create a Facelet containing your UI (input fields, buttons, etc). Then still using JSF you bind this to a so-called backing bean, which is primarily a normal Java class with only one or two JSF specific annotations applied to it (e.g. #ManagedBean).
When the user enters the URL and presses some button, JSF takes care of calling some action method in your Java class (backing bean). In this action method you now have access to the URL the user entered, and from here on plain Java coding starts and JSF specifics end. You can put the code that fetches the URL and does the parsing you require in a separate helper class (separation of concerns), or at your discretion directly in the backing bean. The choice is yours.
Incidentally we had a very junior programmer at our office use JSF for something not unlike what you are requesting here and he succeeded in doing it in a short time. It thus really isn't that hard ;)
No web technology does what you want. Parsing documents found at certain urls is out of the scope of building web interfaces.
However, each of Java's web technologies will give you, without limits, access to a rich and varied (if not too rich and much too varied) set of libraries and frameworks running on JVM. You could safely say that if there is a library for doing something, there will be a Java version available. Downloading and parsing a document will not require more than what is available in the standard library (unless you insist on injecting your dependencies or crosscutting your concerns), so no problems with doing your project with JSP, or JSF/Primefaces, or whatever.
Since you claim to already know Python, and since you will have to add some HTML/CSS anyway, I suggest you try Django. It's dead simple, has a set of OpenID plugins to choose from, will give you admin interface for free (so you can prime the pump with the first set of links).