Starting a Jenkins multi-branch pipeline build from a Bitbucket commit

After some experimentation I’ve finally worked out how to start a Jenkins multi-pipeline build via a notification from Bitbucket when someone pushes a commit.

The first step is to disable CSRF protection (I know…I know…but it’s necessary to allow remote access). You can do this by selecting Manage Jenkins, Configure Global Security then unchecking the Prevent Cross Site Request Forgery exploits option.

Next step, navigate into your job from the main page and select Branch Indexing from the menu on the left. From this page right click on the link that says Run Now, copy the link address and paste it into a text editor.

Now go back to the Jenkins root menu and select People, then choose your user (or preferably a dedicated Jenkins user), choose Configure, and then reveal the API token. Copy it and head back to your text editor.

Assuming the branch indexing run now URL is https://jenkins.example.com/job/my-project/build?delay=0, the Jenkins user is jenkins and the API token is RdFrCiEwgs9boUsJVHoi modify the URL so it looks like this:

https://jenkins:RdFrCiEwgs9boUsJVHoi@jenkins.example.com/job/my-project/build

Next go into the settings of your Bitbucket and create a new webhook, paste in the modified link and save the form.

Commit something and you should see that a moment later Jenkins will run a branch index on the job and then run the build for the branch you committed to.

Multi-branch pipelines are a very new feature to Jenkins 2.0 and are still very part-baked in my opinion. As I get more proficient I will write a tutorial because whilst frustrating to get setup and going they’re a huge time saver.

Updated: a guide to OAuth 2.0 grants

One of the most popular articles on this site is my guide to OAuth 2.0 grants.

I’ve spent some time updating it (I first wrote it in 2013).

Check out the updated article here →

Laravel Passport and league/oauth2-server

Taylor Otwell, the creator of the Laravel framework, has announced a new Laravel project - Laravel Passport - which uses my league/oauth2-server project to “build an OAuth 2.0 backed API server in five minutes”.

This will be the second League of Extraordinary Packages project that has native Laravel support; the first being the amazing Flysystem by Frank de Jonge which power’s Laravel’s Filesystem APIs.

I will hopefully have a tutorial available shortly demonstrating how to use Passport once I’ve got my hands on the code.

Amazon Web Services Developer Associate Certification

Yesterday I took my Amazon Web Services Developer Associate certification exam and I’m very happy to have passed with 92%.

I’ve been using AWS services in production for over 18 months now and I’ve been wanting to validate my skills and extend my knowledge for a while by studying for one of the AWS certification exams.

In January udemy.com had a flash sale so I picked up a few of the courses by Ryan Kroonenburg and I’ve been watching them on and off since then. After booking my exam in February I started to really knuckle down on the revision. I also attended this past week a DynamoDB fundamentals session at the AWS London Loft and added to my revision notes by reading all of the relevant AWS service FAQs.

The 80 minute exam has 55 multiple-choice questions covering IAM, EC2, S3, Elastic Beanstalk, DynamoDB, SWF, SNS and SQS. The questions are either testing you on your general knowledge of AWS services or are asking you to pick the best option in a given scenario.

My exam featured lots of questions about S3 and only two on DynamoDB (which surprised me because I’d heard this particular exam is heavy on the DynamoDB questions). I had three questions about ELB and there were three questions on the AWS SDKs. There was also a really confusingly worded question about IAM SAML federation which required me to choose two options from five very similar options. Amusingly there were a few questions from the example questions on the AWS Certification website that I recognised too. I highly recommend reading the service FAQs as there were a few questions asking questions about limitations of services in specific regions.

All in all I feel like it was a valuable experience; I know many more of the AWS services better from the additional studying - I certainly wouldn’t have been able to answer many of the questions just on my practical knowledge. Having not taken any sort of exam in over five years either it’s opened my mind to potentially studying for additional professional accreditation in the future, not necessarily for the right to call myself a fancy title or to put letters after my name but to really focus in on learning and understanding a tool or a service at a greater depth than is absorbed through general day-to-day practical usage.

OAuth 2.0 Device Flow Grant

When signing into apps and services on devices such as a Playstation or an Apple TV it can be immensely frustrating experience. Generally you will ordeal something similar to one of the following scenarios:

  1. The utterly terrible experience whereby you don’t have anything other than an onscreen keyboard and whatever pointing device/controller to enter your username and painfully complex 50 character password.
  2. A slightly less terrible experience whereby you can pair a bluetooth keyboard to enter your username and that crazy long password but you’re balancing the keyboard on your knees whilst trying to copy the password out of 1password on your iPhone.

Of course if you use the same 8 character password everywhere then it’s less of an issue but you can understand my predicament… ^_^

There are some apps however - such as Youtube for Apple TV - that have a much better end user experience.

When you sign into the YouTube app you’re presented with this screen:

At the URL displayed on screen you see this (after signing into your Google account):

Having entered the code presented on the TV screen a standard OAuth authorisation dialog is shown:

A few seconds after click Allow the Youtube app had refreshed to show my account information.

Awesome!

This lovely UX features an implementation of the still very much in draft phase (at time of writing) OAuth 2.0 Device Flow Grant.

How it works

First an OAuth client (for example the Youtube app) makes a request to the authorization server:

POST /token HTTP/1.1
Host: authorization-server.com
Content-Type: application/x-www-form-urlencoded
    
response_type=device_code
&client_id=s6BhdRkqt3

The authorization server then responds with a JSON payload:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
    "verification_uri": "https://authorization-server.com/authorize",
    "user_code": "94248",
    "device_code": "74tq5miHKB",
    "interval": 5
}

The verification_uri is the URL that the user should navigate to on another device.

The user_code is the code that the user should enter once they’ve authenticated with the authorization server.

Meanwhile the client should attempt to acquire an access token every few seconds (at a rate specified by interval) by POSTing to the access token endpoint on the authorization server:

POST /token HTTP/1.1
Host: authorization-server.com
Content-Type: application/x-www-form-urlencoded

grant_type=device_code
&client_id=s6BhdRkqt3
&code=74tq5miHKB

The value of code should be the device_code from the JSON response in the previous request.

The client should continue to request an access token repeatedly until the end-user grants or denies the request, or the verification code expires.

If the client is polling too frequently it will receive an error from the authorisation server:

HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
	"error":"slow_down"
}

If the user hasn’t yet authorised the client the error will be:

HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
	"error":"authorization_pending"
}

If the user authorises the client an access token will be returned:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
    "access_token": "2YotnFZFEjr1zCsicMWpAA",
    "token_type": "bearer",
    "expires_in": 3600,
    "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA"
}

If the user denies the client an error will be returned:

HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
    "error":"access_denied"
}

Conclusion

The device flow grant provides a really pleasant experience for devices that do not support an easy data-entry method. In addition it is really simple for developers to integrate with.