15 Jan 2015An API, really ?
Well, sort of.
All posts can now be accessed in a json
format (just replace the final /
with a .json
). This is obviously a read-only API.
For example, my previous post is accessible in json
format here.
{
"id": "/2014/12/27/past-and-future-objectives",
"title": "2014 learnings and 2015 objectives",
"url": "http://blog.pixelastic.com/2014/12/27/past-and-future-objectives/",
"tags": [],
"date": "2014-12-27 00:00:00 +0100",
"html": "<p>This is the end of the year, and I do realize now that [...]",
"markdown": "This is the end of the year, and I do realize now that [...]"
}
It currently exposes the initial text in markdown as well as the formatted HTML text, along with some metadata (id, url, date and tags).
I had a need to have my post in json
format for processing them through Grunt, so I thought I might as well expose them publicly. I'm not sure people will ever use it, but at least it does exist !
How was it done ?
Jekyll lets you plug custom made scripts to be called in the generation process in an aptly named _plugins
directory. I just had to create a json.rb file that will take every post and create a new json page from them, using a very minimalistic post.json layout.
All I had to do was build the custom object I wanted to return, which was a mix of generated content, and metadata.
27 Dec 2014This is the end of the year, and I do realize now that I learned and did a lot this year. I would like to write it down today, as well as what I would like to achieve next year, and see in one year how it went.
2014, the year that ends
First of all, I spend the year in an awesome company with very talented and kind people, with immense pools of knowledge and always ready to share it.
They taught me how to test my code, from unit testing to integration testing, and I now can't code without writing the failing test first (TDD FTW!). And this goes without saying all I learned about Agile methodology and conflict resolution.
I also discovered that my areas of expertises were not where I thought they were. I've always considered myself a full stack developer (whatever that means), but I actually don't know that much about back-end code. Never coded anything in Java or .NET (and don't really want to, either). But I actually have a large experience in front-end matters (from CSS to Javascript). I realized that good CSS skills are actually quite rare.
I went to a wide variety of tech conferences and meetups, and wrote extended summaries. At first it was for my colleagues, but I then made them available to everyone. Those meetups were invaluable source of R&D. Seeing 20mn of live performance of someone convinced of what he's talking about is worth hours of blog reading. And the discussions afterwards made me meet some very interesting people and spawn nice discussions.
So I decided to go to the other side and became a speaker. I chose a subject I really enjoyed and tried to make it as accessible as possible, while keeping the message simple. I quite enjoyed it.
Writing summaries of conferences you've attended makes you rethink what you heard and makes you remember it more. But writing your own talk really makes you go deep in what you know and what you don't know and is an invaluable exercise.
On a purely tech-related side, I extensively learned AngularJs and Grunt. I also discovered Jenkins and sharpened my git skills.
I also migrated this website from a cakePHP based application on a shared hosting to a Jekyll generated website on a private server. I now love the clean simplicity of markdown files versionned with git, and am much more at ease administrating my own server.
2015, the year to come
So, what will next year bring ?
I'll continue attending meetups and conferences, and would like to be a speaker more often. There are some subjects I am passionate about and could talk about and share.
I also would like to invest myself more in the open-source world. I actually only submit bug reports, small pull requests and use GitHub mainly as a backup storage for some of my projects. But none get ever used by anybody else than me. In 2015, I would like to be proud enough of one of my projects to release it and have other people use it.
I only scratched the surface of Rails and Node this year, and never actually pushed a full project in production. I would like to go deeper than tutorials and TODO applications.
I would like to stop developing with AngularJS (after 1.5 years using it, I'm still not at all convinced). React seems a very good approach to the view rendering and I would like to test if further. Why not giving Backbone another chance, and trying Ember.
I would like to go back to one of my first loves, CSS. I haven't touched it enough lately and I really want to have a bit of fun with all the new possibilities flexbox can give us.
Grunt is fine, once you know your way around, but I really need to try out Gulp or Brunch also.
I haven't played enough with Vagrant and/or Docker for my taste. Docker is the future and I would really like to have each of the websites hosted on my server encapsulated in their own containers.
Conclusion
Never stop trying, never stop learning.
26 Dec 2014I've been working on a few Angular projects lately, and had to test some $q
promises. And there was one little thing in how Angular implementation of $q
and the $digest
cycle interact that bit me once or twice.
If you ever fire a promise using $q
in one of your tests, know that Angular will not resolve it until you tell it to. It means that your promise will stay in an undefined state (neither resolved nor rejected) and your test will surely fail. This is because Angular promises are tied to the $scope
lifecycle and as we do not have one when running our tests, we have to add a bit of plumbing.
To force Angular to finish every promise, just add the following afterEach
implementation :
afterEach(inject(function ($injector) {
$injector.get('$rootScope').$digest();
}));
But this has a side-effet of triggering all your promises, even those you forgot about, like loading the templateUrl
for your directives. This will in turn block your tests because some promises will fail. The easiest way to correct this is to mock the responses and always respond an empty object.
beforeEach(inject(function($injector) {
$injector.get('$httpBackend').whenGET(/.*/).respond({});
}));
Hope this little tricks helped.
03 Dec 2014I recently put together a small command-line tool to convert Pantone colors to their hexadecimal value.
$ pantone2hex 122C
#fed141
You can grab the code on GitHub.
30 Nov 2014Here are a few simple questions to ask yourself to know if you're storing password incorrectly.
Are you storing them as plaintext ?
Really ? Well, that's bad. Very bad. Whenever a website sends me my password in cleartext in an email I delete my account. I know I can't trust their security. Whatever the size of your company, you'll eventually get a leak of your database, so don't make it easily readable.
Are you hashing password with md5 or sha1 ?
That's a bit better, but is as much useless. md5 and sha1 hash passwords to a limited (albeit very large) set of values. While you can't "un-md5" or "un-sha1" something, you can still create a list of all possible hashes (known as a rainbow table). Rainbow tables for md5 and sha1 can be downloaded and stored on a few hundred gigabytes nowadays. Then an attacker just have to search for a hash in the table to get one of the possible original passwords.
Are you hashing with md5 or sha1, but with a app-wide salt ?
Salting is a very good idea. Instead of hashing the password, you hash the password and a random string (known as the salt). That way, rainbow table found online became useless because they do not know your salt. But chances are that if an attacker got your database, they also got the source code of your app, including the salt. It's just a matter of time for them to build the specific rainbow table matching your salt.
Are your hashing with md5 or sha1, but with a specific salt per user ?
Now we're talking. That is a very effective way to slow down attackers. Even if they get their hands on your database, and the salt associated with each user, they will have to create as many custom rainbow tables as you have users in your database. This moves the attacks from massive brute force to specific users and so diminishes the threat. The only drawback is that, thanks to Moore's Law, computer are getting faster and faster and in a few years times generating hundred or thousands of custom rainbow tables will be inexpensive.
Are your hashing with bcrypt ?
To get the more future-proof implementation, you should use bcrypt. Bcrypt acts as a md5 or sha1 with specific salt per user, except that it's designed to be super slow. And that's a good thing. If an attacker needs to build a rainbow table, it will take him forever. And the best thing is, you can even adjust the level of time the method should take, and increase it in a few years when computers will be faster. The resulting bcrypt hash will contain the salt, and the level of complexity used to generate it.
Conclusion
You now have a good overview of what to do and not do when storing password. Remember that the main goal is to make life as hard as possible for a potential attacker to read one of your users password. And the best solution not only work today, but will still work tomorrow.