Преглед изворни кода

_dbus.schedule_shutdown: fix suggested polkit rule when reboot fails

https://github.com/fphammerle/systemctl-mqtt/commit/452940d2516374f1779a98021b10d8cbb83448ef
Fabian Peter Hammerle пре 2 месеци
родитељ
комит
b0287212c0
2 измењених фајлова са 45 додато и 19 уклоњено
  1. 24 15
      systemctl_mqtt/_dbus/login_manager.py
  2. 21 4
      tests/test_dbus.py

+ 24 - 15
systemctl_mqtt/_dbus/login_manager.py

@@ -48,6 +48,26 @@ def _get_username() -> typing.Optional[str]:
         return None
 
 
+def _log_interactive_authorization_required(
+    *, action_label: str, action_id: str
+) -> None:
+    _LOGGER.error(
+        """failed to %s: interactive authorization required
+
+create %s and insert the following rule:
+polkit.addRule(function(action, subject) {
+    if(action.id === %s && subject.user === %s) {
+        return polkit.Result.YES;
+    }
+});
+""",
+        action_label,
+        "/etc/polkit-1/rules.d/50-systemctl-mqtt.rules",
+        json.dumps(action_id),
+        json.dumps(_get_username() or "USERNAME"),
+    )
+
+
 def get_login_manager_signal_match_rule(member: str) -> jeepney.MatchRule:
     return jeepney.MatchRule(
         type="signal",
@@ -176,21 +196,10 @@ def schedule_shutdown(*, action: str, delay: datetime.timedelta) -> None:
             exc.name == "org.freedesktop.DBus.Error.InteractiveAuthorizationRequired"
             and exc.data == ("Interactive authentication required.",)
         ):
-            _LOGGER.error(
-                """failed to schedule %s: interactive authorization required
-
-create %s and insert the following rule:
-polkit.addRule(function(action, subject) {
-    if(action.id === %s && subject.user === %s) {
-        return polkit.Result.YES;
-    }
-});
-""",
-                action,
-                "/etc/polkit-1/rules.d/50-systemctl-mqtt.rules",
-                # org.freedesktop.login1.lock-sessions
-                json.dumps("org.freedesktop.login1.power-off"),
-                json.dumps(_get_username() or "USERNAME"),
+            _log_interactive_authorization_required(
+                action_label="schedule " + action,
+                action_id="org.freedesktop.login1."
+                + {"poweroff": "power-off"}.get(action, action),
             )
         else:
             _LOGGER.error("failed to schedule %s: %s", action, exc)

+ 21 - 4
tests/test_dbus.py

@@ -115,16 +115,17 @@ class DBusErrorResponseMock(jeepney.wrappers.DBusErrorResponse):
         self.data = data
 
 
-@pytest.mark.parametrize("action", ["poweroff"])
 @pytest.mark.parametrize(
-    ("error_name", "error_message", "log_message"),
+    ("action", "error_name", "error_message", "log_message"),
     [
         (
+            "poweroff",
             "test error",
             "test message",
             "[test error] ('test message',)",
         ),
         (
+            "poweroff",
             "org.freedesktop.DBus.Error.InteractiveAuthorizationRequired",
             "Interactive authentication required.",
             """interactive authorization required
@@ -135,6 +136,22 @@ polkit.addRule(function(action, subject) {
         return polkit.Result.YES;
     }
 });
+""".replace(
+                "{{username}}", getpass.getuser()
+            ),
+        ),
+        (
+            "reboot",
+            "org.freedesktop.DBus.Error.InteractiveAuthorizationRequired",
+            "Interactive authentication required.",
+            """interactive authorization required
+
+create /etc/polkit-1/rules.d/50-systemctl-mqtt.rules and insert the following rule:
+polkit.addRule(function(action, subject) {
+    if(action.id === "org.freedesktop.login1.reboot" && subject.user === "{{username}}") {
+        return polkit.Result.YES;
+    }
+});
 """.replace(
                 "{{username}}", getpass.getuser()
             ),
@@ -142,8 +159,8 @@ polkit.addRule(function(action, subject) {
     ],
 )
 def test__schedule_shutdown_fail(
-    caplog, action, error_name, error_message, log_message
-):
+    caplog, action: str, error_name: str, error_message: str, log_message: str
+) -> None:
     login_manager_mock = unittest.mock.MagicMock()
     login_manager_mock.ScheduleShutdown.side_effect = DBusErrorResponseMock(
         name=error_name,