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

512 lines
14 KiB
Dart

import 'package:graphql/client.dart';
import 'package:selfprivacy/config/get_it_config.dart';
import 'package:selfprivacy/logic/api_maps/graphql_maps/api_map.dart';
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/disk_volumes.graphql.dart';
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/schema.graphql.dart';
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/server_api.graphql.dart';
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/server_settings.graphql.dart';
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/services.graphql.dart';
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/users.graphql.dart';
import 'package:selfprivacy/logic/models/auto_upgrade_settings.dart';
import 'package:selfprivacy/logic/models/hive/backblaze_bucket.dart';
import 'package:selfprivacy/logic/models/hive/user.dart';
import 'package:selfprivacy/logic/models/json/api_token.dart';
import 'package:selfprivacy/logic/models/json/backup.dart';
import 'package:selfprivacy/logic/models/json/device_token.dart';
import 'package:selfprivacy/logic/models/json/dns_records.dart';
import 'package:selfprivacy/logic/models/json/recovery_token_status.dart';
import 'package:selfprivacy/logic/models/json/server_disk_volume.dart';
import 'package:selfprivacy/logic/models/json/server_job.dart';
import 'package:selfprivacy/logic/models/service.dart';
import 'package:selfprivacy/logic/models/ssh_settings.dart';
import 'package:selfprivacy/logic/models/system_settings.dart';
part 'jobs_api.dart';
part 'server_actions_api.dart';
part 'services_api.dart';
part 'users_api.dart';
part 'volume_api.dart';
class GenericResult<T> {
GenericResult({
required this.success,
required this.data,
this.message,
});
/// Whether was a response successfully received,
/// doesn't represent success of the request if `data<T>` is `bool`
final bool success;
final String? message;
final T data;
}
class GenericMutationResult<T> extends GenericResult<T> {
GenericMutationResult({
required super.success,
required this.code,
required super.data,
super.message,
});
final int code;
}
class ServerApi extends ApiMap
with VolumeApi, JobsApi, ServerActionsApi, ServicesApi, UsersApi {
ServerApi({
this.hasLogger = false,
this.isWithToken = true,
this.customToken = '',
this.overrideDomain,
});
@override
bool hasLogger;
@override
bool isWithToken;
@override
String customToken;
@override
String? get rootAddress =>
overrideDomain ?? getIt<ApiConfigModel>().serverDomain?.domainName;
String? overrideDomain;
Future<String?> getApiVersion() async {
QueryResult response;
String? apiVersion;
try {
final GraphQLClient client = await getClient();
response = await client.query$GetApiVersion();
if (response.hasException) {
print(response.exception.toString());
}
apiVersion = response.data!['api']['version'];
} catch (e) {
print(e);
}
return apiVersion;
}
Future<bool> isUsingBinds() async {
QueryResult response;
bool usesBinds = false;
try {
final GraphQLClient client = await getClient();
response = await client.query$SystemIsUsingBinds();
if (response.hasException) {
print(response.exception.toString());
}
usesBinds = response.data!['system']['info']['usingBinds'];
} catch (e) {
print(e);
}
return usesBinds;
}
Future<void> switchService(final String uid, final bool needTurnOn) async {
try {
final GraphQLClient client = await getClient();
if (needTurnOn) {
final variables = Variables$Mutation$EnableService(serviceId: uid);
final mutation = Options$Mutation$EnableService(variables: variables);
await client.mutate$EnableService(mutation);
} else {
final variables = Variables$Mutation$DisableService(serviceId: uid);
final mutation = Options$Mutation$DisableService(variables: variables);
await client.mutate$DisableService(mutation);
}
} catch (e) {
print(e);
}
}
Future<void> setAutoUpgradeSettings(
final AutoUpgradeSettings settings,
) async {
try {
final GraphQLClient client = await getClient();
final input = Input$AutoUpgradeSettingsInput(
allowReboot: settings.allowReboot,
enableAutoUpgrade: settings.enable,
);
final variables = Variables$Mutation$ChangeAutoUpgradeSettings(
settings: input,
);
final mutation = Options$Mutation$ChangeAutoUpgradeSettings(
variables: variables,
);
await client.mutate$ChangeAutoUpgradeSettings(mutation);
} catch (e) {
print(e);
}
}
Future<void> setTimezone(final String timezone) async {
try {
final GraphQLClient client = await getClient();
final variables = Variables$Mutation$ChangeTimezone(
timezone: timezone,
);
final mutation = Options$Mutation$ChangeTimezone(
variables: variables,
);
await client.mutate$ChangeTimezone(mutation);
} catch (e) {
print(e);
}
}
Future<SystemSettings> getSystemSettings() async {
QueryResult<Query$SystemSettings> response;
SystemSettings settings = SystemSettings(
autoUpgradeSettings: AutoUpgradeSettings(
allowReboot: false,
enable: false,
),
sshSettings: SshSettings(
enable: false,
passwordAuthentication: false,
),
timezone: 'Unknown',
);
try {
final GraphQLClient client = await getClient();
response = await client.query$SystemSettings();
if (response.hasException) {
print(response.exception.toString());
}
settings = SystemSettings.fromGraphQL(response.parsedData!.system);
} catch (e) {
print(e);
}
return settings;
}
Future<GenericResult<RecoveryKeyStatus?>> getRecoveryTokenStatus() async {
RecoveryKeyStatus? key;
QueryResult<Query$RecoveryKey> response;
String? error;
try {
final GraphQLClient client = await getClient();
response = await client.query$RecoveryKey();
if (response.hasException) {
print(response.exception.toString());
error = response.exception.toString();
}
key = RecoveryKeyStatus.fromGraphQL(response.parsedData!.api.recoveryKey);
} catch (e) {
print(e);
}
return GenericResult<RecoveryKeyStatus?>(
success: error == null,
data: key,
message: error,
);
}
Future<GenericResult<String>> generateRecoveryToken(
final DateTime? expirationDate,
final int? numberOfUses,
) async {
GenericResult<String> key;
QueryResult<Mutation$GetNewRecoveryApiKey> response;
try {
final GraphQLClient client = await getClient();
final input = Input$RecoveryKeyLimitsInput(
expirationDate: expirationDate,
uses: numberOfUses,
);
final variables = Variables$Mutation$GetNewRecoveryApiKey(
limits: input,
);
final mutation = Options$Mutation$GetNewRecoveryApiKey(
variables: variables,
);
response = await client.mutate$GetNewRecoveryApiKey(
mutation,
);
if (response.hasException) {
print(response.exception.toString());
key = GenericResult<String>(
success: false,
data: '',
message: response.exception.toString(),
);
}
key = GenericResult<String>(
success: true,
data: response.parsedData!.getNewRecoveryApiKey.key!,
);
} catch (e) {
print(e);
key = GenericResult<String>(
success: false,
data: '',
message: e.toString(),
);
}
return key;
}
Future<List<DnsRecord>> getDnsRecords() async {
List<DnsRecord> records = [];
QueryResult<Query$DomainInfo> response;
try {
final GraphQLClient client = await getClient();
response = await client.query$DomainInfo();
if (response.hasException) {
print(response.exception.toString());
}
records = response.parsedData!.system.domainInfo.requiredDnsRecords
.map<DnsRecord>(
(final Fragment$dnsRecordFields fragment) =>
DnsRecord.fromGraphQL(fragment),
)
.toList();
} catch (e) {
print(e);
}
return records;
}
Future<GenericResult<List<ApiToken>>> getApiTokens() async {
GenericResult<List<ApiToken>> tokens;
QueryResult<Query$GetApiTokens> response;
try {
final GraphQLClient client = await getClient();
response = await client.query$GetApiTokens();
if (response.hasException) {
final message = response.exception.toString();
print(message);
tokens = GenericResult<List<ApiToken>>(
success: false,
data: [],
message: message,
);
}
final List<ApiToken> parsed = response.parsedData!.api.devices
.map(
(
final Query$GetApiTokens$api$devices device,
) =>
ApiToken.fromGraphQL(device),
)
.toList();
tokens = GenericResult<List<ApiToken>>(
success: true,
data: parsed,
);
} catch (e) {
print(e);
tokens = GenericResult<List<ApiToken>>(
success: false,
data: [],
message: e.toString(),
);
}
return tokens;
}
Future<GenericResult<void>> deleteApiToken(final String name) async {
GenericResult<void> returnable;
QueryResult<Mutation$DeleteDeviceApiToken> response;
try {
final GraphQLClient client = await getClient();
final variables = Variables$Mutation$DeleteDeviceApiToken(
device: name,
);
final mutation = Options$Mutation$DeleteDeviceApiToken(
variables: variables,
);
response = await client.mutate$DeleteDeviceApiToken(
mutation,
);
if (response.hasException) {
print(response.exception.toString());
returnable = GenericResult<void>(
success: false,
data: null,
message: response.exception.toString(),
);
}
returnable = GenericResult<void>(
success: true,
data: null,
);
} catch (e) {
print(e);
returnable = GenericResult<void>(
success: false,
data: null,
message: e.toString(),
);
}
return returnable;
}
Future<GenericResult<String>> createDeviceToken() async {
GenericResult<String> token;
QueryResult<Mutation$GetNewDeviceApiKey> response;
try {
final GraphQLClient client = await getClient();
final mutation = Options$Mutation$GetNewDeviceApiKey();
response = await client.mutate$GetNewDeviceApiKey(
mutation,
);
if (response.hasException) {
print(response.exception.toString());
token = GenericResult<String>(
success: false,
data: '',
message: response.exception.toString(),
);
}
token = GenericResult<String>(
success: true,
data: response.parsedData!.getNewDeviceApiKey.key!,
);
} catch (e) {
print(e);
token = GenericResult<String>(
success: false,
data: '',
message: e.toString(),
);
}
return token;
}
Future<bool> isHttpServerWorking() async => (await getApiVersion()) != null;
Future<GenericResult<String>> authorizeDevice(
final DeviceToken deviceToken,
) async {
GenericResult<String> token;
QueryResult<Mutation$AuthorizeWithNewDeviceApiKey> response;
try {
final GraphQLClient client = await getClient();
final input = Input$UseNewDeviceKeyInput(
deviceName: deviceToken.device,
key: deviceToken.token,
);
final variables = Variables$Mutation$AuthorizeWithNewDeviceApiKey(
input: input,
);
final mutation = Options$Mutation$AuthorizeWithNewDeviceApiKey(
variables: variables,
);
response = await client.mutate$AuthorizeWithNewDeviceApiKey(
mutation,
);
if (response.hasException) {
print(response.exception.toString());
token = GenericResult<String>(
success: false,
data: '',
message: response.exception.toString(),
);
}
token = GenericResult<String>(
success: true,
data: response.parsedData!.authorizeWithNewDeviceApiKey.token!,
);
} catch (e) {
print(e);
token = GenericResult<String>(
success: false,
data: '',
message: e.toString(),
);
}
return token;
}
Future<GenericResult<String>> useRecoveryToken(
final DeviceToken deviceToken,
) async {
GenericResult<String> token;
QueryResult<Mutation$UseRecoveryApiKey> response;
try {
final GraphQLClient client = await getClient();
final input = Input$UseRecoveryKeyInput(
deviceName: deviceToken.device,
key: deviceToken.token,
);
final variables = Variables$Mutation$UseRecoveryApiKey(
input: input,
);
final mutation = Options$Mutation$UseRecoveryApiKey(
variables: variables,
);
response = await client.mutate$UseRecoveryApiKey(
mutation,
);
if (response.hasException) {
print(response.exception.toString());
token = GenericResult<String>(
success: false,
data: '',
message: response.exception.toString(),
);
}
token = GenericResult<String>(
success: true,
data: response.parsedData!.useRecoveryApiKey.token!,
);
} catch (e) {
print(e);
token = GenericResult<String>(
success: false,
data: '',
message: e.toString(),
);
}
return token;
}
/// TODO: backups're not implemented on server side
Future<BackupStatus> getBackupStatus() async => BackupStatus(
progress: 0.0,
status: BackupStatusEnum.error,
errorMessage: null,
);
Future<List<Backup>> getBackups() async => [];
Future<void> uploadBackblazeConfig(final BackblazeBucket bucket) async {}
Future<void> forceBackupListReload() async {}
Future<void> startBackup() async {}
Future<void> restoreBackup(final String backupId) async {}
}