diff --git a/bin/hedgedoc b/bin/hedgedoc index b6b8173..7f8e76e 100755 --- a/bin/hedgedoc +++ b/bin/hedgedoc @@ -14,15 +14,19 @@ IFS=$'\n' ### Load config SCRIPTNAME="$(basename "$0")" + +# the extra helpers will be located in the same directory +HELPER_SCRIPT_DIR=$(dirname $(readlink -e $0 2>/dev/null) 2>/dev/null) + XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}" -HEDGEDOC_SERVER="${HEDGEDOC_SERVER:-http://127.0.0.1:3000}" +export HEDGEDOC_SERVER="${HEDGEDOC_SERVER:-http://127.0.0.1:3000}" OLD_CODIMD_CONFIG_DIR="${HEDGEDOC_CONFIG_DIR:-$XDG_CONFIG_HOME/codimd}" HEDGEDOC_CONFIG_DIR="${HEDGEDOC_CONFIG_DIR:-$XDG_CONFIG_HOME/$SCRIPTNAME}" [ -e "$OLD_CODIMD_CONFIG_DIR" ] && [ ! -e "$HEDGEDOC_CONFIG_DIR" ] && mv "$OLD_CODIMD_CONFIG_DIR" "$HEDGEDOC_CONFIG_DIR" -HEDGEDOC_COOKIES_FILE="${HEDGEDOC_COOKIES_FILE:-$HEDGEDOC_CONFIG_DIR/key.conf}" +export HEDGEDOC_COOKIES_FILE="${HEDGEDOC_COOKIES_FILE:-$HEDGEDOC_CONFIG_DIR/key.conf}" # Auto-create XDG compliant config dir (https://www.ctrl.blog/entry/xdg-basedir-scripting) mkdir -p "$HEDGEDOC_CONFIG_DIR" @@ -56,7 +60,7 @@ Commands: Delete the given note from the server. - login --email|--ldap [username] [password] + login --email|--ldap|--gitlab [username] [password] Authenticate the CLI with the server. (If not passed as args, user & passsword will be asked for via stdin) Stores session key in \$HEDGEDOC_COOKIES_FILE=$HEDGEDOC_COOKIES_FILE/ @@ -259,6 +263,31 @@ function export_note() { esac } +function user_login_helper_common() { + local login_url=$1; shift + local username_arg=$1; shift + local username=$1; shift + local password=$1; shift + curl \ + --request POST \ + --silent \ + --cookie-jar "$HEDGEDOC_COOKIES_FILE" \ + --data-urlencode "$username_arg=$username" \ + --data-urlencode "password=$password" \ + "${HEDGEDOC_SERVER}/${login_url}" > /dev/null + +} + +function user_login_helper_gitlab() { + local login_url=$1; shift + local username_arg=$1; shift + local username=$1; shift + local password=$1; shift + + bash ${HELPER_SCRIPT_DIR}/login-hedgedoc-via-gitlab.sh $username $password >& /dev/null + +} + function backup_all_notes() { output_path="${1:-archive.zip}" @@ -275,6 +304,7 @@ function user_login() { case "$method" in email) local username_arg="email" login_url="login";; ldap) local username_arg="username" login_url="auth/ldap";; + gitlab) local username_arg="username" login_url="auth/gitlab";; *) echo "Error: Unrecognized login method '--$method'." echo "Usage: $SCRIPTNAME login --email|--ldap [username] [password]" @@ -287,13 +317,16 @@ function user_login() { [[ ! "$password" ]] && password="$(read_password "Please enter your password: ")" echo "" >&2 - curl \ - --request POST \ - --silent \ - --cookie-jar "$HEDGEDOC_COOKIES_FILE" \ - --data-urlencode "$username_arg=$username" \ - --data-urlencode "password=$password" \ - "${HEDGEDOC_SERVER}/${login_url}" > /dev/null + case "$method" in + email) + user_login_helper_common ${login_url} ${username_arg} ${username} ${password};; + ldap) + user_login_helper_common ${login_url} ${username_arg} ${username} ${password};; + gitlab) + user_login_helper_gitlab ${login_url} ${username_arg} ${username} ${password};; + *) + user_login_helper_common ${login_url} ${username_arg} ${username} ${password};; + esac if is_authenticated; then echo "Logged in to $HEDGEDOC_SERVER as $username using $method auth." diff --git a/bin/login-hedgedoc-via-gitlab.sh b/bin/login-hedgedoc-via-gitlab.sh new file mode 100755 index 0000000..d4b8214 --- /dev/null +++ b/bin/login-hedgedoc-via-gitlab.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env bash +# Documentation & Code: https://github.com/hedgedoc/cli + +### Bash environment setup +# http://redsymbol.net/articles/unofficial-bash-strict-mode/ +# https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail + +############################################################################## + +username=${1}; shift +password=${1}; shift + +if [ -z "$username" ]; then + echo "Please pass the username and password. " + exit -1 +fi +if [ -z "$password" ]; then + echo "Please pass the password. " + exit -1 +fi + +export HEDGEDOC_SERVER=${HEDGEDOC_SERVER} +if [ -z "$HEDGEDOC_SERVER" ]; then + echo "Please setup the HEDGEDOC_SERVER. " 1>&2 + exit -1 +fi +cookie=${HEDGEDOC_COOKIES_FILE} +if [ -z "$HEDGEDOC_COOKIES_FILE" ]; then + echo "Please setup the HEDGEDOC_COOKIES_FILE. " 1>&2 + exit -1 +fi + +hedgedochost=$(echo $HEDGEDOC_SERVER | perl -ne 'print "$1" if /(https?:\/\/[^:^\/\\s]+)\//') + +function step1() { + echo + echo "Step 1:" + local headers + headers=$(curl "${HEDGEDOC_SERVER}/auth/gitlab" \ + -H "authority: ${hedgedochost}" \ + -H 'pragma: no-cache' \ + -H 'cache-control: no-cache' \ + -H 'upgrade-insecure-requests: 1' \ + -H "referer: ${HEDGEDOC_SERVER}/" \ + -b $cookie -c $cookie --insecure \ + -s -o /dev/null \ + -D - | grep location | cut -c11-) + export GITLAB_CALLBACK_LOCATION=${headers//[$'\t\r\n']} # need to remove CRLF + echo "GITLAB_CALLBACK_LOCATION is $GITLAB_CALLBACK_LOCATION" + # get the host + export GITLAB_HOST=$(echo $GITLAB_CALLBACK_LOCATION | perl -ne 'print "$1" if /(https?:\/\/[^:^\/\\s]+)\//') + echo "GITLAB_HOST is $GITLAB_HOST" # with http/https prefix +} + +function step2() { + echo + echo "Step 2:" + + local body + body=$(curl $GITLAB_CALLBACK_LOCATION \ + -H 'Connection: keep-alive' \ + -H 'Pragma: no-cache' \ + -H 'Cache-Control: no-cache' \ + -H 'Upgrade-Insecure-Requests: 1' \ + -b $cookie -c $cookie \ + --insecure) + export GITLAB_LOGIN_LOCATION=$(echo "$body" | perl -ne 'print "$1" if /.*?a href="(.+?)"/') + echo "GITLAB_LOGIN_LOCATION is $GITLAB_LOGIN_LOCATION" +} + +function step3() { + echo + echo "Step 3:" + local body + local gitlab_token + local token + + # https://stackoverflow.com/questions/47948887/login-to-gitlab-with-username-and-password-using-curl + body=$(curl $GITLAB_LOGIN_LOCATION \ + -H 'Connection: keep-alive' \ + -H 'Pragma: no-cache' \ + -H 'Cache-Control: no-cache' \ + -H 'Upgrade-Insecure-Requests: 1' \ + -b $cookie -c $cookie --insecure) + gitlab_token=$( echo "$body" | grep 'authenticity_token' | perl -ne 'print "$1\n" if /.*?authenticity_token"[[:blank:]]value="(.+?)"/' | sed -n 1p ) + echo + echo "GET TOKEN" + echo $gitlab_token + token= + if [ -n "$gitlab_token" ]; then + token="--data-urlencode authenticity_token=${gitlab_token}" + fi + local gitlab_login_real=$( echo "$body" | grep 'form' | perl -ne 'print "$1\n" if /.*?action="(.+?)"[[:blank:]]/' | sed -n 1p ) + + export GITLAB_LOGIN_REAL_LOCATION="${GITLAB_HOST}${gitlab_login_real}" + echo "GITLAB_LOGIN_REAL_LOCATION is $GITLAB_LOGIN_REAL_LOCATION" # with http/https prefix + + + local header + header=$(curl $GITLAB_LOGIN_REAL_LOCATION \ + -H 'Connection: keep-alive' \ + -H 'Pragma: no-cache' \ + -H 'Cache-Control: no-cache' \ + -H 'Upgrade-Insecure-Requests: 1' \ + -H "Origin: ${GITLAB_HOST}" \ + -H 'Content-Type: application/x-www-form-urlencoded' \ + -H "Referer: ${GITLAB_LOGIN_LOCATION}" \ + -H 'Accept-Language: en' \ + --data "grant_type=password&username=${username}&password=${password}" ${token} \ + -b $cookie -c $cookie \ + --insecure -D - | grep -i location | cut -c11-) + header=${header//[$'\t\r\n']} + if [ "$header" = "$GITLAB_CALLBACK_LOCATION" ]; then + echo "same callback $header" + else + echo "Mismatch callback: " 1>&2 + echo "header: $header " 1>&2 + echo "callback: $GITLAB_CALLBACK_LOCATION" 1>&2 + exit -1 + fi + +} + +function step4-5() { + echo + echo "Step 4:" + local body + local link + body=$(curl $GITLAB_CALLBACK_LOCATION \ + -H 'Connection: keep-alive' \ + -H 'Pragma: no-cache' \ + -H 'Cache-Control: no-cache' \ + -H 'Upgrade-Insecure-Requests: 1' \ + -b $cookie -c $cookie \ + --insecure) + echo $body + link=$(echo $body | grep window.location | perl -ne 'print "$1\n" if /.*?window.location= "(.+?)";/') + # if not found, try to parse again + if [ -z "$link" ]; then + link=$(echo $body | grep window.location | perl -ne 'print "$1\n" if /.*?let redirectUri = "(.+?)";/') + fi + echo "WILL REDIRECT TO $link " + + + + echo + echo "Step 5:" + curl $link \ + -H "authority: ${hedgedochost}" \ + -H 'pragma: no-cache' \ + -H 'cache-control: no-cache' \ + -b $cookie -c $cookie \ + --compressed --insecure + + echo + echo "DONE" + +} + +# gitlab +# check + +if [ ! -f "$cookie" ]; then + step1 + step2 + step3 + step4-5 +fi +