Link Shorteners and a Call to Action

Standard

Some of you may know that I have a domain I use for link shortening: buze.co. If you hit up the domain root, it redirects you to my blog. But if you go to a shortened URL, such as buze.co/pe4es, it will redirect you to the proper page. I set this up using YOURLS because it seemed like the easiest way to get the domain up and running.

What you probably don’t know is that I have another domain that’s run off the same database. In any normal scenario, you’d probably want to split your databases on a per-service basis, i.e. separate personal from work, which is what this other project is. The reason I serve the same content is because I don’t shorten enough links to require two separate databases. And nobody can see the database anyway, so it doesn’t matter.

To achieve this, I symbolically link the work domain to buze.co. Coincidentally, /www is also a symbolic link.

ln -s /www/work.domain /www/buze.co

My vhost paths are strange, but they get the job done. The actual path for this domain is /var/www/buzelac.com/public_html/ but that’s a different blog post.

/www/buze.co/index.php looks like this:

<?php
$host = $_SERVER['HTTP_HOST'];

if($host == 'work.domain') {
    header('Location: http://work.domain');
} elseif($host == 'buze.co') {
    header('Location: //buzelac.com');
} else {
    echo 'Nothing to see here.'; // this is a fallback just in case
}
?>

And then nginx handles rewrites for any “directory.” If the path isn’t a directory (!-d) and it isn’t a file (!-f), then it rewrites to the YOURLS script. Note: this can be handled with one step using !-e.

YOURLS isn’t bad. In fact, it’s actually pretty cool. It records how many clicks links get, has a stats page with graphs for hits and traffic location, and there’s even a nifty plugin to make it produce links similar in format to other services, such as “pe4es” instead of “23,” the default format.

…What’s the problem?

While YOURLS is a pretty decent link shortener, there’s something about it not being mine that I don’t really know how to explain. Essentially, I think there are some improvements that could be made (both programmatically and aesthetically), so I might as well just write my own.

YOURLS follows what I would call a “Web 2.0″ approach, a term which I think should have been shot before it was even incepted. Clients always say, “This design isn’t ‘Web 2.0′ enough.” or “Yeah, this is good, but can you make it more… ‘Web 2.0′?” These clients don’t even understand what “Web 2.0″ is, they’re just trying to sound savvy and keep up with the latest “trends.” If crappy gradients / color schemes, extremely rounded corners, and ill-fitting typography is what it takes to fit in, then I want to be as far away from conformity as possible.

I digress. The YOURLS code is messy in my opinion. Understandably so, as I don’t think the project was originally intended to be as big as it is. But still another reason that it will be easier for me to start from scratch. I prefer an object-oriented approach. Plus, this way, I’ll be able to easily integrate the new system with my new CMS I’m working on… but that’s another blog post.

The “Call to Action”?

The world doesn’t have enough URL shorteners. So I’m going to create another. Most likely a PHP / Redis approach, because I’m looking for my first project using Redis. But it could easily end up a PHP / SQL project as well. It really depends on how my experiments with Redis go. (I’m not extremely fond of the idea of everything being in memory; I’m really just looking for a NoSQL approach.) It will have to have an import feature, though, so I can copy all of my YOURLS links into the new system. And some sort of API for plugin creation. I’d also like some sort of module-esque system (plugins) to enable features like public URL submits, a user system, etc.

Closing Irony

Some of you reading this clicked the short link, which is currently produced with YOURLS.

Setting up a chrooted SVN environment

Standard

Today, I set up SVN on my server for a friend’s school project. While it’s not the first time I’ve set up SVN, it is the first time I’ve needed to restrict the users to a specific directory. Keeping in mind that I refuse to use Apache on this particular server, there would be no dav_svn.

Installing SVN

  1. Install SVN
  2. Create Repo
  3. ???
  4. Profit
apt-get install subversion
svnadmin create /path/to/svn/repo

…We’re done, right? Well, no. Not close. Remember, you wont find Apache on this server, so somehow, I needed to auth users. Now, I’m sure there’s a way to use SVN over FTP, but again, you’re lucky if you find an FTP server on this box… Cleartext passwords? No thanks.

Locking down an SSH User

I’ve never had the need to chroot a user before. Especially not a shell user. A quick google search brought me to a neat little script called make_chroot_jail. I installed the script in /usr/local/sbin/. Every time I tried to run the script, it would throw errors and never accomplished anything. I googled it and learned that the first line of the script,

#!/bin/sh

sometimes has to be changed to:

#!/bin/bash

depending on the distro used. Once I did this, the errors stopped flowing. But I still wasn’t done. I originally thought I needed to use the full syntax:

make_chroot_jail.sh user /path/to/shell /path/to/home

but the script was including my absolute paths in a variable with paths already set. So /path/to/home became /home/jail/path/to/home. Additionally, it didn’t work properly, as I could still manage everything via ssh with that user. After some trial and error (and reviewing the script source again) I decided that simple is better. The new syntax,

make_chroot_jail.sh user

worked perfectly. It created a home directory based on the user inside of the jail. It also restricted the available applications to a select few standard apps. Unfortunately, this didn’t include the svn applications. This was easy enough to solve by adding the required apps to the APPS var, similar to:

APPS="/bin/bash /bin/cp [...] /usr/bin/svn /usr/bin/svnadmin"

I’m assuming that if you’re reading this and planning on doing what I did, you’ll notice that you need to change the line specific to your distro. If you don’t know what your distro is (or what “distro” means, for that matter), find someone familiar with Linux to do this for you.

I digress; At that point, I tried to connect to the SSH server but couldn’t. I learned that the supported jailed apps are actually copied into the jail. Nothing is updated realtime. I re-ran

make_chroot_jail.sh user

and it updated the jail, adding my svn apps. I still couldn’t connect to the repo, though. I wasted a lot of time on this part. SourceTree offered that it was, in fact, an SVN repo, and asked if I wanted to clone it to git. svnX claimed that it didn’t exist.

Beneficial vs. Detrimental

I like open source. I like free. Free + open source together are like ice cream to me. So I found svnX, a free, open-source SVN client for OS X. But if there’s one word I can use to sum up svnX: crap. Maybe it’s my lack of tolerance (bias) for applications that half-ass GUIs for CLI apps. Or maybe it’s the fact that svnX simply wouldn’t accept that I was using an authenticated user via ssh. I mean, in terms of GUIs, I’ve seen great… and I’ve seen worse than horrible. I could have gotten over the bad UI if the app had done what I wanted, but the fact that this app wouldn’t let me svn+ssh was a complete deal breaker.

What’s next? Versions. I’ve used it before. It’s got a great GUI. It makes sense. But since I primarily use GIT, forking out $60 on the app isn’t going to happen. Luckily, there’s a 30-day trial. Anyway, I downloaded it, plugged in my svn+ssh:// URL, and gave it a password. Boom. Instantly connected. And it worked. *Flawlessly.

Verdict
svnX: Detrimental to my workflow
Versions:  Beneficial to my workflow

*Why wouldn’t there be a “But…”?

I said that Versions worked flawlessly. The app itself did. It even gave me a verbose and understandable error when I tried to commit rev 1 as a test. (Yep. There’s no way I’d be done with this project that easily.) The error was “attempt to write on a readonly database.” This one was actually easily enough to solve. I granted write perms to /path/to/repo/db/rep-cache.db and then it worked. No more hiccups on my end.

One more thing?

In the end, my friend, using Tortoise, told me that he has to enter the pass every time he performs an action. It looks like there’s no password caching in Tortoise. I generated a key, but we haven’t implemented it yet. I’m pretty sure that it will get fairly annoying during dev to have to stop to enter the pass all the time, and that’s where PuTTY / pageant will come in.

Closing Thoughts

All said and done, I definitely prefer GIT.