Archive | December, 2009

Good marketing or .org abuse?

28 Dec

Good marketing or .org abuse?

Google’s (un)intelligent AdSense engine decided to show me an ad the other day. It encour­aged me to “exer­cise my right to eat freely,” and dis­played www.EatFreely.org as the URL. “That’s odd,” I thought, re-reading the ad. “There are the words ‘Hot Pock­ets®’ right there; how can this be an ad for a .org domain?” Take a look at the ad:

The first thing that comes to mind when I hear “Hot Pock­ets” is, of course, Jim Gaffigan’s hilar­i­ous stand-up bit from Beyond the Pale. Com­edy aside, I was intrigued by the use of a .org domain for some­thing asso­ci­ated with Hot Pock­ets. So I clicked and found myself look­ing at a very busy, ani­mated mar­ket­ing site for a fic­tional move­ment to “eat freely,” by which they mean the abil­ity to eat nasty meat stuffed inside a Pop Tart with­out hav­ing to be both­ered by incon­ve­niences like chairs and cutlery.

This was sur­pris­ing. I was under the appar­ently mis­taken notion that .org domains were the exclu­sive domain (ha, sorry for the pun) of non-profit and char­i­ta­ble organiza­tions. Hot Pock­ets’ schlocky mar­ket­ing site mas­querad­ing as such an orga­ni­za­tion imme­di­ately rubbed me the wrong way, much the same way actu­ally eat­ing a Hot Pocket rubs my tongue, esoph­a­gus, stom­ach, and intestines the wrong way. This trav­esty was sul­ly­ing the very name of rep­utable .org sites like Peo­ple for the Eth­i­cal Treat­ment of Ani­mals, the Amer­i­can Lung Asso­ci­a­tionBoys & Girls Clubs of Amer­ica, and even SOTA : The Soci­ety of Typo­graphic Afi­ciona­dos.

As I researched the issue in prepa­ra­tion for my protest to ICANN, I dis­cov­ered this sad fact: Hot Pock­ets are not wrong. At least, not in the sense that their “eat freely” cam­paign site is hosted as a .org; they are wrong in every other sense of the word. The fol­low­ing text is stated on the Pub­lic Inter­est Reg­istry website

When you buy a .ORG, … You’re link­ing your orga­ni­za­tion — your cause — to a world­wide com­mu­nity of mission-driven orga­ni­za­tions that are try­ing to make the world a bet­ter place.

Through the reg­istry for .ORG, your orga­ni­za­tion is linked to a well-established brand of trust and integrity. One of the orig­i­nal top-level domains (TLDs), .ORG became the domain of choice for orga­ni­za­tions ded­i­cated to serv­ing the pub­lic inter­est, and today .ORG is con­sid­ered one of the most trusted domains on the internet.

Non­prof­its, foun­da­tions, phil­an­thropic and cul­tural insti­tu­tions, reli­gious, civic, arts, social and fra­ter­nal orga­ni­za­tions, health and legal ser­vices, clubs and com­mu­nity vol­un­teer groups… if yours is a non­com­mer­cial entity, peo­ple expect to find you in the .ORG community.

Appar­ently the Pub­lic Inter­est Reg­istry has no prob­lem with a brand­ing site for hand-held processed food prod­ucts also obtain­ing a .org domain.

I turned to the font of all true knowl­edge (Wikipedia) for the truth and was sad to read this:

Although .org was rec­om­mended for non-commercial enti­ties, there are no restric­tions to reg­is­tra­tion. There are many instances of .org being used by com­mer­cial sites. .org was also com­monly rec­om­mended for use by indi­vid­u­als, although .name and .info are now alternatives.

(Empha­sis mine.)

So there you have it: any­one can reg­is­ter a .org. That means a lit­tle extra vig­i­lance is required on our part when research­ing things online. Maybe ViagraRules.org or HappyNapsWithAmbien.org aren’t dis­pens­ing unbi­ased infor­ma­tion after all? Caveat brow­sor, I suppose.

In all seri­ous­ness, though, online cam­paigns such as “eat freely” are only going to become more preva­lent. Is the way in which these cam­paigns are branded some­thing we, as con­sumers, should care about? Every ad agency out there is hop­ing to pitch the next Will it Blend phe­nom­e­non (note they appro­pri­ately used a .com domain), and it’s likely that we’ll see more of them wrapped up in .org domains. Sure, it’s unlikely any­one would mis­take EatFreely.org as any­thing but adver­tis­ing. But as I attempted to show with my humor­ous exam­ples above, not all .org domains may be as inno­cent. Drug– or agri­cul­tural prod­ucts com­pa­nies may reg­is­ter a .org domain and put up a site that has all the somber “author­ity” of a gov­ern­ment or true organization’s site, but present only pos­i­tive infor­ma­tion about their prod­ucts while obscur­ing their dangers.

With other top-level domains (TLDs) like .net and recent addi­tions like .name, .info, .biz, etc. there seems lit­tle jus­ti­fi­ca­tion in using .org domains to pro­mote or sell prod­ucts. Reg­is­ter­ing a .org domain should require proof of non-profit 503© or char­i­ta­ble sta­tus (or their equiv­a­lents out­side the U.S.) to com­bat this trend.

But in a sense, I sup­pose Hot Pock­ets have made “the world a bet­ter place” for some. Just ask Jim Gaffi­gan.

A karate Christmas tale

24 Dec

A karate Christmas tale

As a hol­i­day depar­ture from my usual posts, I offer this fic­tional nar­ra­tive. Well, partly fic­tional; the karate stuff is true.

My Sat­ur­day karate class was dif­fi­cult. I just couldn’t seem to get my body to do what my mind was telling it. It was a rough one, too; the only Christ­mas color miss­ing was green: I had red­dish bruises on my white fore­arms and knuck­les. So that after­noon I decided to head south of down­town Seat­tle to visit the Inter­na­tional Dis­trict, the “ID.”

It had been a while since I’d been to the ID. It was a cold, clear Decem­ber after­noon and I kept my thick jacket zip­pered up as I wan­dered about. Grabbed a red bean paste bun and a cold Mr. Boss cof­fee from Uwa­ji­maya, gazed at dis­plays of col­or­ful char­ac­ters grac­ing animé shop win­dows, and lis­tened to the min­gled con­ver­sa­tions of passers-by in Japan­ese, Chi­nese, Viet­namese, and Eng­lish. It was a pleas­ant way to while away an after­noon, but my thoughts kept return­ing to mar­tial arts. Why was it easy to grasp a con­cept men­tally, yet incred­i­bly hard to exe­cute that con­cept phys­i­cally, or at least to do so well or con­sis­tently? Tech­niques like con­nect­ing the upper– and lower body, keep­ing proper pos­ture, sub­tly trans­fer­ring body weight, keep­ing elbows in when per­form­ing uchi ukes (an inside-to-outside chest block) and down when punch­ing. It’s even hard for me to keep my eye­brows from pop­ping up before I strike.

These thoughts occu­pied my mind as I aim­lessly wan­dered about the shops, parks, and alleys of the ID. I’m not sure how much time had passed but my snack was long gone and it was my hunger—weighing a hot bowl of ph? against a deli­cious plate of sushi—that pulled me back to real­ity. Then it struck me: I was lost. This was a part of the ID I did not rec­og­nize. Sur­rounded by unfa­mil­iar store­fronts, I searched for street signs in order to find my way back. It was then that a nearby park caught my atten­tion, for it was bet­ter lit and numer­ous peo­ple, most with chil­dren, milled about. I headed that way.

What greeted me was a sur­prise: a hand­ful of kids, the younger of them hold­ing their par­ents’ hands, lined up wait­ing to see… Santa? He was perched upon a golden bam­boo chair set upon a raised plat­form. Though his garb was the tra­di­tional white-trimmed red suit and a pair of wire-rimmed spec­ta­cles sat atop his nose, the sim­i­lar­i­ties ended there. Santa’s beard lacked the typ­i­cal bushy curls that left only the lips exposed. Instead, ten­drils of dark hair snaked down from the cen­ter of his chin and each cor­ner of his upper lip. This Santa car­ried none of the heft of jolly St. Nick; he was thin but his pos­ture, even while sit­ting, gave the impres­sion of strength and com­mand. White socks and gold-painted wooden san­dals took the place of thick black boots. And a small, red had rimmed with gold lace com­pleted his cos­tume. This Santa was Japanese.

Intrigued by this scene, I edged closer, smil­ing at the fam­i­lies wait­ing their turn. I watched as Santa con­versed qui­etly with a small boy while his par­ents snapped pho­tos. As the boy slid off his lap, Santa turned to look at me as though he’d known I was there all along. Far more than a twin­kle, his eyes blazed as he looked at, no… through me. After a moment, he held up his hand and beck­oned me over. Embar­rassed, I mut­tered apolo­getic sounds to the fam­i­lies in line as I passed them on my way to Santa.

“Sit,” he said, indi­cat­ing his lap. I felt awk­ward and embar­rassed at this, but was unable to decline the offer, as it felt more like a com­mand. So I approached and gin­gerly sat on the edge of his leg. In one deft motion, he shifted his weight and arranged me solidly on his lap as though I were a child myself, despite out­weigh­ing him by at least 20 pounds. I looked at him (mostly to avoid the amused faces of those in the crowd) and felt the inten­sity of this Santa… this was no temp-agency hire; he seemed like the real deal.

“So…” Santa began, “what do you want for Christ­mas?” His voice was soft and low but some­how this question—not usu­ally asked to grown men perched on Santa’s lap—did not seem child­ish. I had to clear my throat before respond­ing. “Well,” I hes­i­tated, won­der­ing how to answer, “I, uh, need some new shirts for work—”

“No!” Santa inter­rupted firmly, but not rudely. “What do you want for Christ­mas?” he ques­tioned me again, and I sud­denly knew what his ques­tion meant. “Uhh… elbow con­trol, that’s what I really need.” I con­fessed. It was true, too: I had such a hard time keep­ing my elbows down when punch­ing and keep­ing them inside when blocking.

“Why?” He asked, star­ing at me intently. “For karate,” I told him; he nod­ded sagely so I con­tin­ued. “Keep­ing your elbow in when punch­ing is impor­tant because it’s more struc­turally sound. If it flares out”—here I demon­strated by bend­ing my elbow as I slowly punched—“the power of the strike is lost when con­tact is made and that elbow bends.”

Santa nod­ded at this, then again asked, “why else?” I thought for a moment, then replied “Chest blocks are weak if they’re like a wind­shield wiper.” I demon­strated the incor­rect block by hold­ing my arm out in front of me, elbow bent 90-degress, and rais­ing my fist in an arc so my fore­arm swept like a wind­shield wiper. “This way only uses the del­toid mus­cles, which are rel­a­tively weak. It’s stronger to reach out and then pull the elbow down to block the attack by redi­rect­ing it.” Here I again per­formed the tech­nique, earn­ing a few chuck­les from the assem­bled crowd. Santa again nod­ded, and I thought I detected a hint of a smile crack his lips.

It seemed my time with Santa was over, so I moved to get off his lap. A strong (but not tense), arm stopped me. “Why else?” Santa asked me again. I had to think a moment before reply­ing. “Main­tain­ing a strong con­nec­tion through­out your body is impor­tant to gen­er­ate and accept power,” I mused, more think­ing out loud than stat­ing a fact. “Keep­ing an ‘elbow out’ fix­a­tion, a ‘hug-the-tree’ pos­ture, helps main­tain the body’s pos­ture.” Uncon­cerned with the onlook­ers, I rolled my shoul­ders for­ward slightly and held my arms out in front of me, curv­ing them a bit at the elbows so my fin­ger tips almost touched, palms down. I visu­al­ized them form­ing an iron hoop such that any pres­sure exerted on them would be trans­ferred to my body (and then into the ground) rather than col­laps­ing under that pres­sure. Santa gave my arms a slight push, test­ing my pos­ture. It must have sat­is­fied him, as he gave a slight approv­ing nod.

After a moment, I tried to stand again. This time, Santa let me. “Uh, thank you Santa,” I said awk­wardly. He gave a nearly imper­cep­ti­ble bow, which I returned before step­ping through the bemused fam­i­lies who’d been watch­ing the strange exchange. I affixed a half-smile to my face and got out of there. Before I knew it, I’d turned down a side street and had emerged back in a famil­iar area. “That,” I said to myself as I returned to my car, “was weird!”

The inter­ven­ing days between my encounter with Santa and Christ­mas morn­ing came and went quickly. I’d nearly for­got­ten about it in all the hol­i­day excite­ment. But that morn­ing, open­ing presents, my wife asked me “Who’s that from?” as she pointed to a small pack­age, roughly the size of a pen or chop­stick con­tainer. It was del­i­cately wrapped in white rice paper and had a gold-lace rib­bon around it. “Ha ha,” I said, smirk­ing at her, sure she was being funny. No one had been to our house so I assumed it was from her. Her look told me that her ques­tion was, in fact, serious.

“It’s not from you?” I asked. “No,” she said, seem­ing sur­prised that I’d ask. Intrigued, I picked up the pack­age. It was very light. I untied the rib­bon and the rice paper fell away, reveal­ing a hum­ble box, which I opened. Inside, a small scroll lay atop a red cloth.

“Who’s it from?” she asked again. There was no name on the pack­age, inside or out. But then I remem­bered my meet­ing in the Inter­na­tional Dis­trict. “Santa, I think,” I said as I removed the scroll from the box. Tak­ing a deep breath, I held it up and let it unfurl. Writ­ten upon the left side of the scroll were a series of katakana char­ac­ters, and on the right was (an Eng­lish trans­la­tion of the Japan­ese, I assumed) this word:

practicePRACTICE!

And below that, much smaller, was a short adden­dum. A smile broke across my lips as I read:

relaxand relax.

& PEAR, and PDFs saved the day (and thousands of dollars)">How .htaccess, PHP & PEAR, and PDFs saved the day (and thousands of dollars)

18 Dec

& PEAR, and PDFs saved the day (and thousands of dollars)" href="http://scottbush.net/v2/blog/2009/12/18/how-htaccess-php-pear-and-pdfs-saved-the-day-and-thousands-of-dollars/" >How .htaccess, PHP <span class=& PEAR, and PDFs saved the day (and thousands of dollars)" class="thumbnail" width="490" height="200" />

no-stampsI’m already off to a rocky start with a blog title that con­tains three techie terms: .htac­cess, PHP and PEAR (and that’s not a fruit; if it were it wouldn’t be in all caps) and PDFs. But those are the ingre­di­ents that, when com­bined with a lit­tle web-development inge­nu­ity, solved a very real prob­lem and saved a lot of real dol­lars. Not a tech geek? This post might not be for you. Unless you hap­pen to want to stop print­ing and fold­ing form let­ters, stuff­ing and address­ing envelopes, and pay­ing for postage, and have a web server at your disposal.

Back­ground

Before the onslaught of techno-babble begins, a bit about the prob­lem I was solv­ing. Each quar­ter, the Uni­ver­sity of Wash­ing­ton (UW) noti­fies stu­dents whose aca­d­e­mic per­for­mance earned them a spot on the Dean’s list. This noti­fi­ca­tion, called a Dean’s let­ter, was sent by mail to qual­i­fy­ing stu­dents’ per­ma­nent addresses.

Due to the deep cuts to the UW’s bud­get, the Office of the Uni­ver­sity Reg­is­trar (in which I work) wanted to switch Dean’s let­ters to an e-mail process. Doing so would save the roughly fifty cents in mate­r­ial and postage cost for each of the 5,000 to 8,000 Dean’s let­ters sent each quar­ter—not to men­tion the happy trees that wouldn’t have to sac­ri­fice them­selves to carry the ink.

Seems sim­ple enough: just e-mail the let­ters to stu­dents, right? Sure, except for:

  • the capa­bil­i­ties of var­i­ous e-mail clients in use by students;
  • many stu­dents’ (and their par­ents’!) desire to keep or frame Dean’s let­ters as a sort of aca­d­e­mic tro­phy; and
  • FERPA, the Fam­ily Edu­ca­tional Rights and Pri­vacy Act of 1974, that reg­u­lates stu­dent edu­ca­tional records. (Get all the details here or here, but in a sen­tence: you can’t dis­play any part of a student’s edu­ca­tional record in a man­ner that would allow oth­ers to see it—and Dean’s let­ters are def­i­nitely a stu­dent record.)

First attempt: Access, Word, Acro­bat and Exchange

pdf_icon_150pxBefore I got involved, the good folks in our Data Man­age­ment office first attempted the switch to e-mail using Microsoft tools: stu­dent data stored in Access (data­base), fed to Dean’s let­ter tem­plates in Word (word pro­cess­ing) via its mail merge func­tion, exported to PDF with Acro­bat 9 (an Adobe prod­uct, not Microsoft’s), and passed to Out­look to be e-mailed via Exchange. Sound like a lot of soft­ware? It was. This approach was tried unsuc­cess­fully for many weeks.

Let me state that I have no grudge against Microsoft tools, nor do I think a solu­tion couldn’t be found using them (Adobe’s Acro­bat 9, how­ever, has an issue I did rant about). But after hear­ing often that mes­sages were mys­te­ri­ously chok­ing the Exchange mail server, I offered to help. I don’t know a thing about Exchange, so rather than try­ing to fix it, I sug­gested a dif­fer­ent approach. Once again, I don’t mean to imply these tools can’t accom­plish this task, only that the dif­fi­cul­ties expe­ri­enced couldn’t be resolved given the time avail­able by our IT staff.

Sec­ond attempt: PHP, PDFs, and e-mailing with PEAR

php-med-transMy approach was to move the solu­tion to the UW’s unix-based servers, which run PHP, an open-source web pro­gram­ming lan­guage. I sug­gested we:

  1. Gen­er­ate PDF files of the Dean’s let­ters as before (using Word’s mail merge and Acrobat) and upload them to the web server.
  2. Export a list of stu­dent data from Access into a comma-separated val­ues (CSV) list.
  3. Write a PHP script to:
    • read in stu­dent data from the CSV file (name, stu­dent num­ber, e-mail address, etc.),
    • rename the cor­rect PDF file to the student’s unique stu­dent ID number,
    • attach that file to an e-mail object using PHP’s PEAR code library, and
    • e-mail the mes­sage with attach­ment to the student’s pri­mary e-mail address.

When I started this project, it seemed pretty straight­for­ward. “I’m just switch­ing out PHP’s mail func­tion for Exchange,” I thought, since that was were the prob­lem lay. I didn’t real­ize the num­ber of obsta­cles that would get in the way.

The first issue to over­come was the vol­ume of mes­sages and their (rel­a­tively) large size due to the PDF attach­ment for each. Sum­mer quar­ter tra­di­tion­ally has fewer stu­dents, yet we still needed to e-mail roughly 2,500 mes­sages. Obvi­ously, send­ing that many mes­sages, each about 80k in file size, couldn’t be done all at once. Doing so would raise some flags with the university’s tech­nol­ogy folks who run the mail servers.

pear_icon_120pxThis prob­lem was solved with PEAR’s Mail_Queue pack­age. It not only pro­vides code to store out­go­ing mes­sages in a data­base (MySQL or oth­ers), from which they can be sent at a throt­tled rate, but it actu­ally pro­vides the SQL state­ment to set up the nec­es­sary fields in the data­base. Very nice! Once set up, it was a sim­ple mat­ter to queue each mes­sage as it was generated—rather than send them imme­di­ately. Then I cre­ated a cron job (a server tool to auto­mat­i­cally per­form processes at defined inter­vals) to run a sim­ple script to release 25 of the queued mes­sages every five minutes.

The next obsta­cle? Recip­i­ents e-mail clients. While I took all the pre­cau­tions I could to ensure the PDF attach­ment was sent prop­erly (includ­ing set­ting the proper MIME-type encod­ing and tests on all major e-mail clients: Gmail, Hot­mail, Out­look 2003/2007, and AOL), some things were just beyond my con­trol. As I fielded stu­dent com­plaints (which, thank­fully, were only about 3% of the total recip­i­ents), it became clear that those who did not receive their attach­ment all used some ver­sion of the UW’s own Alpine soft­ware. Turns out there is an open bug in Alpine that “some­times just doesn’t show an attach­ment.” (That’s all  was told, and dig­ging up more info on it seemed point­less.) And a hand­ful of stu­dents received a PDF, but it was blank. Quite odd, but I did see a blank PDF one stu­dent for­warded me, and con­firmed that what was sent to him did con­tain data—I’m chalk­ing that one up to grem­lins. For all these stu­dents, I re-sent them their let­ters indi­vid­u­ally, and all reported that they received them.

So, while this approach worked, it was not with­out its prob­lems; prob­lems that would only get worse as the vol­ume of let­ters increased. Plus, there’s another (though minor) down­side: not all stu­dents use their UW-provided e-mail address as their pri­mary e-mail. There­fore, this process does send an edu­ca­tional record out­side the uni­ver­sity, which is less secure.

Third attempt: PHP, PDFs, and secure down­loads with .htaccess

As I tried to rec­on­cile the issues with e-mailing these Dean’s let­ters, a much bet­ter solu­tion hit me. To para­phrase (and oth­er­wise man­gle) a metaphor: “if you can’t move the moun­tain to the stu­dent, we’ll bring the stu­dent to the moun­tain!” In other words, we’d send a noti­fi­ca­tion mes­sage via e-mail con­tain­ing a link to the PDF. Excel­lent, prob­lem solved… almost. This approach had its own set of prob­lems, the most glar­ing of which is secu­rity. To com­ply with FERPA, we have to ensure that the exis­tence of a Dean’s letter—or more impor­tantly, the lack of one—cannot be dis­cov­ered by any­one other than its recip­i­ent. Put in prac­ti­cal terms, a URL struc­ture like:

http://university.edu/registrar/deansletters/quarter/studentnumber.pdf

isn’t accept­able. Any­one with an iota of smarts and half a desire to snoop into their class­mates’ edu­ca­tional prowess could type in their stu­dent num­ber and (a) see their let­ter, if it exists, or (b) know that they didn’t make the list sim­ply by the absence of that letter.

pdf_icon_no_lock_150pxPassword-protect the PDFs them­selves? Might work, but PDF pass­words aren’t per­fectly secure, and how would we com­mu­ni­cate the pass­word with the recip­i­ent? If sent in the e-mail along with the link… well, that’s not much secu­rity at all, is it? And any­thing rel­a­tively obvi­ous (stu­dent num­ber, birth year, etc.) would be read­ily guess­able by oth­ers, assum­ing they had also received one and knew the file’s pass­word was their stu­dent num­ber, birth year, etc. And this approach wouldn’t solve the prob­lem of know­ing whether another stu­dent made the Dean’s list merely by the exis­tence of the PDF. No, password-protecting the files won’t work… we need some­thing else.

UWnetIDThe solu­tion to this issue seemed clear: require the stu­dents to log in. Luck­ily, the Uni­ver­sity of Wash­ing­ton has for years now issued NetIDs to all stu­dents. Each unique UW NetID serves as both the stu­dent, staff, or fac­ulty member’s UW-provided e-mail address (when appended with @u.washington.edu) and their authen­ti­ca­tion token for all uni­ver­sity sys­tems. Since it grants access to per­sonal records, course sched­ul­ing, e-mail, and so much else, stu­dents are good about keep­ing their NetID pass­words to them­selves. Yes, NetIDs were a per­fect solu­tion, but how to imple­ment it such that only the intended recip­i­ent can log in and see their letter?

Restrict­ing access to a user (or group of users) is easy with UW NetIDs and .htac­cess files. An .htac­cess file (found on Unix-based sys­tems like the UW’s) is a set of direc­tives that con­trol access to a direc­tory, a file, or even set of files that meet cer­tain cri­te­ria. It’s a sophis­ti­cated yet sim­ple sys­tem that would do the trick: restrict access to a file to spe­cific UW NetID. The only remain­ing issue: set­ting up .htaccess-based con­trols for the files. Remember, we’re deal­ing with many thou­sands of Dean’s let­ters each quar­ter, far too many to create manually.

Once again, PHP comes to the res­cue. My script already opened and read in a CSV data file con­tain­ing the stu­dent recip­i­ents’ infor­ma­tion, and one of the fields in each of those records was the student’s UW NetID. I real­ized I had every­thing I needed to solve the puz­zle! As the script looped through each record in the data file to cre­ate and queue up an e-mail mes­sage to the stu­dent, I could open and write another line to an exist­ing .htac­cess file, like this:

$handle = fopen( $dir . "/.htaccess", "a+");
$htaccessCode = "" .
  "require user " . $studentNetID .
  ""
$writeSuccess = fwrite( $handle, $htaccessCode );

For security’s sake, I won’t explain what each vari­able is (they’re des­ig­nated by the $) but you can see that for each stu­dent, a new Files­Match direc­tive is added to the directory’s .htac­cess file. It spec­i­fies a unique iden­ti­fier (that’s the name of the PDF file) and that access to that file is lim­ited to only one user: the recip­i­ent stu­dent, as iden­ti­fied by their UW NetID.

Sure, this setup results in a sin­gle .htac­cess file con­sist­ing of thou­sands of lines, but it’s still only a few hun­dred kilo­bytes in size and it causes no notice­able per­for­mance hit. And it allows me to gen­er­ate a unique URL for each stu­dent (as shown above) that, when clicked, requests the spe­cific PDF file from the server. Thanks to the .htac­cess file’s entry for that file, the user is prompted for their UW NetID and (pre­sum­ably quite secret) password.

It’s a great solu­tion. First, it saves us hav­ing to send thou­sands of ~80kb e-mails with error-prone attach­ments. Sec­ond, it keeps all stu­dent edu­ca­tional records secure on UW servers—no sent to Hot­mail or other third-party e-mail sys­tems. Third, access is lim­ited to just the intended recip­i­ent and pro­tected by an exist­ing, secure pass­word. But there’s one thing this solu­tion doesn’t yet do: close the “file exis­tence” loophole.

Sup­pose a mis­chie­vous recip­i­ent decided to check whether his friend got a let­ter by enter­ing in her stu­dent num­ber in place of his own in the URL. If he was greeted with a UW NetID log-in prompt, he could pre­sume she did receive a letter—he just couldn’t view it. If he saw the reg­u­lar 404 “file not found” error, he’d know she didn’t make the Dean’s list because no let­ter existed for her. Yes, he’d have to know her stu­dent num­ber but they are not all that secret. And yes, it’s not the worst secu­rity breach, but its still a breach. Clos­ing this secu­rity loop­hole wasn’t hard: just another entry in the .htac­cess file, like this:


  require user xxx

This entry relies on the web site’s han­dling of 404 errors, which is to direct the user to a spe­cific page when­ever a requested file is not found. By requir­ing a spe­cific user (here shown as xxx, though in real­ity a valid staff person’s UW NetID is used), even when a non-existent Dean’s let­ter is requested—actually, any non-existent file, like blahbjhfadf.html, etc.—the user is still prompted for a UW NetID. It’s a slick way to close the “file exis­tence” loop­hole: it’s impos­si­ble to deter­mine whether a given stu­dent num­ber received a Dean’s let­ter because every file request within that direc­tory prompts for a log in.

Sum­mary

This was a long post, but the process of ana­lyz­ing a set of busi­ness needs, try­ing dif­fer­ent approaches to meet them, and out­lin­ing the best tools (PHP func­tions, .htac­cess files, and some cre­ative think­ing) is worth it. The result­ing web­site resolves the issues and allows the UW to inform stu­dents of their Dean’s list sta­tus in a secure man­ner while sav­ing many thou­sands of dol­lars in print­ing and postage cost. I’d call that a suc­cess­ful project!

Tricking an HTML form to POST with unselected radio inputs

10 Dec

Tricking an HTML form to POST with unselected radio inputs

simple-radio-formThis web-development sit­u­a­tion con­fused me: why wasn’t my sim­ple form, con­sist­ing of a sin­gle radio but­ton set, throw­ing the expected error when sub­mit­ted with­out a selec­tion? Spoiler alert: HTML forms don’t include val­ues for uns­e­lected radio but­tons (or check­boxes, it turns out).

The prob­lem

I stum­bled across this issue when, as part of a larger web appli­ca­tion I was build­ing, I cre­ated the first step in the process using my stan­dard form set-up. PHP is my pre­ferred devel­op­ment envi­ron­ment and I’ll typ­i­cally re-use known good code when start­ing a new project. For forms, I start with a form that sub­mits to itself via POST:

 $variableName = (array_key_exists("inputName", $_POST)) ? $_POST["inputName"] : ""; 

and then pro­cess­ing the input via PHP before the rest of the page con­tent, like this:

<form action="< ?= $PHP_SELF ?>" method="post">
// form stuff
</form>

Thus the con­tents of the input (or and empty string “” if the input was not set) is stored in $vari­able­Name. Then I can per­form server-side form val­i­da­tion such as ensur­ing required fields are set, e-mail addresses are valid, and dis­play­ing error mes­sages back to the user, in PHP code that’s only exe­cuted when the form has been sub­mit­ted. I deter­mine that by the exis­tence of PHP’s auto­matic cre­ation of an array stor­ing post values:

if( $_POST) {
// check the user's inputs, create error messages, process form, etc.
}
// other PHP and HTML displayed the first time, before any form submission

This approach has always worked, so I was con­fused when the sim­ple form shown here failed to dis­play the “Please chose an option” mes­sage I expected when sub­mit­ted with­out a choice being made. After a lot of trial and error, I dis­cov­ered that because no value is selected for either radio but­ton in the browser and because it’s the only input in the form, PHP does not cre­ate the $_POST array. There­fore, my if state­ment fails and none of the user mes­sages are gen­er­ated and the form does noth­ing. Tech­ni­cally, it’s not hor­ri­ble; the user sim­ply has to real­ize they didn’t click any­thing and resub­mit. But from a user-experience stand­point, that’s a big fail.

The solu­tion

There are (at least) two ways to solve this:

  • Hid­den input — Set­ting a hid­den input with some arbi­trary value forces the cre­ation of the $_POST array. Also, the same set­ting the name attribute the same as the radio but­tons’ name ensures that assign­ing that name to a vari­able will result in a value for that vari­able. And then you can check whether the vari­able has the hid­den input’s value. If so, the user didn’t select one of the radio buttons.
  • Check­ing for the exis­tence of the spe­cific name — Rather than rely­ing on the exis­tence of the $_POST array, PHP’s isset() func­tion can deter­mine if a value for the radio but­tons was selected:
    if( isset( $_POST["inputName"] ) ) {
    	// a radio button choice was made
    }
    

What I don’t like about the sec­ond approach is it’s not as clean as the hid­den input because it requires another func­tion call. That sim­ple call is hardly a per­for­mance hit, but why add com­plex­ity if you can avoid it? And check­ing for a spe­cific ele­ment in the array lacks the ele­gance of just using if( $_POST ). Check­ing for the exis­tence of the spe­cific vari­able name in $_POST does work to per­form server-side val­i­da­tion on those radio but­tons, though. But even in this case I pre­fer the first approach because col­lect­ing the vari­ables as described above will work (the hid­den input will pro­vide the value) even if no radio but­ton selec­tion was made. Slick.

Adobe’s PDF-generation (and customer service-) FAIL

8 Dec

Adobe’s PDF-generation (and customer service-) FAIL

adobe-dunceRecently I worked on a prob­lem at my job whose solu­tion involved the use of PDF files (and PHP and other cool stuff that I’ll post about soon). Unfor­tu­nately, this process exposed me to some poor soft­ware design and hor­ri­ble customer-service issues from a com­pany I usu­ally like and whose prod­ucts I respect.

A bad soft­ware feature…

Admit­tedly, Adobe’s soft­ware soft­ware has some prob­lems, but I’ve per­son­ally not run into them until now. The “merge to PDF” func­tion pro­vided by Acro­bat Pro­fes­sional 9 (for Win­dows; I’ve not tried this on a Mac) for use in Word’s mail-merge fea­ture has a glar­ing over­sight: it doesn’t pro­vide a way to name the sequenc­ing of the result­ing files. An exam­ple: say you are mail-merging 50 let­ters to PDF. You enter “DeansLet­ter” as the base name for the PDFs but end up with a folder full of PDFs that are named “DeansLetter01001,” “DeansLetter01002,” “DeansLetter01003,” etc.

merge-to-pdf-dialogWhat’s the big deal, you ask? Though it’s annoy­ing you can’t spec­ify the sequence’s start­ing num­ber or the num­ber of dig­its, the huge prob­lem lies in cre­at­ing a large num­ber of PDFs. Strangely, Acro­bat uses some seem­ingly arbi­trary group num­ber, fol­lowed by a three-digit sequence. When gen­er­at­ing over a thou­sand let­ters, as we did, that group num­ber and sequence var­ied so that sort­ing the files by name resulted in a list that was out-of-order rel­a­tive to the data file used in the merge. Put sim­ply: a very large data set in alpha­bet­i­cal order by recip­i­ent last name gen­er­ates a list of mail-merged files that, when sorted sequen­tially, aren’t in alpha­bet­i­cal order.

This of course, is awful. And so eas­ily avoided! Adobe could have sim­ply appended a num­ber begin­ning at 1 increas­ing from there. That way, at least, a nat­ural sort algo­rithm could keep them in order. Or smarter yet: iden­tify the num­ber of items in the data set and append the proper num­ber of lead­ing zeros. So a set of 50 items would begin at 01; 125 items would begin at 001; 13,000 would start at 00001, etc. Easy. But it’s as though Adobe’s engi­neers tested this func­tion with a hand­ful of records. “It works,” I hear them say “merge-to-PDF func­tion: check.” Sure, tech­ni­cally it works… but it’s inel­e­gant and doesn’t work with a lot records, which surely is a com­mon use case for this func­tion. Where is the user test­ing that a great soft­ware com­pany like Adobe should rou­tinely employ? It’s hard to imag­ine a real user not men­tion­ing some­thing like this.

Even Adobe’s own online help is barely coher­ent about this function’s use:

  • To name the PDF that will be cre­ated, type in the Spec­ify PDF File Name box.
  • Note: The PDF will be named using this text plus a series of num­bers. For exam­ple, if you type JulyLetter in the Spec­ify PDF File Name box, the mail-merged PDFs might appear as JulyLetter_0000123, JulyLetter_0000124, July Letter_0000125, and so forth.

    “…a series of num­bers…”? “PDFs might appear”? Tech­ni­cal doc­u­men­ta­tion should never include “might” when describ­ing a result of a soft­ware oper­a­tion. And I can assure you that the num­ber­ing sequence we received didn’t match the help file’s descrip­tion. Terrible.

    …led to an even worse customer-service experience

    Try­ing to be a good cit­i­zen, I left a very com­plete (and polite!) expla­na­tion of the issue (includ­ing a detailed exam­ple) we expe­ri­enced on Adobe’s com­mu­nity help forum. A day later I received a mes­sage from Adobe’s forum mod­er­a­tor telling me my post was a fea­ture request, not a com­ment, and there­fore had been removed. They unhelp­fully sug­gested I re-post it on one of their fea­ture request forums instead. Amaz­ingly, they did not include my post in the e-mail mes­sage, and of course was never posted to the page; it was gone. I’d spent over 10 min­utes writ­ing a help­ful post that they essen­tially deleted, yet they expected me to re-type it some­where else? So I responded—again politely—asking for a copy of my post and explain­ing why I wanted it, but I never heard back. That’s hor­ri­ble. This “ser­vice” cost them a lot of brand loy­alty from me and earned this neg­a­tive press.

    So what is the pur­pose of this post? Not just to com­plain because that never solves any­thing. Instead, I hope that it inspires soft­ware devel­op­ers to test their fea­tures with “edge cases,” (like very big or very tiny data sets), not just the typ­i­cal cases. Any­one mod­er­at­ing a forum should also take note to include a customer’s ini­tial sub­mis­sion in their response (though I know most already do, which is why Adobe’s fail­ure to do so is so frus­trat­ing). And, finally, if some­one at Adobe hap­pens upon this post, maybe they’ll do some­thing about to fix that merge-to-PDF num­ber­ing fea­ture. One can always hope, right?

    Economy of motion is key

    2 Dec

    Economy of motion is key

    In col­lege, I took karate at a com­mu­nity cen­ter in Seattle’s Cen­tral Dis­trict. It was a fun class that included a lot of spar­ring. It used to just wear me out: two or three min­utes of that and I was exhausted. Part of it was adren­a­line, but mostly it was too much mov­ing around. That point was extremely obvi­ous when our instructor’s instruc­tor came to class once. Sen­sei Tyrone was his name, and he “sparred” with our instruc­tor, Andre. Until then, Andre had been the pin­na­cle of mar­tial arts to me—he was fast, knew a lot of cool tech­niques (such as “ox-jaw” or “eagle beak” strikes), and could hit pretty hard. But watch­ing him square off with his instruc­tor showed me where the two dif­fered: Andre moved con­stantly: feet, body, hands; Sen­sei Tyrone barely moved. He essen­tially just stood there. His blocks were minis­cule, his steps short, his strikes direct. At the time, I won­dered if he was just old (funny, he was prob­a­bly only a few years older than I am now). After a few years train­ing with true mar­tial artists at NW Mar­tial Arts, I now real­ize that Sen­sei Tyrone was sim­ply prac­tic­ing advanced karate: karate char­ac­ter­ized by econ­omy of motion.

    As with any­thing I write about mar­tial arts, I must con­fess I’ve only been train­ing for just over two years (exclud­ing those cou­ple years in col­lege). This is just my per­spec­tive as one who is near the begin­ning of the path.

    From my train­ing NW Mar­tial Arts, I’ve learned why econ­omy of motion is impor­tant (beyond just “not get­ting tired.”) Two con­crete exam­ples can illus­trate: arm posi­tion when per­form­ing a knife-hand strike/block (shuto uchi/uke); and the rear foot posi­tion when throw­ing a front kick (mae geri).

    1. Knife-hand strike/block - When first taught the hand posi­tions for a knife-hand strike/block, I was shown that the non-striking/blocking hand was kept retracted to cham­ber just below the rib, par­al­lel to the floor with the palm up (as though a teacup rested on it). This place­ment has the dis­ad­van­tage of slow­ness, as any follow-up using that hand would first need to come up to chest level before striking/blocking. That extra motion (from under the rib to chest), though small, is also a vis­i­ble clue to your oppo­nent that an attack is com­ing.
      Instead of below the rib, plac­ing that hand across your chest at a 45-degree angle is bet­ter because it can move directly toward your oppo­nent. There’s no need to first move the hand into posi­tion. That’s quicker and telegraphs your inten­tion less. Cham­ber­ing on your chest might look a lit­tle slop­pier because the arm’s angle isn’t as straight but it’s more effective—and that’s what’s important.

      knife-hand-strikes

      Both of these women look fierce, but the cham­bered posi­tion of the hand of the per­son on the one the right is closer to what I describe here. In the left image, the cham­bered hand still must rise before strik­ing. (These aren’t per­fect, but find­ing illus­tra­tive pho­tos of this wasn’t easy.)

    2. Front kick — Kick­ing is usu­ally slower than punch­ing (legs are much larger than arms), a fact that is wors­ened by most stu­dents’ ten­dency to let their rear foot—the one they’re about to kick with—point out­ward or even per­pen­dic­u­lar from their front foot. To kick, they must first shift their weight from the back foot so they can rotate that foot for­ward before kick­ing. That rota­tion of the foot toward the oppo­nent takes time and can betray your inten­tion to kick.
      It takes a con­scious effort (at least, it does for me!) to keep the rear foot point­ing for­ward on the line of attack toward your oppo­nent. Keep­ing your hips squarely on that line helps that foot remain for­ward, and the hip posi­tion helps hide your kick by speed­ing it up and elim­i­nat­ing the hip rota­tion oth­er­wise nec­es­sary to kick forward.

    It’s ironic how this truth about good mar­tial arts directly opposes mak­ing good martial-arts films. In a movie, the more exag­ger­ated jump­ing, flip­ping, punch­ing, kick­ing, and block­ing there is, the bet­ter it appears on screen. A strong but small low-block exe­cuted with a direct but deci­sive reverse punch is no where near as awe­some to watch as two guys trad­ing blows and coun­ters for two min­utes. (Not to men­tion the dubbed-in sound effects!). And though I’d rather watch a Shaw Broth­ers film, it’s the sta­ble, direct, powerful—but economical—karate I’d rather learn.