fdroid
Kherel 2021-01-14 22:48:05 +01:00
parent 853e1fdbdd
commit 5e13112486
13 changed files with 239 additions and 22 deletions

View File

@ -0,0 +1,8 @@
import 'package:get_it/get_it.dart';
import 'package:selfprivacy/logic/get_it/console.dart';
final getIt = GetIt.instance;
void getItSetup() {
getIt.registerSingleton<ConsoleModel>(ConsoleModelImplementation());
}

View File

@ -1,11 +1,49 @@
import 'package:dio/dio.dart';
import 'package:selfprivacy/config/get_it_config.dart';
import 'package:selfprivacy/logic/get_it/console.dart';
import 'package:selfprivacy/logic/models/message.dart';
abstract class ApiMap {
String rootAddress;
Dio client = Dio();
// Dio client = Dio();
Dio loggedClient = Dio()..interceptors.add(ConsoleInterceptor());
void close() {
client.close();
loggedClient.close();
}
}
class ConsoleInterceptor extends InterceptorsWrapper {
void addMessage(Message message) {
getIt.get<ConsoleModel>().addMessage(message);
}
@override
Future onRequest(RequestOptions options) async {
addMessage(
Message(
text:
'request-uri: ${options.uri}\nheaders: ${options.headers}\ndata: ${options.data}',
),
);
return super.onRequest(options);
}
@override
Future onResponse(Response response) async {
addMessage(
Message(
text:
'response-uri: ${response.request.uri}\ncode: ${response.statusCode}\n',
),
);
return super.onResponse(response);
}
@override
Future onError(DioError err) async {
return super.onError(err);
}
}

View File

@ -7,7 +7,7 @@ import 'package:selfprivacy/logic/models/dns_records.dart';
class CloudflareApi extends ApiMap {
CloudflareApi([String token]) {
if (token != null) {
client.options = BaseOptions(headers: {'Authorization': 'Bearer $token'});
loggedClient.options = BaseOptions(headers: {'Authorization': 'Bearer $token'});
}
}
@ -23,7 +23,7 @@ class CloudflareApi extends ApiMap {
},
);
Response response = await client.get(url, options: options);
Response response = await loggedClient.get(url, options: options);
if (response.statusCode == HttpStatus.ok) {
return true;
@ -44,7 +44,7 @@ class CloudflareApi extends ApiMap {
},
);
Response response = await client.get(
Response response = await loggedClient.get(
url,
options: options,
queryParameters: {'name': domain},
@ -106,7 +106,7 @@ class CloudflareApi extends ApiMap {
var url = '$rootAddress/zones/$domainZoneId/dns_records';
allFutures.add(
client.post(
loggedClient.post(
url,
data: record.toJson(),
),

View File

@ -9,12 +9,13 @@ import 'package:selfprivacy/logic/models/user.dart';
class HetznerApi extends ApiMap {
HetznerApi([String token]) {
if (token != null) {
client.options = BaseOptions(headers: {'Authorization': 'Bearer $token'});
loggedClient.options =
BaseOptions(headers: {'Authorization': 'Bearer $token'});
}
}
@override
String rootAddress = 'http://api.hetzner.cloud/v1/servers';
String rootAddress = 'https://api.hetzner.cloud/v1/servers';
Future<bool> isValid(String token) async {
var options = Options(
@ -24,7 +25,7 @@ class HetznerApi extends ApiMap {
},
);
Response response = await client.get(rootAddress, options: options);
Response response = await loggedClient.get(rootAddress, options: options);
if (response.statusCode == HttpStatus.ok) {
return true;
@ -50,7 +51,7 @@ class HetznerApi extends ApiMap {
'user-data':
'#cloud-config\nruncmd:\n- curl https://git.selfprivacy.org/ilchub/selfprivacy-nixos-infect/raw/branch/master/nixos-infect | PROVIDER=hetzner NIX_CHANNEL=nixos-20.09 DOMAIN=$domainName USER=${rootUser.login} PASSWORD=${rootUser.password} HASHED_PASSWORD=${rootUser.hashPassword} bash 2>&1 | tee /tmp/infect.log'
};
Response response = await client.post(
Response response = await loggedClient.post(
rootAddress,
data: data,
);

View File

@ -1,13 +1,17 @@
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:hive/hive.dart';
import 'package:selfprivacy/config/get_it_config.dart';
import 'package:selfprivacy/config/hive_config.dart';
import 'package:selfprivacy/logic/api_maps/cloud_flare.dart';
import 'package:selfprivacy/logic/api_maps/hetzner.dart';
import 'package:selfprivacy/logic/get_it/console.dart';
import 'package:selfprivacy/logic/models/cloudflare_domain.dart';
import 'package:selfprivacy/logic/models/message.dart';
import 'package:selfprivacy/logic/models/server_details.dart';
import 'package:selfprivacy/logic/models/user.dart';
import 'package:basic_utils/basic_utils.dart';
import 'package:dio/dio.dart';
part 'app_config_state.dart';
@ -71,6 +75,18 @@ class AppConfigCubit extends Cubit<AppConfigState> {
RRecordType.A,
provider: DnsApiProvider.CLOUDFLARE,
);
getIt.get<ConsoleModel>().addMessage(
Message(
text:
'DnsLookup: address:$address, $RRecordType, provider: CLOUDFLARE',
),
);
getIt.get<ConsoleModel>().addMessage(
Message(
text:
'DnsLookup: address:$address, $RRecordType, provider: CLOUDFLARE',
),
);
if (res.isEmpty || res[0].data != ip4) {
hasError = true;
break;
@ -88,17 +104,28 @@ class AppConfigCubit extends Cubit<AppConfigState> {
var hetznerApi = HetznerApi(state.hetznerKey);
var cloudflareApi = CloudflareApi(state.cloudFlareKey);
var serverDetails = await hetznerApi.createServer(
HetznerServerDetails serverDetails;
try {
serverDetails = await hetznerApi.createServer(
rootUser: state.rootUser,
domainName: state.cloudFlareDomain.name,
);
} catch (e) {
addError(e);
}
try {
cloudflareApi
.createMultipleDnsRecords(
ip4: serverDetails.ip4,
cloudFlareDomain: state.cloudFlareDomain,
)
.then((_) => cloudflareApi.close());
} catch (e) {
addError(e);
}
await box.put(BNames.hetznerServer, serverDetails);
hetznerApi.close();

View File

@ -31,7 +31,6 @@ class AppSettingsCubit extends Cubit<AppSettingsState> {
void updateDarkMode({@required bool isDarkModeOn}) {
box.put(BNames.isDarkModeOn, isDarkModeOn);
emit(state.copyWith(isDarkModeOn: isDarkModeOn));
}

View File

@ -0,0 +1,21 @@
import 'package:flutter/material.dart';
import 'package:selfprivacy/logic/models/message.dart';
abstract class ConsoleModel extends ChangeNotifier {
void addMessage(Message message);
List<Message> get messages;
}
class ConsoleModelImplementation extends ConsoleModel {
List<Message> _messages = [];
@override
List<Message> get messages => _messages;
@override
void addMessage(Message message) {
messages.add(message);
notifyListeners();
}
}

View File

@ -0,0 +1,14 @@
import 'package:intl/intl.dart';
final formater = new DateFormat('hh:mm');
class Message {
Message({
this.text,
}) : time = DateTime.now();
final String text;
final DateTime time;
String get timeString => formater.format(time);
}

View File

@ -9,6 +9,7 @@ import 'package:selfprivacy/ui/pages/rootRoute.dart';
import 'config/bloc_config.dart';
import 'config/bloc_observer.dart';
import 'config/brand_theme.dart';
import 'config/get_it_config.dart';
import 'config/localization.dart';
import 'logic/cubit/app_settings/app_settings_cubit.dart';
@ -17,7 +18,7 @@ final navigatorKey = GlobalKey<NavigatorState>();
void main() async {
await HiveConfig.init();
Bloc.observer = SimpleBlocObserver(navigatorKey: navigatorKey);
getItSetup();
WidgetsFlutterBinding.ensureInitialized();
runApp(

View File

@ -0,0 +1,94 @@
import 'dart:collection';
import 'package:flutter/material.dart';
import 'package:selfprivacy/config/get_it_config.dart';
import 'package:selfprivacy/logic/get_it/console.dart';
import 'package:selfprivacy/ui/components/brand_divider/brand_divider.dart';
import 'package:selfprivacy/ui/components/brand_header/brand_header.dart';
class Console extends StatefulWidget {
const Console({Key key}) : super(key: key);
@override
_ConsoleState createState() => _ConsoleState();
}
class _ConsoleState extends State<Console> {
@override
void initState() {
getIt.get<ConsoleModel>().addListener(update);
super.initState();
}
@override
void dispose() {
getIt<ConsoleModel>().removeListener(update);
super.dispose();
}
void update() => setState(() => {});
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: PreferredSize(
child: Column(
children: [
BrandHeader(title: 'Console', hasBackButton: true),
BrandDivider(),
],
),
preferredSize: Size.fromHeight(53),
),
body: FutureBuilder(
future: getIt.allReady(),
builder: (BuildContext context, AsyncSnapshot<void> snapshot) {
if (snapshot.hasData) {
var messages = getIt.get<ConsoleModel>().messages;
return ListView(
reverse: true,
shrinkWrap: true,
children: [
SizedBox(height: 20),
...UnmodifiableListView(messages
.map((message) => Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: RichText(
text: TextSpan(
style: DefaultTextStyle.of(context).style,
children: <TextSpan>[
TextSpan(
text: '${message.timeString}: ',
style: TextStyle(
fontWeight: FontWeight.bold)),
TextSpan(text: message.text),
],
),
),
))
.toList()
.reversed),
],
);
} else {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Text('Waiting for initialisation'),
SizedBox(
height: 16,
),
CircularProgressIndicator(),
],
);
}
},
),
),
);
}
}

View File

@ -12,6 +12,7 @@ import 'package:selfprivacy/utils/route_transitions/basic.dart';
import 'about/about.dart';
import 'app_settings/app_setting.dart';
import 'console/console.dart';
import 'info/info.dart';
class MorePage extends StatelessWidget {
@ -56,6 +57,11 @@ class MorePage extends StatelessWidget {
iconData: BrandIcons.triangle,
goTo: OnboardingPage(nextPage: RootPage()),
),
_NavItem(
title: 'Console',
iconData: BrandIcons.triangle,
goTo: Console(),
),
],
),
)

View File

@ -301,6 +301,13 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
get_it:
dependency: "direct main"
description:
name: get_it
url: "https://pub.dartlang.org"
source: hosted
version: "5.0.4"
glob:
dependency: transitive
description:

View File

@ -17,6 +17,7 @@ dependencies:
equatable: ^1.2.5
flutter_bloc: ^6.1.1
flutter_secure_storage: ^3.3.5
get_it: ^5.0.4
google_fonts: ^1.1.1
hive: ^1.4.4+1
hive_flutter: ^0.3.1