#!/bin/bash -x

# source the debconf library
if [ -e "/usr/share/debconf/confmodule" ]; then
    . /usr/share/debconf/confmodule
else
    echo "debconf must be installed. Exiting."
    exit 1
fi


TOMCAT=tomcat9
OLD_TOMCAT=tomcat7
TOMCAT_USER=tomcat
TOMCAT_HOME=/var/lib/${TOMCAT}
APACHE_CONF=/etc/apache2
JK_CONF=portal_jk.conf

PG=postgresql
PG_USER=postgres
if [ -e "/etc/postgresql/14/main" ]; then
    PG_CONF=/etc/postgresql/14/main
    PG_DATA=/var/lib/postgresql/14/main
else
    PG_CONF=/etc/postgresql/10/main
    PG_DATA=/var/lib/postgresql/10/main
fi
DB_NAME=oauth
DB_USER=oa4mp
DB_PASS=oa4mp

# Reminder: don't echo to stdout, it messes up debconf

D1_LOG_DIR=/var/log/dataone
if [ ! -e ${D1_LOG_DIR} ]; then
    mkdir -p ${D1_LOG_DIR}
fi
chown -R ${TOMCAT_USER}:${TOMCAT_USER} ${D1_LOG_DIR}

# functions to echo to STDERR or the install log instead of STDOUT
logError () {
    echo -e "$@" 1>&2
}

log () {
    now=$(date "+%Y-%m-%d %H:%M:%S %Z: ")
    echo -e "${now}$@" >> ${D1_LOG_DIR}/dataone-cn-os-core.install.log
}

LONG_DATE=`date +%Y%m%d%H%M%S`

db_get dataone-cn-os-core/cn.router.hostname
HOST_NAME=${RET}
KEY_DIR=/etc/letsencrypt/live/${HOST_NAME}
CERT_DIR=/etc/letsencrypt/live/${HOST_NAME}

HAZELCAST_PORT=5703

SOURCE_DIR=/usr/share/portal
SCRIPT_DIR=${SOURCE_DIR}/debian

D1_CONF=/etc/dataone

VAR_DATAONE=/var/dataone


###############################################################################
# Set up hazelcast configuration
###############################################################################

HAZELCAST_INTERFACE=""
SPACER="        "
db_get dataone-cn-os-core/cn.iplist
IPLIST=(${RET})
for ip in ${IPLIST[@]}
do
    IP_XML_NODE="<interface>${ip}<\/interface>"
    HAZELCAST_INTERFACE=${HAZELCAST_INTERFACE}${IP_XML_NODE}'\n'${SPACER}
done

## replace the string <interface>127.0.0.1</interface> with the environment's iplist
## <interface>127.0.0.1</interface>
sed -i.bak --regexp-extended "s/<interface>127\.0\.0\.1<\/interface>/${HAZELCAST_INTERFACE}/;" ${D1_CONF}/portal/hazelcast.xml

## open up the correct port for hazelcast
for ip in ${IPLIST[@]}
do
    log "Adding 'ufw allow to any port ${HAZELCAST_PORT} from ${IP_ADDRESS}' rule"
    ufw allow to any port ${HAZELCAST_PORT} from ${ip}
	# open postgres port for this IP
	log "Adding 'ufw allow to any port 5432 from ${ip}' rule"	  
	ufw allow to any port 5432 from ${ip}
done

###############################################################################
# Install portal war file
###############################################################################

## Stop tomcat
log "Stopping Tomcat"
systemctl stop ${TOMCAT}

## backup the old war file
if [ -e ${TOMCAT_HOME}/webapps/portal.war.current ]
then
  log "Backing up ${TOMCAT_HOME}/webapps/portal.war.current to ${TOMCAT_HOME}/webapps/portal.war.${LONG_DATE}"
  mv ${TOMCAT_HOME}/webapps/portal.war.current ${TOMCAT_HOME}/webapps/portal.war.${LONG_DATE}
fi  

## remove the portal application directory
if [ -d ${TOMCAT_HOME}/webapps/portal ]
then
  log "Removing the old portal application directories"
  rm -rf ${TOMCAT_HOME}/webapps/portal
fi 

## copy the new war file into the webapps directory
log copying new portal.war file to ${TOMCAT_HOME}/webapps/portal.war
cp ${SOURCE_DIR}/portal.war ${TOMCAT_HOME}/webapps/portal.war

## expand the war file
CURR_DIR=`pwd`

## make portal directory and extract portal.war into it.
log "Making portal application directory: ${TOMCAT_HOME}/webapps/portal"
mkdir ${TOMCAT_HOME}/webapps/portal
cd ${TOMCAT_HOME}/webapps/portal

log "extracting portal.war into ${TOMCAT_HOME}/webapps/portal"
jar -xvf ${TOMCAT_HOME}/webapps/portal.war > /dev/null

mv ${TOMCAT_HOME}/webapps/portal.war ${TOMCAT_HOME}/webapps/portal.war.current

cp ${SOURCE_DIR}/debian/log4j.properties ${TOMCAT_HOME}/webapps/portal/WEB-INF/classes
chown -R ${TOMCAT_USER}:${TOMCAT_USER} ${TOMCAT_HOME}/webapps/portal
log cd to $CURR_DIR
cd $CURR_DIR

## replace the CN URL in the web.xml file to use a hostname as found by issuing a hostname -f
## replace the CILogon callback URLs for the portal in the config file

db_get dataone-cn-os-core/cn.router.hostname
HOSTNAME=$RET

if [ "$HOSTNAME" != "" ]
then
	sed -i.bak  's/\(<param-value>https:\/\/\)cn\.dataone\.org/\1'${HOSTNAME}'/;' ${TOMCAT_HOME}/webapps/portal/WEB-INF/web.xml
	sed -i.bak  's/\(<callbackUri>https:\/\/\)cn\.dataone\.org/\1'${HOSTNAME}'/;' ${TOMCAT_HOME}/webapps/portal/WEB-INF/client.xml
else
	log "HOSTNAME (cn.router.hostname) cannot be set in ${TOMCAT_HOME}/webapps/portal/WEB-INF/web.xml or ${TOMCAT_HOME}/webapps/portal/WEB-INF/client.xml"
fi

############# replace the java key store password in the client.xml file ######################

#first we will try to read it from the dataone-cn-os-core/cn.keystore.password
db_get dataone-cn-os-core/cn.keystore.password

#if it is blank, we will read it from the input form from the template
JAVA_KEYSTORE_PASSWORD=$RET
if [ "$JAVA_KEYSTORE_PASSWORD" = "" ] ;then
    db_get dataone-cn-portal/cn.keystore.password
    JAVA_KEYSTORE_PASSWORD=$RET
    db_reset dataone-cn-portal/cn.keystore.password
fi
sed -i.bak  's/\(password=\"\)JAVA_KEYSTORE_PASSWORD/\1'${JAVA_KEYSTORE_PASSWORD}'/;' ${TOMCAT_HOME}/webapps/portal/WEB-INF/client.xml



###########replace the "OLD_TOMCAT" by "TOMCAT" on the web.xml, client.xml and portal.properties###################
sed -i.bak  's/\(<param-value>\/var\/lib\/\)'${OLD_TOMCAT}'/\1'${TOMCAT}'/;' ${TOMCAT_HOME}/webapps/portal/WEB-INF/web.xml
sed -i.bak  's/\(\/var\/log\/\)'${OLD_TOMCAT}'/\1'${TOMCAT}'/;' ${TOMCAT_HOME}/webapps/portal/WEB-INF/client.xml
sed -i.bak  's/\(\/var\/lib\/\)'${OLD_TOMCAT}'/\1'${TOMCAT}'/;' ${TOMCAT_HOME}/webapps/portal/WEB-INF/portal.properties

## switched postgresql host property to localhost (redmine 7943) so this config is not needed anymore
## configure to hit only a single PG instance - defualt to first in ip list
#for ip in ${IPLIST[@]}
#do
#    PG_HOST=${ip}
#   	sed -i.bak  's/\(host="\)cn\.dataone\.org/\1'${PG_HOST}'/;' ${TOMCAT_HOME}/webapps/portal/WEB-INF/client.xml
#    break # just use the first
#done

## configure the CILogon skin, default to PRODUCTION
MYPROXY_ID=myproxy:oa4mp,2012:/client/42afd3477fac2eb9bfe99d0b409f6cc6
CILOGON_SKIN=DataONE
db_get dataone-cn-os-core/cn.context.label
CONTEXT_LABEL=$RET
if [[ "${CONTEXT_LABEL}" == "DEV" ]]; then
	CILOGON_SKIN=DataONEDev
	MYPROXY_ID=myproxy:oa4mp,2012:/client/24a10c2cd8bda4e6b5cf244ab7532b2
fi
if [[ "${CONTEXT_LABEL}" == "DEV2" ]]; then
	CILOGON_SKIN=DataONEDev2
	MYPROXY_ID=myproxy:oa4mp,2012:/client/24a10c2cd8bda4e6b5cf244ab7532b2
fi
if [[ "${CONTEXT_LABEL}" == "STAGE" ]]; then
	CILOGON_SKIN=DataONEStage
	MYPROXY_ID=myproxy:oa4mp,2012:/client/7a4c0539fc9eb5c066f1619d73f35c37
fi
if [[ "${CONTEXT_LABEL}" == "STAGE2" ]]; then
	CILOGON_SKIN=DataONEStage2
	MYPROXY_ID=myproxy:oa4mp,2012:/client/3f5b88459d880f550e31f485458fc459
fi
if [[ "${CONTEXT_LABEL}" == "SANDBOX" ]]; then
	CILOGON_SKIN=DataONESandbox
	MYPROXY_ID=myproxy:oa4mp,2012:/client/2f533133f3e70b26e60492479aa8f0ef
fi
if [[ "${CONTEXT_LABEL}" == "SANDBOX2" ]]; then
	CILOGON_SKIN=DataONESandbox2
	MYPROXY_ID=myproxy:oa4mp,2012:/client/66a303882b6e4bec1e91cbf2ccda1e86
fi

## replace in the config file
sed -i.bak  's/\(<skin>\)DataONE/\1'${CILOGON_SKIN}'/;' ${TOMCAT_HOME}/webapps/portal/WEB-INF/client.xml

## set MyProxy id in the config file
MYPROXY_ID=${MYPROXY_ID//\//\\\/}
sed -i.bak  's/\(<id>\)MYPROXY_ID/\1'${MYPROXY_ID}'/;' ${TOMCAT_HOME}/webapps/portal/WEB-INF/client.xml

## set the CILogon server correctly (they only have production now)
CILOGON_SERVER=cilogon.org
if [[ "${CONTEXT_LABEL}" == "PRODUCTION" ]]; then
	CILOGON_SERVER=cilogon.org
fi
sed -i.bak  's/\(<serviceUri>https:\/\/\)cilogon\.org/\1'${CILOGON_SERVER}'/;' ${TOMCAT_HOME}/webapps/portal/WEB-INF/client.xml

## set up the MyProxy certificates
# get the private key
db_get dataone-cn-os-core/cn.server.privatekey.filename
KEY_FILENAME=${RET}
KEY_FILE=${KEY_DIR}'/'${KEY_FILENAME}

PK8_KEY_FILE=${KEY_FILE}.pk8
# make PK8 format for private key
openssl pkcs8 -topk8 -in ${KEY_FILE} -nocrypt -out ${PK8_KEY_FILE}
chown ${TOMCAT_USER}:ssl-cert ${PK8_KEY_FILE}
chmod 0650 ${PK8_KEY_FILE}

# get the correct public key (NOT the cert) for the env
db_get dataone-cn-os-core/cn.server.publiccert.filename
SERVER_CERT_FILENAME=${RET}
PUBLIC_SERVER_CERT=${CERT_DIR}'/'${SERVER_CERT_FILENAME}

PUBLIC_KEY_FILE=${PUBLIC_SERVER_CERT}.pk8publickey
openssl x509 -in ${PUBLIC_SERVER_CERT} -pubkey -noout > ${PUBLIC_KEY_FILE}
# set these in the configuration
PK8_KEY_FILE=${PK8_KEY_FILE//\//\\\/}
sed -i.bak  's/\(<privateKeyFile>\)PRIVATE_KEY_PATH/\1'${PK8_KEY_FILE}'/;' ${TOMCAT_HOME}/webapps/portal/WEB-INF/client.xml
PUBLIC_KEY_FILE=${PUBLIC_KEY_FILE//\//\\\/}
sed -i.bak  's/\(<publicKeyFile>\)PUBLIC_KEY_PATH/\1'${PUBLIC_KEY_FILE}'/;' ${TOMCAT_HOME}/webapps/portal/WEB-INF/client.xml

## configure the portal to use public cert and private key for token generation/verification
PUBLIC_SERVER_CERT_ESC=${PUBLIC_SERVER_CERT//\//\\\/}
KEY_FILE_ESC=${KEY_FILE//\//\\\/}
sed -i.bak --regexp-extended  "s/(cn\.server\.publiccert\.filename=).*/\1${PUBLIC_SERVER_CERT_ESC}/;" ${TOMCAT_HOME}/webapps/portal/WEB-INF/portal.properties
sed -i.bak --regexp-extended  "s/(cn\.server\.privatekey\.filename=).*/\1${KEY_FILE_ESC}/;" ${TOMCAT_HOME}/webapps/portal/WEB-INF/portal.properties

## configure the portal to use ORCID API credentials
db_get dataone-cn-portal/orcid.client.id
ORCID_CLIENT_ID=${RET}
ORCID_CLIENT_ID_ESC=${ORCID_CLIENT_ID//\//\\\/}
sed -i.bak --regexp-extended  "s/(orcid\.client\.id=).*/\1${ORCID_CLIENT_ID_ESC}/;" ${TOMCAT_HOME}/webapps/portal/WEB-INF/portal.properties

db_get dataone-cn-portal/orcid.client.secret
ORCID_CLIENT_SECRET=${RET}
ORCID_CLIENT_SECRET_ESC=${ORCID_CLIENT_SECRET//\//\\\/}
sed -i.bak --regexp-extended  "s/(orcid\.client\.secret=).*/\1${ORCID_CLIENT_SECRET_ESC}/;" ${TOMCAT_HOME}/webapps/portal/WEB-INF/portal.properties

db_reset dataone-cn-portal/orcid.client.id  # clear the cached orcid id
db_reset dataone-cn-portal/orcid.client.secret  # clear the cached orcid secret

## make client.xml and portal.property and backup file only readable by the owner
chmod 600 ${TOMCAT_HOME}/webapps/portal/WEB-INF/client.xml*
chmod 600 ${TOMCAT_HOME}/webapps/portal/WEB-INF/portal.properties*

####################################################################################
# Create the /var/dataone/portal/storage directory as the asset file system storage
####################################################################################
if [ ! -d ${VAR_DATAONE} ]; then
	mkdir ${VAR_DATAONE}
fi 

if [ ! -d ${VAR_DATAONE}/portal ]; then
  mkdir ${VAR_DATAONE}/portal
  chown ${TOMCAT_USER}:${TOMCAT_USER} ${VAR_DATAONE}/portal
else 
  chown -R ${TOMCAT_USER}:${TOMCAT_USER} ${VAR_DATAONE}/portal
fi 

if [ ! -d ${VAR_DATAONE}/portal/storage ]; then
  mkdir ${VAR_DATAONE}/portal/storage
  chown ${TOMCAT_USER}:${TOMCAT_USER} ${VAR_DATAONE}/portal/storage
  chmod 700 ${VAR_DATAONE}/portal/storage
  setfacl -d -m u::rwx ${VAR_DATAONE}/portal/storage
fi

###############################################################################
# Configure Tomcat
###############################################################################

# Configure the context file
log "Copying ${SCRIPT_DIR}/portal.xml to ${TOMCAT_HOME}/conf/Catalina/localhost/"
cp ${SCRIPT_DIR}/portal.xml ${TOMCAT_HOME}/conf/Catalina/localhost/

# Add permissions needed by portal
log "Copying ${SCRIPT_DIR}/56portal.policy to ${TOMCAT_HOME}/conf/policy.d/"
cp ${SCRIPT_DIR}/56portal.policy ${TOMCAT_HOME}/conf/policy.d/

###############################################################################
# Configure Apache
###############################################################################

## Stop apache
log "Stopping Apache"
/etc/init.d/apache2 stop

## copy in jk mount configuration file
if [ -e ${APACHE_CONF}/jk_mount/${JK_CONF} ]
then 
  JK_DIFF=`diff ${SCRIPT_DIR}/${JK_CONF} ${APACHE_CONF}/jk_mount/${JK_CONF}`
  if [ "${JK_DIFF}" != "" ]
  then
    log "Backing up ${APACHE_CONF}/jk_mount/${JK_CONF} to ${APACHE_CONF}/jk_mount/${JK_CONF}.${LONG_DATE}"
    mv ${APACHE_CONF}/jk_mount/${JK_CONF} ${APACHE_CONF}/jk_mount/${JK_CONF}.${LONG_DATE}
  fi
fi
log "Copying ${JK_CONF} site file to ${APACHE_CONF}/jk_mount/"
cp ${SCRIPT_DIR}/${JK_CONF} ${APACHE_CONF}/jk_mount/

###############################################################################
# Configure Postgres
###############################################################################
## Add the postgres user to the root group
usermod -a -G root ${PG_USER}

## create portal database and user
log "Creating ${DB_NAME} database schema"
su ${PG_USER} -c "dropdb ${DB_NAME}"
su ${PG_USER} -c "createdb ${DB_NAME}"

log "Creating ${DB_USER} user" 
su ${PG_USER} -c "dropuser ${DB_USER}"
su ${PG_USER} -c "psql -c \"CREATE USER ${DB_USER} WITH PASSWORD '${DB_PASS}'\""

# run the script to create user and tables
su ${PG_USER} -c "psql -f ${SCRIPT_DIR}/portal-tables.sql ${DB_NAME}"

## modify pg_hba.conf to allow traffic from each CN
IP_ADDRESS=127.0.0.1
for ip in ${IPLIST[@]}
do
    IP_ADDRESS=${ip}
    PG_HBA_IS_MODIFIED=`grep "${DB_NAME} ${DB_USER} ${IP_ADDRESS} 255.255.255.255 password" ${PG_CONF}/pg_hba.conf`
	if [ "${PG_HBA_IS_MODIFIED}" == "" ]
	then
	  log "backing up ${PG_CONF}/pg_hba.conf to ${PG_CONF}/pg_hba.conf.bak"
	  cp ${PG_CONF}/pg_hba.conf ${PG_CONF}/pg_hba.conf.bak
	  chown postgres ${PG_CONF}/pg_hba.conf
	  chgrp postgres ${PG_CONF}/pg_hba.conf
	
	  log "appending 'host ${DB_NAME} ${DB_USER} ${IP_ADDRESS} 255.255.255.255 password' to ${PG_CONF}/pg_hba.conf"
	  echo "host ${DB_NAME} ${DB_USER} ${IP_ADDRESS} 255.255.255.255 password" >> ${PG_CONF}/pg_hba.conf
	  
	fi
done

## modify /etc/postgresql/10/main/postgresql.conf to listen on more than 'localhost'
## original line looks like this:
## #listen_addresses = 'localhost'
## we want this:
## listen_addresses = '*'

PG_LISTEN_IS_MODIFIED=`egrep "listen_addresses *= *'\*'" ${PG_CONF}/postgresql.conf`
if [ "${PG_LISTEN_IS_MODIFIED}" == "" ]
then
	sed -i.bak  "s/\(listen_addresses\s*\=\s*\)'localhost'/\1 '*'/;" ${PG_CONF}/postgresql.conf
fi
# make sure it is not commented out
sed -i.bak  "s/#\(listen_addresses\)/\1 /;" ${PG_CONF}/postgresql.conf

# enable SSL access for the server
PG_SSL_IS_MODIFIED=`grep -P "ssl *= *(?:false|off|no|0)" ${PG_CONF}/postgresql.conf`
if [ "${PG_SSL_IS_MODIFIED}" == "" ]
then
	sed -i.bak  "s/\(ssl\s*\=\s*\).\+/\1true/;" ${PG_CONF}/postgresql.conf
fi
# make sure it is not commented out
sed -i.bak  "s/#\(ssl\s*\=.\)/\1/;" ${PG_CONF}/postgresql.conf

# edit the postgresql.conf to use the given certificate/key
sed -i.bak --regexp-extended  "s/(ssl_cert_file\s*=).*/\1 \'${PUBLIC_SERVER_CERT_ESC}\'/;" ${PG_CONF}/postgresql.conf
sed -i.bak --regexp-extended  "s/(ssl_key_file\s*=).*/\1 \'${KEY_FILE_ESC}\'/;" ${PG_CONF}/postgresql.conf
# make sure it is not commented out
sed -i.bak  "s/#\(ssl_cert_file\)/\1 /;" ${PG_CONF}/postgresql.conf
sed -i.bak  "s/#\(ssl_key_file\)/\1 /;" ${PG_CONF}/postgresql.conf

## Restart the postgres db
log "Restarting postgres database"
/etc/init.d/${PG} restart

###############################################################################
# Start Apache and Tomcat
###############################################################################

## Start Apache
/etc/init.d/apache2 start

## Start Tomcat
log "starting Tomcat server"
systemctl start ${TOMCAT}

## Update DateONE Version Info Doc
#java -jar /usr/share/dataone-cn-version-tool/dataone-cn-version-tool.jar -F/usr/share/dataone-cn-version-tool/version-tool.properties -html > /var/www/cn-version.html

db_stop
exit 0