#!/bin/bash

## Copyright (C) 2025 - 2025 ENCRYPTED SUPPORT LLC <adrelanos@whonix.org>
## See the file COPYING for copying conditions.

set -o errexit
set -o nounset
set -o errtrace
set -o pipefail
shopt -s inherit_errexit
shopt -s shift_verbose

## Per-wiki credentials, keyed by full WIKI URL. Populated from the
## credentials file. Provides a structured alternative to setting
## WIKI_API_USER_NAME / WIKI_API_USER_PASS via a `case` block.
declare -A WIKI_USER_NAMES
declare -A WIKI_USER_PASSES

error_message_if_missing_wiki_url_variable() {
  die 1 "environment variable WIKI_URL missing! Run for example:
  WIKI_URL=https://www.whonix.org/w ${0##*/}"
}

require_auth_data() {
  if [ -z "${WIKI_API_USER_NAME-}" ]; then
    die 1 "User name not supplied!"
  fi
  if [ -z "${WIKI_API_USER_PASS-}" ]; then
    die 1 "Password not supplied!"
  fi
}

source_credentials() {
  local mode

  # The file '~/.credentials' is for backwards compatibility and should be
  # removed on future releases.
  for file_name in /usr/share/mediawiki-shell/credentials \
    ~/.mediawikishell_credentials \
    ~/.credentials; do
    test -f "${file_name}" || continue
    ## Refuse to 'source' a credentials file with group- or world-write
    ## bits set: 'source' executes its argument as bash, so a writable
    ## credentials file is an arbitrary code execution sink for any
    ## local user with the relevant write permission.
    ##
    ## Mode is the octal permission string from 'stat -c %a' (e.g. 600,
    ## 644, 0664). Pattern intent (matched against last 2 digits):
    ##   *[2367]?  group-write bit set (2nd-to-last octal digit is 2/3/6/7)
    ##   *[2367]   other-write bit set (last octal digit is 2/3/6/7)
    ##   ''        stat returned no mode -> fail closed
    mode="$(stat -c '%a' -- "${file_name}")"
    case "$mode" in
      *[2367]?|*[2367]|'')
        die 1 "credentials file '${file_name}' has insecure or unreadable mode '$mode'; refusing to source"
        ;;
    esac
    log info "Sourcing credentials file: ${file_name}"
    # shellcheck source=credentials disable=SC1090,SC1091
    source -- "${file_name}"
  done
}

[[ -v WIKI_URL ]] || error_message_if_missing_wiki_url_variable
case "${WIKI_URL}" in
  kicksecure)
    WIKI_URL="https://www.kicksecure.com/w"
    ;;
  whonix)
    WIKI_URL="https://www.whonix.org/w"
    ;;
esac

source_credentials

## If the credentials file populated WIKI_USER_NAMES / WIKI_USER_PASSES,
## look up the active wiki's credentials by full URL. A credentials file
## that sets WIKI_API_USER_NAME / WIKI_API_USER_PASS directly (e.g. via
## a `case` block) takes precedence. Both WIKI_USER_NAMES and
## WIKI_USER_PASSES are associative arrays, so there is no code
## injection risk here.
[[ -v WIKI_API_USER_NAME ]] || WIKI_API_USER_NAME="${WIKI_USER_NAMES[$WIKI_URL]-}"
[[ -v WIKI_API_USER_PASS ]] || WIKI_API_USER_PASS="${WIKI_USER_PASSES[$WIKI_URL]-}"

[[ -v WIKI_API ]] || WIKI_API="$WIKI_URL/api.php"
[[ -v WIKI_INDEX ]] || WIKI_INDEX="$WIKI_URL/index.php"
