OAuth2 in the Shell

For some scripts at work I need to log into our Gitlab instance and use its API. To do that you need an OAuth2 token, and I wasn't able to find any examples that I could crib from, so I'm posting what I made. Hopefully this'll help you do the same for your scripts. I should mention that I'm using this with Gitlab as per their instructions, it might be slightly different for other OAuth implementors, but should be roughly the same.

First let's just put the whole script out there before we break it down:


xdg-open "https://gitlab.example.com/oauth/authorize?client_id=${OAUTH_CLIENT}&redirect_uri=http://localhost:${PORT}/&response_type=code" &> /dev/null

OAUTH_CODE=$( echo -e "HTTP/1.1 200 OK\n\n<HTML><body><blink>Thank you</blink></body></HTML>" | nc -l -p ${PORT} | sed -n "s/^GET.*code=\([a-fA-F0-9]*\).*/\1/p" ) 

if [ "${OAUTH_CODE}" == "" ] ; then
    echo "Unable to get OAUTH code"
    exit 1

OAUTH_TOKEN=$(curl -X POST -F "client_id=${OAUTH_CLIENT}" -F "client_secret=${OAUTH_SECRET}" -F "code=${OAUTH_CODE}" -F "grant_type=authorization_code" -F "redirect_uri=http://localhost:5000/" https://gitlab.example.com/oauth/token | jq --raw-output ."access_token" )

if [ "${OAUTH_TOKEN}" == "" ] ; then
    echo "Unable to get OAUTH token"
    exit 1

When you want to use an OAuth2 client with Gitlab the first thing you need to do register as a client, getting the OAUTH_CLIENT and OAUTH_SECRET strings. You'll need to use the first one in the call to open the user's browser.

xdg-open "https://gitlab.example.com/oauth/authorize?client_id=${OAUTH_CLIENT}&redirect_uri=http://localhost:${PORT}/&response_type=code" &> /dev/null

The thing to notice in this call is that we're using localhost for the redirect URL. That means that after (assuming they do) they authenticate the script it will redirect the browser back this host with the code needed to get the token. We then need a webserver running on this machine to get that code.

OAUTH_CODE=$( echo -e "HTTP/1.1 200 OK\n\n<HTML><body><blink>Thank you</blink></body></HTML>" | nc -l -p ${PORT} | sed -n "s/^GET.*code=\([a-fA-F0-9]*\).*/\1/p" ) 

For our webserver we're using the trusty netcat to open a port and give us the data sent there. We go ahead and give the browser a nice webpage to say thanks (you know it's a serious Thank You when you use the <blink> tag). The output you get from netcat is something like this:

GET /?code=123456789abcdef HTTP/1.1
Host: localhost:5000
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:66.0) Gecko/20100101 Firefox/66.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1

So we use sed to pull out the code field by replacing the line with just the code and printing it. This gives us the code that we can then turn into a token.

OAUTH_TOKEN=$(curl -X POST -F "client_id=${OAUTH_CLIENT}" -F "client_secret=${OAUTH_SECRET}" -F "code=${OAUTH_CODE}" -F "grant_type=authorization_code" -F "redirect_uri=http://localhost:5000/" https://gitlab.example.com/oauth/token | jq --raw-output ."access_token" )

We set up a rather long curl call with several parameters that results in a JSON object that looks something like:

 "access_token": "de6780bc506a0446309bd9362820ba8aed28aa506c71eedbe1c5c4f9dd350e54",
 "token_type": "bearer",
 "expires_in": 7200,
 "refresh_token": "8257e65c97202ed1726cf9571600918f3bffb2544b26e00a61df9897668c33a1"

Which we then use jq to select the access_token and we're good to go. Now we can use that token to access the Gitlab API as we need it.

posted May 8, 2019 | permanent link

Knot Boards

Each year Cub Scouts has a birthday party for Scouting in February, which is called the Blue & Gold banquet. We have a tradition that at the banquet were we thank all of our volunteers who help make the Cub Scout Pack run. For the Den Leaders, who are so critical to the program, I like to do something special that helps them to run a better program for the scouts. For 2018 (notice I'm a little behind) I decided to make all of the Den Leaders for our Pack knot boards.

SVG file for the knotboard design

When I was a Scout I remember my mom making knot boards. Back then we had a piece of paper with the various knots that was varnished onto a piece of plywood, which had a rope attached to it. High technology for the time, but today I'm a member of TheLab.ms makerspace and have access to a laser cutter. While these knot boards are the same in spirit, we can do some very cool things with big toys.

Laser actively cutting boards with a cool sparkle

First step is to pull out Inkscape and design the graphics. I grabbed a rope border from Open Clipart and grabbed some knot graphics from a Scouting PDF (which I can't find a link to). I put those together to create the basic design along with labes for the knots. I also added a place for each Scout to sign their name as a Thank you to the Den Leader. I then make some small circles for the laser cutter to cut out holes for the ropes. I made a long oblong region on the right so the board would have a handle and a post to tie the hitches around. Then lastly I added the outline to cut out the board.

To get the design into the laser cutter I exported it from Inkscape in two graphics. I exported the cut lines as a DXF and I exported the etching as a 300 DPI PNG. The cut lines were simpler and the laser cutter software was able to handle those and create simple controls for the cutter. The knots on the other hand were more complex vector objects and the laser cutter software couldn't handle them. Inkscape could, so I had it do the rendering to a bitmap. The laser cutter can then setup scans that use the bitmap data which worked very well.

For the boards I used ΒΌth" Lauan Plywood which I was able to get in 2'x2' sheets at Lowe's. Those sheets have a nice grain on both sides. I also liked being able to get sheets that were exactly the size I needed to fit into the laser cutter. Saved me a step. I'm certain the knot boards would be great in many other woods and other materials.

Cut knot boards sitting the bed of the laser cutter

After cutting out the knot boards I needed short lengths of rope to be able to insert into the holes. I couldn't find anywhere that would sell me short pieces of rope. I felt like I needed a Monty Python sketch. To make short lengths of the paracord I looped it in a circle with the circumference as the length I needed. Then I took a blowtorch and cut the circle. This also sealed the ends of the paracord.

Final knot boards with ropes in the holes

posted Feb 2, 2019 | permanent link

Texas Linux Fest 2019 in Dallas

Texas Linux Fest 2019 will be in Dallas! It will be held May 31st and June 1st at the Irving Convention Center and the Call For Papers is open right now.

A few years ago I started to suggest to TXLF staff that coming to Dallas was a good idea. I wanted there to be more tech conferences in Dallas, and I love the community organized nature of TXLF and similarly SCALE. Plus, it was Texas Linux Fest, it can't always be in Austin! This year I was able to convince them to take the risk and try a year in Dallas. It is a huge risk, as it is likely that many sponsors and regular attendees might not be interested in traveling up I-35 to attend. Being in Dallas also opens up huge opportunity to reach new audiences and new sponsors. Now to prove that.

I'm excited that we were able to secure the conference center in Irving. It is on a light rail line that goes to both airports, and surrounded by restaurants if you don't want to take the train. We'll be securing blocks of rooms at local hotels if you want to attend from afar. It should be an easy adventure and put you in a location that you can enjoy the best of Dallas.

Now is your time to help out by submitting a talk to make the conference great. If you know of a sponsor we'd love to hear from you as well. And we'll be having registrations open as we announce the speakers.

Hope to see y'all in Dallas!

posted Jan 10, 2019 | permanent link

Letting Information Go

There's a lot of information stored all over the Internet about me, about you, about everyone. At best, most of it can just go away because it's useless, at worst it is potentially harmful. A humorous take on this by Molly Lewis:

The place that this is the most obvious is social media. I really liked this post on old tweets by Vicki Lai which talks about the why and how of deleting Tweets. It applies to all social media. But this all got me thinking about my blog.

Blog posts tend to be more thought out (or at least I try) and seem to me to be part of the larger web. So just deleting them after a matter of time doesn't feel the same as tweets. If someone was writing about the Unity HUD I would hope they'd reference my HUD 2.0 post, as I love the direction it was going. I have other posts that are... less significant. The ones that are the most interesting are the ones that are linked to by other people, so what I'm going to do is stop linking to old blog posts. That way posts that aren't linked to by other people will stop being indexed by search engines and effectively disappear from the Internet. I have no idea if this will actually work.

The policy that I settled on was to have the latest five posts on my blog page, and then having the archives point to posts of the last two years. This means I need to write five posts every two years (easy right!) to keep it consistent. Turned out implementing it in Jekyll was a little tricky, but this post on Jekyll date filtering helped me put it together.

I think that my attitudes to data are generational difference. For my generation the idea that we could have hard drives big enough to keep historical data is exciting. Talking to younger people I think they understand it is a liability. Perhaps fixing my blog is just me trying to be young.

posted Oct 1, 2018 | permanent link

Jekyll and Mastodon

A while back I moved my website to Jekyll for all the static-y goodness that provides. Recently I was looking to add Mastodon to my domain as well. Doing so with Jekyll isn't hard, but searching for it seemed like something no one had written up. For your searchable pleasure I am writing it up.

I used Masto.host to put the Mastodon instance at social.gould.cx. But I wanted my Mastodon address to be @[email protected]. To do that you need to link the gould.cx domain to point at social.gould.cx. To do that you need a .well-known/host-meta file that redirects webfinger to the Mastodon instance:

<?xml version='1.0' encoding='UTF-8'?>
<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'>

<!-- Needed for Mastodon -->
<Link rel='lrdd'
 template='https://social.gould.cx/.well-known/webfinger?resource={uri}' />


The issue is that Jekyll doesn't copy static files that are in hidden directories. This is good for if you have a Git repository, so it doesn't copy the .git directory. We can get around this by using Jekyll's YAML front matter to set the location of the file.

layout: null
permalink: /.well-known/host-meta
<?xml version='1.0' encoding='UTF-8'?>
<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'>

<!-- Needed for Mastodon -->
<Link rel='lrdd'
 template='https://social.gould.cx/.well-known/webfinger?resource={uri}' />


This file can then be placed anywhere, and Jekyll will put it in the right location on the static site. And you can folow me as @[email protected] even though my Mastodon instance is social.gould.cx.

posted Jan 29, 2018 | permanent link

All the older posts...