mirror of
https://github.com/Yubico/yubioath-flutter.git
synced 2024-11-22 16:32:01 +03:00
Use the logging package, and log from RPC.
This commit is contained in:
parent
d9b5cdc951
commit
064fb038e6
@ -1,14 +1,16 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:developer' as developer;
|
|
||||||
|
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:logging/logging.dart';
|
||||||
|
|
||||||
import '../../core/rpc.dart';
|
import '../../core/rpc.dart';
|
||||||
import '../../core/state.dart';
|
import '../../core/state.dart';
|
||||||
|
|
||||||
import 'models.dart';
|
import 'models.dart';
|
||||||
|
|
||||||
|
final log = Logger('app.state');
|
||||||
|
|
||||||
final attachedDevicesProvider =
|
final attachedDevicesProvider =
|
||||||
StateNotifierProvider<AttachedDeviceNotifier, List<DeviceNode>>(
|
StateNotifierProvider<AttachedDeviceNotifier, List<DeviceNode>>(
|
||||||
(ref) => AttachedDeviceNotifier(ref.watch(rpcProvider)));
|
(ref) => AttachedDeviceNotifier(ref.watch(rpcProvider)));
|
||||||
@ -32,8 +34,7 @@ class AttachedDeviceNotifier extends StateNotifier<List<DeviceNode>> {
|
|||||||
|
|
||||||
if (_usbState != scan['state']) {
|
if (_usbState != scan['state']) {
|
||||||
var usbResult = await _rpc.command('get', ['usb']);
|
var usbResult = await _rpc.command('get', ['usb']);
|
||||||
developer.log('USB state change',
|
log.info('USB state change', jsonEncode(usbResult));
|
||||||
name: 'controller', error: jsonEncode(usbResult));
|
|
||||||
|
|
||||||
_usbState = usbResult['data']['state'];
|
_usbState = usbResult['data']['state'];
|
||||||
|
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:developer' as developer;
|
|
||||||
|
|
||||||
|
import 'package:logging/logging.dart';
|
||||||
import 'package:async/async.dart';
|
import 'package:async/async.dart';
|
||||||
|
|
||||||
import 'models.dart';
|
import 'models.dart';
|
||||||
|
|
||||||
|
final log = Logger('rpc');
|
||||||
|
|
||||||
class Signaler {
|
class Signaler {
|
||||||
final _send = StreamController<String>();
|
final _send = StreamController<String>();
|
||||||
final _recv = StreamController<Signal>();
|
final _recv = StreamController<Signal>();
|
||||||
@ -40,6 +42,21 @@ class _Request {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Level _forPythonName(String name) {
|
||||||
|
switch (name) {
|
||||||
|
case 'DEBUG':
|
||||||
|
return Level.CONFIG;
|
||||||
|
case 'INFO':
|
||||||
|
return Level.INFO;
|
||||||
|
case 'WARNING':
|
||||||
|
return Level.WARNING;
|
||||||
|
case 'ERROR':
|
||||||
|
return Level.SEVERE;
|
||||||
|
default:
|
||||||
|
return Level.INFO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class RpcSession {
|
class RpcSession {
|
||||||
final Process _process;
|
final Process _process;
|
||||||
final StreamController<_Request> _requests = StreamController();
|
final StreamController<_Request> _requests = StreamController();
|
||||||
@ -50,8 +67,18 @@ class RpcSession {
|
|||||||
.transform(const Utf8Decoder())
|
.transform(const Utf8Decoder())
|
||||||
.transform(const LineSplitter())
|
.transform(const LineSplitter())
|
||||||
.map((event) => RpcResponse.fromJson(jsonDecode(event)))) {
|
.map((event) => RpcResponse.fromJson(jsonDecode(event)))) {
|
||||||
stderr.addStream(_process.stderr);
|
_process.stderr
|
||||||
developer.log('Launched ykman subprocess...', name: 'rpc');
|
.transform(const Utf8Decoder())
|
||||||
|
.transform(const LineSplitter())
|
||||||
|
.map((event) => jsonDecode(event))
|
||||||
|
.listen((event) {
|
||||||
|
Logger('rpc.${event['name']}').log(
|
||||||
|
_forPythonName(event['level']),
|
||||||
|
event['message'],
|
||||||
|
//time: DateTime.fromMillisecondsSinceEpoch(event['time'] * 1000),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
log.info('Launched ykman subprocess...');
|
||||||
_pump();
|
_pump();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,8 +95,24 @@ class RpcSession {
|
|||||||
return request.completer.future;
|
return request.completer.future;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setLogLevel(Level level) {
|
||||||
|
String pyLevel;
|
||||||
|
if (level.value <= Level.CONFIG.value) {
|
||||||
|
pyLevel = 'debug';
|
||||||
|
} else if (level.value <= Level.INFO.value) {
|
||||||
|
pyLevel = 'info';
|
||||||
|
} else if (level.value <= Level.WARNING.value) {
|
||||||
|
pyLevel = 'warning';
|
||||||
|
} else if (level.value <= Level.SEVERE.value) {
|
||||||
|
pyLevel = 'error';
|
||||||
|
} else {
|
||||||
|
pyLevel = 'critical';
|
||||||
|
}
|
||||||
|
command('logging', [], params: {'level': pyLevel});
|
||||||
|
}
|
||||||
|
|
||||||
void _send(Map data) {
|
void _send(Map data) {
|
||||||
developer.log('SEND', name: 'rpc', error: jsonEncode(data));
|
log.fine('SEND', jsonEncode(data));
|
||||||
_process.stdin.writeln(jsonEncode(data));
|
_process.stdin.writeln(jsonEncode(data));
|
||||||
_process.stdin.flush();
|
_process.stdin.flush();
|
||||||
}
|
}
|
||||||
@ -85,7 +128,7 @@ class RpcSession {
|
|||||||
bool completed = false;
|
bool completed = false;
|
||||||
while (!completed) {
|
while (!completed) {
|
||||||
final response = await _responses.next;
|
final response = await _responses.next;
|
||||||
developer.log('RECV', name: 'rpc', error: jsonEncode(response));
|
log.fine('RECV', jsonEncode(response));
|
||||||
response.map(
|
response.map(
|
||||||
signal: (signal) {
|
signal: (signal) {
|
||||||
request.signal?._recv.sink.add(signal);
|
request.signal?._recv.sink.add(signal);
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'dart:developer' as developer;
|
import 'dart:developer' as developer;
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
import 'package:logging/logging.dart';
|
||||||
|
|
||||||
import 'app.dart';
|
import 'app.dart';
|
||||||
import 'core/rpc.dart';
|
import 'core/rpc.dart';
|
||||||
@ -13,6 +13,8 @@ import 'core/state.dart';
|
|||||||
import 'app/main_page.dart';
|
import 'app/main_page.dart';
|
||||||
import 'error_page.dart';
|
import 'error_page.dart';
|
||||||
|
|
||||||
|
final log = Logger('main');
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
@ -35,14 +37,16 @@ void main() async {
|
|||||||
prefProvider.overrideWithValue(await SharedPreferences.getInstance())
|
prefProvider.overrideWithValue(await SharedPreferences.getInstance())
|
||||||
];
|
];
|
||||||
|
|
||||||
developer.log('Starting subprocess: $exe', name: 'main');
|
log.info('Starting subprocess: $exe');
|
||||||
try {
|
try {
|
||||||
var rpc = await RpcSession.launch(exe!);
|
var rpc = await RpcSession.launch(exe!);
|
||||||
developer.log('ykman process started', name: 'main');
|
// Enable logging TODO: Make this configurable
|
||||||
|
_initLogging(Level.INFO, rpc);
|
||||||
|
log.info('ykman process started', exe);
|
||||||
overrides.add(rpcProvider.overrideWithValue(rpc));
|
overrides.add(rpcProvider.overrideWithValue(rpc));
|
||||||
page = const MainPage();
|
page = const MainPage();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
developer.log('ykman process failed: $e', name: 'main');
|
log.warning('ykman process failed: $e');
|
||||||
page = ErrorPage(error: e.toString());
|
page = ErrorPage(error: e.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,6 +56,22 @@ void main() async {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _initLogging(Level level, RpcSession rpc) {
|
||||||
|
//TODO: Add support for logging to stderr and file
|
||||||
|
Logger.root.onRecord.listen((record) {
|
||||||
|
developer.log(
|
||||||
|
'${record.level} ${record.message}',
|
||||||
|
error: record.error,
|
||||||
|
name: record.loggerName,
|
||||||
|
time: record.time,
|
||||||
|
level: record.level.value,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
Logger.root.level = level;
|
||||||
|
rpc.setLogLevel(level);
|
||||||
|
}
|
||||||
|
|
||||||
//TODO: Remove below this
|
//TODO: Remove below this
|
||||||
|
|
||||||
class MyApp extends StatelessWidget {
|
class MyApp extends StatelessWidget {
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:developer' as developer;
|
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
import 'package:logging/logging.dart';
|
||||||
|
|
||||||
import '../core/state.dart';
|
import '../core/state.dart';
|
||||||
import 'models.dart';
|
import 'models.dart';
|
||||||
|
|
||||||
|
final log = Logger('oath.state');
|
||||||
|
|
||||||
final _sessionProvider =
|
final _sessionProvider =
|
||||||
Provider.autoDispose.family<RpcNodeSession, List<String>>(
|
Provider.autoDispose.family<RpcNodeSession, List<String>>(
|
||||||
(ref, devicePath) => RpcNodeSession(
|
(ref, devicePath) => RpcNodeSession(
|
||||||
@ -34,8 +36,7 @@ class OathStateNotifier extends StateNotifier<OathState?> {
|
|||||||
|
|
||||||
refresh() async {
|
refresh() async {
|
||||||
var result = await _session.command('get');
|
var result = await _session.command('get');
|
||||||
developer.log('application status',
|
log.config('application status', jsonEncode(result));
|
||||||
name: 'oath', error: jsonEncode(result));
|
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
state = OathState.fromJson(result['data']);
|
state = OathState.fromJson(result['data']);
|
||||||
}
|
}
|
||||||
@ -47,7 +48,7 @@ class OathStateNotifier extends StateNotifier<OathState?> {
|
|||||||
var key = result['key'];
|
var key = result['key'];
|
||||||
await _session.command('validate', params: {'key': key});
|
await _session.command('validate', params: {'key': key});
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
developer.log('UNLOCKED');
|
log.config('applet unlocked');
|
||||||
state = state?.copyWith(locked: false);
|
state = state?.copyWith(locked: false);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -117,7 +118,7 @@ class CredentialListNotifier extends StateNotifier<List<OathPair>?> {
|
|||||||
await _session.command('code', target: ['accounts', credential.id]);
|
await _session.command('code', target: ['accounts', credential.id]);
|
||||||
code = OathCode.fromJson(result);
|
code = OathCode.fromJson(result);
|
||||||
}
|
}
|
||||||
developer.log('Calculate', name: 'oath', error: jsonEncode(code));
|
log.config('Calculate', jsonEncode(code));
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
final creds = state!.toList();
|
final creds = state!.toList();
|
||||||
final i = creds.indexWhere((e) => e.credential.id == credential.id);
|
final i = creds.indexWhere((e) => e.credential.id == credential.id);
|
||||||
@ -143,9 +144,9 @@ class CredentialListNotifier extends StateNotifier<List<OathPair>?> {
|
|||||||
|
|
||||||
refresh() async {
|
refresh() async {
|
||||||
if (_locked) return;
|
if (_locked) return;
|
||||||
developer.log('refreshing credentials...', name: 'oath');
|
log.config('refreshing credentials...');
|
||||||
var result = await _session.command('calculate_all', target: ['accounts']);
|
var result = await _session.command('calculate_all', target: ['accounts']);
|
||||||
developer.log('Entries', name: 'oath', error: jsonEncode(result));
|
log.config('Entries', jsonEncode(result));
|
||||||
|
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
var current = state?.toList() ?? [];
|
var current = state?.toList() ?? [];
|
||||||
|
@ -304,7 +304,7 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.1"
|
version: "1.0.1"
|
||||||
logging:
|
logging:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: logging
|
name: logging
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
|
@ -36,6 +36,7 @@ dependencies:
|
|||||||
# cupertino_icons: ^1.0.2
|
# cupertino_icons: ^1.0.2
|
||||||
|
|
||||||
async: ^2.8.2
|
async: ^2.8.2
|
||||||
|
logging: ^1.0.2
|
||||||
shared_preferences: ^2.0.8
|
shared_preferences: ^2.0.8
|
||||||
flutter_riverpod: ^1.0.0
|
flutter_riverpod: ^1.0.0
|
||||||
json_annotation: ^4.3.0
|
json_annotation: ^4.3.0
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 739f3122a43adfcd2549374bc4cd11e88a483a8d
|
Subproject commit 318b0981d545950a45a8c9b9e17de9332e1f64b5
|
Loading…
Reference in New Issue
Block a user