Install
=======


Installation on Ubuntu 22
--------------------------------

Follow below to customize your installation.


Install PostgreSQL with PostGIS
------------------------------------------

QuartzMap requires PostgreSQL with PostGIS.

If you do not already have it installed, install it now.

.. code-block:: bash

	apt -y install postgresql postgresql-contrib postgis


Install Prerequisties
------------------------------------------

.. code-block:: bash

	apt-get -y install apache2 libapache2-mod-php php-{pgsql,zip,gd,simplexml} proftpd libapache2-mod-fcgid postfix python3-certbot-apache


Create the PostGIS Database
--------------------------------

.. code-block:: sql

	CREATE USER quartz with password 'SuperSecret';

	CREATE DATABASE quartz with OWNER quartz;


Create the Database Objects
--------------------------------

.. code-block:: sql

   CREATE TYPE public.userlevel AS ENUM ('Admin', 'User');

   CREATE TABLE public.user (	id SERIAL PRIMARY KEY,
   name character varying(250),
   email character varying(250),
   password character varying(255),
   ftp_user character varying(250),
   accesslevel public.userlevel,
   owner_id integer NOT NULL	REFERENCES public.user(id),
   UNIQUE(email)
   );

   CREATE TABLE public.access_groups (	id SERIAL PRIMARY KEY,
   name character varying(255) NOT NULL,
   owner_id integer NOT NULL	REFERENCES public.user(id)
   );

   CREATE TABLE public.user_access (	id SERIAL PRIMARY KEY,
   user_id integer NOT NULL REFERENCES public.user(id),
   access_group_id integer NOT NULL	REFERENCES public.access_groups(id),
   UNIQUE(user_id, access_group_id)
   );

   CREATE TABLE public.map ( id SERIAL PRIMARY KEY,
   name character varying(50) NOT NULL,
   description character varying(50) NOT NULL,
   is_public BOOLEAN DEFAULT false,
   owner_id integer NOT NULL REFERENCES public.user(id)
   );

   CREATE TABLE public.map_access ( id SERIAL PRIMARY KEY,
   map_id integer NOT NULL REFERENCES public.map(id),
   access_group_id integer NOT NULL REFERENCES public.access_groups(id),
   UNIQUE(map_id, access_group_id)
   );

   CREATE TABLE public.permalink (	id SERIAL PRIMARY KEY,
   description character varying(255),
   query character varying(255),
   map_id integer NOT NULL	REFERENCES public.map(id),
   created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
   expires TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP + interval '1 hour',
   visits  integer NOT NULL DEFAULT 0,
   visits_limit integer NOT NULL DEFAULT 1,
   hash character varying(36) NOT NULL,
   owner_id integer NOT NULL	REFERENCES public.user(id)
   );

   CREATE TABLE public.signup ( id SERIAL PRIMARY KEY,
   name character varying(250),
   email character varying(250),
   password character varying(250),
   verify character varying(250),
   UNIQUE(email)
   );



Install QGIS Server
-----------------------------

To advertise WMS, WFS, and WTMS, install QGIS server.



.. code-block:: bash

   RELEASE=$(lsb_release -cs)
   wget --no-check-certificate --quiet -O /etc/apt/keyrings/qgis-archive-keyring.gpg https://download.qgis.org/downloads/qgis-archive-keyring.gpg

   cat >>/etc/apt/sources.list.d/qgis.sources <<CAT_EOF
   Types: deb deb-src
   URIs: https://qgis.org/ubuntu
   Suites: ${RELEASE}
   Architectures: amd64
   Components: main
   Signed-By: /etc/apt/keyrings/qgis-archive-keyring.gpg
   CAT_EOF

   apt-get update -y || true
   apt-get install -y qgis-server
	
   if [ -d /etc/logrotate.d ]; then
   cat >/etc/logrotate.d/qgisserver <<CAT_EOF
   /var/log/qgisserver.log {
	su www-data www-data
	size 100M
	notifempty
	missingok
	rotate 3
	daily
	compress
	create 660 www-data www-data
   }
   CAT_EOF
	fi
	
	touch /var/log/qgisserver.log
	chown www-data:www-data /var/log/qgisserver.log



Configure ProFTPD
----------------------------

Configure ProFTPD to jail users to FTP directories

.. code-block:: bash

   sed -i.save '
      s/#DefaultRoot~/DefaultRoot ~/
      s/# RequireValidShelloff/RequireValidShell off/' /etc/proftpd/proftpd.conf

Restart ProFTPD for changes to take effect.

.. code-block:: bash
      systemctl enable proftpd
      systemctl restart proftpd


Configure Apache
----------------------------

.. code-block:: bash

   a2enmod ssl headers expires fcgid cgi
   
   cp installer/apache2.conf /etc/apache2/sites-available/default-ssl.conf

   # Below is required for Certbot to provision SSL

   for f in 000-default default-ssl; do
	   sed -i.save "s/#ServerName example.com/#ServerName ${HNAME}/" /etc/apache2/sites-available/${f}.conf
   done

   a2ensite 000-default default-ssl
   systemctl reload apache2

Request certificate from Let's Encrypt:

   certbot --apache --agree-tos --email hostmaster@${HNAME} --no-eff-email -d ${HNAME}


Create Data and Cache Directories
----------------------------

Set the DATA_DIR outside of public directories

.. code-block:: bash

   mkdir -p "${APPS_DIR}"
   mkdir -p "${CACHE_DIR}"
   mkdir -p "${DATA_DIR}"


Grant Apache permissions
---------------------------- 

.. code-block:: bash

   chown -R www-data:www-data "${APPS_DIR}"
   chown -R www-data:www-data "${CACHE_DIR}"
   chown -R www-data:www-data "${DATA_DIR}"


   cp -r . /var/www/html/
   chown -R www-data:www-data /var/www/html
   rm -rf /var/www/html/installer

Restart Apache for changes to take effect

.. code-block:: bash

   systemctl restart apache2


Create Groups and Permissions
---------------------------- 

.. code-block:: bash

   # create group for all FTP users
   groupadd qatusers

   create_ftp_user

   # install ftp user creation script
   for f in update; do
	   cp installer/${f}_ftp_user.sh /usr/local/bin/
	   chown www-data:www-data /usr/local/bin/${f}_ftp_user.sh
	   chmod 0550 /usr/local/bin/${f}_ftp_user.sh
   done

   cat >/etc/sudoers.d/q2w <<CAT_EOF
   www-data ALL = NOPASSWD: /usr/local/bin/update_ftp_user.sh
   CAT_EOF
   echo -e "postgres and other passwords are saved in /root/auth.txt file"


Create incl/const.php file
---------------------------------------

Copy the incl/const.php.dist file



.. code-block:: php

   cat >admin/incl/const.php <<CAT_EOF
   <?php
   define("DB_HOST", "localhost");
   define("DB_NAME", "${APP_DB}");
   define("DB_USER", "${APP_DB}");
   define("DB_PASS", "${APP_DB_PASS}");
   define("DB_PORT", 5432);
   define("DB_SCMA", 'public');
   define("APPS_DIR", "${APPS_DIR}");
   define("CACHE_DIR", "${CACHE_DIR}");
   define("DATA_DIR", "${DATA_DIR}");
   define("SUPER_ADMIN_ID", 1);
   define("SESS_USR_KEY", 'q2w_user');
   ?>
   CAT_EOF



