Contributing to IN COMMON Code

Introduction

IN COMMON was born out of the need of several non-profit organizations involved with the Commons to pool technical resources together and create the tools that would facilitate their cooperation and respective actions to identify, promote, and defend the Commons. From there, the IN COMMON Charter was written to establish a collective towards these goals.

IN COMMON code is free software. It aims to serve communities and we aim for a large and diverse community to contribute in the spirit of the Charter: we welcome commoners from a diversity of knowledges and backgrounds. This document introduces our technical setup to prospective developers and contributors, including the technical choices we made and the supporting online community resources.

IN COMMON software has a long term vision and thrives for minimalism, modularity, and advanced features to face current and upcoming challenges for the Commons: some choices may seem obscure at first sight, and we welcome discussion about them to unfold a common vision that will enable a large number of contributors to embrace it. For example, the model is conceived with collective agency in mind, which entails a number of unfamiliar features:

E.g., minimalist User model

the User model for example is meant to give absolutely no information about the actual person behind the account – although it requires an email for authentication, it is stored in a hash form, so we do not know it ; personally identifiable information such as email addresses or phone numbers are stored encrypted and matched on their cryptographic hashes – email notifications, therefore, are entirely voluntary and may go to a different address as the one used for login.
This enables an entirely new way of allowing remote users, verified by third parties, to interact with the API.

E.g., no Session

There is no concept of session in the IN COMMON API, as it’s made to work over HTTPS, a stateless protocol: the security model prevents many attacks from occurring that plague web systems, such as session fixation attacks, replay attacks or time-based attacks. This is to ensure the security and anonymity of users who may be in delicate situations, while focusing on collective action. Some applications on top of the API, such as administrative interfaces and third-party front ends may use sessions, but these remain out of the scope of the IN COMMON API.

E.g., no ACLs

The roadmap includes moving away from classical Access-Control Lists to avoid tying people to authorization, and use Object Capabilities instead, to enable responsible sharing of responsibilities with trusted people, using proxy objects to facilitate OCAP revocation. Such advanced concepts enable cooperation between untrusted parties.

E.g., opaque API through OCAP

Contrary to the classical approach to open APIs, where machines can easily know routes to resources, we apply OCAP concepts to tie the authorization to the resource itself, so that routes are only used internally: instead of POST /resources/foo, one would use a unique URI to access that resource, so that attacks against the API are rendered inoperant, leaving the space for cooperative access: if someone abuses a given URI, it is disabled to deter further abuse. Each Agent, comprising one or more users, is responsible for passing on capabilities to more people – each time using new URIs, so as to limit the propagation of malevolent behavior and facilitate trust between cooperating parties.

One of the main features of IN COMMON API is to enable decentralized compatible instances who can manage their own database, sharing only what they want to share, keeping a unique internal view of resources, e.g., to enable statistical comparison with competing market forces or hostile parties without disclosing such data. As a result, the IN COMMON database works as a synchronization cache among commoners who cooperate to identify, promote, and defend the Commons.

Another important aspect of the approach of IN COMMON is the focus on the quality of information: we aim to validate all fields and ensure the maintenance of high-quality data for the long term, developing not only software tools to help along, but also deploying shared infrastructure and methodologies for collective maintenance of data. Since IN COMMON data focuses on human geography, it differs from merely geographical data for which it relies on the excellent OpenStreetMap initiative: we’re building a social and political layer on top of OSM, to facilitate self-determination and a global conversation among commoners.

Tools

Ruby and Ruby on Rails

IN COMMON code is built with Ruby and Ruby on Rails (RoR).

This is the technical stack used by OpenStreetMap, as well as Discourse and Gitlab, three important elements of our ecosystem: we use OSM as the basis for accurate geographical information, Discourse for the ongoing conversation and Gitlab for our development platform via Framagit.

Style Guide and Code Quality

RoR comes with various tools we use to improve code quality:

  • RSpec to run tests through specifications
  • Rubocop to check consistency of the source code, and enforce a common style
  • Brakeman to detect possible vulnerabilities in our dependencies
  • SimpleCov to evaluate that implementation follows specification
  • Guard to automate various tasks (including the above) as we produce code
  • and more…

For general information on Ruby coding styles, see https://rubystyle.guide/

Watching the Code

Guard is configured to automatically:

  • run the code against specifications
  • watch coding style (and eventually enforce it)
  • measure coverage (the ratio of tested code)
  • warn about potential security issues

Usually, running bundle exec guard in a dedicated terminal window is sufficient to receive live information on our code quality as we program. It’s an invaluable tool to keep running while you’re coding.

Any time you will change a file it’s watching, it will run appropriate tests to ensure consistent code quality.
Usually, running bundle exec guard in a dedicated terminal window is sufficient to receive live information on our code quality as we program.

Documentation

We use several tools for documenting IN COMMON source code and API:

  • YARD allows us to turn comments into consistent and useful HTML documentation.
  • ERD allows us to generate graphical representations of the model dependencies.
  • Besides, the API is documented statically using Slate to produce browseable code at https://doc.incommon.cc/ that complements the API Documentation section of our forum. It lives in the incommon-doc repository if you like to contribute!

Documenting the Code

Note: this section covers source code documentation: the API itself is documented on its own, using Slate.

You can run YARD server to automatically update HTML documentation as you code:

yard server -s puma -r

Browse to http://localhost:8808/ to go through the source code documentation and explore how the program works.

YARD Example

Using YARD requires a bit of effort with documentation. The following diff shows the regular comment before and after it was converted to YARD – extended RDoc – format. Although it seems less readable, it generates more readable HTML in the end, that facilitates navigating within the source code and follow its logic.

Sample diff showing differences between plain and structured comments
diff --git a/app/lib/sso/from_discourse.rb b/app/lib/sso/from_discourse.rb
index 66742e2..62060f0 100644
--- a/app/lib/sso/from_discourse.rb
+++ b/app/lib/sso/from_discourse.rb
@@ -5,16 +5,20 @@ module SSO
     attr_accessor :nonce, :token, :user_info, :status

     class << self
-      # See config/initializers/sso.rb
-      # This is a hash:
-      # SSO::FromDiscourse.config = {
-      #   sso_url: 'https://talk.incommon.cc/session/sso_provider',
-      #   return_url: "#{API_ROOT_URL}/my/account",
-      #   sso_secret: Rails.application.credentials.sso_secret,
-      # }
-      # In config/routes.rb:
-      # ...
-      # get 'my/account/:token' => 'authentications#sso_login'
+      # The SSO configuration Hash (usually set in +config/initializers/sso.rb+)
+      # @return [Hash] the SSO configuration hash with attributes:
+      #   - +sso_url+: the Discourse SSO provider endpoint
+      #   - +return_url+: the local route to authentication handler
+      #   - +sso_secret+: the secret set in Discourse SSO settings
+      # @example SSO configuration hash in +config/initializers/sso.rb+
+      #   SSO::FromDiscourse.config = {
+      #     sso_url: 'https://talk.incommon.cc/session/sso_provider',
+      #     return_url: "#{API_ROOT_URL}/my/account",
+      #     sso_secret: Rails.application.credentials.sso_secret,
+      #   }
+      # @example SSO authentication route in +config/routes.rb+:
+      #   ...
+      #   get 'my/account/:token' => 'authentications#sso_login'
       attr_accessor :config
     end

When you code, do not try to do perfect documentation in YARD format: rather, follow your thought, and come back later to improve the documentation. Often, reviewers will try and improve documentation as they grasp the intent of the code. Unless you’re well versed into YARD already, trying to make good documentation right away will wreck your train of thought: first write your specs, then write the intent of your code in comments, make the spec pass, and only then you may start thinking of bettering the documentation.

Developer Setup

The easiest way to get started is to use the incommon-docker repository: it provides a clean Docker setup for development.

git clone --recursive https://framagit.org/incommon.cc/incommon-docker
cd incommon-docker

cp app.env.example app.env
cp postgres.env.example postgres.env
vim postgres.env
vim app.env

alias dc=docker-compose
dc up

This Docker setup follows the develop branch of [incommon-api] code: any git push to that branch will update the code in the incommon-docker for immediate review.

Developer Communication

Communication in free software is critical, especially as different contributor contexts and low-bandwidth – compared to face to face – can lead to misunderstandings. We need to spend time together to work better together and enjoy it :slight_smile:

We use four tools to communicate:

  • the API section of our forum to discuss features, roadmaps, document releases, and more.
  • the Issues, Milestones, and Merge Requests features of Gitlab on our
    IN COMMON repositories to review changes and track progress.
  • the #incommon-api IRC channel on the Freenode network for chat.
  • the incommon Jit.si room for voice or video conference.

IN COMMON Talk Forum

Developers should ensure their notification level in the following categories are set to Watching or at least Tracking, so that they don’t miss critical input. Discourse rewards reading, so keep an eye on them, according to your interests. :slight_smile:

See #api, #api:dev, #api:doc, #api:i18n, #api:releases, #api:support, and the #get-started and #howto tags.

IN COMMON Repositories

We like to use a simple process inspired by GitFlow workflow on the Framagit, in a nutshell:

  • the master branch is for public releases
  • the develop branch is where new code is merged
  • other transient branches are used to develop new features (feature-foo), or fix identified issues (fix-123, referencing Issue #123)
  • Merge Requests (MR) from transient branches are made against the develop branch
  • once a release quality is reached, the develop branch is merged into the master branch, tagged (we use Semantic Versioning) and deployed into production

Head to the IN COMMON Organization on Framagit.

IRC channels

Freenode IRC channels are used for quick access to team members for clarifying situations, instant help and support, and general chat about the code, API, and documentation. Usually such conversations give way to new Issues or forum topics.

IRC, although a synchronous text chat medium, is better used asynchronously: be there, and don’t expect instant responses, as often other people are busy with their ongoing tasks. But it’s a low pressure way of passing on information or welcoming newcomers.

Besides #incommon-api there’s a more general #incommon channel where anyone is welcome to talk about IN COMMON. The difference is that the former is more focused on code, e.g., it will inform of changes in the development platform (commits, issues, builds, topics…)[1].

To get started, connect to Freenode.

If you did not already, you should register a nickname with nickserv on Freenode, so you can access the chat rooms and people can identify you clearly and leave you memos while you’re disconnected.

Register with NickServ

Once you’re connected to Freenode IRC, preferrably using SSL, you can register a nickname for yourself:

/nick Elisee
/query nickserv register some_S3Kr!t0FyourZ you@example.net

If all goes well you can now connect with nickname Elisee and password some_S3Kr!t0FyourZ to keep your online identity consistent. It will allow you to join some channels only reserved to registered people (to avoid spammers), receive memos, register channels of your own, etc. Welcome to IRC, the simple, low pressure, ads-free Internet Relay Chat since 1993.

Freenode chat rooms are relayed to the Matrix network, so you can use this as well to connect.

Matrix Channels

#freenode_#incommon:matrix.org
#freenode_#incommon-api:matrix.org


  1. this is not yet put in place but really should :slight_smile: ↩︎

1 Like