oidc: init debug
Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
parent
87e53501e3
commit
a84ee7a6ec
@ -66,8 +66,7 @@ errno = "0.2.8"
|
|||||||
rdev = { git = "https://github.com/asur4s/rdev" }
|
rdev = { git = "https://github.com/asur4s/rdev" }
|
||||||
url = { version = "2.1", features = ["serde"] }
|
url = { version = "2.1", features = ["serde"] }
|
||||||
|
|
||||||
[target.'cfg(not(target_os = "linux"))'.dependencies]
|
reqwest = { version = "0.11", features = ["blocking", "json", "rustls-tls"], default-features=false }
|
||||||
reqwest = { version = "0.11", features = ["json", "rustls-tls"], default-features=false }
|
|
||||||
|
|
||||||
[target.'cfg(not(any(target_os = "android", target_os = "linux")))'.dependencies]
|
[target.'cfg(not(any(target_os = "android", target_os = "linux")))'.dependencies]
|
||||||
cpal = "0.13.5"
|
cpal = "0.13.5"
|
||||||
|
@ -2,15 +2,12 @@ import 'dart:async';
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hbb/consts.dart';
|
|
||||||
import 'package:flutter_hbb/models/platform_model.dart';
|
import 'package:flutter_hbb/models/platform_model.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
import 'package:url_launcher/url_launcher_string.dart';
|
|
||||||
|
|
||||||
import '../../common.dart';
|
import '../../common.dart';
|
||||||
import '../widgets/button.dart';
|
|
||||||
|
|
||||||
class _IconOP extends StatelessWidget {
|
class _IconOP extends StatelessWidget {
|
||||||
final String icon;
|
final String icon;
|
||||||
@ -92,10 +89,12 @@ class ConfigOP {
|
|||||||
class WidgetOP extends StatefulWidget {
|
class WidgetOP extends StatefulWidget {
|
||||||
final ConfigOP config;
|
final ConfigOP config;
|
||||||
final RxString curOP;
|
final RxString curOP;
|
||||||
|
final Function(String) cbLogin;
|
||||||
const WidgetOP({
|
const WidgetOP({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.config,
|
required this.config,
|
||||||
required this.curOP,
|
required this.curOP,
|
||||||
|
required this.cbLogin,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -107,9 +106,8 @@ class WidgetOP extends StatefulWidget {
|
|||||||
class _WidgetOPState extends State<WidgetOP> {
|
class _WidgetOPState extends State<WidgetOP> {
|
||||||
Timer? _updateTimer;
|
Timer? _updateTimer;
|
||||||
String _stateMsg = '';
|
String _stateMsg = '';
|
||||||
String _stateFailedMsg = '';
|
String _FailedMsg = '';
|
||||||
String _url = '';
|
String _url = '';
|
||||||
String _username = '';
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -138,17 +136,28 @@ class _WidgetOPState extends State<WidgetOP> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final String stateMsg = resultMap['state_msg'];
|
final String stateMsg = resultMap['state_msg'];
|
||||||
final String failedMsg = resultMap['failed_msg'];
|
String failedMsg = resultMap['failed_msg'];
|
||||||
// to-do: test null url
|
final String? url = resultMap['url'];
|
||||||
final String url = resultMap['url'];
|
final authBody = resultMap['auth_body'];
|
||||||
if (_stateMsg != stateMsg) {
|
if (_stateMsg != stateMsg || _FailedMsg != failedMsg) {
|
||||||
if (_url.isEmpty && url.isNotEmpty) {
|
if (_url.isEmpty && url != null && url.isNotEmpty) {
|
||||||
launchUrl(Uri.parse(url));
|
launchUrl(Uri.parse(url));
|
||||||
_url = url;
|
_url = url;
|
||||||
}
|
}
|
||||||
|
if (authBody != null) {
|
||||||
|
_updateTimer?.cancel();
|
||||||
|
final String username = authBody['user']['name'];
|
||||||
|
widget.curOP.value = '';
|
||||||
|
widget.cbLogin(username);
|
||||||
|
}
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_stateMsg = stateMsg;
|
_stateMsg = stateMsg;
|
||||||
_stateFailedMsg = failedMsg;
|
_FailedMsg = failedMsg;
|
||||||
|
if (failedMsg.isNotEmpty) {
|
||||||
|
widget.curOP.value = '';
|
||||||
|
_updateTimer?.cancel();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -156,74 +165,95 @@ class _WidgetOPState extends State<WidgetOP> {
|
|||||||
|
|
||||||
_resetState() {
|
_resetState() {
|
||||||
_stateMsg = '';
|
_stateMsg = '';
|
||||||
_stateFailedMsg = '';
|
_FailedMsg = '';
|
||||||
_url = '';
|
_url = '';
|
||||||
_username = '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ConstrainedBox(
|
return Column(
|
||||||
constraints: const BoxConstraints(minWidth: 500),
|
children: [
|
||||||
child: Column(
|
ButtonOP(
|
||||||
children: [
|
op: widget.config.op,
|
||||||
ButtonOP(
|
curOP: widget.curOP,
|
||||||
op: widget.config.op,
|
iconWidth: widget.config.iconWidth,
|
||||||
curOP: widget.curOP,
|
primaryColor: str2color(widget.config.op, 0x7f),
|
||||||
iconWidth: widget.config.iconWidth,
|
height: 40,
|
||||||
primaryColor: str2color(widget.config.op, 0x7f),
|
onTap: () async {
|
||||||
height: 40,
|
_resetState();
|
||||||
onTap: () {
|
widget.curOP.value = widget.config.op;
|
||||||
widget.curOP.value = widget.config.op;
|
await bind.mainAccountAuth(op: widget.config.op);
|
||||||
bind.mainAccountAuth(op: widget.config.op);
|
_beginQueryState();
|
||||||
_beginQueryState();
|
},
|
||||||
},
|
),
|
||||||
),
|
Obx(() {
|
||||||
Obx(() => Offstage(
|
if (widget.curOP.isNotEmpty &&
|
||||||
offstage: widget.curOP.value != widget.config.op,
|
widget.curOP.value != widget.config.op) {
|
||||||
child: Text(
|
_FailedMsg = '';
|
||||||
_stateMsg,
|
}
|
||||||
style: TextStyle(fontSize: 12),
|
return Offstage(
|
||||||
))),
|
offstage:
|
||||||
Obx(
|
_FailedMsg.isEmpty && widget.curOP.value != widget.config.op,
|
||||||
() => Offstage(
|
child: Row(
|
||||||
offstage: widget.curOP.value != widget.config.op,
|
children: [
|
||||||
child: const SizedBox(
|
Text(
|
||||||
height: 5.0,
|
_stateMsg,
|
||||||
),
|
style: TextStyle(fontSize: 12),
|
||||||
),
|
),
|
||||||
),
|
SizedBox(width: 8),
|
||||||
Obx(
|
Text(
|
||||||
() => Offstage(
|
_FailedMsg,
|
||||||
offstage: widget.curOP.value != widget.config.op,
|
style: TextStyle(
|
||||||
child: ConstrainedBox(
|
fontSize: 14,
|
||||||
constraints: BoxConstraints(maxHeight: 20),
|
color: Colors.red,
|
||||||
child: ElevatedButton(
|
|
||||||
onPressed: () {
|
|
||||||
widget.curOP.value = '';
|
|
||||||
_updateTimer?.cancel();
|
|
||||||
_resetState();
|
|
||||||
},
|
|
||||||
child: Text(
|
|
||||||
translate('Cancel'),
|
|
||||||
style: TextStyle(fontSize: 15),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
],
|
||||||
|
));
|
||||||
|
}),
|
||||||
|
Obx(
|
||||||
|
() => Offstage(
|
||||||
|
offstage: widget.curOP.value != widget.config.op,
|
||||||
|
child: const SizedBox(
|
||||||
|
height: 5.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Obx(
|
||||||
|
() => Offstage(
|
||||||
|
offstage: widget.curOP.value != widget.config.op,
|
||||||
|
child: ConstrainedBox(
|
||||||
|
constraints: BoxConstraints(maxHeight: 20),
|
||||||
|
child: ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
widget.curOP.value = '';
|
||||||
|
_updateTimer?.cancel();
|
||||||
|
_resetState();
|
||||||
|
bind.mainAccountAuthCancel();
|
||||||
|
},
|
||||||
|
child: Text(
|
||||||
|
translate('Cancel'),
|
||||||
|
style: TextStyle(fontSize: 15),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
));
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class LoginWidgetOP extends StatelessWidget {
|
class LoginWidgetOP extends StatelessWidget {
|
||||||
final List<ConfigOP> ops;
|
final List<ConfigOP> ops;
|
||||||
final RxString curOP = ''.obs;
|
final RxString curOP;
|
||||||
|
final Function(String) cbLogin;
|
||||||
|
|
||||||
LoginWidgetOP({
|
LoginWidgetOP({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.ops,
|
required this.ops,
|
||||||
|
required this.curOP,
|
||||||
|
required this.cbLogin,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -233,6 +263,7 @@ class LoginWidgetOP extends StatelessWidget {
|
|||||||
WidgetOP(
|
WidgetOP(
|
||||||
config: op,
|
config: op,
|
||||||
curOP: curOP,
|
curOP: curOP,
|
||||||
|
cbLogin: cbLogin,
|
||||||
),
|
),
|
||||||
const Divider()
|
const Divider()
|
||||||
])
|
])
|
||||||
@ -256,6 +287,7 @@ class LoginWidgetUserPass extends StatelessWidget {
|
|||||||
final String usernameMsg;
|
final String usernameMsg;
|
||||||
final String passMsg;
|
final String passMsg;
|
||||||
final bool isInProgress;
|
final bool isInProgress;
|
||||||
|
final RxString curOP;
|
||||||
final Function(String, String) onLogin;
|
final Function(String, String) onLogin;
|
||||||
const LoginWidgetUserPass({
|
const LoginWidgetUserPass({
|
||||||
Key? key,
|
Key? key,
|
||||||
@ -264,6 +296,7 @@ class LoginWidgetUserPass extends StatelessWidget {
|
|||||||
required this.usernameMsg,
|
required this.usernameMsg,
|
||||||
required this.passMsg,
|
required this.passMsg,
|
||||||
required this.isInProgress,
|
required this.isInProgress,
|
||||||
|
required this.curOP,
|
||||||
required this.onLogin,
|
required this.onLogin,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@ -271,86 +304,90 @@ class LoginWidgetUserPass extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var userController = TextEditingController(text: username);
|
var userController = TextEditingController(text: username);
|
||||||
var pwdController = TextEditingController(text: pass);
|
var pwdController = TextEditingController(text: pass);
|
||||||
return ConstrainedBox(
|
return Column(
|
||||||
constraints: const BoxConstraints(minWidth: 500),
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
child: Column(
|
children: [
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
const SizedBox(
|
||||||
children: [
|
height: 8.0,
|
||||||
const SizedBox(
|
),
|
||||||
height: 8.0,
|
Row(
|
||||||
),
|
children: [
|
||||||
Row(
|
ConstrainedBox(
|
||||||
children: [
|
constraints: const BoxConstraints(minWidth: 100),
|
||||||
ConstrainedBox(
|
child: Text(
|
||||||
constraints: const BoxConstraints(minWidth: 100),
|
'${translate("Username")}:',
|
||||||
child: Text(
|
textAlign: TextAlign.start,
|
||||||
'${translate("Username")}:',
|
).marginOnly(bottom: 16.0)),
|
||||||
textAlign: TextAlign.start,
|
const SizedBox(
|
||||||
).marginOnly(bottom: 16.0)),
|
width: 24.0,
|
||||||
const SizedBox(
|
),
|
||||||
width: 24.0,
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: TextField(
|
|
||||||
decoration: InputDecoration(
|
|
||||||
border: const OutlineInputBorder(),
|
|
||||||
errorText: usernameMsg.isNotEmpty ? usernameMsg : null),
|
|
||||||
controller: userController,
|
|
||||||
focusNode: FocusNode()..requestFocus(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 8.0,
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
ConstrainedBox(
|
|
||||||
constraints: const BoxConstraints(minWidth: 100),
|
|
||||||
child: Text('${translate("Password")}:')
|
|
||||||
.marginOnly(bottom: 16.0)),
|
|
||||||
const SizedBox(
|
|
||||||
width: 24.0,
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: TextField(
|
|
||||||
obscureText: true,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
border: const OutlineInputBorder(),
|
|
||||||
errorText: passMsg.isNotEmpty ? passMsg : null),
|
|
||||||
controller: pwdController,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 4.0,
|
|
||||||
),
|
|
||||||
Offstage(
|
|
||||||
offstage: !isInProgress, child: const LinearProgressIndicator()),
|
|
||||||
const SizedBox(
|
|
||||||
height: 12.0,
|
|
||||||
),
|
|
||||||
Row(children: [
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Container(
|
child: TextField(
|
||||||
height: 50,
|
decoration: InputDecoration(
|
||||||
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
|
border: const OutlineInputBorder(),
|
||||||
child: ElevatedButton(
|
errorText: usernameMsg.isNotEmpty ? usernameMsg : null),
|
||||||
child: const Text(
|
controller: userController,
|
||||||
'Login',
|
focusNode: FocusNode()..requestFocus(),
|
||||||
style: TextStyle(fontSize: 18),
|
|
||||||
),
|
|
||||||
onPressed: () {
|
|
||||||
onLogin(userController.text, pwdController.text);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
]),
|
],
|
||||||
],
|
),
|
||||||
),
|
const SizedBox(
|
||||||
|
height: 8.0,
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
ConstrainedBox(
|
||||||
|
constraints: const BoxConstraints(minWidth: 100),
|
||||||
|
child:
|
||||||
|
Text('${translate("Password")}:').marginOnly(bottom: 16.0)),
|
||||||
|
const SizedBox(
|
||||||
|
width: 24.0,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: TextField(
|
||||||
|
obscureText: true,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
border: const OutlineInputBorder(),
|
||||||
|
errorText: passMsg.isNotEmpty ? passMsg : null),
|
||||||
|
controller: pwdController,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 4.0,
|
||||||
|
),
|
||||||
|
Offstage(
|
||||||
|
offstage: !isInProgress, child: const LinearProgressIndicator()),
|
||||||
|
const SizedBox(
|
||||||
|
height: 12.0,
|
||||||
|
),
|
||||||
|
Row(children: [
|
||||||
|
Expanded(
|
||||||
|
child: Container(
|
||||||
|
height: 50,
|
||||||
|
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
|
||||||
|
child: Obx(() => ElevatedButton(
|
||||||
|
style: curOP.value.isEmpty || curOP.value == 'rustdesk'
|
||||||
|
? null
|
||||||
|
: ElevatedButton.styleFrom(
|
||||||
|
primary: Colors.grey,
|
||||||
|
),
|
||||||
|
child: const Text(
|
||||||
|
'Login',
|
||||||
|
style: TextStyle(fontSize: 18),
|
||||||
|
),
|
||||||
|
onPressed: curOP.value.isEmpty || curOP.value == 'rustdesk'
|
||||||
|
? () {
|
||||||
|
onLogin(userController.text, pwdController.text);
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -364,6 +401,7 @@ Future<bool> loginDialog() async {
|
|||||||
var passMsg = '';
|
var passMsg = '';
|
||||||
var isInProgress = false;
|
var isInProgress = false;
|
||||||
var completer = Completer<bool>();
|
var completer = Completer<bool>();
|
||||||
|
final RxString curOP = ''.obs;
|
||||||
|
|
||||||
gFFI.dialogManager.show((setState, close) {
|
gFFI.dialogManager.show((setState, close) {
|
||||||
cancel() {
|
cancel() {
|
||||||
@ -379,6 +417,7 @@ Future<bool> loginDialog() async {
|
|||||||
isInProgress = true;
|
isInProgress = true;
|
||||||
});
|
});
|
||||||
cancel() {
|
cancel() {
|
||||||
|
curOP.value = '';
|
||||||
if (isInProgress) {
|
if (isInProgress) {
|
||||||
setState(() {
|
setState(() {
|
||||||
isInProgress = false;
|
isInProgress = false;
|
||||||
@ -386,17 +425,16 @@ Future<bool> loginDialog() async {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
curOP.value = 'rustdesk';
|
||||||
username = username0;
|
username = username0;
|
||||||
pass = pass0;
|
pass = pass0;
|
||||||
if (username.isEmpty) {
|
if (username.isEmpty) {
|
||||||
usernameMsg = translate('Username missed');
|
usernameMsg = translate('Username missed');
|
||||||
debugPrint('REMOVE ME ====================== username empty');
|
|
||||||
cancel();
|
cancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (pass.isEmpty) {
|
if (pass.isEmpty) {
|
||||||
passMsg = translate('Password missed');
|
passMsg = translate('Password missed');
|
||||||
debugPrint('REMOVE ME ====================== password empty');
|
|
||||||
cancel();
|
cancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -404,7 +442,6 @@ Future<bool> loginDialog() async {
|
|||||||
final resp = await gFFI.userModel.login(username, pass);
|
final resp = await gFFI.userModel.login(username, pass);
|
||||||
if (resp.containsKey('error')) {
|
if (resp.containsKey('error')) {
|
||||||
passMsg = resp['error'];
|
passMsg = resp['error'];
|
||||||
debugPrint('REMOVE ME ====================== password error');
|
|
||||||
cancel();
|
cancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -414,8 +451,6 @@ Future<bool> loginDialog() async {
|
|||||||
completer.complete(true);
|
completer.complete(true);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
debugPrint(err.toString());
|
debugPrint(err.toString());
|
||||||
debugPrint(
|
|
||||||
'REMOVE ME ====================== login error ${err.toString()}');
|
|
||||||
cancel();
|
cancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -438,6 +473,7 @@ Future<bool> loginDialog() async {
|
|||||||
usernameMsg: usernameMsg,
|
usernameMsg: usernameMsg,
|
||||||
passMsg: passMsg,
|
passMsg: passMsg,
|
||||||
isInProgress: isInProgress,
|
isInProgress: isInProgress,
|
||||||
|
curOP: curOP,
|
||||||
onLogin: onLogin,
|
onLogin: onLogin,
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
@ -451,11 +487,19 @@ Future<bool> loginDialog() async {
|
|||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 8.0,
|
height: 8.0,
|
||||||
),
|
),
|
||||||
LoginWidgetOP(ops: [
|
LoginWidgetOP(
|
||||||
ConfigOP(op: 'Github', iconWidth: 24),
|
ops: [
|
||||||
ConfigOP(op: 'Google', iconWidth: 24),
|
ConfigOP(op: 'Github', iconWidth: 24),
|
||||||
ConfigOP(op: 'Okta', iconWidth: 46),
|
ConfigOP(op: 'Google', iconWidth: 24),
|
||||||
]),
|
ConfigOP(op: 'Okta', iconWidth: 46),
|
||||||
|
],
|
||||||
|
curOP: curOP,
|
||||||
|
cbLogin: (String username) {
|
||||||
|
gFFI.userModel.userName.value = username;
|
||||||
|
completer.complete(true);
|
||||||
|
close();
|
||||||
|
},
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -291,12 +291,12 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
|
|||||||
return SettingsList(
|
return SettingsList(
|
||||||
sections: [
|
sections: [
|
||||||
SettingsSection(
|
SettingsSection(
|
||||||
title: Text(translate("Account")),
|
title: Text(translate('Account')),
|
||||||
tiles: [
|
tiles: [
|
||||||
SettingsTile.navigation(
|
SettingsTile.navigation(
|
||||||
title: Obx(() => Text(gFFI.userModel.userName.value.isEmpty
|
title: Obx(() => Text(gFFI.userModel.userName.value.isEmpty
|
||||||
? translate("Login")
|
? translate('Login')
|
||||||
: '${translate("Logout")} (${gFFI.userModel.userName.value})')),
|
: '${translate('Logout')} (${gFFI.userModel.userName.value})')),
|
||||||
leading: Icon(Icons.person),
|
leading: Icon(Icons.person),
|
||||||
onPressed: (context) {
|
onPressed: (context) {
|
||||||
if (gFFI.userModel.userName.value.isEmpty) {
|
if (gFFI.userModel.userName.value.isEmpty) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
|
|
||||||
@ -9,7 +10,7 @@ import 'model.dart';
|
|||||||
import 'platform_model.dart';
|
import 'platform_model.dart';
|
||||||
|
|
||||||
class UserModel {
|
class UserModel {
|
||||||
var userName = "".obs;
|
var userName = ''.obs;
|
||||||
WeakReference<FFI> parent;
|
WeakReference<FFI> parent;
|
||||||
|
|
||||||
UserModel(this.parent) {
|
UserModel(this.parent) {
|
||||||
@ -18,7 +19,7 @@ class UserModel {
|
|||||||
|
|
||||||
void refreshCurrentUser() async {
|
void refreshCurrentUser() async {
|
||||||
await getUserName();
|
await getUserName();
|
||||||
final token = await bind.mainGetLocalOption(key: "access_token");
|
final token = await bind.mainGetLocalOption(key: 'access_token');
|
||||||
if (token == '') return;
|
if (token == '') return;
|
||||||
final url = await bind.mainGetApiServer();
|
final url = await bind.mainGetApiServer();
|
||||||
final body = {
|
final body = {
|
||||||
@ -28,8 +29,8 @@ class UserModel {
|
|||||||
try {
|
try {
|
||||||
final response = await http.post(Uri.parse('$url/api/currentUser'),
|
final response = await http.post(Uri.parse('$url/api/currentUser'),
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
'Content-Type': 'application/json',
|
||||||
"Authorization": "Bearer $token"
|
'Authorization': 'Bearer $token'
|
||||||
},
|
},
|
||||||
body: json.encode(body));
|
body: json.encode(body));
|
||||||
final status = response.statusCode;
|
final status = response.statusCode;
|
||||||
@ -44,9 +45,9 @@ class UserModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void resetToken() async {
|
void resetToken() async {
|
||||||
await bind.mainSetLocalOption(key: "access_token", value: "");
|
await bind.mainSetLocalOption(key: 'access_token', value: '');
|
||||||
await bind.mainSetLocalOption(key: "user_info", value: "");
|
await bind.mainSetLocalOption(key: 'user_info', value: '');
|
||||||
userName.value = "";
|
userName.value = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> _parseResp(String body) async {
|
Future<String> _parseResp(String body) async {
|
||||||
@ -57,13 +58,13 @@ class UserModel {
|
|||||||
}
|
}
|
||||||
final token = data['access_token'];
|
final token = data['access_token'];
|
||||||
if (token != null) {
|
if (token != null) {
|
||||||
await bind.mainSetLocalOption(key: "access_token", value: token);
|
await bind.mainSetLocalOption(key: 'access_token', value: token);
|
||||||
}
|
}
|
||||||
final info = data['user'];
|
final info = data['user'];
|
||||||
if (info != null) {
|
if (info != null) {
|
||||||
final value = json.encode(info);
|
final value = json.encode(info);
|
||||||
await bind.mainSetOption(key: "user_info", value: value);
|
await bind.mainSetOption(key: 'user_info', value: value);
|
||||||
userName.value = info["name"];
|
userName.value = info['name'];
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
@ -74,7 +75,7 @@ class UserModel {
|
|||||||
}
|
}
|
||||||
final userInfo = await bind.mainGetLocalOption(key: 'user_info');
|
final userInfo = await bind.mainGetLocalOption(key: 'user_info');
|
||||||
if (userInfo.trim().isEmpty) {
|
if (userInfo.trim().isEmpty) {
|
||||||
return "";
|
return '';
|
||||||
}
|
}
|
||||||
final m = jsonDecode(userInfo);
|
final m = jsonDecode(userInfo);
|
||||||
if (m == null) {
|
if (m == null) {
|
||||||
@ -88,10 +89,10 @@ class UserModel {
|
|||||||
Future<void> logOut() async {
|
Future<void> logOut() async {
|
||||||
final tag = gFFI.dialogManager.showLoading(translate('Waiting'));
|
final tag = gFFI.dialogManager.showLoading(translate('Waiting'));
|
||||||
final url = await bind.mainGetApiServer();
|
final url = await bind.mainGetApiServer();
|
||||||
final _ = await http.post(Uri.parse("$url/api/logout"),
|
final _ = await http.post(Uri.parse('$url/api/logout'),
|
||||||
body: {
|
body: {
|
||||||
"id": await bind.mainGetMyId(),
|
'id': await bind.mainGetMyId(),
|
||||||
"uuid": await bind.mainGetUuid(),
|
'uuid': await bind.mainGetUuid(),
|
||||||
},
|
},
|
||||||
headers: await getHttpHeaders());
|
headers: await getHttpHeaders());
|
||||||
await Future.wait([
|
await Future.wait([
|
||||||
@ -100,30 +101,30 @@ class UserModel {
|
|||||||
bind.mainSetLocalOption(key: 'selected-tags', value: ''),
|
bind.mainSetLocalOption(key: 'selected-tags', value: ''),
|
||||||
]);
|
]);
|
||||||
parent.target?.abModel.clear();
|
parent.target?.abModel.clear();
|
||||||
userName.value = "";
|
userName.value = '';
|
||||||
gFFI.dialogManager.dismissByTag(tag);
|
gFFI.dialogManager.dismissByTag(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Map<String, dynamic>> login(String userName, String pass) async {
|
Future<Map<String, dynamic>> login(String userName, String pass) async {
|
||||||
final url = await bind.mainGetApiServer();
|
final url = await bind.mainGetApiServer();
|
||||||
try {
|
try {
|
||||||
final resp = await http.post(Uri.parse("$url/api/login"),
|
final resp = await http.post(Uri.parse('$url/api/login'),
|
||||||
headers: {"Content-Type": "application/json"},
|
headers: {'Content-Type': 'application/json'},
|
||||||
body: jsonEncode({
|
body: jsonEncode({
|
||||||
"username": userName,
|
'username': userName,
|
||||||
"password": pass,
|
'password': pass,
|
||||||
"id": await bind.mainGetMyId(),
|
'id': await bind.mainGetMyId(),
|
||||||
"uuid": await bind.mainGetUuid()
|
'uuid': await bind.mainGetUuid()
|
||||||
}));
|
}));
|
||||||
final body = jsonDecode(resp.body);
|
final body = jsonDecode(resp.body);
|
||||||
bind.mainSetLocalOption(
|
bind.mainSetLocalOption(
|
||||||
key: "access_token", value: body['access_token'] ?? "");
|
key: 'access_token', value: body['access_token'] ?? '');
|
||||||
bind.mainSetLocalOption(
|
bind.mainSetLocalOption(
|
||||||
key: "user_info", value: jsonEncode(body['user']));
|
key: 'user_info', value: jsonEncode(body['user']));
|
||||||
this.userName.value = body['user']?['name'] ?? "";
|
this.userName.value = body['user']?['name'] ?? '';
|
||||||
return body;
|
return body;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return {"error": "$err"};
|
return {'error': '$err'};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1085,7 +1085,13 @@ pub fn install_install_path() -> SyncReturn<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn main_account_auth(op: String) {
|
pub fn main_account_auth(op: String) {
|
||||||
account_auth(op);
|
let id = get_id();
|
||||||
|
let uuid = get_uuid();
|
||||||
|
account_auth(op, id, uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main_account_auth_cancel() {
|
||||||
|
account_auth_cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main_account_auth_result() -> String {
|
pub fn main_account_auth_result() -> String {
|
||||||
|
@ -2,13 +2,14 @@ use hbb_common::{
|
|||||||
anyhow::{self, bail},
|
anyhow::{self, bail},
|
||||||
tokio, ResultType,
|
tokio, ResultType,
|
||||||
};
|
};
|
||||||
use reqwest::Response;
|
use reqwest::blocking::Response;
|
||||||
|
use serde::de::DeserializeOwned;
|
||||||
use serde_derive::Deserialize;
|
use serde_derive::Deserialize;
|
||||||
use serde_json::{Map, Value};
|
use serde_json::{Map, Value};
|
||||||
use serde::de::DeserializeOwned;
|
|
||||||
|
|
||||||
pub mod account;
|
pub mod account;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum HbbHttpResponse<T> {
|
pub enum HbbHttpResponse<T> {
|
||||||
ErrorFormat,
|
ErrorFormat,
|
||||||
Error(String),
|
Error(String),
|
||||||
@ -16,16 +17,11 @@ pub enum HbbHttpResponse<T> {
|
|||||||
Data(T),
|
Data(T),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main(flavor = "current_thread")]
|
|
||||||
async fn resp_to_serde_map(resp: Response) -> reqwest::Result<Map<String, Value>> {
|
|
||||||
resp.json().await
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: DeserializeOwned> TryFrom<Response> for HbbHttpResponse<T> {
|
impl<T: DeserializeOwned> TryFrom<Response> for HbbHttpResponse<T> {
|
||||||
type Error = reqwest::Error;
|
type Error = reqwest::Error;
|
||||||
|
|
||||||
fn try_from(resp: Response) -> Result<Self, <Self as TryFrom<Response>>::Error> {
|
fn try_from(resp: Response) -> Result<Self, <Self as TryFrom<Response>>::Error> {
|
||||||
let map = resp_to_serde_map(resp)?;
|
let map = resp.json::<Map<String, Value>>()?;
|
||||||
if let Some(error) = map.get("error") {
|
if let Some(error) = map.get("error") {
|
||||||
if let Some(err) = error.as_str() {
|
if let Some(err) = error.as_str() {
|
||||||
Ok(Self::Error(err.to_owned()))
|
Ok(Self::Error(err.to_owned()))
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
use super::HbbHttpResponse;
|
use super::HbbHttpResponse;
|
||||||
use hbb_common::{config::Config, log, sleep, tokio, tokio::sync::RwLock, ResultType};
|
use hbb_common::{
|
||||||
|
config::{Config, LocalConfig},
|
||||||
|
log, sleep, tokio, ResultType,
|
||||||
|
};
|
||||||
|
use reqwest::blocking::Client;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
sync::Arc,
|
sync::{Arc, RwLock},
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
@ -15,12 +19,12 @@ lazy_static::lazy_static! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const QUERY_INTERVAL_SECS: f32 = 1.0;
|
const QUERY_INTERVAL_SECS: f32 = 1.0;
|
||||||
const QUERY_TIMEOUT_SECS: u64 = 60;
|
const QUERY_TIMEOUT_SECS: u64 = 60 * 3;
|
||||||
const REQUESTING_ACCOUNT_AUTH: &str = "Requesting account auth";
|
const REQUESTING_ACCOUNT_AUTH: &str = "Requesting account auth";
|
||||||
const WAITING_ACCOUNT_AUTH: &str = "Waiting account auth";
|
const WAITING_ACCOUNT_AUTH: &str = "Waiting account auth";
|
||||||
const LOGIN_ACCOUNT_AUTH: &str = "Login account auth";
|
const LOGIN_ACCOUNT_AUTH: &str = "Login account auth";
|
||||||
|
|
||||||
#[derive(Deserialize, Clone)]
|
#[derive(Deserialize, Clone, Debug)]
|
||||||
pub struct OidcAuthUrl {
|
pub struct OidcAuthUrl {
|
||||||
code: String,
|
code: String,
|
||||||
url: Url,
|
url: Url,
|
||||||
@ -45,7 +49,7 @@ pub struct AuthBody {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct OidcSession {
|
pub struct OidcSession {
|
||||||
client: reqwest::Client,
|
client: Client,
|
||||||
state_msg: &'static str,
|
state_msg: &'static str,
|
||||||
failed_msg: String,
|
failed_msg: String,
|
||||||
code_url: Option<OidcAuthUrl>,
|
code_url: Option<OidcAuthUrl>,
|
||||||
@ -66,7 +70,7 @@ pub struct AuthResult {
|
|||||||
impl OidcSession {
|
impl OidcSession {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
client: reqwest::Client::new(),
|
client: Client::new(),
|
||||||
state_msg: REQUESTING_ACCOUNT_AUTH,
|
state_msg: REQUESTING_ACCOUNT_AUTH,
|
||||||
failed_msg: "".to_owned(),
|
failed_msg: "".to_owned(),
|
||||||
code_url: None,
|
code_url: None,
|
||||||
@ -77,30 +81,28 @@ impl OidcSession {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn auth(op: &str, id: &str, uuid: &str) -> ResultType<HbbHttpResponse<OidcAuthUrl>> {
|
fn auth(op: &str, id: &str, uuid: &str) -> ResultType<HbbHttpResponse<OidcAuthUrl>> {
|
||||||
Ok(OIDC_SESSION
|
Ok(OIDC_SESSION
|
||||||
.read()
|
.read()
|
||||||
.await
|
.unwrap()
|
||||||
.client
|
.client
|
||||||
.post(format!("{}/api/oidc/auth", *API_SERVER))
|
.post(format!("{}/api/oidc/auth", *API_SERVER))
|
||||||
.json(&HashMap::from([("op", op), ("id", id), ("uuid", uuid)]))
|
.json(&HashMap::from([("op", op), ("id", id), ("uuid", uuid)]))
|
||||||
.send()
|
.send()?
|
||||||
.await?
|
|
||||||
.try_into()?)
|
.try_into()?)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn query(code: &str, id: &str, uuid: &str) -> ResultType<HbbHttpResponse<AuthBody>> {
|
fn query(code: &str, id: &str, uuid: &str) -> ResultType<HbbHttpResponse<AuthBody>> {
|
||||||
let url = reqwest::Url::parse_with_params(
|
let url = reqwest::Url::parse_with_params(
|
||||||
&format!("{}/api/oidc/auth-query", *API_SERVER),
|
&format!("{}/api/oidc/auth-query", *API_SERVER),
|
||||||
&[("code", code), ("id", id), ("uuid", uuid)],
|
&[("code", code), ("id", id), ("uuid", uuid)],
|
||||||
)?;
|
)?;
|
||||||
Ok(OIDC_SESSION
|
Ok(OIDC_SESSION
|
||||||
.read()
|
.read()
|
||||||
.await
|
.unwrap()
|
||||||
.client
|
.client
|
||||||
.get(url)
|
.get(url)
|
||||||
.send()
|
.send()?
|
||||||
.await?
|
|
||||||
.try_into()?)
|
.try_into()?)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,36 +115,42 @@ impl OidcSession {
|
|||||||
self.auth_body = None;
|
self.auth_body = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn before_task(&mut self) {
|
fn before_task(&mut self) {
|
||||||
self.reset();
|
self.reset();
|
||||||
self.running = true;
|
self.running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn after_task(&mut self) {
|
fn after_task(&mut self) {
|
||||||
self.running = false;
|
self.running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn auth_task(op: String, id: String, uuid: String) {
|
fn sleep(secs: f32) {
|
||||||
let code_url = match Self::auth(&op, &id, &uuid).await {
|
std::thread::sleep(std::time::Duration::from_secs_f32(secs));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn auth_task(op: String, id: String, uuid: String) {
|
||||||
|
let auth_request_res = Self::auth(&op, &id, &uuid);
|
||||||
|
log::info!("Request oidc auth result: {:?}", &auth_request_res);
|
||||||
|
let code_url = match auth_request_res {
|
||||||
Ok(HbbHttpResponse::<_>::Data(code_url)) => code_url,
|
Ok(HbbHttpResponse::<_>::Data(code_url)) => code_url,
|
||||||
Ok(HbbHttpResponse::<_>::Error(err)) => {
|
Ok(HbbHttpResponse::<_>::Error(err)) => {
|
||||||
OIDC_SESSION
|
OIDC_SESSION
|
||||||
.write()
|
.write()
|
||||||
.await
|
.unwrap()
|
||||||
.set_state(REQUESTING_ACCOUNT_AUTH, err);
|
.set_state(REQUESTING_ACCOUNT_AUTH, err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
OIDC_SESSION
|
OIDC_SESSION
|
||||||
.write()
|
.write()
|
||||||
.await
|
.unwrap()
|
||||||
.set_state(REQUESTING_ACCOUNT_AUTH, "Invalid auth response".to_owned());
|
.set_state(REQUESTING_ACCOUNT_AUTH, "Invalid auth response".to_owned());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
OIDC_SESSION
|
OIDC_SESSION
|
||||||
.write()
|
.write()
|
||||||
.await
|
.unwrap()
|
||||||
.set_state(REQUESTING_ACCOUNT_AUTH, err.to_string());
|
.set_state(REQUESTING_ACCOUNT_AUTH, err.to_string());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -150,22 +158,29 @@ impl OidcSession {
|
|||||||
|
|
||||||
OIDC_SESSION
|
OIDC_SESSION
|
||||||
.write()
|
.write()
|
||||||
.await
|
.unwrap()
|
||||||
.set_state(WAITING_ACCOUNT_AUTH, "".to_owned());
|
.set_state(WAITING_ACCOUNT_AUTH, "".to_owned());
|
||||||
OIDC_SESSION.write().await.code_url = Some(code_url.clone());
|
OIDC_SESSION.write().unwrap().code_url = Some(code_url.clone());
|
||||||
|
|
||||||
let begin = Instant::now();
|
let begin = Instant::now();
|
||||||
let query_timeout = OIDC_SESSION.read().await.query_timeout;
|
let query_timeout = OIDC_SESSION.read().unwrap().query_timeout;
|
||||||
while OIDC_SESSION.read().await.keep_querying && begin.elapsed() < query_timeout {
|
while OIDC_SESSION.read().unwrap().keep_querying && begin.elapsed() < query_timeout {
|
||||||
match Self::query(&code_url.code, &id, &uuid).await {
|
match Self::query(&code_url.code, &id, &uuid) {
|
||||||
Ok(HbbHttpResponse::<_>::Data(auth_body)) => {
|
Ok(HbbHttpResponse::<_>::Data(auth_body)) => {
|
||||||
|
LocalConfig::set_option(
|
||||||
|
"access_token".to_owned(),
|
||||||
|
auth_body.access_token.clone(),
|
||||||
|
);
|
||||||
|
LocalConfig::set_option(
|
||||||
|
"user_info".to_owned(),
|
||||||
|
serde_json::to_string(&auth_body.user).unwrap_or_default(),
|
||||||
|
);
|
||||||
OIDC_SESSION
|
OIDC_SESSION
|
||||||
.write()
|
.write()
|
||||||
.await
|
.unwrap()
|
||||||
.set_state(LOGIN_ACCOUNT_AUTH, "".to_owned());
|
.set_state(LOGIN_ACCOUNT_AUTH, "".to_owned());
|
||||||
OIDC_SESSION.write().await.auth_body = Some(auth_body);
|
OIDC_SESSION.write().unwrap().auth_body = Some(auth_body);
|
||||||
return;
|
return;
|
||||||
// to-do, set access-token
|
|
||||||
}
|
}
|
||||||
Ok(HbbHttpResponse::<_>::Error(err)) => {
|
Ok(HbbHttpResponse::<_>::Error(err)) => {
|
||||||
if err.contains("No authed oidc is found") {
|
if err.contains("No authed oidc is found") {
|
||||||
@ -173,7 +188,7 @@ impl OidcSession {
|
|||||||
} else {
|
} else {
|
||||||
OIDC_SESSION
|
OIDC_SESSION
|
||||||
.write()
|
.write()
|
||||||
.await
|
.unwrap()
|
||||||
.set_state(WAITING_ACCOUNT_AUTH, err);
|
.set_state(WAITING_ACCOUNT_AUTH, err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -186,13 +201,13 @@ impl OidcSession {
|
|||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sleep(QUERY_INTERVAL_SECS).await;
|
Self::sleep(QUERY_INTERVAL_SECS);
|
||||||
}
|
}
|
||||||
|
|
||||||
if begin.elapsed() >= query_timeout {
|
if begin.elapsed() >= query_timeout {
|
||||||
OIDC_SESSION
|
OIDC_SESSION
|
||||||
.write()
|
.write()
|
||||||
.await
|
.unwrap()
|
||||||
.set_state(WAITING_ACCOUNT_AUTH, "timeout".to_owned());
|
.set_state(WAITING_ACCOUNT_AUTH, "timeout".to_owned());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,20 +219,20 @@ impl OidcSession {
|
|||||||
self.failed_msg = failed_msg;
|
self.failed_msg = failed_msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn account_auth(op: String, id: String, uuid: String) {
|
fn wait_stop_querying() {
|
||||||
if OIDC_SESSION.read().await.running {
|
|
||||||
OIDC_SESSION.write().await.keep_querying = false;
|
|
||||||
}
|
|
||||||
let wait_secs = 0.3;
|
let wait_secs = 0.3;
|
||||||
sleep(wait_secs).await;
|
while OIDC_SESSION.read().unwrap().running {
|
||||||
while OIDC_SESSION.read().await.running {
|
Self::sleep(wait_secs);
|
||||||
sleep(wait_secs).await;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tokio::spawn(async move {
|
pub fn account_auth(op: String, id: String, uuid: String) {
|
||||||
OIDC_SESSION.write().await.before_task().await;
|
Self::auth_cancel();
|
||||||
Self::auth_task(op, id, uuid).await;
|
Self::wait_stop_querying();
|
||||||
OIDC_SESSION.write().await.after_task().await;
|
OIDC_SESSION.write().unwrap().before_task();
|
||||||
|
std::thread::spawn(|| {
|
||||||
|
Self::auth_task(op, id, uuid);
|
||||||
|
OIDC_SESSION.write().unwrap().after_task();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,7 +245,11 @@ impl OidcSession {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_result() -> AuthResult {
|
pub fn auth_cancel() {
|
||||||
OIDC_SESSION.read().await.get_result_()
|
OIDC_SESSION.write().unwrap().keep_querying = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_result() -> AuthResult {
|
||||||
|
OIDC_SESSION.read().unwrap().get_result_()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
13
src/main.rs
13
src/main.rs
@ -32,8 +32,8 @@ fn main() {
|
|||||||
if !common::global_init() {
|
if !common::global_init() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
use hbb_common::log;
|
|
||||||
use clap::App;
|
use clap::App;
|
||||||
|
use hbb_common::log;
|
||||||
let args = format!(
|
let args = format!(
|
||||||
"-p, --port-forward=[PORT-FORWARD-OPTIONS] 'Format: remote-id:local-port:remote-port[:remote-host]'
|
"-p, --port-forward=[PORT-FORWARD-OPTIONS] 'Format: remote-id:local-port:remote-port[:remote-host]'
|
||||||
-k, --key=[KEY] ''
|
-k, --key=[KEY] ''
|
||||||
@ -45,7 +45,7 @@ fn main() {
|
|||||||
.about("RustDesk command line tool")
|
.about("RustDesk command line tool")
|
||||||
.args_from_usage(&args)
|
.args_from_usage(&args)
|
||||||
.get_matches();
|
.get_matches();
|
||||||
use hbb_common::{env_logger::*, config::LocalConfig};
|
use hbb_common::{config::LocalConfig, env_logger::*};
|
||||||
init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "info"));
|
init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "info"));
|
||||||
if let Some(p) = matches.value_of("port-forward") {
|
if let Some(p) = matches.value_of("port-forward") {
|
||||||
let options: Vec<String> = p.split(":").map(|x| x.to_owned()).collect();
|
let options: Vec<String> = p.split(":").map(|x| x.to_owned()).collect();
|
||||||
@ -73,7 +73,14 @@ fn main() {
|
|||||||
}
|
}
|
||||||
let key = matches.value_of("key").unwrap_or("").to_owned();
|
let key = matches.value_of("key").unwrap_or("").to_owned();
|
||||||
let token = LocalConfig::get_option("access_token");
|
let token = LocalConfig::get_option("access_token");
|
||||||
cli::start_one_port_forward(options[0].clone(), port, remote_host, remote_port, key, token);
|
cli::start_one_port_forward(
|
||||||
|
options[0].clone(),
|
||||||
|
port,
|
||||||
|
remote_host,
|
||||||
|
remote_port,
|
||||||
|
key,
|
||||||
|
token,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
common::global_clean();
|
common::global_clean();
|
||||||
}
|
}
|
@ -1,4 +1,5 @@
|
|||||||
use crate::ipc::Data;
|
use crate::ipc::Data;
|
||||||
|
use bytes::Bytes;
|
||||||
pub use connection::*;
|
pub use connection::*;
|
||||||
use hbb_common::{
|
use hbb_common::{
|
||||||
allow_err,
|
allow_err,
|
||||||
@ -20,7 +21,6 @@ use std::{
|
|||||||
sync::{Arc, Mutex, RwLock, Weak},
|
sync::{Arc, Mutex, RwLock, Weak},
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
use bytes::Bytes;
|
|
||||||
|
|
||||||
pub mod audio_service;
|
pub mod audio_service;
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
@ -140,7 +140,8 @@ pub async fn create_tcp_connection(
|
|||||||
.write_to_bytes()
|
.write_to_bytes()
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
&sk,
|
&sk,
|
||||||
).into(),
|
)
|
||||||
|
.into(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
timeout(CONNECT_TIMEOUT, stream.send(&msg_out)).await??;
|
timeout(CONNECT_TIMEOUT, stream.send(&msg_out)).await??;
|
||||||
|
@ -842,14 +842,16 @@ pub(crate) fn check_connect_status(reconnect: bool) -> mpsc::UnboundedSender<ipc
|
|||||||
tx
|
tx
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main(flavor = "current_thread")]
|
pub fn account_auth(op: String, id: String, uuid: String) {
|
||||||
pub async fn account_auth(op: String) {
|
account::OidcSession::account_auth(op, id, uuid);
|
||||||
account::OidcSession::account_auth(op, get_id(), get_uuid()).await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main(flavor = "current_thread")]
|
pub fn account_auth_cancel() {
|
||||||
pub async fn account_auth_result() -> String {
|
account::OidcSession::auth_cancel();
|
||||||
serde_json::to_string(&account::OidcSession::get_result().await).unwrap_or_default()
|
}
|
||||||
|
|
||||||
|
pub fn account_auth_result() -> String {
|
||||||
|
serde_json::to_string(&account::OidcSession::get_result()).unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
// notice: avoiding create ipc connecton repeatly,
|
// notice: avoiding create ipc connecton repeatly,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user