]> git.plutz.net Git - serve0/commitdiff
Merge commit '57d399ab91c160327aaab1ab318ce701e727807b'
authorPaul Hänsch <paul@plutz.net>
Tue, 19 Oct 2021 15:11:10 +0000 (17:11 +0200)
committerPaul Hänsch <paul@plutz.net>
Tue, 19 Oct 2021 15:11:10 +0000 (17:11 +0200)
1  2 
cgilite/cgilite.sh
cgilite/users.sh

diff --combined cgilite/cgilite.sh
index a2aa32924bdc7ed30cc35fb053b416859a05f93c,310dd64a0f4e99280c99b1eca756e93e7f2aa97c..310dd64a0f4e99280c99b1eca756e93e7f2aa97c
@@@ -48,7 -48,7 +48,7 @@@ _EXEC="${_EXEC:-${0%/*}}
  _DATA="${_DATA:-.}"
  _EXEC="${_EXEC%/}" _DATA="${_DATA%/}" _BASE="${_BASE%/}"
  
- # Carriare Return and Line Break characters for convenience
+ # Carriage Return and Line Break characters for convenience
  CR="\r"
  BR='
  '
@@@ -90,7 -90,7 +90,7 @@@ HEX_DECODE()
          *) out="${out}${in%"${in#?}"}"; in="${in#?}"; continue;;
      esac;
  
-     # Hex escaes for printf (e.g. \x41) are not portable 
+     # Hex escapes for printf (e.g. \x41) are not portable 
      # The portable way for Hex output is transforming Hex to Octal
      # (e.g. \x41 = \101)
      case $in in
@@@ -195,6 -195,8 +195,8 @@@ if [ "${REQUEST_METHOD}" = POST -a "${C
    cgilite_post="$(head -c "$CONTENT_LENGTH")"
  fi
  
+ PATH_INFO="$(PATH "/${PATH_INFO#${_BASE}}")"
  debug(){ [ $# -gt 0 ] && printf '%s\n' "$@" >&2 || tee -a /dev/stderr; }
  [ "${DEBUG+x}" ] && env >&2
  
diff --combined cgilite/users.sh
index 4c730ee3753367567f6e08e527df6bd9da4f85a0,7721def9c5c07927502309a9a11ed8e60af523b9..7721def9c5c07927502309a9a11ed8e60af523b9
@@@ -13,24 -13,70 +13,70 @@@ HTTP_HOST="$(HEADER Host)
  MAILFROM="${MAILDOMAIN:-noreply@${HTTP_HOST%:*}}"
  
  user_db="${_DATA}/users.db"
- unset USER_ID USER_NAME USER_EMAIL
+ unset USER_ID USER_NAME USER_STATUS USER_EMAIL USER_PWSALT USER_PWHASH \
+       USER_EXPIRE USER_DEVICES USER_FUTUREUSE
  
  # USER DB
  # UID UNAME   STATUS (pending|active|deleted) EMAIL   PWSALT  PWHASH  EXPIRE  DEVICES FUTUREUSE
  
- user_init(){
-    local user_id="$(SESSION_VAR user_id)"
-    local UID  UNAME   STATUS  EMAIL   PWSALT  PWHASH  EXPIRE  DEVICES FUTUREUSE
-    [ "$user_id" ] \
-    && read -r UID     UNAME   STATUS  EMAIL   PWSALT  PWHASH  EXPIRE  DEVICES FUTUREUSE <<-EOF
+ user_id="$(SESSION_VAR user_id)"
+ if [ "$user_id" -a -f "$user_db" -a -r "$user_db" ]; then
+    read -r USER_ID USER_NAME USER_STATUS USER_EMAIL USER_PWSALT USER_PWHASH \
+            USER_EXPIRE USER_DEVICES USER_FUTUREUSE <<-EOF
        $(grep "^${user_id}     " "$user_db")
        EOF
-    [ "$STATUS" -a "$EXPIRE" ] \
-    && if [ "$STATUS" = active -a "$EXPIRE" -gt "$_DATE" ]; then
-      USER_ID="$UID"
-      USER_NAME="$(UNSTRING "$UNAME")"
-      USER_EMAIL="$(UNSTRING "$EMAIL")"
-    fi
+   if [ "$USER_ID" -a "$USER_STATUS" = active -a "$USER_EXPIRE" -gt "$_DATE" ]; then
+        USER_NAME="$(UNSTRING "$USER_NAME")"
+       USER_EMAIL="$(UNSTRING "$USER_EMAIL")"
+     USER_DEVICES="$(UNSTRING "$USER_DEVICES")"
+     unset USER_PWSALT USER_PWHASH
+   else
+     unset USER_ID USER_NAME USER_STATUS USER_EMAIL USER_PWSALT USER_PWHASH \
+           USER_EXPIRE USER_DEVICES USER_FUTUREUSE
+   fi
+ fi
+ unset user_id
+ user_update_user() {
+   # internal function for user update
+   local uid="$1" uname status email pwsalt pwhash expire devices futureuse
+   local UID UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE
+   local arg
+   for arg in "$@"; do case $arg in
+     uname=*) uname="${arg#*=}";;
+     status=*) status="${arg#*=}";;
+     email=*) email="${arg#*=}";;
+     password=*) pwsalt="$(randomid)"; pwhash="$(user_pwhash "$pwsalt" "${arg#*=}")";;
+     devices=*) devices="${arg#*=}";;
+   esac; done
+   if LOCK "$user_db"; then
+     while read -r UID UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES \
+                   FUTUREUSE; do
+     if [ "$UID" = "$uid" ]; then
+       printf '%s      %s      %s      %s      %s      %s      %s      %s      %s\n' \
+              "$uid" "$(STRING "${uname-$(UNSTRING "$UNAME")}")" \
+              "${status:-${status-${STATUS}}${status+\\}}" \
+              "${email:-${email-${EMAIL}}${email+\\}}" \
+              "${pwsalt:-${PWSALT}}" "${pwhash:-${PWHASH}}" \
+              "$((_DATE + 86400 * 730))" \
+              "$(STRING "${devices-$(UNSTRING "$DEVICES")}")" \
+              "${FUTUREUSE:-\\}"
+     elif [ "$STATUS" = pending -a ! "$EXPIRE" -ge "$_DATE" ]; then
+       # omit expired invitations from output
+       :
+     else
+       printf '%s      %s      %s      %s      %s      %s      %s      %s      %s\n' \
+              "$UID" "$UNAME" "$STATUS" "$EMAIL" "$PWSALT" "$PWHASH" \
+              "$EXPIRE" "$DEVICES" "$FUTUREUSE"
+     fi
+     done <"$user_db" >"${user_db}.$$"
+     mv -- "${user_db}.$$" "$user_db"
+     RELEASE "$user_db"
+   else
+     return 1
+   fi
  }
  
  user_checkname(){
@@@ -89,7 -135,7 +135,7 @@@ user_register()
    local pwsalt="$(randomid)"
    local pw="$(POST pw |grep -m1 -xE '.{6,}' )" pwconfirm="$(POST pwconfirm)"
  
-   if [ "$USER_REGISTRATION" != true ]; then
+   if [ "$USER_REGISTRATION" != true -a -s "$user_db" ]; then
      REDIRECT "${_BASE}${PATH_INFO}#ERROR_REGISTRATION_DISABLED"
    fi
  
               "$uid" "$(STRING "$email")" "$(( $_DATE + 86400 ))" \
               >>"$user_db"
        RELEASE "$user_db"
+       debug "Sending Activation Link:" \
+             "https://${HTTP_HOST}${_BASE}${PATH_INFO}?user_confirm=${uid}+$(session_mac "$uid")"
        sendmail -t -f "$MAILFROM" <<-EOF
        From: ${MAILFROM}
        To: ${email}
  
        You can activate your account using this link:
  
-           https://${HTTP_HOST%:*}/${_BASE}${PATH_INFO}?user_confirm=${uid}+$(session_mac "$uid")
+           https://${HTTP_HOST}${_BASE}${PATH_INFO}?user_confirm=${uid}+$(session_mac "$uid")
  
        This registration link will expire after 24 hours.
  
    fi
  }
  
+ user_invite(){
+   local uid="$(timeid)"
+   local email="$(POST email |user_checkemail)"
+   local message="$(POST message)"
+   if [ ! "email" ]; then
+     REDIRECT "${_BASE}${PATH_INFO}#ERROR_EMAIL_INVALID"
+   elif user_emailexist "$email"; then
+     REDIRECT "${_BASE}${PATH_INFO}#ERROR_EMAIL_EXISTS"
+   elif LOCK "$user_db"; then
+     printf '%s        \\      pending %s      \\      \\      %i      \\      \\\n' \
+            "$uid" "$(STRING "$email")" "$(( $_DATE + 86400 ))" \
+            >>"$user_db"
+     RELEASE "$user_db"
+     debug "Sending Invitation Link:" \
+           "https://${HTTP_HOST}${BASE}${PATH_INFO}?user_confirm=${uid}+$(session_mac "$uid")"
+     sendmail -t -f "$MAILFROM" <<-EOF
+       From: ${MAILFROM}
+       To: ${email}
+       Subject: You have been invited to ${HTTP_HOST%:*}
+       ${USER_NAME:-Someone} has offered an invitation to this email address.
+       ${message}
+       You can create your account using this link:
+           https://${HTTP_HOST}${_BASE}${PATH_INFO}?user_confirm=${uid}+$(session_mac "$uid")
+       This registration link will expire after 24 hours.
+       If you do not know what this is about, then someone else probably
+       entered your email address by accident. In this case you shoud
+       simply ignore this message and we will remove your email address from
+       our database within the next day.
+       This is an automatic email. Any direct reply will not be received.
+       Your Account Registration Robot.
+       EOF
+     REDIRECT "${_BASE}${PATH_INFO}#USER_REGISTER_CONFIRM"
+   else
+     REDIRECT "${_BASE}${PATH_INFO}#ERROR_USER_NOLOCK"
+   fi
+ }
  user_confirm(){
    # enable account
    local UID   UNAME   STATUS  EMAIL   PWSALT  PWHASH  EXPIRE  DEVICES FUTUREUSE
    local pwsalt="$(randomid)"
    local pw="$(POST pw |grep -m1 -xE '.{6,}' )" pwconfirm="$(POST pwconfirm)"
  
+   read -r UID UNAME   STATUS  EMAIL   PWSALT  PWHASH  EXPIRE  DEVICES FUTUREUSE <<-EOF
+       $(grep "^${uid:-invalid}        " "$user_db")
+       EOF
    if [ "$signature" != "$(session_mac "$uid")" ]; then
      REDIRECT "${_BASE}${PATH_INFO}?${QUERY_STRING}#ERROR_LINK_INVALID"
    elif [ ! "$uname" ]; then
      REDIRECT "${_BASE}${PATH_INFO}?${QUERY_STRING}#ERROR_PW_EMPTYTOOSHORT"
    elif [ "$pw" != "$pwconfirm" ]; then
      REDIRECT "${_BASE}${PATH_INFO}?${QUERY_STRING}#ERROR_PW_MISMATCH"
-   elif LOCK "$user_db"; then
-     read -r UID       UNAME   STATUS  EMAIL   PWSALT  PWHASH  EXPIRE  DEVICES FUTUREUSE <<-EOF
-       $(grep "^${uid} " "$user_db")
-       EOF
-     if [ "$STATUS" != pending -o "$EXPIRE" -le "$_DATE" ]; then
-       RELEASE "$user_db"
-       REDIRECT "${_BASE}${PATH_INFO}?${QUERY_STRING}#ERROR_LINK_INVALID"
-     else
-       printf '%s      %s      active  %s      %s      %s      %i      %s      %s\n' \
-              "$UID" "$(STRING "$uname")" "$EMAIL" \
-              "$pwsalt" "$(user_pwhash "$pwsalt" "$pw")" \
-              "$(( $_DATE + 86400 * 730 ))" "$DEVICES" "$FUTUREUSE" \
-              >"${user_db}.$$"
-       grep -v "^${uid}        " "$user_db" >>"${user_db}.$$"
-       mv "${user_db}.$$" "${user_db}"
-       RELEASE "$user_db"
-       SESSION_COOKIE new
-       SESSION_BIND user_id "$UID"
-       REDIRECT "${_BASE}${PATH_INFO}#USER_REGISTER_CONFIRM"
-     fi
+   elif [ "$STATUS" != pending -o \! "$EXPIRE" -gt "$_DATE" ]; then
+     REDIRECT "${_BASE}${PATH_INFO}?${QUERY_STRING}#ERROR_LINK_INVALID"
+   elif user_update_user "$UID" uname="$uname" status=active password="$pw"; then
+     SESSION_COOKIE new
+     SESSION_BIND user_id "$UID"
+     REDIRECT "${_BASE}${PATH_INFO}?user_register=confirm#USER_REGISTER_CONFIRM"
    else
      REDIRECT "${_BASE}${PATH_INFO}#ERROR_USER_NOLOCK"
    fi
@@@ -243,11 -325,10 +325,10 @@@ user_disable()
    :
  }
  
- user_init
  [ "$REQUEST_METHOD" = POST ] && case "$(POST action)" in
    user_register) user_register ;;
    user_confirm)  user_confirm ;;
+   user_invite)   user_invite ;;
    user_login)    user_login ;;
    user_logout)   user_logout ;;
    user_update)
@@@ -261,7 -342,7 +342,7 @@@ esa
  w_user_register(){
    if [ "$(GET user_confirm)" ]; then
      w_user_confirm
-   elif [ "$USER_REGISTRATION" != true ]; then
+   elif [ "$USER_REGISTRATION" != true -a -s "$user_db" ]; then
      cat <<-EOF
        [div #user_register .disabled
        User Registration is disabled.
@@@ -326,6 -407,26 +407,26 @@@ w_user_confirm()
    fi
  }
  
+ w_user_invite(){
+   if [ "$(GET user_confirm)" ]; then
+     w_user_confirm
+   elif [ "$USER_ID" ]; then
+     cat <<-EOF
+       [form #user_invite method=POST
+         [input placeholder="Email Recipient" name=email autocomplete=off]
+         [textarea name="message" placeholder="Message to recipient" . ]
+         [submit "action" "user_invite" Send Invitation]
+       ]
+       EOF
+   else
+     cat <<-EOF
+       [div #user_invite .notallowed
+         Only registered users may send an invitation to another user.
+       ]
+       EOF
+   fi
+ }
  w_user_login(){
    if [ ! "$USER_ID" ]; then
      cat <<-EOF