selfprivacy.org.app/lib/logic/api_maps/server.dart

285 lines
7.0 KiB
Dart
Raw Normal View History

2021-03-26 01:30:34 +02:00
import 'dart:async';
2022-02-01 03:56:05 +02:00
import 'dart:convert';
2022-02-08 08:59:35 +02:00
import 'dart:io';
2021-01-21 23:01:42 +02:00
2021-01-21 09:35:38 +02:00
import 'package:dio/dio.dart';
2021-03-26 01:30:34 +02:00
import 'package:selfprivacy/config/get_it_config.dart';
2021-08-29 16:54:28 +03:00
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
2021-12-06 20:31:19 +02:00
import 'package:selfprivacy/logic/models/backblaze_bucket.dart';
import 'package:selfprivacy/logic/models/backup.dart';
2021-06-08 21:52:44 +03:00
import 'package:selfprivacy/logic/models/user.dart';
2021-01-21 09:35:38 +02:00
import 'api_map.dart';
2021-03-26 01:30:34 +02:00
class ServerApi extends ApiMap {
2022-02-16 09:28:29 +02:00
bool hasLogger;
2021-03-26 01:30:34 +02:00
bool isWithToken;
2022-02-16 09:28:29 +02:00
ServerApi({this.hasLogger = false, this.isWithToken = true});
2021-03-26 01:30:34 +02:00
BaseOptions get options {
var options = BaseOptions();
if (isWithToken) {
var cloudFlareDomain = getIt<ApiConfigModel>().cloudFlareDomain;
var domainName = cloudFlareDomain!.domainName;
2021-11-18 21:10:40 +02:00
var apiToken = getIt<ApiConfigModel>().hetznerServer?.apiToken;
2021-03-26 01:30:34 +02:00
2021-11-18 21:10:40 +02:00
options = BaseOptions(baseUrl: 'https://api.$domainName', headers: {
2021-12-06 20:31:19 +02:00
'Authorization': 'Bearer $apiToken',
2021-11-18 21:10:40 +02:00
});
2021-03-26 01:30:34 +02:00
}
return options;
2021-01-21 23:01:42 +02:00
}
Future<bool> isHttpServerWorking() async {
bool res;
Response response;
2021-03-26 01:30:34 +02:00
var client = await getClient();
2021-01-21 23:01:42 +02:00
try {
2021-09-15 16:15:54 +03:00
response = await client.get('/services/status');
2021-01-21 23:01:42 +02:00
res = response.statusCode == HttpStatus.ok;
} catch (e) {
res = false;
2021-01-21 09:35:38 +02:00
}
2021-03-26 15:38:39 +02:00
close(client);
2021-01-21 23:01:42 +02:00
return res;
2021-01-21 09:35:38 +02:00
}
2021-01-21 23:01:42 +02:00
2021-06-08 21:52:44 +03:00
Future<bool> createUser(User user) async {
bool res;
Response response;
var client = await getClient();
2021-11-18 21:10:40 +02:00
// POST request with JSON body containing username and password
2021-06-08 21:52:44 +03:00
try {
2021-06-21 00:08:52 +03:00
response = await client.post(
2021-11-18 21:10:40 +02:00
'/users',
data: {
'username': user.login,
'password': user.password,
},
2021-06-21 00:08:52 +03:00
options: Options(
2021-11-18 21:10:40 +02:00
contentType: 'application/json',
2021-06-21 00:08:52 +03:00
),
);
2021-11-18 21:10:40 +02:00
res = response.statusCode == HttpStatus.created;
2021-06-08 21:52:44 +03:00
} catch (e) {
2021-06-21 00:08:52 +03:00
print(e);
2021-06-08 21:52:44 +03:00
res = false;
}
2021-06-21 00:08:52 +03:00
2021-06-08 21:52:44 +03:00
close(client);
return res;
}
2021-12-20 17:25:31 +02:00
Future<bool> deleteUser(User user) async {
bool res;
Response response;
var client = await getClient();
try {
response = await client.delete(
'/users/${user.login}',
options: Options(
contentType: 'application/json',
),
);
res = response.statusCode == HttpStatus.ok;
} catch (e) {
print(e);
res = false;
}
close(client);
return res;
}
2021-03-26 01:30:34 +02:00
String get rootAddress =>
throw UnimplementedError('not used in with implementation');
2021-07-29 08:24:42 +03:00
Future<bool> apply() async {
bool res;
Response response;
var client = await getClient();
try {
response = await client.get(
2021-09-15 16:15:54 +03:00
'/system/configuration/apply',
2021-07-29 08:24:42 +03:00
);
res = response.statusCode == HttpStatus.ok;
} catch (e) {
print(e);
res = false;
}
close(client);
return res;
}
2021-08-29 16:54:28 +03:00
2021-08-29 18:02:51 +03:00
Future<void> switchService(ServiceTypes type, bool needToTurnOn) async {
var client = await getClient();
client.post('/services/${type.url}/${needToTurnOn ? 'enable' : 'disable'}');
client.close();
}
2021-09-02 22:32:07 +03:00
Future<void> sendSsh(String ssh) async {
var client = await getClient();
2021-11-18 21:10:40 +02:00
client.put(
'/services/ssh/key/send',
2021-09-02 22:32:07 +03:00
data: {"public_key": ssh},
);
client.close();
}
Future<Map<ServiceTypes, bool>> servicesPowerCheck() async {
var client = await getClient();
Response response = await client.get('/services/status');
close(client);
return {
ServiceTypes.passwordManager: response.data['bitwarden'] == 0,
ServiceTypes.git: response.data['gitea'] == 0,
ServiceTypes.cloud: response.data['nextcloud'] == 0,
ServiceTypes.vpn: response.data['ocserv'] == 0,
ServiceTypes.socialNetwork: response.data['pleroma'] == 0,
};
}
2021-12-06 20:31:19 +02:00
Future<void> uploadBackblazeConfig(BackblazeBucket bucket) async {
var client = await getClient();
client.put(
'/services/restic/backblaze/config',
data: {
'accountId': bucket.applicationKeyId,
'accountKey': bucket.applicationKey,
'bucket': bucket.bucketName,
},
);
client.close();
}
Future<void> startBackup() async {
var client = await getClient();
client.put('/services/restic/backup/create');
client.close();
}
Future<List<Backup>> getBackups() async {
Response response;
var client = await getClient();
try {
response = await client.get(
'/services/restic/backup/list',
);
2021-12-09 05:44:05 +02:00
return response.data.map<Backup>((e) => Backup.fromJson(e)).toList();
2021-12-06 20:31:19 +02:00
} catch (e) {
print(e);
}
close(client);
return <Backup>[];
}
Future<BackupStatus> getBackupStatus() async {
Response response;
var client = await getClient();
try {
response = await client.get(
'/services/restic/backup/status',
);
return BackupStatus.fromJson(response.data);
} catch (e) {
print(e);
}
close(client);
return BackupStatus(
status: BackupStatusEnum.error,
errorMessage: 'Network error',
progress: 0,
);
}
Future<void> forceBackupListReload() async {
var client = await getClient();
client.get('/services/restic/backup/reload');
client.close();
}
Future<void> restoreBackup(String backupId) async {
var client = await getClient();
client.put('/services/restic/backup/restore', data: {'backupId': backupId});
client.close();
}
Future<bool> pullConfigurationUpdate() async {
var client = await getClient();
Response response = await client.get('/system/configuration/pull');
close(client);
return response.statusCode == HttpStatus.ok;
}
Future<bool> reboot() async {
var client = await getClient();
Response response = await client.get('/system/reboot');
client.close();
return response.statusCode == HttpStatus.ok;
}
Future<bool> upgrade() async {
var client = await getClient();
Response response = await client.get('/system/configuration/upgrade');
client.close();
return response.statusCode == HttpStatus.ok;
}
2022-02-01 03:56:05 +02:00
Future<String> getDkim() async {
var client = await getClient();
Response response = await client.get('/services/mailserver/dkim');
client.close();
// if got 404 raise exception
if (response.statusCode == HttpStatus.notFound) {
throw Exception('No DKIM key found');
}
final base64toString = utf8.fuse(base64);
2022-02-08 08:59:35 +02:00
return base64toString
.decode(response.data)
.split('(')[1]
.split(')')[0]
.replaceAll('"', '');
2022-02-01 03:56:05 +02:00
}
2021-08-29 18:02:51 +03:00
}
2021-08-29 16:54:28 +03:00
extension UrlServerExt on ServiceTypes {
String get url {
switch (this) {
// case ServiceTypes.mail:
2022-02-16 09:28:29 +02:00
// return ''; // cannot be switch off
2021-08-29 16:54:28 +03:00
// case ServiceTypes.messenger:
// return ''; // external service
// case ServiceTypes.video:
2022-02-16 09:28:29 +02:00
// return ''; // jitsi meet not working
2021-08-29 16:54:28 +03:00
case ServiceTypes.passwordManager:
return 'bitwarden';
case ServiceTypes.cloud:
return 'nextcloud';
case ServiceTypes.socialNetwork:
return 'pleroma';
case ServiceTypes.git:
return 'gitea';
case ServiceTypes.vpn:
return 'ocserv';
default:
throw Exception('wrong state');
}
}
2021-08-29 18:02:51 +03:00
}