From fd1d997ec1b8cc22c7821028989a0de5a3dc6fba Mon Sep 17 00:00:00 2001
From: Mikhail Novosyolov <mikhailnov@nixtux.ru>
Date: Fri, 22 Apr 2022 18:26:16 +0300
Subject: [PATCH] Implement config GUI

---
 .gear/doskast.spec                   | 11 +++-
 Makefile                             | 11 +++-
 doskast-student-config.sh            | 82 ++++++++++++++++++++++++++++
 doskast-student-connect.sh           |  2 +
 ru.mos.doskast-student-config.policy | 21 +++++++
 5 files changed, 124 insertions(+), 3 deletions(-)
 create mode 100755 doskast-student-config.sh
 create mode 100755 doskast-student-connect.sh
 create mode 100644 ru.mos.doskast-student-config.policy

diff --git a/.gear/doskast.spec b/.gear/doskast.spec
index c777fcd..2f872bc 100644
--- a/.gear/doskast.spec
+++ b/.gear/doskast.spec
@@ -37,15 +37,21 @@ Requires(pre): apache2-base
 %package student
 Summary: Doskast for client (student)
 Group: Graphical desktop/Other
-Requires: xpra
 Requires: curl
+Requires: polkit
+Requires: xpra
+Requires: zenity
 
 %description student
 %summary
 
 %files student
+%{_bindir}/doskast-student-config
+%{_sbindir}/doskast-student-config
 %{_unitdir}/doskast-student.service
+%{_datadir}/polkit-1/actions/ru.mos.doskast-student-config.policy
 %config(noreplace) %{_sysconfdir}/systemd/system/doskast-student.service.d/doskast-student-firewall.conf
+%config(noreplace) %{_sysconfdir}/doskastrc
 
 %post student
 %post_service doskast-student.socket doskast-student.service
@@ -64,3 +70,6 @@ desktop-file-validate *.desktop
 %makeinstall_std
 
 mkdir -p %{buildroot}/var/spool/doskast
+mkdir -p %{buildroot}%{_sysconfdir}
+touch %{buildroot}%{_sysconfdir}/doskastrc
+chmod 0644 %{buildroot}%{_sysconfdir}/doskastrc
diff --git a/Makefile b/Makefile
index 6477661..9e7846d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,7 @@
 PREFIX ?= /usr
 BINDIR ?= $(PREFIX)/bin
+SBINDIR ?= $(PREFIX)/sbin
+DATADIR ?= $(PREFIX)/share
 SYSCONFDIR ?= /etc
 UNITDIR ?= /lib/systemd/system
 
@@ -18,10 +20,15 @@ install:
 	install -m0644 doskast-student-firewall.conf $(DESTDIR)/etc/systemd/system/doskast-student.service.d
 
 	mkdir -p --mode=0755 $(DESTDIR)$(BINDIR)
+	mkdir -p --mode=0755 $(DESTDIR)$(SBINDIR)
 	install -m0755 doskast-server-watcher.sh $(DESTDIR)$(BINDIR)/doskast-server-watcher
+	install -m0755 doskast-student-config.sh $(DESTDIR)$(SBINDIR)/doskast-student-config
+	echo -e '#!/bin/sh\n$(BINDIR)/doskast-student-config "$$@"' > $(DESTDIR)$(BINDIR)/doskast-student-config
+	chmod 0755 $(DESTDIR)$(BINDIR)/doskast-student-config
 
 	mkdir -p --mode=0755 $(DESTDIR)$(SYSCONFDIR)/xdg/autostart
 	install -m0644 doskast-server-watcher.desktop $(DESTDIR)$(SYSCONFDIR)/xdg/autostart
 
-rpm:
-	rpmbuild --define "_sourcedir $$PWD" -bb doskast.spec
+	mkdir -p --mode=0755 $(DESTDIR)$(DATADIR)/polkit-1/actions
+	install -m0644 ru.mos.doskast-student-config.policy $(DESTDIR)$(DATADIR)/polkit-1/actions
+
diff --git a/doskast-student-config.sh b/doskast-student-config.sh
new file mode 100755
index 0000000..64ff595
--- /dev/null
+++ b/doskast-student-config.sh
@@ -0,0 +1,82 @@
+#!/bin/bash
+
+set -e
+set -u
+set -f
+set -o pipefail
+
+echo_err(){
+	echo "$@" 1>&2
+}
+
+#readonly dir="${XDG_CONFIG_HOME:-$HOME/.config}"
+readonly dir="/etc"
+mkdir -p "$dir"
+readonly config="$dir/doskastrc"
+
+_zenity(){
+	zenity --width=250 --title="Doskast" "$@"
+}
+	
+# $1: path
+_create_config(){
+	if ! echo 'board=' > "$1"; then
+		_zenity --error --text="Ошибка при создании пустого конфига"
+		return 1
+	fi
+}
+
+# $1: IP
+_write_systemd_config(){
+	mkdir -p /etc/systemd/system/doskast-student.service.d
+	cat > /etc/systemd/system/doskast-student.service.d/doskast-student-firewall.conf << EOF
+[Service]
+IPAddressDeny=any
+# IP-адрес доски
+IPAddressAllow=$1
+EOF
+}
+
+corrupted=0
+board=""
+if ! test -f "$config"; then
+	echo_err "No config $config, creating it"
+	_create_config "$config"
+else
+	if ! . "$config"; then
+		corrupted=1
+	fi
+	if test -z "${board:-}"; then
+		corrupted=1
+	fi
+	if [ "$corrupted" = 1 ]; then
+		echo_err "Config file $config is corrupted, recreating it..."
+		_create_config "$config"
+	fi
+fi
+
+# TODO: validate IP
+if ! answer="$(zenity \
+	--entry \
+	--title="Doskast" \
+	--text="Введите IP-адрес доски:" \
+	--entry-text "$board"
+)"; then
+	_zenity --error --text="Произошла неизвестная ошибка."
+	exit 1
+fi
+
+if test -z "$answer" ; then
+	zenity --title="Doskast" --error --text="Введено пустое знаничение. Попробуйте заново."
+	exit 1
+fi
+
+if ! _write_systemd_config "$answer"; then
+	_zenity --error --text="Ошибка при сохранении настроек eBPF-фаерволирования."
+	exit 1
+fi
+
+if echo board="$answer" > "$config"; then
+	# жаба, чтобы был нулевой код возврата при нажатии "Отмена"
+	_zenity --info --text="Настройки сохранены" || :
+fi
diff --git a/doskast-student-connect.sh b/doskast-student-connect.sh
new file mode 100755
index 0000000..05a7907
--- /dev/null
+++ b/doskast-student-connect.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+
diff --git a/ru.mos.doskast-student-config.policy b/ru.mos.doskast-student-config.policy
new file mode 100644
index 0000000..841158f
--- /dev/null
+++ b/ru.mos.doskast-student-config.policy
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE policyconfig PUBLIC "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
+<policyconfig>
+<vendor>KDE</vendor>
+<vendor_url>http://osmesh.ru</vendor_url>
+<icon_name>document-page-setup</icon_name>
+<action id="ru.mos.doskast-student-config">
+<description>Setup student part of Doskast</description>
+<description xml:lang="ru">Настройка ученичоеской части Doskast</description>
+<message>Enter password to setup Doskast</message>
+<message xml:lang="ru">Введите пароль для настройки Doskast</message>
+<defaults>
+<allow_any>auth_admin</allow_any>
+<allow_inactive>auth_admin</allow_inactive>
+<allow_active>auth_admin</allow_active>
+</defaults>
+<annotate key="org.freedesktop.policykit.exec.path">/usr/sbin/doskast-student-setup</annotate>
+<annotate key="org.freedesktop.policykit.exec.allow_gui">true</annotate>
+</action>
+</policyconfig>