From cb5aed8e79fea157b674a8da36bf34c59526203b Mon Sep 17 00:00:00 2001 From: Junyuan Feng Date: Tue, 24 May 2022 12:44:12 +0800 Subject: [PATCH] fix & opt - apt/yum if not root, auto try saved pwd - ServerPrivateInfo.authorization: Object => String pwd - fix apt parse: caused by irrelevant output - serverprovider replace _servers[idx] with s --- ios/Runner.xcodeproj/project.pbxproj | 12 +++--- .../model/server/server_private_info.dart | 8 ++-- lib/data/model/sftp/download_worker.dart | 3 +- lib/data/provider/apt.dart | 13 +++++-- lib/data/provider/server.dart | 39 +++++++++---------- lib/data/res/build_data.dart | 6 +-- lib/generated/intl/messages_en.dart | 4 +- lib/generated/l10n.dart | 8 ++-- lib/l10n/intl_en.arb | 4 +- lib/view/page/apt.dart | 25 +++++++++--- lib/view/page/server/edit.dart | 15 +++---- macos/Runner.xcodeproj/project.pbxproj | 12 +++--- 12 files changed, 79 insertions(+), 70 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index ecb3e2d8..defd1fb6 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -354,7 +354,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 142; + CURRENT_PROJECT_VERSION = 143; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -362,7 +362,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.142; + MARKETING_VERSION = 1.0.143; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -484,7 +484,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 142; + CURRENT_PROJECT_VERSION = 143; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -492,7 +492,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.142; + MARKETING_VERSION = 1.0.143; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -508,7 +508,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 142; + CURRENT_PROJECT_VERSION = 143; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -516,7 +516,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.142; + MARKETING_VERSION = 1.0.143; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; diff --git a/lib/data/model/server/server_private_info.dart b/lib/data/model/server/server_private_info.dart index c2bedb4f..4eddeb7f 100644 --- a/lib/data/model/server/server_private_info.dart +++ b/lib/data/model/server/server_private_info.dart @@ -17,7 +17,7 @@ class ServerPrivateInfo { late String ip; late int port; late String user; - late Object authorization; + late String pwd; String? pubKeyId; ServerPrivateInfo( @@ -25,14 +25,14 @@ class ServerPrivateInfo { required this.ip, required this.port, required this.user, - required this.authorization, + required this.pwd, this.pubKeyId}); ServerPrivateInfo.fromJson(Map json) { name = json["name"].toString(); ip = json["ip"].toString(); port = json["port"].toInt(); user = json["user"].toString(); - authorization = json["authorization"]; + pwd = json["authorization"].toString(); pubKeyId = json["pubKeyId"]?.toString(); } Map toJson() { @@ -41,7 +41,7 @@ class ServerPrivateInfo { data["ip"] = ip; data["port"] = port; data["user"] = user; - data["authorization"] = authorization; + data["authorization"] = pwd; data["pubKeyId"] = pubKeyId; return data; } diff --git a/lib/data/model/sftp/download_worker.dart b/lib/data/model/sftp/download_worker.dart index 3def2e3d..e6dfa92e 100644 --- a/lib/data/model/sftp/download_worker.dart +++ b/lib/data/model/sftp/download_worker.dart @@ -58,8 +58,7 @@ class SftpDownloadWorker { SSHClient client; if (spi.pubKeyId == null) { client = SSHClient(socket, - username: spi.user, - onPasswordRequest: () => spi.authorization as String); + username: spi.user, onPasswordRequest: () => spi.pwd); } else { client = SSHClient(socket, username: spi.user, diff --git a/lib/data/provider/apt.dart b/lib/data/provider/apt.dart index b2ac2f1e..d6109f90 100644 --- a/lib/data/provider/apt.dart +++ b/lib/data/provider/apt.dart @@ -11,7 +11,7 @@ import 'package:toolbox/data/model/apt/upgrade_pkg_info.dart'; import 'package:toolbox/data/model/distribution.dart'; typedef PwdRequestFunc = Future Function( - bool lastTimes, String? userName); + int triedTimes, String? userName); final pwdRequestWithUserReg = RegExp(r'\[sudo\] password for (.+):'); class AptProvider extends BusyProvider { @@ -87,7 +87,12 @@ class AptProvider extends BusyProvider { list = list.sublist(0, endLine); break; default: - list = list.sublist(4); + // avoid other outputs + // such as: [Could not chdir to home directory /home/test: No such file or directory, , WARNING: apt does not have a stable CLI interface. Use with caution in scripts., , Listing...] + final idx = list.indexWhere((element) => element.contains('[upgradable from:')); + if (idx != -1) { + list = list.sublist(idx); + } list.removeWhere((element) => element.isEmpty); } upgradeable = list.map((e) => UpgradePkgInfo(e, dist!)).toList(); @@ -153,8 +158,8 @@ class AptProvider extends BusyProvider { final user = pwdRequestWithUserReg.firstMatch(event)?.group(1); logger.info('sudo password request for $user'); triedTimes++; - final pwd = await (onPasswordRequest ?? (_, __) async => '')( - triedTimes == 3, user); + final pwd = + await (onPasswordRequest ?? (_, __) async => '')(triedTimes, user); if (pwd.isEmpty) { logger.info('sudo password request cancelled'); return; diff --git a/lib/data/provider/server.dart b/lib/data/provider/server.dart index 91e203cb..faf4984d 100644 --- a/lib/data/provider/server.dart +++ b/lib/data/provider/server.dart @@ -43,6 +43,7 @@ const shellCmd = "export LANG=en_US.utf-8 \necho '$seperator' \n" const shellPath = '.serverbox.sh'; const memPrefix = 'Mem:'; final cpuTempReg = RegExp('(x86_pkg_temp|cpu_thermal)'); +final numReg = RegExp(r'\s{1,}'); class ServerProvider extends BusyProvider { List _servers = []; @@ -91,8 +92,7 @@ class ServerProvider extends BusyProvider { final socket = await SSHSocket.connect(spi.ip, spi.port); if (spi.pubKeyId == null) { return SSHClient(socket, - username: spi.user, - onPasswordRequest: () => spi.authorization as String); + username: spi.user, onPasswordRequest: () => spi.pwd); } final key = locator().get(spi.pubKeyId!); return SSHClient(socket, @@ -163,25 +163,23 @@ class ServerProvider extends BusyProvider { } Future _getData(ServerPrivateInfo spi) async { - final idx = _servers.indexWhere((element) => element.info == spi); - final state = _servers[idx].connectionState; + final s = _servers.firstWhere((element) => element.info == spi); + final state = s.connectionState; if (state == ServerConnectionState.failed || state == ServerConnectionState.disconnected) { - _servers[idx].connectionState = ServerConnectionState.connecting; + s.connectionState = ServerConnectionState.connecting; notifyListeners(); final time1 = DateTime.now(); try { - _servers[idx].client = await genClient(spi); + s.client = await genClient(spi); final time2 = DateTime.now(); logger.info( 'Connected to [${spi.name}] in [${time2.difference(time1).toString()}].'); - _servers[idx].connectionState = ServerConnectionState.connected; - _servers[idx] - .client! - .run("echo '$shellCmd' > $shellPath && chmod +x $shellPath"); + s.connectionState = ServerConnectionState.connected; + s.client!.run("echo '$shellCmd' > $shellPath && chmod +x $shellPath"); } catch (e) { - _servers[idx].connectionState = ServerConnectionState.failed; - _servers[idx].status.failedInfo = '$e ## '; + s.connectionState = ServerConnectionState.failed; + s.status.failedInfo = '$e ## '; logger.warning(e); } finally { notifyListeners(); @@ -189,12 +187,11 @@ class ServerProvider extends BusyProvider { } // if client is null, return - final si = _servers[idx]; - if (si.client == null) return; - final raw = await si.client!.run("sh $shellPath").string; + if (s.client == null) return; + final raw = await s.client!.run("sh $shellPath").string; if (raw.isEmpty) { - _servers[idx].connectionState = ServerConnectionState.failed; - _servers[idx].status.failedInfo = 'Empty output'; + s.connectionState = ServerConnectionState.failed; + s.status.failedInfo = 'Empty output'; notifyListeners(); return; } @@ -210,8 +207,8 @@ class ServerProvider extends BusyProvider { _getTcp(spi, lines[4]); _getNetSpeed(spi, lines[0]); } catch (e) { - _servers[idx].connectionState = ServerConnectionState.failed; - servers[idx].status.failedInfo = e.toString(); + s.connectionState = ServerConnectionState.failed; + s.status.failedInfo = e.toString(); logger.warning(e); rethrow; } finally { @@ -307,7 +304,7 @@ class ServerProvider extends BusyProvider { final idx = lines.lastWhere((element) => element.startsWith('Tcp:'), orElse: () => ''); if (idx != '') { - final vals = idx.split(RegExp(r'\s{1,}')); + final vals = idx.split(numReg); info.status.tcp = TcpStatus(vals[5].i, vals[6].i, vals[7].i, vals[8].i); } } @@ -320,7 +317,7 @@ class ServerProvider extends BusyProvider { if (items.indexOf(item) == 0 || item.isEmpty) { continue; } - final vals = item.split(RegExp(r'\s{1,}')); + final vals = item.split(numReg); list.add(DiskInfo(vals[0], vals[5], int.parse(vals[4].replaceFirst('%', '')), vals[2], vals[1], vals[3])); } diff --git a/lib/data/res/build_data.dart b/lib/data/res/build_data.dart index 02ed1abd..a17a9650 100644 --- a/lib/data/res/build_data.dart +++ b/lib/data/res/build_data.dart @@ -2,9 +2,9 @@ class BuildData { static const String name = "ServerBox"; - static const int build = 142; + static const int build = 143; static const String engine = "Flutter 3.0.1 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision fb57da5f94 (3 days ago) • 2022-05-19 15:50:29 -0700\nEngine • revision caaafc5604\nTools • Dart 2.17.1 • DevTools 2.12.2\n"; - static const String buildAt = "2022-05-23 17:46:58.865964"; - static const int modifications = 5; + static const String buildAt = "2022-05-23 17:48:09.246927"; + static const int modifications = 0; } diff --git a/lib/generated/intl/messages_en.dart b/lib/generated/intl/messages_en.dart index 385d27b8..7cbb98a5 100644 --- a/lib/generated/intl/messages_en.dart +++ b/lib/generated/intl/messages_en.dart @@ -133,7 +133,7 @@ class MessageLookup extends MessageLookupByLibrary { "license": MessageLookupByLibrary.simpleMessage("License"), "loadingFiles": MessageLookupByLibrary.simpleMessage("Loading files..."), - "loss": MessageLookupByLibrary.simpleMessage("Loss"), + "loss": MessageLookupByLibrary.simpleMessage("loss"), "madeWithLove": m8, "max": MessageLookupByLibrary.simpleMessage("max"), "min": MessageLookupByLibrary.simpleMessage("min"), @@ -203,7 +203,7 @@ class MessageLookup extends MessageLookupByLibrary { "stop": MessageLookupByLibrary.simpleMessage("Stop"), "sureDelete": m12, "sureToDeleteServer": m13, - "ttl": MessageLookupByLibrary.simpleMessage("TTL"), + "ttl": MessageLookupByLibrary.simpleMessage("ttl"), "unknown": MessageLookupByLibrary.simpleMessage("unknown"), "unknownError": MessageLookupByLibrary.simpleMessage("Unknown error"), "unkownConvertMode": diff --git a/lib/generated/l10n.dart b/lib/generated/l10n.dart index f34472c1..d6421246 100644 --- a/lib/generated/l10n.dart +++ b/lib/generated/l10n.dart @@ -330,20 +330,20 @@ class S { ); } - /// `TTL` + /// `ttl` String get ttl { return Intl.message( - 'TTL', + 'ttl', name: 'ttl', desc: '', args: [], ); } - /// `Loss` + /// `loss` String get loss { return Intl.message( - 'Loss', + 'loss', name: 'loss', desc: '', args: [], diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index 660a6535..6e7f47d6 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -27,8 +27,8 @@ "min": "min", "max": "max", "ms": "ms", - "ttl": "TTL", - "loss": "Loss", + "ttl": "ttl", + "loss": "loss", "noResult": "No result", "pingInputIP": "Please input a target IP/domain.", "clear": "Clear", diff --git a/lib/view/page/apt.dart b/lib/view/page/apt.dart index 847515ce..a3032a95 100644 --- a/lib/view/page/apt.dart +++ b/lib/view/page/apt.dart @@ -71,11 +71,14 @@ class _AptManagePageState extends State }; // ignore: prefer_function_declarations_over_variables - PwdRequestFunc onPwdRequest = (lastTime, user) async { + PwdRequestFunc onPwdRequest = (triedTimes, user) async { if (!mounted) return ''; + if (triedTimes == 1) { + return widget.spi.pwd; + } await showRoundDialog( context, - lastTime ? s.lastTry : (user ?? s.unknown), + triedTimes == 3 ? s.lastTry : (user ?? s.unknown), TextField( controller: textController, keyboardType: TextInputType.visiblePassword, @@ -105,7 +108,7 @@ class _AptManagePageState extends State () => scrollController.jumpTo(scrollController.position.maxScrollExtent), () => scrollControllerUpdate - .jumpTo(scrollControllerUpdate.position.maxScrollExtent), + .jumpTo(scrollControllerUpdate.positions.last.maxScrollExtent), onPwdRequest); _aptProvider.refreshInstalled(); } @@ -130,9 +133,19 @@ class _AptManagePageState extends State const SizedBox( height: 37, ), - Text( - apt.error!, - textAlign: TextAlign.center, + SizedBox( + height: _media.size.height * 0.4, + child: Padding( + padding: EdgeInsets.all(17), + child: RoundRectCard( + SingleChildScrollView( + padding: EdgeInsets.all(17), + child: Text( + apt.error!, + textAlign: TextAlign.center, + )), + ), + ), ), ], ); diff --git a/lib/view/page/server/edit.dart b/lib/view/page/server/edit.dart index 582466c6..14ced5ec 100644 --- a/lib/view/page/server/edit.dart +++ b/lib/view/page/server/edit.dart @@ -214,18 +214,13 @@ class _ServerEditPageState extends State with AfterLayoutMixin { _keyInfo ??= locator().get(widget.spi!.pubKeyId!); } - final authorization = usePublicKey - ? { - "privateKey": _keyInfo!.privateKey, - "passphrase": _keyInfo!.password - } - : passwordController.text; + final authorization = passwordController.text; final spi = ServerPrivateInfo( name: nameController.text, ip: ipController.text, port: int.parse(portController.text), user: usernameController.text, - authorization: authorization, + pwd: authorization, pubKeyId: usePublicKey ? _keyInfo!.id : null); if (widget.spi == null) { @@ -260,10 +255,10 @@ class _ServerEditPageState extends State with AfterLayoutMixin { ipController.text = widget.spi?.ip ?? ''; portController.text = (widget.spi?.port ?? 22).toString(); usernameController.text = widget.spi?.user ?? ''; - if (widget.spi?.authorization is String) { - passwordController.text = widget.spi?.authorization as String? ?? ''; + if (widget.spi?.pwd is String) { + passwordController.text = widget.spi?.pwd ?? ''; } else { - final auth = widget.spi?.authorization as Map; + final auth = widget.spi?.pwd as Map; passwordController.text = auth['passphrase']; keyController.text = auth['privateKey']; usePublicKey = true; diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index a21d436a..ef67b7e1 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -420,14 +420,14 @@ CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 142; + CURRENT_PROJECT_VERSION = 143; DEVELOPMENT_TEAM = BA88US33G6; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/../Frameworks", ); - MARKETING_VERSION = 1.0.142; + MARKETING_VERSION = 1.0.143; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 5.0; @@ -550,14 +550,14 @@ CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 142; + CURRENT_PROJECT_VERSION = 143; DEVELOPMENT_TEAM = BA88US33G6; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/../Frameworks", ); - MARKETING_VERSION = 1.0.142; + MARKETING_VERSION = 1.0.143; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -574,14 +574,14 @@ CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 142; + CURRENT_PROJECT_VERSION = 143; DEVELOPMENT_TEAM = BA88US33G6; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/../Frameworks", ); - MARKETING_VERSION = 1.0.142; + MARKETING_VERSION = 1.0.143; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 5.0;