Password Handling in Editorial Scripts

August 31, 2013 by Gabe | [mmd] |

The ability to share elaborate and fully customized workflows in Editorial is great. Embedding Python code is awesome. Accidentally sharing your user credentials that are hard coded in an Editorial workflow is neither great or awesome.

Editorial and Pythonista provide its own version of a keychain.1 If you are making workflows that require login credentials, I highly suggest using the Keychain module. Here's how.

Here's an example taken from my updated Markdown to Evernote HTML workflow. This is a good example of the Keychain and Pickle modules working together.

#coding: utf-8
import workflow
import webbrowser
import console
import keychain
import pickle
import evernote.edam.userstore.constants as UserStoreConstants
import evernote.edam.type.ttypes as Types
from evernote.api.client import EvernoteClient
import markdown2
import cgi
import editor

#keychain.delete_password('evernote', 'editorial')
login = keychain.get_password('evernote', 'editorial')
if login is not None:
    auth_token = pickle.loads(login)
else:
    token_choice = console.alert('Token Needed', 'A Developer Token is needed. Go get one?', 'Yes', 'I have One', 'Cancel')
    if token_choice == 1:
        webbrowser.open('safari-https://www.evernote.com/Login.action?targetUrl=%2Fapi%2FDeveloperToken.action')
        raise KeyboardInterrupt
    elif token_choice == 2:
        auth_token = console.password_alert('Evernote Developer Token', 'Paste Your Evernote Developer Token')
        pickle_token = pickle.dumps(auth_token)
        keychain.set_password('evernote', 'editorial', pickle_token)
    else:
        raise KeyboardInterrupt

The first thing the script does is to check to see if there is a keychain entry for an editorial account inside the evernote service. In this way, we can have a single service with multiple account logins.

The use of Pickle allows us to store structured data inside the keychain. In this case we're just storing the Evernote authorization token. It's not necessary to use Pickle when storing a simple user name and password combination or something like a single token. However, it does make some things easier when there's more structured or varied login information. I use it out of habit and easy of copy and paste.

Don't be too discouraged but the complexity of this script. Most of this code is to handle the conditions of missing login credentials. If you've already recorded an Evernote login in the Keychain, then the script simply loads the credentials with login = keychain.get_password('evernote', 'editorial')

We "un-pickle" the token with auth_token = pickle.loads(login).

Later in the script, we'll use the token to login to Evernote with a line like this:

client = EvernoteClient(token=auth_token, sandbox=False)

There. All this login stuff is handled by the script without us ever hardcoding it in.

To cut to the chase, if you ever share Editorial or Pythonista workflows, use the Keychain module. It's darn easy to use and will save you many panicked minutes trying to change passwords you accidentally shared from Editorial.2


  1. There's no syncing built-in to the Keychain module. You could create your own, but that's up to you. 

  2. Or so I hear. Yeah. I'd never do that kind of dumb thing.