.. External Manuals tutorial
.. Author: Hossein Safavi, Benjamin Vandendriessche

.. STATUS: production

.. _external_man:

################
External Manuals
################

The following guidelines should be followed when preparing **User Manuals** for external use, in order to:

* Use appropriate templates and generate a landing page
* Activate user access control
* Deploy the manual

.. rubric:: Quick Navigation
.. contents::
   :local:
   :depth: 2

----

************************
Templates & Landing Page
************************

Manuals meant to be deployed as separate units for external users should live in separate branches of the :doc:`Byteflies Documentation <getting_started>`. A **template branch** (``external_template_manual``) is available (see the :ref:`instructions here <pullreq>` to update your documentation *fork*). Branch-off from the template branch as follows:

.. code-block:: bash

   git checkout -b external_insert-manual-name_manual external_template_manual

.. warning:: Never merge an ``external`` branch into master!

The root of the Sphinx file structure is organized as follows:

 * ``index.rst``: contains the **landing page** elements; only the ``toctree`` title should be updated
 * ``manual.rst``: copy the **content** from the relevant *Tech Team* Manual to this file
 * ``images`` (directory): copy any **figures** referenced in ``manuals.rst`` to this directory

The main version of every User Manual should be located in the ``manuals`` document category. Do not maintain different versions in the ``external_`` branch. The branch's only purpose is to ensure consistent deployment and hosting. If you need to make changes in the manual, do so first, publish your changes to the production documentation, and finally copy the manual to the ``manual.rst`` file in the relevant ``external_`` branch.

Next, generate the HTML page for the branch. The Sphinx build process will generate **circular reference warnings**. This is to be expected as the content will be rendered as a single page. Please do not remove the ``EXTERNAL`` tags. Continue with :ref:`the next section <deploy>` to publish the manual.

.. hint:: Do a make clean before copying the HTML data to the server, as images from other documents may linger.

----

.. _deploy:

******
Deploy
******

Currently, the public manuals can be deployed to an AWS hosted web-server running in a ``t2.micro`` instance.

Connecting to the Server
========================

In order to complete the steps in this section, you must have access to the *private key* associated with this instance labeled ``byteflies_docserver.pem``. To copy a file to the server you can issue the following command in your shell:

.. code-block:: bash

   scp -i "byteflies_docserver.pem" you_local_file \
        ubuntu@docs.byteflies.be:directory_on_server/remote_file_name

Publishing New Manuals
======================

All manuals are served from ``/var/www/html``. Let's say we wish to publish a new manual titled ``The Byteflies Way of Life`` which has its associated files locally in ``~/byteflies_life``. Then we can take the following steps:

.. code-block:: bash

   scp -i "byteflies_docserver.pem" -rp ~/byteflies_life \
        ubuntu@docs.byteflies.be:~/byteflies_life

Then you can connect through SSH:

.. code-block:: bash

   ssh -i "byteflies_docserver.pem" ubuntu@docs.byteflies.be

Copy your files over to the nginx html directory:

.. code-block:: bash

   sudo mv ~/byteflies_life /var/www/html/byteflies_life
   sudo chmod -R 555 /var/www/html/byteflies_life

The next step will be to modify the nginx site config. The file is located in ``/etc/nginx/sites-enabled/default``.
For each publication, we will make an additional entry to this file. The start of the file may look as follows:

.. code-block:: bash

        server_tokens off;

        server {
                listen 80 default_server;
                listen [::]:80 default_server;
                server_name docs.byteflies.be;
                return 301 https://$server_name$request_uri;
        }

        server {
                listen 443 ssl default_server;
                listen [::]:443 ssl default_server;

                include snippets/ssl-docs.byteflies.be.conf;
                include snippets/ssl-params.conf;

                root /var/www/html;

                index index.html index.htm index.nginx-debian.html;

                server_name _;

                location / {
                        return 301 http://www.byteflies.com;
                        #try_files $uri =404;
                }

                location ~ /.well-known {
                        allow all;
                }

                location /cwru {
                        alias /var/www/html/cwru;
                        # First attempt to serve request as file, then
                        # as directory, then fall back to displaying a 404.
                        try_files $uri $uri/ =404;
                        auth_basic "Restricted Content";
                        auth_basic_user_file /etc/nginx/.htpasswd-cwru;
                }


.. warning:: The first server block is meant to redirect users from ``http`` to ``https`` with a free SSL certificate from **letsencrypt** so it should remain untouched.

.. note:: In the second server block, you can see that accessing the root of the server (i.e. ``http://docs.byteflies.be``) automatically redirects to the main Byteflies website.

The snippets included at the start of the server block set the proper encryption parameters. The key part that must be
included for each new site is the following (in this case adapted to our example):

.. code-block:: bash

    server {
            ...

            location /byteflies_life {
                    alias /var/www/html/byteflies_life;
                    # First attempt to serve request as file, then
                    # as directory, then fall back to displaying a 404.
                    try_files $uri $uri/ =404;
            }
            ...
    }

Finally, you can apply this new configuration by running: ``sudo service nginx restart``.

.. hint:: Before restarting the service or in case of error, you can execute ``sudo nginx -t`` which will check the syntax of the configuration file. It is recommended that you run this step before attempting to restart the service.

User Access Control
===================

If you wish to restrict access to a published manual to a specific set of users, you can do so quite easily. Say you wish to restrict the manual ``The Byteflies Way of Life`` with a specific username and password, you would issue the following commands:

.. code-block:: bash

    sudo htpasswd -c /etc/nginx/.htpasswd-byteflies_life my_new_user

You will be asked to supply a password for the user. The username and hashed password will be stored in
``/etc/nginx/.htpasswd-byteflies_life``. You can repeat this process for any additional credentials that you want to create.

.. warning:: For each new manual, make sure to use the **new password file** so that authentication can be done separately (with different credentials) for each publication.

Then, you must adjust the relevant entry in the nginx config as follows:

.. code-block:: bash
   :emphasize-lines: 9,10

    server {
            ...

            location /byteflies_life {
                    alias /var/www/html/byteflies_life;
                    # First attempt to serve request as file, then
                    # as directory, then fall back to displaying a 404.
                    try_files $uri $uri/ =404;
                    auth_basic "Restricted Content";
                    auth_basic_user_file /etc/nginx/.htpasswd-byteflies_life;
            }
            ...
    }

Finally run: ``sudo service nginx restart``.
