new: shutdown | reboot on rootless user

This commit is contained in:
lollipopkit
2023-09-03 16:40:29 +08:00
parent ab09fa6614
commit 61218f9ca3
8 changed files with 95 additions and 70 deletions

View File

@@ -2,19 +2,24 @@ import 'dart:async';
import 'package:dartssh2/dartssh2.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:toolbox/core/extension/stringx.dart';
import 'package:toolbox/core/extension/uint8list.dart';
import 'package:toolbox/core/utils/ui.dart';
typedef OnStd = void Function(String data, StreamSink<Uint8List> sink);
typedef OnStdin = void Function(StreamSink<Uint8List> sink);
import '../../data/res/misc.dart';
typedef _OnStdout = void Function(String data, StreamSink<Uint8List> sink);
typedef _OnStdin = void Function(StreamSink<Uint8List> sink);
typedef PwdRequestFunc = Future<String?> Function(String? user);
extension SSHClientX on SSHClient {
Future<int?> exec(
String cmd, {
OnStd? onStderr,
OnStd? onStdout,
OnStdin? stdin,
_OnStdout? onStderr,
_OnStdout? onStdout,
_OnStdin? stdin,
}) async {
final session = await execute(cmd);
@@ -49,4 +54,33 @@ extension SSHClientX on SSHClient {
session.close();
return session.exitCode;
}
Future<int?> execWithPwd(
String cmd, {
BuildContext? context,
_OnStdout? onStdout,
_OnStdout? onStderr,
_OnStdin? stdin,
}) async {
var isRequestingPwd = false;
return await exec(
cmd,
onStderr: (data, sink) async {
onStderr?.call(data, sink);
if (isRequestingPwd) return;
isRequestingPwd = true;
if (data.contains('[sudo] password for ')) {
final user = pwdRequestWithUserReg.firstMatch(data)?.group(1);
if (context == null) return;
final pwd = await showPwdDialog(context, user);
if (pwd == null || pwd.isEmpty) {
return;
}
sink.add('$pwd\n'.uint8List);
}
},
onStdout: onStdout,
stdin: stdin,
);
}
}

View File

@@ -5,13 +5,11 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:toolbox/core/extension/context.dart';
import 'package:toolbox/core/extension/ssh_client.dart';
import 'package:toolbox/data/model/app/tab.dart';
import 'package:url_launcher/url_launcher.dart';
import '../../data/model/server/snippet.dart';
import '../../data/provider/snippet.dart';
import '../../data/res/misc.dart';
import '../../data/res/ui.dart';
import '../../locator.dart';
import '../../view/widget/input_field.dart';
@@ -97,21 +95,6 @@ Future<String?> showPwdDialog(
);
}
Future<void> onPwd(
String event,
StreamSink<Uint8List> stdin,
PwdRequestFunc? onPwdReq,
) async {
if (event.contains('[sudo] password for ')) {
final user = pwdRequestWithUserReg.firstMatch(event)?.group(1);
final pwd = await onPwdReq?.call(user);
if (pwd == null || pwd.isEmpty) {
return;
}
stdin.add('$pwd\n'.uint8List);
}
}
Widget buildSwitch(
BuildContext context,
StorePropertyBase<bool> prop, {