#!/bin/bash
# propagates ASCEDS data requested through the web interface for managed clients

SPATH="$(dirname "$(readlink -f ${BASH_SOURCE[0]})")"    # dir of the script
SNAME="$(basename ${BASH_SOURCE[0]})"                    # name of the script

ASCEDSCONF='local site certbot'
ASCEDSLIBS='utils'

if [ ! -r "${SPATH}/asceds-website-head" ] ; then
   echo "No header ${SPATH}/asceds-website-head. Exiting"
   exit 9
fi

. ${SPATH}/asceds-website-head

asceds-web-propagate-usage()
{
  cat << ENDUSAGE

Propagates ASCEDS data requested through the web interface for managed clients

asceds-web-propagate [-h] [-q] [-c <client_name>]
-h --> display usage and exit
-q --> no question asked; sends output to the logs in ${ASCEDSLOGDIR}/
-c <client_name> --> propagate only <client_name> 

Propagate: requests in ${ASCEDSWEBDIR}/cert_queue/*.asceds
If run the queue (by cron), sends notification by email to requestors.
If cert.conf exists and ASCEDS_CERT_ID not empty, 
   removes web certificate files.
If ~asceds/<hostname>/.newcerts is present, just sends the certificate files
   through asceds-send-cert -c <client> (for atomic operation); 
Else, performs a full setup (generates new certificate and sends it)
   through asceds-client-setup -c  <client>.
Removes request file.

ENDUSAGE
exit 0
}

# output to terminal by default
QUIETRUN=""

# client to use with the -c option
CLIENT_NAME=''

# general validation and parse of the command line
for ARG in ${ARGS} ; do
   #echo "ARG=${ARG}"
   if [ "${ARG}" != "${ARG//[^-_a-zA-Z0-9.]/}" ] ; then
      asceds-error "Malformed argument ${ARG}"
   elif [ "${ARG}" == "-q" ] ; then
      shift
      asceds-exec-noninteractive "$*"
      # bring other scripts in non-interactive mode
      QUIETRUN="y"
   elif [ "${ARG}" == "-h" ] ; then
      shift
      asceds-web-propagate-usage
   elif [ "${ARG}" == "-c" ] ; then
      shift
      CLIENT_NAME=$( cat <<< $1 | tr '[:upper:]' '[:lower:]' )
      if [ -z "${CLIENT_NAME}" ] || [[ "${CLIENT_NAME}" = "-"* ]] ; then
         asceds-error "No client name passwed as argument"
      fi 
      asceds-expand-hostname "${CLIENT_NAME}" && \
         CLIENT_NAME="${ASCEDS_FQDN}"
      asceds-validate-fqdn "${CLIENT_NAME}" || \
         asceds-error "Invalid client FQDN ${CLIENT_NAME}"
   else
      shift
   fi
done

PROPAGATELIST=''
if [ -n "${CLIENT_NAME}" ] ; then
   PROPAGATELIST="${ASCEDSWEBDIR}/cert_queue/${CLIENT_NAME}.asceds"
   if [ ! -r "${PROPAGATELIST}" ] ; then
      asceds-error "No propagate request file ${PROPAGATELIST}"
   fi
else
   if [ "$( echo ${ASCEDSWEBDIR}/cert_queue/*.asceds )" != "${ASCEDSWEBDIR}/cert_queue/*.asceds" ] ; then
      PROPAGATELIST=$( echo ${ASCEDSWEBDIR}/cert_queue/*.asceds )
   fi
fi

# asceds-echo "Searching for propagate requests"
if [ -n "${PROPAGATELIST}" ] ; then
   for REQ in ${PROPAGATELIST} ; do
      CLIENT=$( basename ${REQ} )
      CLIENT=${CLIENT%.*}

      # parse request file
      # . ${REQ}
      asceds-parse-propagatereq "${REQ}"

      # compare ${CLIENT_DOMAIN_NAME} with hostname in ${REQ}
      if [ "${CLIENT}" != "${CLIENT_DOMAIN_NAME}" ] ; then
         asceds-error "Name of propagate request file ${CLIENT} doesn't match content ${CLIENT_DOMAIN_NAME}."
      fi

      CERTCONFFILE="${ASCEDSHOMEDIR}/${CLIENT_DOMAIN_NAME}_cert.conf"      
      # if existing client
      if [ -r "${CERTCONFFILE}" ] ; then
         # check if transition unmanaged -> managed
         asceds-extract "ASCEDS_CERT_ID" "${CERTCONFFILE}"
         if [ -n "${VARVAL}" ] ; then
            # this was an unmanaged client
            if [ "${VARVAL}" == "${VARVAL//[^a-zA-Z0-9]/}" ] && \
               [ -d "${ASCEDSWEBDIR}/html/cert/keys/${VARVAL}" ] ; then
               echo "Migrating ${CLIENT_DOMAIN_NAME} from unmanaged to managed !!!"
               ${RM} -Rf ${ASCEDSWEBDIR}/html/cert/keys/${VARVAL} > /dev/null
               # the cert.conf file will be replaced, no need to adjust it
            else
               asceds-warning "There is something wrong with ASCEDS_CERT_ID in ${CERTCONFFILE}"
               asceds-mailto-alarm "Bad ASCEDS_CERT_ID in ${CERTCONFFILE}" "${ASCEDSLOGF}"
            fi
         fi

         # backup cert.conf
         ${MV} -f ${CERTCONFFILE} ${CERTCONFFILE}.bak > /dev/null 2>&1
      fi

      # log
      echo "--> ${REQUEST_DATE} Web user ${REQUESTED_BY} propagated asceds data for ${CLIENT_DOMAIN_NAME}"
      echo "client type change: ${ACK_CHANGE_TYPE}"
      echo "--> ${REQUEST_DATE} Web user ${REQUESTED_BY}" >> ${ASCEDSWEBHISTFILE}
      echo "    propagated asceds data for ${CLIENT_DOMAIN_NAME}" >> ${ASCEDSWEBHISTFILE}
      echo "    client type change: ${ACK_CHANGE_TYPE}" >> ${ASCEDSWEBHISTFILE}

      # propagate 
      if [ -r "${ASCEDSHOMEDIR}/${CLIENT}/.newcerts" ] ; then
         echo "New certificate files already exist for ${CLIENT}."
         echo "Sending them over."
         
         # send certificate files to the client
         sudo -u asceds -i ${ASCEDSBINDIR}/asceds-send-cert -q -c ${CLIENT}
      else
         echo "Setting up fresh certificate files for ${CLIENT}."
         asceds-client-setup -q -c ${CLIENT_DOMAIN_NAME} > /dev/null 2>&1
         RETVAL=$?
         # this executes: asceds-certbot-gencert -e -c client -s sans
         #                asceds-send-cert -c client
         if [ "${RETVAL}" != "0" ] ; then
            ${RM} -f ${REQ} > /dev/null 2>&1
            asceds-error "asceds-client-setup unsuccessful."
         fi
      fi
      
      if [ -z "${CLIENT_NAME}" ] ; then
         # if request was executed by cron running the queue,
         # notify: send email to requestor
         SUBJ="Propagated certificate for ${CLIENT_DOMAIN_NAME}"
         BODY="${REQUEST_DATE} Web user ${REQUESTED_BY} 
            propagated certificate for ${CLIENT_DOMAIN_NAME}"

         if [ -z "${ALARMSEND}" ] ; then
            asceds-error "No mailer installed: no email will be sent"
         else
            cat <<< ${BODY} | ${ALARMSEND} -s "${SUBJ}" ${REQUESTED_BY}
         fi
      else
         # show the cert data on the web page
         if [ -r "${ASCEDSHOMEDIR}/${CLIENT_NAME}/cert.pem" ] ; then
            echo "New certificate propagated by ASCEDS:"
            if [ -n "${OPENSSLEXT}" ] ; then
               eval ${OPENSSLEXT} < ${ASCEDSHOMEDIR}/${CLIENT_NAME}/cert.pem \
                    | sed -e "s/^/   /"
            fi
            echo "   Certificate Validity:" 
            openssl x509 -dates -noout < ${ASCEDSHOMEDIR}/${CLIENT_NAME}/cert.pem | \
               sed -e "s/^/      /"
         else
            asceds-warning "Cannot find certificate file ${ASCEDSHOMEDIR}/${CLIENT_NAME}/cert.pem"
         fi
      fi

      # clean
      ${RM} -f ${REQ} > /dev/null 2>&1   
   done
fi

