Implement an advanced registration loop to begin supporting multiple registration methods
This commit is contained in:
parent
7cdff45600
commit
bea7df3390
192
rowbot
192
rowbot
|
@ -354,12 +354,14 @@ state_resolve() {
|
|||
|
||||
# This is a false positive.
|
||||
# shellcheck disable=SC2102
|
||||
if [[ -v config[$1] ]]; then
|
||||
ns_config[$1]=${config[$1]}
|
||||
elif [[ -v config[$ns-$1] ]]; then
|
||||
if [[ -v config[$ns-$1] ]]; then
|
||||
ns_config[$1]=${config[$ns-$1]}
|
||||
elif [[ -v config[$1] ]]; then
|
||||
ns_config[$1]=${config[$1]}
|
||||
elif [[ -v DEFAULT ]]; then
|
||||
ns_config[$1]=$DEFAULT
|
||||
elif [[ -v DEFAULT_N && $DEFAULT_N ]]; then
|
||||
ns_config[$1]=$DEFAULT_N
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
|
@ -400,6 +402,17 @@ state_get() {
|
|||
fi
|
||||
}
|
||||
|
||||
state_keys() {
|
||||
# The `ns_config` variable is a reference to an array
|
||||
# shellcheck disable=SC2178
|
||||
declare -n ns_config=__rowbot_state_store_"${NS-global}"
|
||||
declare -n array_keys=${1-CONFIG_KEYS}
|
||||
# The `array_keys` variable initializes a variable declared by the calling
|
||||
# code.
|
||||
# shellcheck disable=SC2034
|
||||
array_keys=( "${!ns_config[@]}" )
|
||||
}
|
||||
|
||||
state_has() {
|
||||
local ns=${NS-global} found=1 managed
|
||||
# The `ns_config` variable is a reference to an array
|
||||
|
@ -736,6 +749,103 @@ on_sys_exit_997_annoyatron900() {
|
|||
# register with the server
|
||||
###
|
||||
|
||||
on_sys_first_020_enroll() {
|
||||
NS=enroll state_resolve caps
|
||||
NS=enroll state_resolve pass
|
||||
NS=irc DEFAULT=rowbot-dev state_resolve nick
|
||||
NS=irc DEFAULT=rowbot state_resolve ident
|
||||
NS=irc DEFAULT=rowbot state_resolve realname
|
||||
|
||||
log_debug "beginning irc registration handshake"
|
||||
|
||||
if NS=enroll state_has caps; then
|
||||
log_debug "requesting list of available capabilities"
|
||||
irc_cap ls
|
||||
fi
|
||||
|
||||
if NS=enroll state_has pass; then
|
||||
log_debug "sending account password"
|
||||
irc_pass "$(NS=enroll state_get pass)"
|
||||
fi
|
||||
|
||||
log_debug "sending registration data"
|
||||
irc_nick "$(NS=irc state_get nick)"
|
||||
irc_user "$(NS=irc state_get ident)" "$(NS=irc state_get realname)"
|
||||
}
|
||||
|
||||
on_msg_CAP_enroll() {
|
||||
local avail_cap{s,} desired_cap{s,} caps mechanism advertised
|
||||
|
||||
if NS=enroll state_has caps; then
|
||||
case ${msg_args[1]^^} in
|
||||
LS)
|
||||
if ! NS=enroll QUIET="" state_get requested-caps; then
|
||||
NS=avail_caps state_keys avail_caps
|
||||
read -ra desired_caps < <(NS=enroll state_get caps)
|
||||
|
||||
# The `avail_caps` array gets initialized in the state_keys function.
|
||||
# shellcheck disable=SC2154
|
||||
for avail_cap in "${avail_caps[@]}"; do
|
||||
for desired_cap in "${desired_caps[@]}"; do
|
||||
if [[ $avail_cap = "$desired_cap" ]]; then
|
||||
caps+=( "$avail_cap" )
|
||||
NS=caps state_put "$avail_cap" ""
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
irc_cap req "${caps[@]}"
|
||||
NS=enroll state_put requested-caps yes
|
||||
fi
|
||||
;;
|
||||
NAK)
|
||||
irc_cap end
|
||||
NS=enroll state_put have-caps no
|
||||
;;
|
||||
ACK)
|
||||
NS=enroll state_put have-caps yes
|
||||
|
||||
if NS=caps state_has sasl; then
|
||||
if NS=enroll state_has pass; then
|
||||
mechanism=plain
|
||||
elif NS=net QUIET="" state_get tls && NS=net state_has client-cert; then
|
||||
mechanism=external
|
||||
fi
|
||||
|
||||
NS=sasl DEFAULT_N=$mechanism state_resolve mechanism
|
||||
NS=sasl DEFAULT=yes state_resolve required
|
||||
|
||||
if ! NS=sasl state_has mechanism; then
|
||||
die "please specify an appropriate sasl mechanism"
|
||||
fi
|
||||
|
||||
advertised=$(NS=avail_caps state_get sasl)
|
||||
mechanism=$(NS=sasl state_get mechanism)
|
||||
|
||||
if [[ ,$advertised, = *,"${mechanism^^}",* ]]; then
|
||||
irc_authenticate mechanism "$(NS=sasl state_get mechanism)"
|
||||
else
|
||||
if NS=sasl QUIET="" state_get required; then
|
||||
die "%s is not a valid sasl mechanism" "$mechanism"
|
||||
else
|
||||
log_warn "connecting without sasl"
|
||||
irc_cap end
|
||||
fi
|
||||
fi
|
||||
else
|
||||
irc_cap end
|
||||
fi
|
||||
esac
|
||||
fi
|
||||
}
|
||||
|
||||
on_msg_AUTHENTICATE_enroll() {
|
||||
# Any fail scenario is already covered.
|
||||
# shellcheck disable=SC2155
|
||||
local mechanism=$(NS=sasl state_get mechanism)
|
||||
irc_authenticate +
|
||||
}
|
||||
|
||||
on_sys_init_010_bootup() {
|
||||
DEFAULT=${USER:-uplime} state_resolve owner
|
||||
DEFAULT=\` state_resolve trigger
|
||||
|
@ -746,15 +856,6 @@ on_sys_init_020_welcome() {
|
|||
NS=irc state_resolve chans
|
||||
}
|
||||
|
||||
on_sys_first_020_welcome() {
|
||||
NS=irc DEFAULT=rowbot-dev state_resolve nick
|
||||
NS=irc DEFAULT=rowbot state_resolve ident
|
||||
NS=irc DEFAULT=rowbot state_resolve realname
|
||||
log_debug "registering with the server"
|
||||
irc_nick "$(NS=irc state_get nick)"
|
||||
irc_user "$(NS=irc state_get ident)" "$(NS=irc state_get realname)"
|
||||
}
|
||||
|
||||
on_msg_005_welcome() {
|
||||
local param key value
|
||||
|
||||
|
@ -797,6 +898,35 @@ on_msg_396_privmagic() {
|
|||
# irc receive handlers
|
||||
###
|
||||
|
||||
irc_on_AUTHENTICATE() {
|
||||
log_debug "received authentication acknowledgement"
|
||||
}
|
||||
|
||||
irc_on_CAP() {
|
||||
local cap caps
|
||||
|
||||
case ${msg_args[1]^^} in
|
||||
LS)
|
||||
caps=${msg_args[-1]}
|
||||
|
||||
while [[ $caps ]]; do
|
||||
cap=${caps%% *} caps=${caps#"$cap"} caps=${caps# }
|
||||
|
||||
if [[ $cap = *=* ]]; then
|
||||
NS=avail_caps state_put "${cap%%=*}" "${cap#*=}"
|
||||
else
|
||||
NS=avail_caps state_put "$cap" ""
|
||||
fi
|
||||
done
|
||||
;;
|
||||
NAK)
|
||||
log_error "unable to request capabilities for %s" "$(NS=irc state_get nick)"
|
||||
;;
|
||||
ACK)
|
||||
log_debug "have successfully received capabilities from server: %s" "${msg_args[-1]}"
|
||||
esac
|
||||
}
|
||||
|
||||
irc_on_ERROR() {
|
||||
log_error "${msg_args[0]}"
|
||||
exit
|
||||
|
@ -983,6 +1113,30 @@ irc_accept() {
|
|||
net_send "ACCEPT $1"
|
||||
}
|
||||
|
||||
irc_authenticate() {
|
||||
case ${1,,} in
|
||||
mechanism)
|
||||
net_send "AUTHENTICATE %s" "${2^^}"
|
||||
;;
|
||||
*)
|
||||
net_send "AUTHENTICATE %s" "$*"
|
||||
esac
|
||||
}
|
||||
|
||||
irc_cap() {
|
||||
case ${1,,} in
|
||||
ls)
|
||||
net_send "CAP LS %s" "${2-302}"
|
||||
;;
|
||||
req)
|
||||
shift
|
||||
net_send "CAP REQ :%s" "$*"
|
||||
;;
|
||||
end)
|
||||
net_send "CAP END"
|
||||
esac
|
||||
}
|
||||
|
||||
irc_join() {
|
||||
local chans
|
||||
printf -v chans %s, "$@"
|
||||
|
@ -1027,6 +1181,10 @@ irc_part() {
|
|||
fi
|
||||
}
|
||||
|
||||
irc_pass() {
|
||||
net_send "PASS $1"
|
||||
}
|
||||
|
||||
irc_ping() {
|
||||
net_send "PING :%s" "$1"
|
||||
}
|
||||
|
@ -1053,16 +1211,6 @@ irc_privmsg() {
|
|||
log_info "<%s/%s> %s" "${config[nick]}" "$1" "$msg"
|
||||
}
|
||||
|
||||
irc_part() {
|
||||
if (( $# )); then
|
||||
if (( $# > 1 )); then
|
||||
net_send "PART $1 :$2"
|
||||
else
|
||||
net_send "PART $1"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
irc_quit() {
|
||||
if (( $# )); then
|
||||
net_send "QUIT :%s" "$1"
|
||||
|
|
Loading…
Reference in New Issue