Desenvolupat prototip inicial

L'estructura del codi del backend està completa, caldrà anar
desenvolupant més codi però sota la mateixa estructura.

Aquest commit introdueix la implementació de l'inici de sessió amb
comptes de Google de la UPC i un mètode de l'API que retorna totes les
assignatures disponibles.
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..48bb61b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+config.php
+vendor
diff --git a/.htaccess b/.htaccess
new file mode 100644
index 0000000..74b487f
--- /dev/null
+++ b/.htaccess
@@ -0,0 +1,5 @@
+Options -Indexes
+ErrorDocument 404 /404.html
+
+RewriteEngine On
+RewriteRule "^api/v1/(.+)$" "/api.php?path=$1" [L]
diff --git a/404.html b/404.html
new file mode 100644
index 0000000..6e3c541
--- /dev/null
+++ b/404.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>404 - No trobat</title>
+    <style>
+    html {
+      font-family: 'Roboto', 'Helvetica', 'Arial', sans-serif;
+    }
+    </style>
+  </head>
+  <body>
+    <h1>Error 404</h1>
+    <p>Ho sentim, però si cercaves existència i unicitat, ens sap greu informar-te que aquesta pàgina ni tan sols existeix :(</p>
+    <p>Potser, però, t'interesa fer-li una ullada a la <a href="https://dafme.upc.edu/ca/apunts">comi apunts</a>.</p>
+  </body>
+</html>
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..4edaf74
--- /dev/null
+++ b/README.md
@@ -0,0 +1,21 @@
+# DeleFME/covid-tracability-backend
+Per veure el repositori principal, aneu a [DeleFME/covid-tracability](https://github.com/DeleFME/covid-tracability).
+
+## Requisits
+- Servidor web Apache
+- MariaDB o MySQL
+- Composer
+
+## Instal·lació
+Per instal·lar el backend, seguiu els següents passos:
+
+1. Cloneu aquest repositori al directori arrel del vostre servidor web.
+2. Feu un duplicat de l'arxiu `config.default.php` amb el nom `config.php`, i ompliu el fitxer amb la configuració desitjada.
+3. [Instal·leu Composer](https://getcomposer.org/doc/00-intro.md) a la vostra màquina (si no el teniu ja instal·lat) i executeu la comanda `composer install` al directori arrel.
+4. Instal·leu la base de dades seguint els següents pasos:
+    a. A MariaDB/MySQL, executeu la següent comanda per inicialitzar la base de dades: `CREATE DATABASE covid_tracability CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;` (es pot substituir `covid_tracability` per un altre nom de la base de dades).
+    b. Executeu la comanda `mysql -u usuari -p covid_tracability < utils/db_structure.sql`, on `usuari` és l'usuari de MariaDB/MySQL.
+5. Configureu Apache perquè faci cas a l'arxiu `.htaccess` del directori arrel. \[[+ info sobre com fer-ho](https://askubuntu.com/questions/429869/is-this-a-correct-way-to-enable-htaccess-in-apache-2-4-7)\]
+6. Ja teniu el servidor disponible a `http://localhost/`!
+
+Nota: per tal d'utilitzar Apache amb diversos projectes, el que es pot fer és posar el repositori a un altre directori, i configurar un `virtualhost` que respongui les peticions d'un host com `covid-tracability-backend.test` servint els documents de l'altre directori. També s'hauria de configurar a l'arxiu [hosts](https://ca.wikipedia.org/wiki/Fitxer_de_hosts) la resolució d'aquest domini (`covid-tracability-backend.test`) a l'IP `172.0.0.1`.
diff --git a/api.php b/api.php
new file mode 100644
index 0000000..31c2b14
--- /dev/null
+++ b/api.php
@@ -0,0 +1,4 @@
+<?php
+require_once('core.php');
+
+DAFME\Covid\API::process((string)($_GET['path'] ?? ''));
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..b9435c2
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,10 @@
+{
+    "require": {
+        "google/apiclient": "^2.7"
+    },
+    "autoload": {
+        "psr-4": {
+            "DAFME\\Covid\\": "inc/"
+        }
+    }
+}
diff --git a/composer.lock b/composer.lock
new file mode 100644
index 0000000..ff0a193
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,868 @@
+{
+    "_readme": [
+        "This file locks the dependencies of your project to a known state",
+        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+        "This file is @generated automatically"
+    ],
+    "content-hash": "2171b3490ad9a848ba367cda53615683",
+    "packages": [
+        {
+            "name": "firebase/php-jwt",
+            "version": "v5.2.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/firebase/php-jwt.git",
+                "reference": "feb0e820b8436873675fd3aca04f3728eb2185cb"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/firebase/php-jwt/zipball/feb0e820b8436873675fd3aca04f3728eb2185cb",
+                "reference": "feb0e820b8436873675fd3aca04f3728eb2185cb",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": ">=4.8 <=9"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Firebase\\JWT\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Neuman Vong",
+                    "email": "neuman+pear@twilio.com",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Anant Narayanan",
+                    "email": "anant@php.net",
+                    "role": "Developer"
+                }
+            ],
+            "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.",
+            "homepage": "https://github.com/firebase/php-jwt",
+            "keywords": [
+                "jwt",
+                "php"
+            ],
+            "time": "2020-03-25T18:49:23+00:00"
+        },
+        {
+            "name": "google/apiclient",
+            "version": "v2.7.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/googleapis/google-api-php-client.git",
+                "reference": "9df720d72c59456b5466e3f66e1e78cfe422a5ba"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/googleapis/google-api-php-client/zipball/9df720d72c59456b5466e3f66e1e78cfe422a5ba",
+                "reference": "9df720d72c59456b5466e3f66e1e78cfe422a5ba",
+                "shasum": ""
+            },
+            "require": {
+                "firebase/php-jwt": "~2.0||~3.0||~4.0||~5.0",
+                "google/apiclient-services": "~0.13",
+                "google/auth": "^1.10",
+                "guzzlehttp/guzzle": "~5.3.1||~6.0||~7.0",
+                "guzzlehttp/psr7": "^1.2",
+                "monolog/monolog": "^1.17|^2.0",
+                "php": ">=5.4",
+                "phpseclib/phpseclib": "~0.3.10||~2.0"
+            },
+            "require-dev": {
+                "cache/filesystem-adapter": "^0.3.2",
+                "composer/composer": "^1.10",
+                "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0",
+                "phpcompatibility/php-compatibility": "^9.2",
+                "phpunit/phpunit": "^4.8.36|^5.0",
+                "squizlabs/php_codesniffer": "~2.3",
+                "symfony/css-selector": "~2.1",
+                "symfony/dom-crawler": "~2.1"
+            },
+            "suggest": {
+                "cache/filesystem-adapter": "For caching certs and tokens (using Google_Client::setCache)"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Google_": "src/"
+                },
+                "classmap": [
+                    "src/Google/Service/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "Apache-2.0"
+            ],
+            "description": "Client library for Google APIs",
+            "homepage": "http://developers.google.com/api-client-library/php",
+            "keywords": [
+                "google"
+            ],
+            "time": "2020-09-18T20:02:04+00:00"
+        },
+        {
+            "name": "google/apiclient-services",
+            "version": "v0.147",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/googleapis/google-api-php-client-services.git",
+                "reference": "8624bd004cfccb33b760ae7650d0b750168cd7f7"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/8624bd004cfccb33b760ae7650d0b750168cd7f7",
+                "reference": "8624bd004cfccb33b760ae7650d0b750168cd7f7",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.4"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^4.8|^5"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-0": {
+                    "Google_Service_": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "Apache-2.0"
+            ],
+            "description": "Client library for Google APIs",
+            "homepage": "http://developers.google.com/api-client-library/php",
+            "keywords": [
+                "google"
+            ],
+            "time": "2020-09-20T00:24:43+00:00"
+        },
+        {
+            "name": "google/auth",
+            "version": "v1.13.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/googleapis/google-auth-library-php.git",
+                "reference": "173191f5defd1d9ae8bdfc28da31b63eb73dd34e"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/googleapis/google-auth-library-php/zipball/173191f5defd1d9ae8bdfc28da31b63eb73dd34e",
+                "reference": "173191f5defd1d9ae8bdfc28da31b63eb73dd34e",
+                "shasum": ""
+            },
+            "require": {
+                "firebase/php-jwt": "~2.0|~3.0|~4.0|~5.0",
+                "guzzlehttp/guzzle": "^5.3.1|^6.2.1|^7.0",
+                "guzzlehttp/psr7": "^1.2",
+                "php": ">=5.4",
+                "psr/cache": "^1.0",
+                "psr/http-message": "^1.0"
+            },
+            "require-dev": {
+                "guzzlehttp/promises": "0.1.1|^1.3",
+                "kelvinmo/simplejwt": "^0.2.5",
+                "phpseclib/phpseclib": "^2",
+                "phpunit/phpunit": "^4.8.36|^5.7",
+                "sebastian/comparator": ">=1.2.3",
+                "squizlabs/php_codesniffer": "^3.5"
+            },
+            "suggest": {
+                "phpseclib/phpseclib": "May be used in place of OpenSSL for signing strings or for token management. Please require version ^2."
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Google\\Auth\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "Apache-2.0"
+            ],
+            "description": "Google Auth Library for PHP",
+            "homepage": "http://github.com/google/google-auth-library-php",
+            "keywords": [
+                "Authentication",
+                "google",
+                "oauth2"
+            ],
+            "time": "2020-09-18T20:03:05+00:00"
+        },
+        {
+            "name": "guzzlehttp/guzzle",
+            "version": "7.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/guzzle/guzzle.git",
+                "reference": "7edeaa528fbb57123028bd5a76b9ce9540194e26"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/guzzle/guzzle/zipball/7edeaa528fbb57123028bd5a76b9ce9540194e26",
+                "reference": "7edeaa528fbb57123028bd5a76b9ce9540194e26",
+                "shasum": ""
+            },
+            "require": {
+                "ext-json": "*",
+                "guzzlehttp/promises": "^1.0",
+                "guzzlehttp/psr7": "^1.6.1",
+                "php": "^7.2.5",
+                "psr/http-client": "^1.0"
+            },
+            "provide": {
+                "psr/http-client-implementation": "1.0"
+            },
+            "require-dev": {
+                "ext-curl": "*",
+                "php-http/client-integration-tests": "dev-phpunit8",
+                "phpunit/phpunit": "^8.5.5",
+                "psr/log": "^1.1"
+            },
+            "suggest": {
+                "ext-curl": "Required for CURL handler support",
+                "ext-intl": "Required for Internationalized Domain Name (IDN) support",
+                "psr/log": "Required for using the Log middleware"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "7.1-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "GuzzleHttp\\": "src/"
+                },
+                "files": [
+                    "src/functions_include.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Michael Dowling",
+                    "email": "mtdowling@gmail.com",
+                    "homepage": "https://github.com/mtdowling"
+                },
+                {
+                    "name": "Márk Sági-Kazár",
+                    "email": "mark.sagikazar@gmail.com",
+                    "homepage": "https://sagikazarmark.hu"
+                }
+            ],
+            "description": "Guzzle is a PHP HTTP client library",
+            "homepage": "http://guzzlephp.org/",
+            "keywords": [
+                "client",
+                "curl",
+                "framework",
+                "http",
+                "http client",
+                "psr-18",
+                "psr-7",
+                "rest",
+                "web service"
+            ],
+            "funding": [
+                {
+                    "url": "https://github.com/GrahamCampbell",
+                    "type": "github"
+                },
+                {
+                    "url": "https://github.com/Nyholm",
+                    "type": "github"
+                },
+                {
+                    "url": "https://github.com/alexeyshockov",
+                    "type": "github"
+                },
+                {
+                    "url": "https://github.com/gmponos",
+                    "type": "github"
+                }
+            ],
+            "time": "2020-09-22T09:10:04+00:00"
+        },
+        {
+            "name": "guzzlehttp/promises",
+            "version": "v1.3.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/guzzle/promises.git",
+                "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646",
+                "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.5.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^4.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.4-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "GuzzleHttp\\Promise\\": "src/"
+                },
+                "files": [
+                    "src/functions_include.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Michael Dowling",
+                    "email": "mtdowling@gmail.com",
+                    "homepage": "https://github.com/mtdowling"
+                }
+            ],
+            "description": "Guzzle promises library",
+            "keywords": [
+                "promise"
+            ],
+            "time": "2016-12-20T10:07:11+00:00"
+        },
+        {
+            "name": "guzzlehttp/psr7",
+            "version": "1.6.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/guzzle/psr7.git",
+                "reference": "239400de7a173fe9901b9ac7c06497751f00727a"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a",
+                "reference": "239400de7a173fe9901b9ac7c06497751f00727a",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.4.0",
+                "psr/http-message": "~1.0",
+                "ralouphie/getallheaders": "^2.0.5 || ^3.0.0"
+            },
+            "provide": {
+                "psr/http-message-implementation": "1.0"
+            },
+            "require-dev": {
+                "ext-zlib": "*",
+                "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8"
+            },
+            "suggest": {
+                "zendframework/zend-httphandlerrunner": "Emit PSR-7 responses"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.6-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "GuzzleHttp\\Psr7\\": "src/"
+                },
+                "files": [
+                    "src/functions_include.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Michael Dowling",
+                    "email": "mtdowling@gmail.com",
+                    "homepage": "https://github.com/mtdowling"
+                },
+                {
+                    "name": "Tobias Schultze",
+                    "homepage": "https://github.com/Tobion"
+                }
+            ],
+            "description": "PSR-7 message implementation that also provides common utility methods",
+            "keywords": [
+                "http",
+                "message",
+                "psr-7",
+                "request",
+                "response",
+                "stream",
+                "uri",
+                "url"
+            ],
+            "time": "2019-07-01T23:21:34+00:00"
+        },
+        {
+            "name": "monolog/monolog",
+            "version": "2.1.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/Seldaek/monolog.git",
+                "reference": "f9eee5cec93dfb313a38b6b288741e84e53f02d5"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/Seldaek/monolog/zipball/f9eee5cec93dfb313a38b6b288741e84e53f02d5",
+                "reference": "f9eee5cec93dfb313a38b6b288741e84e53f02d5",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2",
+                "psr/log": "^1.0.1"
+            },
+            "provide": {
+                "psr/log-implementation": "1.0.0"
+            },
+            "require-dev": {
+                "aws/aws-sdk-php": "^2.4.9 || ^3.0",
+                "doctrine/couchdb": "~1.0@dev",
+                "elasticsearch/elasticsearch": "^6.0",
+                "graylog2/gelf-php": "^1.4.2",
+                "php-amqplib/php-amqplib": "~2.4",
+                "php-console/php-console": "^3.1.3",
+                "php-parallel-lint/php-parallel-lint": "^1.0",
+                "phpspec/prophecy": "^1.6.1",
+                "phpunit/phpunit": "^8.5",
+                "predis/predis": "^1.1",
+                "rollbar/rollbar": "^1.3",
+                "ruflin/elastica": ">=0.90 <3.0",
+                "swiftmailer/swiftmailer": "^5.3|^6.0"
+            },
+            "suggest": {
+                "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
+                "doctrine/couchdb": "Allow sending log messages to a CouchDB server",
+                "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client",
+                "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
+                "ext-mbstring": "Allow to work properly with unicode symbols",
+                "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)",
+                "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
+                "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)",
+                "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
+                "php-console/php-console": "Allow sending log messages to Google Chrome",
+                "rollbar/rollbar": "Allow sending log messages to Rollbar",
+                "ruflin/elastica": "Allow sending log messages to an Elastic Search server"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Monolog\\": "src/Monolog"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Jordi Boggiano",
+                    "email": "j.boggiano@seld.be",
+                    "homepage": "http://seld.be"
+                }
+            ],
+            "description": "Sends your logs to files, sockets, inboxes, databases and various web services",
+            "homepage": "http://github.com/Seldaek/monolog",
+            "keywords": [
+                "log",
+                "logging",
+                "psr-3"
+            ],
+            "funding": [
+                {
+                    "url": "https://github.com/Seldaek",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/monolog/monolog",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2020-07-23T08:41:23+00:00"
+        },
+        {
+            "name": "phpseclib/phpseclib",
+            "version": "2.0.29",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpseclib/phpseclib.git",
+                "reference": "497856a8d997f640b4a516062f84228a772a48a8"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/497856a8d997f640b4a516062f84228a772a48a8",
+                "reference": "497856a8d997f640b4a516062f84228a772a48a8",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "require-dev": {
+                "phing/phing": "~2.7",
+                "phpunit/phpunit": "^4.8.35|^5.7|^6.0",
+                "squizlabs/php_codesniffer": "~2.0"
+            },
+            "suggest": {
+                "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.",
+                "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.",
+                "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.",
+                "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations."
+            },
+            "type": "library",
+            "autoload": {
+                "files": [
+                    "phpseclib/bootstrap.php"
+                ],
+                "psr-4": {
+                    "phpseclib\\": "phpseclib/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Jim Wigginton",
+                    "email": "terrafrost@php.net",
+                    "role": "Lead Developer"
+                },
+                {
+                    "name": "Patrick Monnerat",
+                    "email": "pm@datasphere.ch",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Andreas Fischer",
+                    "email": "bantu@phpbb.com",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Hans-Jürgen Petrich",
+                    "email": "petrich@tronic-media.com",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Graham Campbell",
+                    "email": "graham@alt-three.com",
+                    "role": "Developer"
+                }
+            ],
+            "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.",
+            "homepage": "http://phpseclib.sourceforge.net",
+            "keywords": [
+                "BigInteger",
+                "aes",
+                "asn.1",
+                "asn1",
+                "blowfish",
+                "crypto",
+                "cryptography",
+                "encryption",
+                "rsa",
+                "security",
+                "sftp",
+                "signature",
+                "signing",
+                "ssh",
+                "twofish",
+                "x.509",
+                "x509"
+            ],
+            "funding": [
+                {
+                    "url": "https://github.com/terrafrost",
+                    "type": "github"
+                },
+                {
+                    "url": "https://www.patreon.com/phpseclib",
+                    "type": "patreon"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2020-09-08T04:24:43+00:00"
+        },
+        {
+            "name": "psr/cache",
+            "version": "1.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/cache.git",
+                "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8",
+                "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Psr\\Cache\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "http://www.php-fig.org/"
+                }
+            ],
+            "description": "Common interface for caching libraries",
+            "keywords": [
+                "cache",
+                "psr",
+                "psr-6"
+            ],
+            "time": "2016-08-06T20:24:11+00:00"
+        },
+        {
+            "name": "psr/http-client",
+            "version": "1.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/http-client.git",
+                "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621",
+                "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.0 || ^8.0",
+                "psr/http-message": "^1.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Psr\\Http\\Client\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "http://www.php-fig.org/"
+                }
+            ],
+            "description": "Common interface for HTTP clients",
+            "homepage": "https://github.com/php-fig/http-client",
+            "keywords": [
+                "http",
+                "http-client",
+                "psr",
+                "psr-18"
+            ],
+            "time": "2020-06-29T06:28:15+00:00"
+        },
+        {
+            "name": "psr/http-message",
+            "version": "1.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/http-message.git",
+                "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
+                "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Psr\\Http\\Message\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "http://www.php-fig.org/"
+                }
+            ],
+            "description": "Common interface for HTTP messages",
+            "homepage": "https://github.com/php-fig/http-message",
+            "keywords": [
+                "http",
+                "http-message",
+                "psr",
+                "psr-7",
+                "request",
+                "response"
+            ],
+            "time": "2016-08-06T14:39:51+00:00"
+        },
+        {
+            "name": "psr/log",
+            "version": "1.1.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/log.git",
+                "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc",
+                "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.1.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Psr\\Log\\": "Psr/Log/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "http://www.php-fig.org/"
+                }
+            ],
+            "description": "Common interface for logging libraries",
+            "homepage": "https://github.com/php-fig/log",
+            "keywords": [
+                "log",
+                "psr",
+                "psr-3"
+            ],
+            "time": "2020-03-23T09:12:05+00:00"
+        },
+        {
+            "name": "ralouphie/getallheaders",
+            "version": "3.0.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/ralouphie/getallheaders.git",
+                "reference": "120b605dfeb996808c31b6477290a714d356e822"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
+                "reference": "120b605dfeb996808c31b6477290a714d356e822",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.6"
+            },
+            "require-dev": {
+                "php-coveralls/php-coveralls": "^2.1",
+                "phpunit/phpunit": "^5 || ^6.5"
+            },
+            "type": "library",
+            "autoload": {
+                "files": [
+                    "src/getallheaders.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Ralph Khattar",
+                    "email": "ralph.khattar@gmail.com"
+                }
+            ],
+            "description": "A polyfill for getallheaders.",
+            "time": "2019-03-08T08:55:37+00:00"
+        }
+    ],
+    "packages-dev": [],
+    "aliases": [],
+    "minimum-stability": "stable",
+    "stability-flags": [],
+    "prefer-stable": false,
+    "prefer-lowest": false,
+    "platform": [],
+    "platform-dev": [],
+    "plugin-api-version": "1.1.0"
+}
diff --git a/config.default.php b/config.default.php
new file mode 100644
index 0000000..7a5af80
--- /dev/null
+++ b/config.default.php
@@ -0,0 +1,31 @@
+<?php
+// App configuration
+
+$conf = [];
+
+// Nom de l'aplicatiu
+$conf['appName'] = 'App de traçabilitat DAFME';
+
+// Configuració de la base de dades
+$conf['db'] = [];
+$conf['db']['host'] = '';
+$conf['db']['database'] = '';
+$conf['db']['user'] = '';
+$conf['db']['password'] = '';
+
+// Enllaç al formulari de Google de l'FME
+$conf['formUrl'] = 'https://docs.google.com/forms/d/e/1FAIpQLSfT9o287VqLyhwR8LPdloAQWhuqCgA3NfdhgP5vb9_sVQHL-g/viewform';
+
+// Credencials de les APIs de Google (seguir pasos de
+// https://developers.google.com/identity/protocols/oauth2/web-server#creatingcred)
+$conf['goog'] = [];
+$conf['goog']['clientId'] = '';
+$conf['goog']['secret'] = '';
+
+// Lloc on s'allotja l'API (backend, és a dir, aquest programari)
+//   Exemple: https://covid-backend.fme.upc.edu/
+$conf['fullPath'] = '';
+
+// Lloc on s'allotja el web (frontend)
+//   Exemple: https://covid.fme.upc.edu/
+$conf['homeUrl'] = '';
diff --git a/core.php b/core.php
new file mode 100644
index 0000000..e58a7eb
--- /dev/null
+++ b/core.php
@@ -0,0 +1,22 @@
+<?php
+// core.php - El fitxer més elemental, estimat Watson
+
+// Get settings
+require(__DIR__.'/config.php');
+
+// Set composer
+require(__DIR__.'/vendor/autoload.php');
+
+// Set timezone and locale accordingly
+date_default_timezone_set('Europe/Madrid');
+
+// Connect to the DB
+$con = new PDO('mysql:host='.$conf['db']['host'].';dbname='.$conf['db']['database'].';charset=utf8mb4', $conf['db']['user'], $conf['db']['password']);
+
+// Session settings
+session_set_cookie_params([
+  'lifetime' => 0,
+  'path' => ($conf['path'] ?? '/'),
+  'httponly' => true
+]);
+session_start();
diff --git a/inc/API.php b/inc/API.php
new file mode 100644
index 0000000..0d5530e
--- /dev/null
+++ b/inc/API.php
@@ -0,0 +1,104 @@
+<?php
+namespace DAFME\Covid;
+
+class API {
+  private static function returnJSON($array) {
+    echo json_encode($array);
+  }
+
+  public static function returnError($errorMessage = 'Unexpected error') {
+    http_response_code(400);
+    self::returnJson([
+      'status' => 'error',
+      'errorMessage' =>  $errorMessage
+    ]);
+  }
+
+  public static function returnPayload($payload) {
+    self::returnJson([
+      'status' => 'ok',
+      'payload' => $payload
+    ]);
+  }
+
+  public static function returnOk() {
+    self::returnJson([
+      'status' => 'ok'
+    ]);
+  }
+
+  private static function checkSignInStatus() {
+    if (!Users::isSignedIn()) {
+      self::returnError('The user hasn\'t signed in.');
+      exit();
+    }    
+  }
+
+  public static function process($path) {
+    global $conf;
+
+    header('Content-Type: application/json');
+
+    if (isset($conf['frontendUrl']) && !empty($conf['frontendUrl']))
+      header('Access-Control-Allow-Origin: '.$conf['frontendUrl']);
+
+    $parts = explode('/', $path);
+    $method = $parts[0] ?? '';
+
+    switch ($method) {
+      case 'getAuthUrl':
+        $auth = new Auth();
+        self::returnPayload([
+          'url' => $auth->getAuthUrl()
+        ]);
+        break;
+
+      case 'isSignedIn':
+        $isSignedIn = \DAFME\Covid\Users::isSignedIn();
+        self::returnPayload([
+          'signedIn' => $isSignedIn
+        ]);
+        break;
+
+      case 'signOut':
+        \DAFME\Covid\Users::signOut();
+        self::returnOk();
+        break;
+
+      case 'getAllSubjects':
+        $subjects = Subjects::getAll();
+
+        if ($subjects === false)
+          self::returnError();
+
+        self::returnPayload([
+          'subjects' => $subjects
+        ]);
+        break;
+
+      case 'getUserSubjects':
+        self::checkSignInStatus();
+        // @TODO: Implement this method
+        break;
+
+      case 'setUserSubjects':
+        self::checkSignInStatus();
+        // @TODO: Implement this method
+        break;
+
+      case 'getClasses':
+        self::checkSignInStatus();
+        // @TODO: Implement this method
+        break;
+
+      case 'setClassState':
+        self::checkSignInStatus();
+        // @TODO: Handle this method
+        break;
+
+      default:
+        self::returnError('The method requested doesn\'t exist.');
+        break;
+    }
+  }
+}
diff --git a/inc/Auth.php b/inc/Auth.php
new file mode 100644
index 0000000..c0fc078
--- /dev/null
+++ b/inc/Auth.php
@@ -0,0 +1,59 @@
+<?php
+namespace DAFME\Covid;
+
+class Auth {
+  private $client;
+
+  public function __construct() {
+    global $conf;
+    $this->client = new \Google_Client();
+    $this->client->setApplicationName = 'dafme-covid-tracability-backend';
+    $this->client->setClientId($conf['goog']['clientId']);
+    $this->client->setClientSecret($conf['goog']['secret']);
+    $this->client->addScope('https://www.googleapis.com/auth/userinfo.email');
+    $this->client->setRedirectUri($conf['fullPath'].'oauth2callback.php');
+    $this->client->setAccessType('online');
+  }
+
+  public function getAuthUrl() {
+    return $this->client->createAuthUrl();
+  }
+
+  public function handleCallback() {
+    global $_GET, $con;
+    if (isset($_GET['error']) || !isset($_GET['code'])) return 1;
+
+    $accessToken = null;
+
+    try {
+      $accessToken = $this->client->fetchAccessTokenWithAuthCode($_GET['code']);
+    } catch (\Exception $exception) {
+      return 2;
+    }
+
+    $id = $this->client->verifyIdToken();
+    if ($id === false)
+      return 3;
+
+    if (!isset($id['sub']) || !isset($id['email']) || !isset($id['email_verified']))
+      return 4;
+
+    if ($id['email_verified'] === false)
+      return 5;
+
+    $sub = $id['sub'];
+    $email = $id['email'];
+
+    if (preg_match('/upc.edu$/', $id['email']) !== 1)
+      return 6;
+
+    if (!Users::signIn($sub, $email))
+      return 7;
+
+    return 0;
+  }
+
+  public function setAccessToken($token) {
+    $this->client->setAccessToken($token);
+  }
+}
diff --git a/inc/Subjects.php b/inc/Subjects.php
new file mode 100644
index 0000000..4d2cfdb
--- /dev/null
+++ b/inc/Subjects.php
@@ -0,0 +1,14 @@
+<?php
+namespace DAFME\Covid;
+
+class Subjects {
+  public static function getAll() {
+    global $con;
+    $query = $con->prepare('SELECT * FROM subjects');
+
+    if (!$query->execute())
+      return false;
+
+    return $query->fetchAll(\PDO::FETCH_ASSOC);
+  }
+}
diff --git a/inc/Users.php b/inc/Users.php
new file mode 100644
index 0000000..7679e04
--- /dev/null
+++ b/inc/Users.php
@@ -0,0 +1,51 @@
+<?php
+namespace DAFME\Covid;
+
+class Users {
+  private static function getUserId($sub) {
+    global $con;
+    $query = $con->prepare('SELECT id FROM users WHERE sub = ?');
+    if (!$query->execute([$sub]))
+      return false;
+
+    if ($query->rowCount() < 1)
+      return false;
+
+    $row = $query->fetch();
+    return $row['id'] ?? false;
+  }
+
+  public static function add($sub, $email) {
+    global $con;
+    $query = $con->prepare('INSERT INTO users (sub, email) VALUES (?, ?)');
+    if (!$query->execute([$sub, $email]))
+      return false;
+
+    return $con->lastInsertId();
+  }
+
+  public static function signIn($sub, $email) {
+    global $_SESSION;
+
+    $userId = self::getUserId($sub);
+
+    if ($userId === false)
+      $userId = self::add($sub, $email);
+
+    if ($userId === false)
+      return false;
+
+    $_SESSION['userId'] = $userId;
+    return true;
+  }
+
+  public static function signOut() {
+    global $_SESSION;
+    unset($_SESSION['userId']);
+  }
+
+  public static function isSignedIn() {
+    global $_SESSION;
+    return isset($_SESSION['userId']);
+  }
+}
diff --git a/oauth2callback.php b/oauth2callback.php
new file mode 100644
index 0000000..bf059bd
--- /dev/null
+++ b/oauth2callback.php
@@ -0,0 +1,33 @@
+<?php
+// Oauth2 callback, which is meant to complete the sign in process
+
+require_once('core.php');
+header('Content-Type: text/plain');
+
+$auth = new DAFME\Covid\Auth();
+$returnCode = $auth->handleCallback();
+
+switch ($returnCode) {
+  case 0:
+    header('Location: '.$conf['frontendUrl']);
+    break;
+
+  case 1:
+    echo 'Hi ha hagut un problema iniciant sessió. Probablement has denegat l\'inici de sessió.';
+    break;
+
+  case 2:
+  case 3:
+  case 4:
+  case 7:
+    echo 'Hi ha hagut un problema iniciant sessió. Sisplau prova de fer-ho de nou.';
+    break;
+
+  case 5:
+    echo 'El correu electrònic del teu compte no està verificat. Verifica\'l i torna a iniciar sessió';
+    break;
+
+  case 6:
+    echo 'El teu compte no pertany a la UPC. Sisplau, inicia sessió amb el teu compte de Google de la UPC.';
+    break;
+}
diff --git a/utils/db_structure.sql b/utils/db_structure.sql
new file mode 100644
index 0000000..cedf7a6
--- /dev/null
+++ b/utils/db_structure.sql
@@ -0,0 +1,24 @@
+-- SQL sentences to set up all the DB tables
+
+CREATE TABLE users (
+  id INT NOT NULL AUTO_INCREMENT,
+  PRIMARY KEY(id),
+  sub VARCHAR(255) NOT NULL UNIQUE,
+  email VARCHAR(320)
+);
+
+CREATE TABLE subjects (
+  id INT NOT NULL AUTO_INCREMENT,
+  PRIMARY KEY(id),
+  friendly_name VARCHAR(100) NOT NULL UNIQUE, -- Nom que es mostra al web
+  calendar_name VARCHAR(100) NOT NULL -- Nom al calendari de la FME
+);
+
+CREATE TABLE user_subjects (
+  id INT NOT NULL AUTO_INCREMENT,
+  PRIMARY KEY(id),
+  user_id INT NOT NULL,
+  subject_id INT NOT NULL
+);
+
+-- @TODO: Add form completion log table