2021-03-25 23:30:34 +00:00
|
|
|
import 'dart:async';
|
2021-01-21 21:01:42 +00:00
|
|
|
import 'dart:io';
|
|
|
|
|
2021-01-21 07:35:38 +00:00
|
|
|
import 'package:dio/dio.dart';
|
2021-03-25 23:30:34 +00:00
|
|
|
import 'package:selfprivacy/config/get_it_config.dart';
|
2021-08-29 13:54:28 +00:00
|
|
|
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
2021-12-06 18:31:19 +00:00
|
|
|
import 'package:selfprivacy/logic/models/backblaze_bucket.dart';
|
|
|
|
import 'package:selfprivacy/logic/models/backup.dart';
|
2021-06-08 18:52:44 +00:00
|
|
|
import 'package:selfprivacy/logic/models/user.dart';
|
2021-01-21 07:35:38 +00:00
|
|
|
|
|
|
|
import 'api_map.dart';
|
|
|
|
|
2021-03-25 23:30:34 +00:00
|
|
|
class ServerApi extends ApiMap {
|
|
|
|
bool hasLoger;
|
|
|
|
bool isWithToken;
|
|
|
|
|
|
|
|
ServerApi({this.hasLoger = false, this.isWithToken = true});
|
|
|
|
|
|
|
|
BaseOptions get options {
|
|
|
|
var options = BaseOptions();
|
|
|
|
|
|
|
|
if (isWithToken) {
|
|
|
|
var cloudFlareDomain = getIt<ApiConfigModel>().cloudFlareDomain;
|
|
|
|
var domainName = cloudFlareDomain!.domainName;
|
2021-11-18 19:10:40 +00:00
|
|
|
var apiToken = getIt<ApiConfigModel>().hetznerServer?.apiToken;
|
2022-02-07 07:53:13 +00:00
|
|
|
print(apiToken);
|
2021-11-18 19:10:40 +00:00
|
|
|
options = BaseOptions(baseUrl: 'https://api.$domainName', headers: {
|
2021-12-06 18:31:19 +00:00
|
|
|
'Authorization': 'Bearer $apiToken',
|
2021-11-18 19:10:40 +00:00
|
|
|
});
|
2021-03-25 23:30:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return options;
|
2021-01-21 21:01:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Future<bool> isHttpServerWorking() async {
|
|
|
|
bool res;
|
|
|
|
Response response;
|
2021-03-25 23:30:34 +00:00
|
|
|
|
|
|
|
var client = await getClient();
|
2021-01-21 21:01:42 +00:00
|
|
|
try {
|
2021-09-15 13:15:54 +00:00
|
|
|
response = await client.get('/services/status');
|
2021-01-21 21:01:42 +00:00
|
|
|
res = response.statusCode == HttpStatus.ok;
|
|
|
|
} catch (e) {
|
|
|
|
res = false;
|
2021-01-21 07:35:38 +00:00
|
|
|
}
|
2021-03-26 13:38:39 +00:00
|
|
|
close(client);
|
2021-01-21 21:01:42 +00:00
|
|
|
return res;
|
2021-01-21 07:35:38 +00:00
|
|
|
}
|
2021-01-21 21:01:42 +00:00
|
|
|
|
2021-06-08 18:52:44 +00:00
|
|
|
Future<bool> createUser(User user) async {
|
|
|
|
bool res;
|
|
|
|
Response response;
|
|
|
|
|
|
|
|
var client = await getClient();
|
2021-11-18 19:10:40 +00:00
|
|
|
// POST request with JSON body containing username and password
|
2021-06-08 18:52:44 +00:00
|
|
|
try {
|
2021-06-20 21:08:52 +00:00
|
|
|
response = await client.post(
|
2021-11-18 19:10:40 +00:00
|
|
|
'/users',
|
|
|
|
data: {
|
|
|
|
'username': user.login,
|
|
|
|
'password': user.password,
|
|
|
|
},
|
2021-06-20 21:08:52 +00:00
|
|
|
options: Options(
|
2021-11-18 19:10:40 +00:00
|
|
|
contentType: 'application/json',
|
2021-06-20 21:08:52 +00:00
|
|
|
),
|
|
|
|
);
|
2021-11-18 19:10:40 +00:00
|
|
|
res = response.statusCode == HttpStatus.created;
|
2021-06-08 18:52:44 +00:00
|
|
|
} catch (e) {
|
2021-06-20 21:08:52 +00:00
|
|
|
print(e);
|
2021-06-08 18:52:44 +00:00
|
|
|
res = false;
|
|
|
|
}
|
2021-06-20 21:08:52 +00:00
|
|
|
|
2021-06-08 18:52:44 +00:00
|
|
|
close(client);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2021-12-20 15:25:31 +00: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-25 23:30:34 +00:00
|
|
|
String get rootAddress =>
|
|
|
|
throw UnimplementedError('not used in with implementation');
|
2021-07-29 05:24:42 +00:00
|
|
|
|
|
|
|
Future<bool> apply() async {
|
|
|
|
bool res;
|
|
|
|
Response response;
|
|
|
|
|
|
|
|
var client = await getClient();
|
|
|
|
try {
|
|
|
|
response = await client.get(
|
2021-09-15 13:15:54 +00:00
|
|
|
'/system/configuration/apply',
|
2021-07-29 05:24:42 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
res = response.statusCode == HttpStatus.ok;
|
|
|
|
} catch (e) {
|
|
|
|
print(e);
|
|
|
|
res = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
close(client);
|
|
|
|
return res;
|
|
|
|
}
|
2021-08-29 13:54:28 +00:00
|
|
|
|
2021-08-29 15:02:51 +00: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 19:32:07 +00:00
|
|
|
|
|
|
|
Future<void> sendSsh(String ssh) async {
|
|
|
|
var client = await getClient();
|
2021-11-18 19:10:40 +00:00
|
|
|
client.put(
|
|
|
|
'/services/ssh/key/send',
|
2021-09-02 19:32:07 +00:00
|
|
|
data: {"public_key": ssh},
|
|
|
|
);
|
|
|
|
client.close();
|
|
|
|
}
|
2021-09-29 13:08:19 +00:00
|
|
|
|
|
|
|
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 18:31:19 +00: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 03:44:05 +00:00
|
|
|
return response.data.map<Backup>((e) => Backup.fromJson(e)).toList();
|
2021-12-06 18:31:19 +00: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-07 07:53:13 +00:00
|
|
|
|
|
|
|
Future<bool> autoUpgradeSettings() async {
|
|
|
|
var client = await getClient();
|
|
|
|
Response response = await client.get('/system/configuration/upgrade');
|
|
|
|
client.close();
|
|
|
|
return response.statusCode == HttpStatus.ok;
|
|
|
|
}
|
2021-08-29 15:02:51 +00:00
|
|
|
}
|
2021-08-29 13:54:28 +00:00
|
|
|
|
|
|
|
extension UrlServerExt on ServiceTypes {
|
|
|
|
String get url {
|
|
|
|
switch (this) {
|
|
|
|
// case ServiceTypes.mail:
|
|
|
|
// return ''; // cannot be swithch off
|
|
|
|
// case ServiceTypes.messenger:
|
|
|
|
// return ''; // external service
|
|
|
|
// case ServiceTypes.video:
|
|
|
|
// return ''; // jeetsu meet not working
|
|
|
|
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 15:02:51 +00:00
|
|
|
}
|