#!/bin/bash

cvmfs_test_name="Test authz helper interface"
cvmfs_test_autofs_on_startup=false
cvmfs_test_suites="quick"

TEST632_PRIVATE_MOUNT=

secure_mount() {
  local mntpnt="$1"
  TEST632_PRIVATE_MOUNT="$mntpnt"
  do_local_mount_as_root "$mntpnt"          \
                         "$CVMFS_TEST_REPO" \
                         "$(get_repo_url $CVMFS_TEST_REPO)" \
                         "" \
                         "CVMFS_AUTHZ_ENV_TEST=ABC" || return 1
}

secure_unmount() {
  sudo umount $TEST632_PRIVATE_MOUNT
  TEST632_PRIVATE_MOUNT=
}

cleanup() {
  echo "running cleanup()..."
  if [ "x$TEST632_PRIVATE_MOUNT" != "x" ]; then
    sudo umount $TEST632_PRIVATE_MOUNT
    sudo rmdir $TEST632_PRIVATE_MOUNT
    sudo rm -rf "${TEST632_PRIVATE_MOUNT}c"
  fi
}


cvmfs_run_test() {
  local logfile=$1
  local script_location=$2
  local scratch_dir=$(pwd)

  echo "set a trap for system directory cleanup"
  trap cleanup EXIT HUP INT TERM

  echo "create a fresh repository named $CVMFS_TEST_REPO with user $CVMFS_TEST_USER"
  create_empty_repo $CVMFS_TEST_REPO $CVMFS_TEST_USER || return $?

  echo "gather information about the just created repo"
  load_repo_config $CVMFS_TEST_REPO
  local spool_dir="$CVMFS_SPOOL_DIR"
  local cache_base="$CVMFS_CACHE_BASE"

  echo "Ensure that we can access the repo for editing"
  sudo sh -c "echo CVMFS_AUTHZ_HELPER=/usr/libexec/cvmfs/authz/cvmfs_allow_helper \
    >> ${spool_dir}/client.local" || return 10

  echo "put some stuff into $CVMFS_TEST_REPO"
  start_transaction $CVMFS_TEST_REPO                           || return $?
  echo "Hello World" > /cvmfs/$CVMFS_TEST_REPO/hello_world     || return 3
  echo "Hello World v2" > /cvmfs/$CVMFS_TEST_REPO/hello_world2 || return 3
  publish_repo $CVMFS_TEST_REPO -v                             || return $?

  local mntpnt="${scratch_dir}/secure_mnt"
  echo "mount secure mount point"
  secure_mount $mntpnt || return 20

  echo "No memberhsip string set, this should work"
  sudo -u nobody /bin/sh -c "cat ${mntpnt}/hello_world" || return 30
  secure_unmount

  echo "lock down repository"
  local authz_file="${scratch_dir}/authz_file"
  echo "deny%NOACCESS" > $authz_file || return 40
  start_transaction $CVMFS_TEST_REPO || return $?
  publish_repo $CVMFS_TEST_REPO -v -F $authz_file || return $?

  echo "remount secure mount point"
  secure_mount $mntpnt || return 50
  echo "Access forbidden, this should not work"
  sudo -u nobody /bin/sh -c "cat ${mntpnt}/hello_world" && return 51
  echo "As root, however, it should work"
  sudo cat ${mntpnt}/hello_world || return 52
  secure_unmount

  echo "open up repository"
  echo "allow%PUBLICACCESS" > $authz_file || return 60
  start_transaction $CVMFS_TEST_REPO || return $?
  publish_repo $CVMFS_TEST_REPO -v -F $authz_file || return $?

  echo "remount secure mount point"
  secure_mount $mntpnt || return 70
  echo "Repo has open membership, this should work"
  sudo -u nobody /bin/sh -c "cat ${mntpnt}/hello_world" || return 71

  echo "kill and restart secure mount"
  local secure_mnt_pid=$(get_xattr pid $mntpnt)
  echo "secure mount point has pid $secure_mnt_pid"
  local authz_helper_pid=$(pgrep -P $secure_mnt_pid cvmfs_allow)
  echo "authz helper has pid $authz_helper_pid; killing it."
  sudo kill -SEGV $authz_helper_pid
  echo "authz helper has died, access should fail"
  sudo -u nobody setsid /bin/sh -c "cat ${mntpnt}/hello_world" && return 74
  echo "Waiting for rate-limit timeout to pass"
  sleep 11
  echo "authz helper should be restarted on access"
  sudo -u nobody setsid /bin/sh -c "cat ${mntpnt}/hello_world" || return 75
  local authz_helper_pid_new=$(pgrep -P $secure_mnt_pid cvmfs_allow)
  echo "new authz helper pid $authz_helper_pid_new"
  [ "x$authz_helper_pid_new" = "x" ] && return 76
  [ "x$authz_helper_pid" = "x$authz_helper_pid_new" ] && return 77

  echo "checking authz attribute"
  attr -l $mntpnt || return 72
  local authz_attr=$(get_xattr authz $mntpnt)
  echo "extended attribute 'authz' is $authz_attr"
  [ "x$authz_attr" = "xallow%PUBLICACCESS" ] || return 73

  echo "checking environment of authz helper"
  local secure_mnt_pid=$(get_xattr pid $mntpnt)
  echo "secure mount point has pid $secure_mnt_pid"
  local authz_helper_pid=$(pgrep -P $secure_mnt_pid cvmfs_allow)
  echo "authz helper has pid $authz_helper_pid"
  sudo cat /proc/$authz_helper_pid/environ | grep -a ENV_TEST=ABC || return 80
  sudo cat /proc/$authz_helper_pid/environ | grep -a CVMFS_AUTHZ_ENV_TEST=ABC && return 81

  return 0
}
