Krolyxon
Commit 6fa78da

Branches

Refs →

aurora.localbincampus-login

108 lines · 3.6 KB · Bourne Again Shell (bash)

1#!/usr/bin/env bash
2# campus-login: detect a captive portal and open it in your browser,
3# reporting every step through the notification daemon.
4#
5# Usage: campus-login [-n|--no-wait] [-h|--help]
6# -n, --no-wait don't wait around to confirm you're online afterwards
7#
8# Env overrides:
9# PROBE_URL plain-HTTP URL that returns 204 when there is no portal
10# WAIT_TIMEOUT seconds to wait for connectivity after opening the portal
11
12set -u
13
14PROBE_URL=${PROBE_URL:-http://connectivitycheck.gstatic.com/generate_204}
15WAIT_TIMEOUT=${WAIT_TIMEOUT:-180}
16WAIT=1
17
18case "${1:-}" in
19 -n|--no-wait) WAIT=0 ;;
20 -h|--help) sed -n '2,12p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
21esac
22
23# --- notifications ----------------------------------------------------------
24# Every notification shares one "synchronous" tag so they replace each other
25# instead of stacking (works with dunst, mako, swaync).
26notify() { # notify <urgency> <icon> <title> <body>
27 local urgency=$1 icon=$2 title=$3 body=$4
28 echo "$title: $body"
29 command -v notify-send >/dev/null 2>&1 || return 0
30 notify-send -a campus-login -u "$urgency" -i "$icon" \
31 -h string:x-canonical-private-synchronous:campus-login \
32 -h string:x-dunst-stack-tag:campus-login \
33 "$title" "$body"
34}
35
36# --- probe ------------------------------------------------------------------
37# Prints "<http_code> <redirect_url>". curl resolves relative redirects for us,
38# so no more grepping/sed-ing the Location header.
39probe() {
40 curl -s -o /dev/null --max-time 5 \
41 -w '%{http_code} %{redirect_url}' "$PROBE_URL" 2>/dev/null
42}
43
44read -r CODE URL < <(probe)
45CODE=${CODE:-000}
46
47case "$CODE" in
48 000)
49 notify critical network-error "No connection" \
50 "Couldn't reach the network. Are you connected to the Wi-Fi?"
51 exit 2
52 ;;
53 204)
54 notify low network-wireless "Already online" \
55 "No captive portal detected."
56 exit 0
57 ;;
58esac
59
60if [[ -n "${URL:-}" ]]; then
61 notify normal network-wireless-acquiring "Captive portal detected" "$URL"
62else
63 # Some portals hijack the request and answer 200 without redirecting.
64 # Opening a plain-HTTP page lets the portal intercept it in the browser.
65 URL=$PROBE_URL
66 notify normal network-wireless-acquiring "Captive portal likely" \
67 "Got HTTP $CODE with no redirect. Opening a test page to trigger it."
68fi
69
70# --- pick a browser ---------------------------------------------------------
71# $BROWSER is often unset when launched from fuzzel/rofi, so fall back.
72launch=()
73if [[ -n "${BROWSER:-}" ]]; then
74 read -ra launch <<< "$BROWSER"
75fi
76if ! (( ${#launch[@]} )) || ! command -v "${launch[0]}" >/dev/null 2>&1; then
77 launch=()
78 for b in xdg-open firefox chromium google-chrome-stable brave; do
79 if command -v "$b" >/dev/null 2>&1; then launch=("$b"); break; fi
80 done
81fi
82
83if ! (( ${#launch[@]} )); then
84 notify critical dialog-error "No browser found" \
85 "Set \$BROWSER or install one. Portal URL: $URL"
86 exit 3
87fi
88
89# Detach so the browser outlives this script (and the launcher).
90setsid -f "${launch[@]}" "$URL" >/dev/null 2>&1
91notify normal web-browser "Opened portal" "${launch[0]} -> $URL"
92
93# --- wait for confirmation --------------------------------------------------
94(( WAIT )) || exit 0
95
96end=$((SECONDS + WAIT_TIMEOUT))
97while (( SECONDS < end )); do
98 sleep 3
99 read -r CODE _ < <(probe)
100 if [[ "${CODE:-000}" == 204 ]]; then
101 notify normal network-wireless "Connected" "You're online."
102 exit 0
103 fi
104done
105
106notify normal network-wireless-offline "Still not online" \
107 "No connectivity after ${WAIT_TIMEOUT}s. The login may not have completed."
108exit 4