Alex Clark

President of ACLARKNET. President & Executive Director of DC Python.


Creator of Python Pillow.

>>> from PIL import Image
>>> Image.__version__

Musician at Headstraight.


SAML: 1, Alex Clark: 0

Published on 2017-06-26 00:00:00

Courtesy of quickmeme

Via quickmeme


I don’t like to give up on a technical challenge, particularly when the progress is slow-but-consistent. It’s only when I know I can’t make any discernible progress easily or at all that I can force myself to give up.

I’m not talking about giving up for the day and getting back to it. I’m talking about declaring failure and getting back to it way later, if at all. Well, this post is about how SAML got the better of me about one month ago. I really wanted this particular task to be successful, but I eventually had to give up and declare the task “too hard for me given the context, and possibly not even a good idea in the first place”.

Because I don’t explicitly mention this anywhere else in the article, I’ll mention it now:

Cue debate on the merits of this approach vs. other approaches e.g. OAuth2.

The task at hand

The task was to make Django act as a SAML Identity Provider (IdP), enough to convince a commercial service, acting as a SAML Service Provider (SP), to use it as one. While I didn’t achieve the desired end result, a learned a ton of information about SAML that I never really wanted to know, but feel better and good about now that I know it.

IdP vs SP

I’m not going to go into too much detail here but for the unfamiliar, the SAML protocol defines both Identity Providers (IdP) and Service Providers (SP). SAML Identity Providers answer requests from SAML Service Providers and make the decision about whether the principal (e.g. user) is allowed to access the Service Provider.

After discovering this fact, confusion about this aspect of the SAML protocol lingered and continues to linger. Does that mean the IdP is or contains the user database? As of right now, I don’t think so. But that wasn’t clear initially (and still isn’t, but perhaps is now “less unclear”).

No, the IdP is not the user database. Rather, the IdP is “the thing that answers SAML requests in accordance with the protocol’s definition of how to do so.” But it can’t hurt if the IdP needs to go no further than Django’s user database to validate an SP’s SAML assertion, right? I certainly thought so initially, and spent a whole lot of time trying to make it so.


Turns out implementing SAML presents many challenges, one of which is one must “deal with” XML. I don’t have any specific gripes about XML, but parsing XML does add a layer of complexity I could have done without.


You know what’s worse than parsing XML? Signing your XML. And you know what’s worse than that? Signing only a portion of it. (Lingering bitter sentiments from the me-of-one-month-ago.)


First, I spent some time researching the existing available options. I took it as a “red flag” not a lot of folks seemed to be using Django as an IdP, but I thought worst case, I’d be creating an insecure-but-viable-proof-of-concept. And I got close, but lost patience when I couldn’t get the commercial Service Provider to validate my SAML assertions (oh, and let’s not forget my confusion about SP-initiated vs IdP-initiated logins; I eventually decided that the “flow” of IdP-initiated was simpler and focused mostly on that; SP -> IdP -> SP, vs IdP -> SP.)

Eventually I created five, count them five, separate test repositories while tackling SAML. Part of that proliferation-of-repositories is possibly due to some anti-branching sentiment on my part (I’m not really anti-branching, but sometimes I prefer to “start clean” instead of branching):


I found a bunch of cool Python tooling for dealing with all-things-SAML that I will make a note of here:

TLDR: Consider a commercial IdP like OneLogin or Auth0.

Project Makefile Open for Business

Published on 2016-11-23 00:00:00

Makefile for Python Web Development & Related Projects

A while back I was asked to present to the Configuration Management Working Group of DC.


From that moment it was on: an excuse to finish and talk about the Makefile I’d been dragging around formerly since January and informerly for much longer.

Finishing the Makefile

I started writing slides on the impressive then I realized I had to finished the Makefile to finish the slides. This mostly involved deciding on target names and testing target execution.

Finishing the Slides

As I mentioned above, is very nice. I had hoped to be able to build the slides myself with reveal.js, but in lieu of JavaScript skills I settled on using the editor. Later I exported and converted them to PDF with pandoc, which was not as nice (through no fault of pandoc, I’m sure; I just wish I could get a better PDF copy from the HTML export.)

Closed for Business

For month after month as I continued to tweak, the project-makefile repository README contained the following:


At some point I started using a ``Makefile`` in my development
projects. This repository contains that ``Makefile``.


Open for Business

Now it looks like this:


I invite everyone to use and contribute.

Cioppino Sprint Report

Published on 2011-02-16 00:00:00

The Cioppino Sprint was held in Bodega Bay, CA in 2011.

It was a beautiful location for a gathering of awesome Plone folks; and much was accomplished.

Bodega Bay

Sprint report

It’s a bit overwhelming to try and capture everything that happened (and I was only there for two days!); hopefully this report will be useful. The focus of this sprint was evaluator approachability (i.e. making Plone look good to prospective new users).

Day 1 and Day 2

Steve McMahon (SteveM) was our host. Alex Limi (limi) provided general direction regarding strategies to improve, documentation, and end user support. But most importantly, he pointed out that the first stop for any prospective new user is the website, so it’s important that it look good.

David Glick (davisagli) and Elizabeth Leddy (eleddy) wasted no time in diving in to the 150 or so open tickets in the (now defunct) issue tracker.

I (aclark) quickly fell into the role of the “deployment witch” (a role I enjoy), and suggested people simply push the ACLARK button (née Staples Easy Button) whenever they needed their code deployed to

We closed a good number of tickets this way.


  • Ross Patterson (zenwryly) grabbed a hold of the PloneOrg add-on (the add-on that powers and added tests (among other things).

  • Tyler Randles (hennaheto) and Trish Ang (feeeeesh) fixed a number of CSS annoyances, which were committed by SteveM (while Tyler & Trish pondered core commit access). My favorite of which is the now-blissfully-aligned username and password fields of the login_form:

  • zenwryly fixed the team section of

  • davisagli completed the last remaining task to fix PloneSoftwareCenter permissions on (the sharing tab finally works now!)

  • limi fixed a CSS sprite issue on (involving https, I think).

  • SteveM tackled SSL certificate issues on

  • aclark took a stab at by converting the old style add-on Product that powers it to a new style Egg package. zenwryly then took that ball and ran with it, added tests and otherwise prepared for the future (i.e. Plone 4 compat).

  • Jon Stahl (remotely) added a “follow” section to

  • hennaheto and feeeeesh produced this amazing (but possibly non-compliant) sprint logo

Day 3, Day 4 and Day 5

Unfortunately, I had to leave on Friday morning but these are some of the things that happened after I left. Most importantly, Tom Kapanka (spanktar) arrived Thursday night and Bill Deegan arrived on Friday. And then:

  • zenwryly updated PloneServicesCenter to Plone 4.

  • limi and zenwryly replaced images of “showcased sites” in PloneServicesCenter with a web screenshot service to eliminate the need for storing images. (This move is still in progress, and various folks are working on issues with the web screenshot service. Please be patient!)

  • zenwryly and limi moved content from to

  • aclark (remotely) pulled the DNS trigger on (re-configured A records for, to resolve to the same IP as

  • eleddy and spanktar created and released cioppino.twothumbs to facilitate “thumb style” (up/down) ratings in PloneSoftwareCenter.

  • davisagli made it so Plone can start without PIL (via fixes to PlonePAS and And these fixes even made it in to Plone 4.1a3! To be clear, Plone still requires PIL to render images but it will start if it’s missing.

  • davisagli and eleddy refactored the PloneOrg buildout

  • Bill and limi moved the remaining old Plone installers from Sourceforge to

Post-sprint sprinting

One of the great things about a sprint is that it really focuses attendees on accomplishing their tasks, long after they have left the event. To that end:

  • aclark triaged the remaining tickets in the tracker, and did a final tally of closed ticket rankings: davisagli (55), aclark (32), eleddy (28), limi (7). davisagli wins!

  • aclark got inspired to begin uploading the half dozen or so missing videos from various Plone Conference 2008 talks (which were finally sent to him by the video company circa last year). Look for these to land on soon.

  • eleddy continued to develop the “two thumbs” feature.

  • eleddy and aclark deployed the “two thumbs” feature to (This feature may not work as expected yet, eleddy is resolving issues.) Check it out:

  • limi continued to improve the documentation/ and support/ sections of

That’s it! Just so you don’t worry the sprinters worked too hard, you can rest assured everyone was in good hands with zenwryly and his travelling-bar.

First Post

Published on 2007-03-16 00:00:00

I have decided to start a blog


Why? To show Plone can be used for blogging, but also:

  • I have been reading a lot of Plone blogs lately and they have inspired me to write my own.

  • I want to interact with other Plone users.

  • I want to use new technology.

To that end, this post is about my build tools. But first I’ll note the current, likely better, alternatives:

I used Buildout for the first time at the Baarn UI Sprint 2007 and I’ve also used Chris McDonough’s Buildit. There are even more to choose from, but for now I enjoy typing:

newzope test-site ProductA ProductB ProductC

and having a working instance a few seconds later with Product{A,B,C} installed.