GSoC Week 3: encrypt_content_client - REST resource and SJCL library

PHP Code Sniffer

As instructed by my mentor Colan, as my codebase is growing every day, I should install a coding standards checking tool. He suggested using Code Sniffer for PHP. After some tries I, could not get it to work on my online IDE (cloud9) so I decided to download a package for my local code editor - Atom. The package is called linter-drupalcs and it uses the widely available Drupal’s CS rules installable via Composer

drupalcs

 

It is a great tool for fixing formatting and other coding standards’ issues, it will help me get better coding habits and I hopefully will see fewer PHPCS errors popping out as I am coding! I am sharing settings for Atom as it took me a while to set it up properly, hope it helps someone!

DrupalCS Settings

 

I spent two hours going through files fixing the code and adding comments. I think it’s a really good thing to get good coding habits early on in the project.

Reworking the architecture document

As the main JavaScript cryptography library has changed in my module and few ideas came to my mind as I was coding, I need to go through and rework some of the sections there. The architecture document for my module is available here - still a work in progress but any feedback is welcome!

New permission

A requirement came up when developing the custom REST resource, an idea of an “encryption client” permission. This permission would allow administrators to control who can have access to encrypting/decrypting content using this module.

New permission

 

This documentation page helped me understand how permissions work in Drupal 8. The permission I created may grow in the future to allow more detailed control over client-side encryption (separate permissions for encryption, decryption, key generation, and editing encrypted content).

More work on the SJCL wrapper

I continued to work on the JavaScript library wrapper:

  • Generate encryption container

This is a very important part of my module, it’s a field that will store encryption keys for the encrypted content. Here is a simplified flow of how it will work:

  1. Create a hash of the longest string in all fields sent by a form.

  2. Encrypt content of all fields using symmetric encryption (AES) using the hash from step 1 as the password.

  3. Get all user’s public keys and encrypt that hash (called data-key) for every user and store it as JSON in the encryption_container field. 

 

  •   Elliptic Curve Cryptography (ECC) key generation

I have created a page for generating ECC key pairs using a new JavaScript library that I have created and attached it to the form on that page. Users will have an option of either only downloading a file with generated keys or calling a REST route to update their keys in the database.

Extending REST resource

  • Update user’s key

Now that I have generated keys I want to store them using the custom resource I have already created. I had to add a new resource route (by following this tutorial), an endpoint which does not accept any arguments (/ecc/update) so I can call it using POST request passing JSON with public and private keys. I used Postman to test my API:

 

Postman API Testing

 

Useful tutorials on this topic:

  1. How to create Custom Rest Resources for POST methods in Drupal 8
  2. RESTful Web Services API overview
  3. Update a node / Entity programmatically in Drupal 8

 

  • Get keys for all users

I have continued to work on the REST resource and created a documentation section on that. I want to follow general API design standards. I extended my GET method so now it returns an array with UIDs and public ECC keys.

Interesting issues

  • "message": "No route found for \"POST /ecc/1/public/\": Method Not Allowed (Allow: GET, HEAD, DELETE)

When trying to make POST calls to my resource I was getting this error, this page helped me understand that when testing API calls from Postman I need to authenticate using a CSRF token and set the correct content type before making calls.

Plans for week 4

  • Encryption for nodes, only article type at first

  • Add localStorage / cookies for client-side key storage

  • When updating keys ask for previous key’s password to validate ownership

  • Allow users add own key pair