mirror of
https://github.com/JGeek00/adguard-home-manager.git
synced 2025-04-23 15:29:13 +00:00
Added auth token to server modal and dns statistics request
This commit is contained in:
parent
360b6865be
commit
97e4fea015
9 changed files with 171 additions and 15 deletions
7
lib/functions/encode_base64.dart
Normal file
7
lib/functions/encode_base64.dart
Normal file
|
@ -0,0 +1,7 @@
|
|||
import 'dart:convert';
|
||||
|
||||
String encodeBase64UserPass(String user, String pass) {
|
||||
String credentials = "$user:$pass";
|
||||
Codec<String, String> stringToBase64 = utf8.fuse(base64);
|
||||
return stringToBase64.encode(credentials);
|
||||
}
|
73
lib/models/dns_statistics.dart
Normal file
73
lib/models/dns_statistics.dart
Normal file
|
@ -0,0 +1,73 @@
|
|||
import 'dart:convert';
|
||||
|
||||
DnsStatistics dnsStatisticsFromJson(String str) => DnsStatistics.fromJson(json.decode(str));
|
||||
|
||||
String dnsStatisticsToJson(DnsStatistics data) => json.encode(data.toJson());
|
||||
|
||||
class DnsStatistics {
|
||||
final String timeUnits;
|
||||
final List<Map<String, int>> topQueriedDomains;
|
||||
final List<Map<String, int>> topClients;
|
||||
final List<Map<String, int>> topBlockedDomains;
|
||||
final List<int> dnsQueries;
|
||||
final List<int> blockedFiltering;
|
||||
final List<int> replacedSafebrowsing;
|
||||
final List<int> replacedParental;
|
||||
final int numDnsQueries;
|
||||
final int numBlockedFiltering;
|
||||
final int numReplacedSafebrowsing;
|
||||
final int numReplacedSafesearch;
|
||||
final int numReplacedParental;
|
||||
final double avgProcessingTime;
|
||||
|
||||
DnsStatistics({
|
||||
required this.timeUnits,
|
||||
required this.topQueriedDomains,
|
||||
required this.topClients,
|
||||
required this.topBlockedDomains,
|
||||
required this.dnsQueries,
|
||||
required this.blockedFiltering,
|
||||
required this.replacedSafebrowsing,
|
||||
required this.replacedParental,
|
||||
required this.numDnsQueries,
|
||||
required this.numBlockedFiltering,
|
||||
required this.numReplacedSafebrowsing,
|
||||
required this.numReplacedSafesearch,
|
||||
required this.numReplacedParental,
|
||||
required this.avgProcessingTime,
|
||||
});
|
||||
|
||||
factory DnsStatistics.fromJson(Map<String, dynamic> json) => DnsStatistics(
|
||||
timeUnits: json["time_units"],
|
||||
topQueriedDomains: List<Map<String, int>>.from(json["top_queried_domains"].map((x) => Map.from(x).map((k, v) => MapEntry<String, int>(k, v)))),
|
||||
topClients: List<Map<String, int>>.from(json["top_clients"].map((x) => Map.from(x).map((k, v) => MapEntry<String, int>(k, v)))),
|
||||
topBlockedDomains: List<Map<String, int>>.from(json["top_blocked_domains"].map((x) => Map.from(x).map((k, v) => MapEntry<String, int>(k, v)))),
|
||||
dnsQueries: List<int>.from(json["dns_queries"].map((x) => x)),
|
||||
blockedFiltering: List<int>.from(json["blocked_filtering"].map((x) => x)),
|
||||
replacedSafebrowsing: List<int>.from(json["replaced_safebrowsing"].map((x) => x)),
|
||||
replacedParental: List<int>.from(json["replaced_parental"].map((x) => x)),
|
||||
numDnsQueries: json["num_dns_queries"],
|
||||
numBlockedFiltering: json["num_blocked_filtering"],
|
||||
numReplacedSafebrowsing: json["num_replaced_safebrowsing"],
|
||||
numReplacedSafesearch: json["num_replaced_safesearch"],
|
||||
numReplacedParental: json["num_replaced_parental"],
|
||||
avgProcessingTime: json["avg_processing_time"].toDouble(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"time_units": timeUnits,
|
||||
"top_queried_domains": List<dynamic>.from(topQueriedDomains.map((x) => Map.from(x).map((k, v) => MapEntry<String, dynamic>(k, v)))),
|
||||
"top_clients": List<dynamic>.from(topClients.map((x) => Map.from(x).map((k, v) => MapEntry<String, dynamic>(k, v)))),
|
||||
"top_blocked_domains": List<dynamic>.from(topBlockedDomains.map((x) => Map.from(x).map((k, v) => MapEntry<String, dynamic>(k, v)))),
|
||||
"dns_queries": List<dynamic>.from(dnsQueries.map((x) => x)),
|
||||
"blocked_filtering": List<dynamic>.from(blockedFiltering.map((x) => x)),
|
||||
"replaced_safebrowsing": List<dynamic>.from(replacedSafebrowsing.map((x) => x)),
|
||||
"replaced_parental": List<dynamic>.from(replacedParental.map((x) => x)),
|
||||
"num_dns_queries": numDnsQueries,
|
||||
"num_blocked_filtering": numBlockedFiltering,
|
||||
"num_replaced_safebrowsing": numReplacedSafebrowsing,
|
||||
"num_replaced_safesearch": numReplacedSafesearch,
|
||||
"num_replaced_parental": numReplacedParental,
|
||||
"avg_processing_time": avgProcessingTime,
|
||||
};
|
||||
}
|
|
@ -8,6 +8,7 @@ class Server {
|
|||
String user;
|
||||
String password;
|
||||
bool defaultServer;
|
||||
String authToken;
|
||||
|
||||
Server({
|
||||
required this.id,
|
||||
|
@ -18,6 +19,7 @@ class Server {
|
|||
this.port,
|
||||
required this.user,
|
||||
required this.password,
|
||||
required this.defaultServer
|
||||
required this.defaultServer,
|
||||
required this.authToken
|
||||
});
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
import 'package:adguard_home_manager/models/dns_statistics.dart';
|
||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
|
||||
|
@ -10,6 +12,7 @@ class ServersProvider with ChangeNotifier {
|
|||
List<Server> _serversList = [];
|
||||
Server? _selectedServer;
|
||||
bool? _isServerConnected;
|
||||
DnsStatistics? _dnsStatistics;
|
||||
|
||||
List<Server> get serversList {
|
||||
return _serversList;
|
||||
|
@ -23,6 +26,10 @@ class ServersProvider with ChangeNotifier {
|
|||
return _isServerConnected;
|
||||
}
|
||||
|
||||
DnsStatistics? get dnsStatistics {
|
||||
return _dnsStatistics;
|
||||
}
|
||||
|
||||
void setDbInstance(Database db) {
|
||||
_dbInstance = db;
|
||||
}
|
||||
|
@ -42,6 +49,11 @@ class ServersProvider with ChangeNotifier {
|
|||
notifyListeners();
|
||||
}
|
||||
|
||||
void setDnsStatistics(DnsStatistics data) {
|
||||
_dnsStatistics = data;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<bool> createServer(Server server) async {
|
||||
final saved = await saveServerIntoDb(server);
|
||||
if (saved == true) {
|
||||
|
@ -127,7 +139,7 @@ class ServersProvider with ChangeNotifier {
|
|||
try {
|
||||
return await _dbInstance!.transaction((txn) async {
|
||||
await txn.rawInsert(
|
||||
'INSERT INTO servers (id, name, connectionMethod, domain, path, port, user, password, defaultServer) VALUES ("${server.id}", "${server.name}", "${server.connectionMethod}", "${server.domain}", ${server.path != null ? "${server.path}" : null}, ${server.port}, "${server.user}", "${server.password}", 0)',
|
||||
'INSERT INTO servers (id, name, connectionMethod, domain, path, port, user, password, defaultServer, authToken) VALUES ("${server.id}", "${server.name}", "${server.connectionMethod}", "${server.domain}", ${server.path != null ? "${server.path}" : null}, ${server.port}, "${server.user}", "${server.password}", 0, "${server.authToken}")',
|
||||
);
|
||||
return true;
|
||||
});
|
||||
|
@ -140,7 +152,7 @@ class ServersProvider with ChangeNotifier {
|
|||
try {
|
||||
return await _dbInstance!.transaction((txn) async {
|
||||
await txn.rawUpdate(
|
||||
'UPDATE servers SET name = "${server.name}", connectionMethod = "${server.connectionMethod}", domain = "${server.domain}", path = ${server.path != null ? "${server.path}" : null}, port = ${server.port}, user = "${server.user}", password = "${server.password}" WHERE id = "${server.id}"',
|
||||
'UPDATE servers SET name = "${server.name}", connectionMethod = "${server.connectionMethod}", domain = "${server.domain}", path = ${server.path != null ? "${server.path}" : null}, port = ${server.port}, user = "${server.user}", password = "${server.password}", authToken = "${server.authToken}" WHERE id = "${server.id}"',
|
||||
);
|
||||
return true;
|
||||
});
|
||||
|
@ -191,10 +203,19 @@ class ServersProvider with ChangeNotifier {
|
|||
user: server['user'],
|
||||
password: server['password'],
|
||||
defaultServer: convertFromIntToBool(server['defaultServer'])!,
|
||||
authToken: server['authToken']
|
||||
);
|
||||
_serversList.add(serverObj);
|
||||
if (convertFromIntToBool(server['defaultServer']) == true) {
|
||||
_selectedServer = serverObj;
|
||||
final dnsStatistics = await getDnsStatistics(serverObj);
|
||||
if (dnsStatistics['result'] == 'success') {
|
||||
_dnsStatistics = dnsStatistics['data'];
|
||||
_isServerConnected = true;
|
||||
}
|
||||
else {
|
||||
_isServerConnected = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||
|
||||
class Home extends StatelessWidget {
|
||||
const Home({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serversProvider = Provider.of<ServersProvider>(context);
|
||||
|
||||
return Container();
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@ Future<Map<String, dynamic>> loadDb() async {
|
|||
'adguard_home_manager.db',
|
||||
version: 1,
|
||||
onCreate: (Database db, int version) async {
|
||||
await db.execute("CREATE TABLE servers (id TEXT PRIMARY KEY, name TEXT, connectionMethod TEXT, domain TEXT, path TEXT, port INTEGER, user TEXT, password TEXT, defaultServer INTEGER)");
|
||||
await db.execute("CREATE TABLE servers (id TEXT PRIMARY KEY, name TEXT, connectionMethod TEXT, domain TEXT, path TEXT, port INTEGER, user TEXT, password TEXT, defaultServer INTEGER, authToken TEXT)");
|
||||
},
|
||||
onUpgrade: (Database db, int oldVersion, int newVersion) async {
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import 'dart:io';
|
|||
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
import 'package:adguard_home_manager/models/dns_statistics.dart';
|
||||
import 'package:adguard_home_manager/models/server.dart';
|
||||
|
||||
Future login(Server server) async {
|
||||
|
@ -44,4 +45,32 @@ Future login(Server server) async {
|
|||
} catch (e) {
|
||||
return {'result': 'error'};
|
||||
}
|
||||
}
|
||||
|
||||
Future getDnsStatistics(Server server) async {
|
||||
try {
|
||||
final result = await http.get(
|
||||
Uri.parse("${server.connectionMethod}://${server.domain}${server.path ?? ""}${server.port != null ? ':${server.port}' : ""}/control/stats"),
|
||||
headers: {
|
||||
'Authorization': 'Basic ${server.authToken}'
|
||||
}
|
||||
);
|
||||
if (result.statusCode == 200) {
|
||||
return {
|
||||
'result': 'success',
|
||||
'data': DnsStatistics.fromJson(jsonDecode(result.body))
|
||||
};
|
||||
}
|
||||
else {
|
||||
return {'result': 'error'};
|
||||
}
|
||||
} on SocketException {
|
||||
return {'result': 'no_connection'};
|
||||
} on TimeoutException {
|
||||
return {'result': 'no_connection'};
|
||||
} on HandshakeException {
|
||||
return {'result': 'ssl_error'};
|
||||
} catch (e) {
|
||||
return {'result': 'error'};
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
// ignore_for_file: use_build_context_synchronously
|
||||
|
||||
import 'package:adguard_home_manager/functions/encode_base64.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
@ -206,7 +207,7 @@ class _AddServerModalState extends State<AddServerModal> {
|
|||
final mediaQuery = MediaQuery.of(context);
|
||||
|
||||
void connect() async {
|
||||
final Server serverObj = Server(
|
||||
Server serverObj = Server(
|
||||
id: uuid.v4(),
|
||||
name: nameController.text,
|
||||
connectionMethod: connectionType,
|
||||
|
@ -214,14 +215,24 @@ class _AddServerModalState extends State<AddServerModal> {
|
|||
port: int.parse(portController.text),
|
||||
user: userController.text,
|
||||
password: passwordController.text,
|
||||
defaultServer: defaultServer
|
||||
defaultServer: defaultServer,
|
||||
authToken: ''
|
||||
);
|
||||
setState(() => isConnecting = true);
|
||||
final result = await login(serverObj);
|
||||
setState(() => isConnecting = false);
|
||||
if (result['result'] == 'success') {
|
||||
serverObj.authToken = encodeBase64UserPass(serverObj.user, serverObj.password);
|
||||
final serverCreated = await serversProvider.createServer(serverObj);
|
||||
if (serverCreated == true) {
|
||||
final dnsStatistics = await getDnsStatistics(serverObj);
|
||||
if (dnsStatistics['result'] == 'success') {
|
||||
serversProvider.setDnsStatistics(dnsStatistics['data']);
|
||||
serversProvider.setIsServerConnected(true);
|
||||
}
|
||||
else {
|
||||
serversProvider.setIsServerConnected(false);
|
||||
}
|
||||
Navigator.pop(context);
|
||||
}
|
||||
else {
|
||||
|
@ -284,10 +295,12 @@ class _AddServerModalState extends State<AddServerModal> {
|
|||
port: int.parse(portController.text),
|
||||
user: userController.text,
|
||||
password: passwordController.text,
|
||||
defaultServer: defaultServer
|
||||
defaultServer: defaultServer,
|
||||
authToken: ''
|
||||
);
|
||||
final result = await login(serverObj);
|
||||
if (result['result'] == 'success') {
|
||||
serverObj.authToken = encodeBase64UserPass(serverObj.user, serverObj.password);
|
||||
final serverSaved = await serversProvider.editServer(serverObj);
|
||||
if (serverSaved == true) {
|
||||
Navigator.pop(context);
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
// ignore_for_file: use_build_context_synchronously
|
||||
import 'package:adguard_home_manager/widgets/add_server_modal.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:expandable/expandable.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
import 'package:adguard_home_manager/widgets/servers_list/delete_modal.dart';
|
||||
import 'package:adguard_home_manager/widgets/add_server_modal.dart';
|
||||
|
||||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||
import 'package:adguard_home_manager/models/server.dart';
|
||||
|
@ -54,21 +54,27 @@ class ServersList extends StatelessWidget {
|
|||
}
|
||||
|
||||
void connectToServer(Server server) async {
|
||||
Future connectSuccess(result) async {
|
||||
serversProvider.setSelectedServer(server);
|
||||
}
|
||||
|
||||
final ProcessModal process = ProcessModal(context: context);
|
||||
process.open(AppLocalizations.of(context)!.connecting);
|
||||
|
||||
final result = await login(server);
|
||||
|
||||
process.close();
|
||||
|
||||
if (result['result'] == 'success') {
|
||||
await connectSuccess(result);
|
||||
serversProvider.setSelectedServer(server);
|
||||
|
||||
final dnsStatistics = await getDnsStatistics(server);
|
||||
if (dnsStatistics['result'] == 'success') {
|
||||
serversProvider.setDnsStatistics(dnsStatistics['data']);
|
||||
serversProvider.setIsServerConnected(true);
|
||||
}
|
||||
else {
|
||||
serversProvider.setIsServerConnected(false);
|
||||
}
|
||||
|
||||
process.close();
|
||||
}
|
||||
else {
|
||||
process.close();
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(AppLocalizations.of(context)!.cannotConnect),
|
||||
|
|
Loading…
Add table
Reference in a new issue