diff --git a/lib/logic/api_maps/graphql_maps/server_api/users_api.dart b/lib/logic/api_maps/graphql_maps/server_api/users_api.dart index 5be86a3d..c1b2b801 100644 --- a/lib/logic/api_maps/graphql_maps/server_api/users_api.dart +++ b/lib/logic/api_maps/graphql_maps/server_api/users_api.dart @@ -37,12 +37,9 @@ mixin UsersApi on ApiMap { if (response.hasException) { print(response.exception.toString()); } - if (response.parsedData?.users.getUser != null) { - user = User( - login: response.parsedData!.users.getUser!.username, - sshKeys: response.parsedData!.users.getUser?.sshKeys ?? const [], - isFoundOnServer: true, - ); + final responseUser = response.parsedData?.users.getUser; + if (responseUser != null) { + user = User.fromGraphQL(responseUser); } } catch (e) { print(e); diff --git a/lib/logic/api_maps/rest_maps/server.dart b/lib/logic/api_maps/rest_maps/server.dart index 2563fa50..5c94d990 100644 --- a/lib/logic/api_maps/rest_maps/server.dart +++ b/lib/logic/api_maps/rest_maps/server.dart @@ -4,6 +4,7 @@ import 'dart:io'; import 'package:dio/dio.dart'; import 'package:selfprivacy/config/get_it_config.dart'; +import 'package:selfprivacy/logic/api_maps/rest_maps/api_map.dart'; import 'package:selfprivacy/logic/common_enum/common_enum.dart'; import 'package:selfprivacy/logic/models/hive/backblaze_bucket.dart'; import 'package:selfprivacy/logic/models/hive/server_domain.dart'; @@ -15,8 +16,6 @@ import 'package:selfprivacy/logic/models/json/device_token.dart'; import 'package:selfprivacy/logic/models/json/recovery_token_status.dart'; import 'package:selfprivacy/logic/models/timezone_settings.dart'; -import 'package:selfprivacy/logic/api_maps/rest_maps/api_map.dart'; - class ApiResponse { ApiResponse({ required this.statusCode, @@ -71,9 +70,7 @@ class ServerApi extends ApiMap { baseUrl: 'https://api.$overrideDomain', connectTimeout: 10000, receiveTimeout: 10000, - headers: customToken != null - ? {'Authorization': 'Bearer $customToken'} - : null, + headers: customToken != null ? {'Authorization': 'Bearer $customToken'} : null, ); } @@ -132,6 +129,7 @@ class ServerApi extends ApiMap { statusCode: e.response?.statusCode ?? HttpStatus.internalServerError, data: User( login: user.login, + type: UserType.normal, password: user.password, isFoundOnServer: false, ), @@ -143,8 +141,7 @@ class ServerApi extends ApiMap { bool isFoundOnServer = false; int code = 0; - final bool isUserCreated = (response.statusCode != null) && - (response.statusCode == HttpStatus.created); + final bool isUserCreated = (response.statusCode != null) && (response.statusCode == HttpStatus.created); if (isUserCreated) { isFoundOnServer = true; @@ -158,6 +155,7 @@ class ServerApi extends ApiMap { statusCode: code, data: User( login: user.login, + type: UserType.normal, password: user.password, isFoundOnServer: isFoundOnServer, ), @@ -273,9 +271,7 @@ class ServerApi extends ApiMap { final Dio client = await getClient(); try { response = await client.get('/services/ssh/keys/${user.login}'); - res = (response.data as List) - .map((final e) => e as String) - .toList(); + res = (response.data as List).map((final e) => e as String).toList(); } on DioError catch (e) { print(e.message); return ApiResponse>( @@ -334,9 +330,7 @@ class ServerApi extends ApiMap { return ApiResponse( statusCode: code, data: null, - errorMessage: response.data?.containsKey('error') ?? false - ? response.data['error'] - : null, + errorMessage: response.data?.containsKey('error') ?? false ? response.data['error'] : null, ); } @@ -347,8 +341,7 @@ class ServerApi extends ApiMap { final Dio client = await getClient(); try { response = await client.delete('/users/${user.login}'); - res = response.statusCode == HttpStatus.ok || - response.statusCode == HttpStatus.notFound; + res = response.statusCode == HttpStatus.ok || response.statusCode == HttpStatus.notFound; } on DioError catch (e) { print(e.message); res = false; @@ -359,8 +352,7 @@ class ServerApi extends ApiMap { } @override - String get rootAddress => - throw UnimplementedError('not used in with implementation'); + String get rootAddress => throw UnimplementedError('not used in with implementation'); Future apply() async { bool res = false; @@ -453,8 +445,7 @@ class ServerApi extends ApiMap { final Dio client = await getClient(); try { response = await client.get('/services/restic/backup/list'); - backups = - response.data.map((final e) => Backup.fromJson(e)).toList(); + backups = response.data.map((final e) => Backup.fromJson(e)).toList(); } on DioError catch (e) { print(e.message); } catch (e) { @@ -517,9 +508,7 @@ class ServerApi extends ApiMap { final Dio client = await getClient(); try { response = await client.get('/system/configuration/pull'); - result = (response.statusCode != null) - ? (response.statusCode == HttpStatus.ok) - : false; + result = (response.statusCode != null) ? (response.statusCode == HttpStatus.ok) : false; } on DioError catch (e) { print(e.message); } finally { @@ -535,9 +524,7 @@ class ServerApi extends ApiMap { final Dio client = await getClient(); try { response = await client.get('/system/reboot'); - result = (response.statusCode != null) - ? (response.statusCode == HttpStatus.ok) - : false; + result = (response.statusCode != null) ? (response.statusCode == HttpStatus.ok) : false; } on DioError catch (e) { print(e.message); } finally { @@ -553,9 +540,7 @@ class ServerApi extends ApiMap { final Dio client = await getClient(); try { response = await client.get('/system/configuration/upgrade'); - result = (response.statusCode != null) - ? (response.statusCode == HttpStatus.ok) - : false; + result = (response.statusCode != null) ? (response.statusCode == HttpStatus.ok) : false; } on DioError catch (e) { print(e.message); } finally { @@ -604,8 +589,7 @@ class ServerApi extends ApiMap { Future getServerTimezone() async { // I am not sure how to initialize TimeZoneSettings with default value... final Dio client = await getClient(); - final Response response = - await client.get('/system/configuration/timezone'); + final Response response = await client.get('/system/configuration/timezone'); close(client); return TimeZoneSettings.fromString(response.data); @@ -632,11 +616,7 @@ class ServerApi extends ApiMap { try { response = await client.get('/services/mailserver/dkim'); final Codec base64toString = utf8.fuse(base64); - dkim = base64toString - .decode(response.data) - .split('(')[1] - .split(')')[0] - .replaceAll('"', ''); + dkim = base64toString.decode(response.data).split('(')[1].split(')')[0].replaceAll('"', ''); } on DioError catch (e) { print(e.message); } finally { @@ -667,9 +647,7 @@ class ServerApi extends ApiMap { return ApiResponse( statusCode: code, - data: response.data != null - ? RecoveryKeyStatus.fromJson(response.data) - : null, + data: response.data != null ? RecoveryKeyStatus.fromJson(response.data) : null, ); } @@ -839,11 +817,7 @@ class ServerApi extends ApiMap { return ApiResponse( statusCode: code, - data: (response.data != null) - ? response.data - .map((final e) => ApiToken.fromJson(e)) - .toList() - : [], + data: (response.data != null) ? response.data.map((final e) => ApiToken.fromJson(e)).toList() : [], ); } diff --git a/lib/logic/cubit/forms/setup/initializing/root_user_form_cubit.dart b/lib/logic/cubit/forms/setup/initializing/root_user_form_cubit.dart index b3cf606f..cc4ef6cf 100644 --- a/lib/logic/cubit/forms/setup/initializing/root_user_form_cubit.dart +++ b/lib/logic/cubit/forms/setup/initializing/root_user_form_cubit.dart @@ -1,8 +1,8 @@ import 'dart:async'; import 'package:cubit_form/cubit_form.dart'; -import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart'; import 'package:selfprivacy/logic/cubit/forms/factories/field_cubit_factory.dart'; +import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart'; import 'package:selfprivacy/logic/models/hive/user.dart'; class RootUserFormCubit extends FormCubit { @@ -22,6 +22,7 @@ class RootUserFormCubit extends FormCubit { FutureOr onSubmit() async { final User user = User( login: userName.state.value, + type: UserType.primary, password: password.state.value, ); serverInstallationCubit.setRootUser(user); diff --git a/lib/logic/cubit/forms/user/user_form_cubit.dart b/lib/logic/cubit/forms/user/user_form_cubit.dart index 92f66f15..d745b5f5 100644 --- a/lib/logic/cubit/forms/user/user_form_cubit.dart +++ b/lib/logic/cubit/forms/user/user_form_cubit.dart @@ -1,10 +1,10 @@ import 'dart:async'; import 'package:cubit_form/cubit_form.dart'; -import 'package:selfprivacy/logic/cubit/forms/factories/field_cubit_factory.dart'; import 'package:selfprivacy/logic/cubit/client_jobs/client_jobs_cubit.dart'; -import 'package:selfprivacy/logic/models/job.dart'; +import 'package:selfprivacy/logic/cubit/forms/factories/field_cubit_factory.dart'; import 'package:selfprivacy/logic/models/hive/user.dart'; +import 'package:selfprivacy/logic/models/job.dart'; import 'package:selfprivacy/utils/password_generator.dart'; class UserFormCubit extends FormCubit { @@ -29,6 +29,7 @@ class UserFormCubit extends FormCubit { FutureOr onSubmit() { final User user = User( login: login.state.value, + type: UserType.normal, password: password.state.value, ); jobsCubit.addJob(CreateUserJob(user: user)); diff --git a/lib/logic/cubit/server_installation/server_installation_repository.dart b/lib/logic/cubit/server_installation/server_installation_repository.dart index c9ca0e96..91c09714 100644 --- a/lib/logic/cubit/server_installation/server_installation_repository.dart +++ b/lib/logic/cubit/server_installation/server_installation_repository.dart @@ -12,10 +12,11 @@ import 'package:selfprivacy/config/hive_config.dart'; import 'package:selfprivacy/logic/api_maps/rest_maps/api_factory_creator.dart'; import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/dns_provider.dart'; import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/dns_provider_factory.dart'; +import 'package:selfprivacy/logic/api_maps/rest_maps/server.dart'; import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/server_provider.dart'; import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/server_provider_factory.dart'; -import 'package:selfprivacy/logic/api_maps/rest_maps/server.dart'; import 'package:selfprivacy/logic/common_enum/common_enum.dart'; +import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart'; import 'package:selfprivacy/logic/models/hive/backblaze_credential.dart'; import 'package:selfprivacy/logic/models/hive/server_details.dart'; import 'package:selfprivacy/logic/models/hive/server_domain.dart'; @@ -26,8 +27,6 @@ import 'package:selfprivacy/logic/models/server_basic_info.dart'; import 'package:selfprivacy/ui/components/action_button/action_button.dart'; import 'package:selfprivacy/ui/components/brand_alert/brand_alert.dart'; -import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart'; - class IpNotFoundException implements Exception { IpNotFoundException(this.message); final String message; @@ -41,12 +40,10 @@ class ServerAuthorizationException implements Exception { class ServerInstallationRepository { Box box = Hive.box(BNames.serverInstallationBox); Box usersBox = Hive.box(BNames.usersBox); - ServerProviderApiFactory? serverProviderApiFactory = - ApiFactoryCreator.createServerProviderApiFactory( + ServerProviderApiFactory? serverProviderApiFactory = ApiFactoryCreator.createServerProviderApiFactory( ServerProvider.hetzner, // TODO: HARDCODE FOR NOW!!! ); // TODO: Remove when provider selection is implemented. - DnsProviderApiFactory? dnsProviderApiFactory = - ApiFactoryCreator.createDnsProviderApiFactory( + DnsProviderApiFactory? dnsProviderApiFactory = ApiFactoryCreator.createDnsProviderApiFactory( DnsProvider.cloudflare, // TODO: HARDCODE FOR NOW!!! ); @@ -54,15 +51,11 @@ class ServerInstallationRepository { final String? providerApiToken = getIt().hetznerKey; final String? cloudflareToken = getIt().cloudFlareKey; final ServerDomain? serverDomain = getIt().serverDomain; - final BackblazeCredential? backblazeCredential = - getIt().backblazeCredential; - final ServerHostingDetails? serverDetails = - getIt().serverDetails; + final BackblazeCredential? backblazeCredential = getIt().backblazeCredential; + final ServerHostingDetails? serverDetails = getIt().serverDetails; - if (serverDetails != null && - serverDetails.provider != ServerProvider.unknown) { - serverProviderApiFactory = - ApiFactoryCreator.createServerProviderApiFactory( + if (serverDetails != null && serverDetails.provider != ServerProvider.unknown) { + serverProviderApiFactory = ApiFactoryCreator.createServerProviderApiFactory( serverDetails.provider, ); } @@ -82,15 +75,12 @@ class ServerInstallationRepository { serverDetails: serverDetails!, rootUser: box.get(BNames.rootUser), isServerStarted: box.get(BNames.isServerStarted, defaultValue: false), - isServerResetedFirstTime: - box.get(BNames.isServerResetedFirstTime, defaultValue: false), - isServerResetedSecondTime: - box.get(BNames.isServerResetedSecondTime, defaultValue: false), + isServerResetedFirstTime: box.get(BNames.isServerResetedFirstTime, defaultValue: false), + isServerResetedSecondTime: box.get(BNames.isServerResetedSecondTime, defaultValue: false), ); } - if (box.get(BNames.isRecoveringServer, defaultValue: false) && - serverDomain != null) { + if (box.get(BNames.isRecoveringServer, defaultValue: false) && serverDomain != null) { return ServerInstallationRecovery( providerApiToken: providerApiToken, cloudFlareKey: cloudflareToken, @@ -116,10 +106,8 @@ class ServerInstallationRepository { serverDetails: serverDetails, rootUser: box.get(BNames.rootUser), isServerStarted: box.get(BNames.isServerStarted, defaultValue: false), - isServerResetedFirstTime: - box.get(BNames.isServerResetedFirstTime, defaultValue: false), - isServerResetedSecondTime: - box.get(BNames.isServerResetedSecondTime, defaultValue: false), + isServerResetedFirstTime: box.get(BNames.isServerResetedFirstTime, defaultValue: false), + isServerResetedSecondTime: box.get(BNames.isServerResetedSecondTime, defaultValue: false), isLoading: box.get(BNames.isLoading, defaultValue: false), dnsMatches: null, ); @@ -183,13 +171,7 @@ class ServerInstallationRepository { final String? ip4, final Map skippedMatches, ) async { - final List addresses = [ - '$domainName', - 'api.$domainName', - 'cloud.$domainName', - 'meet.$domainName', - 'password.$domainName' - ]; + final List addresses = ['$domainName', 'api.$domainName', 'cloud.$domainName', 'meet.$domainName', 'password.$domainName']; final Map matches = {}; @@ -205,19 +187,15 @@ class ServerInstallationRepository { ); getIt.get().addMessage( Message( - text: - 'DnsLookup: address: $address, $RRecordType, provider: CLOUDFLARE, ip4: $ip4', + text: 'DnsLookup: address: $address, $RRecordType, provider: CLOUDFLARE, ip4: $ip4', ), ); getIt.get().addMessage( Message( - text: - 'DnsLookup: ${lookupRecordRes == null ? 'empty' : (lookupRecordRes[0].data != ip4 ? 'wrong ip4' : 'right ip4')}', + text: 'DnsLookup: ${lookupRecordRes == null ? 'empty' : (lookupRecordRes[0].data != ip4 ? 'wrong ip4' : 'right ip4')}', ), ); - if (lookupRecordRes == null || - lookupRecordRes.isEmpty || - lookupRecordRes[0].data != ip4) { + if (lookupRecordRes == null || lookupRecordRes.isEmpty || lookupRecordRes[0].data != ip4) { matches[address] = false; } else { matches[address] = true; @@ -233,8 +211,7 @@ class ServerInstallationRepository { final String cloudFlareKey, final BackblazeCredential backblazeCredential, { required final void Function() onCancel, - required final Future Function(ServerHostingDetails serverDetails) - onSuccess, + required final Future Function(ServerHostingDetails serverDetails) onSuccess, }) async { final ServerProviderApi api = serverProviderApiFactory!.getServerProvider(); try { @@ -338,10 +315,8 @@ class ServerInstallationRepository { final ServerDomain domain, { required final void Function() onCancel, }) async { - final DnsProviderApi dnsProviderApi = - dnsProviderApiFactory!.getDnsProvider(); - final ServerProviderApi serverApi = - serverProviderApiFactory!.getServerProvider(); + final DnsProviderApi dnsProviderApi = dnsProviderApiFactory!.getDnsProvider(); + final ServerProviderApi serverApi = serverProviderApiFactory!.getServerProvider(); await dnsProviderApi.removeSimilarRecords( ip4: serverDetails.ip4, @@ -357,9 +332,7 @@ class ServerInstallationRepository { final NavigationService nav = getIt.get(); nav.showPopUpDialog( BrandAlert( - title: e.response!.data['errors'][0]['code'] == 1038 - ? 'modals.10'.tr() - : 'providers.domain.states.error'.tr(), + title: e.response!.data['errors'][0]['code'] == 1038 ? 'modals.10'.tr() : 'providers.domain.states.error'.tr(), contentText: 'modals.6'.tr(), actions: [ ActionButton( @@ -392,8 +365,7 @@ class ServerInstallationRepository { } Future createDkimRecord(final ServerDomain cloudFlareDomain) async { - final DnsProviderApi dnsProviderApi = - dnsProviderApiFactory!.getDnsProvider(); + final DnsProviderApi dnsProviderApi = dnsProviderApiFactory!.getDnsProvider(); final ServerApi api = ServerApi(); String dkimRecordString = ''; @@ -460,31 +432,25 @@ class ServerInstallationRepository { final DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); if (kIsWeb) { return deviceInfo.webBrowserInfo.then( - (final WebBrowserInfo value) => - '${value.browserName} ${value.platform}', + (final WebBrowserInfo value) => '${value.browserName} ${value.platform}', ); } else { if (Platform.isAndroid) { return deviceInfo.androidInfo.then( - (final AndroidDeviceInfo value) => - '${value.model} ${value.version.release}', + (final AndroidDeviceInfo value) => '${value.model} ${value.version.release}', ); } else if (Platform.isIOS) { return deviceInfo.iosInfo.then( - (final IosDeviceInfo value) => - '${value.utsname.machine} ${value.systemName} ${value.systemVersion}', + (final IosDeviceInfo value) => '${value.utsname.machine} ${value.systemName} ${value.systemVersion}', ); } else if (Platform.isLinux) { - return deviceInfo.linuxInfo - .then((final LinuxDeviceInfo value) => value.prettyName); + return deviceInfo.linuxInfo.then((final LinuxDeviceInfo value) => value.prettyName); } else if (Platform.isMacOS) { return deviceInfo.macOsInfo.then( - (final MacOsDeviceInfo value) => - '${value.hostName} ${value.computerName}', + (final MacOsDeviceInfo value) => '${value.hostName} ${value.computerName}', ); } else if (Platform.isWindows) { - return deviceInfo.windowsInfo - .then((final WindowsDeviceInfo value) => value.computerName); + return deviceInfo.windowsInfo.then((final WindowsDeviceInfo value) => value.computerName); } } return 'Unidentified'; @@ -576,8 +542,7 @@ class ServerInstallationRepository { ); final String serverIp = await getServerIpFromDomain(serverDomain); if (recoveryCapabilities == ServerRecoveryCapabilities.legacy) { - final Map apiResponse = - await serverApi.servicesPowerCheck(); + final Map apiResponse = await serverApi.servicesPowerCheck(); if (apiResponse.isNotEmpty) { return ServerHostingDetails( apiToken: apiToken, @@ -600,8 +565,7 @@ class ServerInstallationRepository { ); } } - final ApiResponse deviceAuthKey = - await serverApi.createDeviceToken(); + final ApiResponse deviceAuthKey = await serverApi.createDeviceToken(); final ApiResponse apiResponse = await serverApi.authorizeDevice( DeviceToken(device: await getDeviceName(), token: deviceAuthKey.data), ); @@ -633,14 +597,14 @@ class ServerInstallationRepository { final ServerApi serverApi = ServerApi(); const User fallbackUser = User( isFoundOnServer: false, + type: UserType.primary, note: "Couldn't find main user on server, API is outdated", login: 'UNKNOWN', sshKeys: [], ); final String? serverApiVersion = await serverApi.getApiVersion(); - final ApiResponse> users = - await serverApi.getUsersList(withMainUser: true); + final ApiResponse> users = await serverApi.getUsersList(withMainUser: true); if (serverApiVersion == null || !users.isSuccess) { return fallbackUser; } @@ -652,6 +616,7 @@ class ServerInstallationRepository { return User( isFoundOnServer: true, login: users.data[0], + type: UserType.primary, ); } on FormatException { return fallbackUser; @@ -739,8 +704,7 @@ class ServerInstallationRepository { Future deleteServer(final ServerDomain serverDomain) async { final ServerProviderApi api = serverProviderApiFactory!.getServerProvider(); - final DnsProviderApi dnsProviderApi = - dnsProviderApiFactory!.getDnsProvider(); + final DnsProviderApi dnsProviderApi = dnsProviderApiFactory!.getDnsProvider(); await api.deleteServer( domainName: serverDomain.domainName, diff --git a/lib/logic/cubit/users/users_cubit.dart b/lib/logic/cubit/users/users_cubit.dart index 3ce0d18e..46e39568 100644 --- a/lib/logic/cubit/users/users_cubit.dart +++ b/lib/logic/cubit/users/users_cubit.dart @@ -1,10 +1,9 @@ import 'package:hive/hive.dart'; import 'package:selfprivacy/config/hive_config.dart'; +import 'package:selfprivacy/logic/api_maps/rest_maps/server.dart'; import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart'; import 'package:selfprivacy/logic/models/hive/user.dart'; -import 'package:selfprivacy/logic/api_maps/rest_maps/server.dart'; - export 'package:provider/provider.dart'; part 'users_state.dart'; @@ -15,8 +14,8 @@ class UsersCubit extends ServerInstallationDependendCubit { serverInstallationCubit, const UsersState( [], - User(login: 'root'), - User(login: 'loading...'), + User(login: 'root', type: UserType.root), + User(login: 'loading...', type: UserType.primary), ), ); Box box = Hive.box(BNames.usersBox); @@ -30,30 +29,26 @@ class UsersCubit extends ServerInstallationDependendCubit { final List loadedUsers = box.values.toList(); final primaryUser = serverInstallationBox.get( BNames.rootUser, - defaultValue: const User(login: 'loading...'), + defaultValue: const User(login: 'loading...', type: UserType.primary), ); - final List rootKeys = [ - ...serverInstallationBox.get(BNames.rootKeys, defaultValue: []) - ]; + final List rootKeys = [...serverInstallationBox.get(BNames.rootKeys, defaultValue: [])]; if (loadedUsers.isNotEmpty) { emit( UsersState( loadedUsers, - User(login: 'root', sshKeys: rootKeys), + User(login: 'root', sshKeys: rootKeys, type: UserType.root), primaryUser, ), ); } - final ApiResponse> usersFromServer = - await api.getUsersList(); + final ApiResponse> usersFromServer = await api.getUsersList(); if (usersFromServer.isSuccess) { - final List updatedList = - mergeLocalAndServerUsers(loadedUsers, usersFromServer.data); + final List updatedList = mergeLocalAndServerUsers(loadedUsers, usersFromServer.data); emit( UsersState( updatedList, - User(login: 'root', sshKeys: rootKeys), + User(login: 'root', sshKeys: rootKeys, type: UserType.root), primaryUser, ), ); @@ -64,11 +59,9 @@ class UsersCubit extends ServerInstallationDependendCubit { box.clear(); box.addAll(usersWithSshKeys); - final User rootUserWithSshKeys = - (await loadSshKeys([state.rootUser])).first; + final User rootUserWithSshKeys = (await loadSshKeys([state.rootUser])).first; serverInstallationBox.put(BNames.rootKeys, rootUserWithSshKeys.sshKeys); - final User primaryUserWithSshKeys = - (await loadSshKeys([state.primaryUser])).first; + final User primaryUserWithSshKeys = (await loadSshKeys([state.primaryUser])).first; serverInstallationBox.put(BNames.rootUser, primaryUserWithSshKeys); emit( UsersState( @@ -95,6 +88,7 @@ class UsersCubit extends ServerInstallationDependendCubit { mergedUsers.add( User( login: localUser.login, + type: UserType.normal, isFoundOnServer: true, password: localUser.password, sshKeys: localUser.sshKeys, @@ -105,6 +99,7 @@ class UsersCubit extends ServerInstallationDependendCubit { mergedUsers.add( User( login: localUser.login, + type: UserType.normal, isFoundOnServer: false, password: localUser.password, note: localUser.note, @@ -117,6 +112,7 @@ class UsersCubit extends ServerInstallationDependendCubit { mergedUsers.add( User( login: serverUser, + type: UserType.normal, isFoundOnServer: true, ), ); @@ -129,16 +125,14 @@ class UsersCubit extends ServerInstallationDependendCubit { final List updatedUsers = []; for (final User user in users) { - if (user.isFoundOnServer || - user.login == 'root' || - user.login == state.primaryUser.login) { - final ApiResponse> sshKeys = - await api.getUserSshKeys(user); + if (user.isFoundOnServer || user.login == 'root' || user.login == state.primaryUser.login) { + final ApiResponse> sshKeys = await api.getUserSshKeys(user); print('sshKeys for $user: ${sshKeys.data}'); if (sshKeys.isSuccess) { updatedUsers.add( User( login: user.login, + type: user.type, isFoundOnServer: true, password: user.password, sshKeys: sshKeys.data, @@ -149,6 +143,7 @@ class UsersCubit extends ServerInstallationDependendCubit { updatedUsers.add( User( login: user.login, + type: user.type, isFoundOnServer: true, password: user.password, note: user.note, @@ -159,6 +154,7 @@ class UsersCubit extends ServerInstallationDependendCubit { updatedUsers.add( User( login: user.login, + type: user.type, isFoundOnServer: false, password: user.password, note: user.note, @@ -173,17 +169,14 @@ class UsersCubit extends ServerInstallationDependendCubit { List updatedUsers = List.from(state.users); final ApiResponse> usersFromServer = await api.getUsersList(); if (usersFromServer.isSuccess) { - updatedUsers = - mergeLocalAndServerUsers(updatedUsers, usersFromServer.data); + updatedUsers = mergeLocalAndServerUsers(updatedUsers, usersFromServer.data); } final List usersWithSshKeys = await loadSshKeys(updatedUsers); box.clear(); box.addAll(usersWithSshKeys); - final User rootUserWithSshKeys = - (await loadSshKeys([state.rootUser])).first; + final User rootUserWithSshKeys = (await loadSshKeys([state.rootUser])).first; serverInstallationBox.put(BNames.rootKeys, rootUserWithSshKeys.sshKeys); - final User primaryUserWithSshKeys = - (await loadSshKeys([state.primaryUser])).first; + final User primaryUserWithSshKeys = (await loadSshKeys([state.primaryUser])).first; serverInstallationBox.put(BNames.rootUser, primaryUserWithSshKeys); emit( UsersState( @@ -197,8 +190,7 @@ class UsersCubit extends ServerInstallationDependendCubit { Future createUser(final User user) async { // If user exists on server, do nothing - if (state.users - .any((final User u) => u.login == user.login && u.isFoundOnServer)) { + if (state.users.any((final User u) => u.login == user.login && u.isFoundOnServer)) { return; } // If user is root or primary user, do nothing @@ -240,14 +232,14 @@ class UsersCubit extends ServerInstallationDependendCubit { final ApiResponse result = await api.addRootSshKey(publicKey); if (result.isSuccess) { // Add ssh key to the array of root keys - final List rootKeys = serverInstallationBox - .get(BNames.rootKeys, defaultValue: []) as List; + final List rootKeys = serverInstallationBox.get(BNames.rootKeys, defaultValue: []) as List; rootKeys.add(publicKey); serverInstallationBox.put(BNames.rootKeys, rootKeys); emit( state.copyWith( rootUser: User( login: state.rootUser.login, + type: UserType.root, isFoundOnServer: true, password: state.rootUser.password, sshKeys: rootKeys, @@ -261,11 +253,11 @@ class UsersCubit extends ServerInstallationDependendCubit { if (result.isSuccess) { // If it is primary user, update primary user if (user.login == state.primaryUser.login) { - final List primaryUserKeys = - List.from(state.primaryUser.sshKeys); + final List primaryUserKeys = List.from(state.primaryUser.sshKeys); primaryUserKeys.add(publicKey); final User updatedUser = User( login: state.primaryUser.login, + type: UserType.primary, isFoundOnServer: true, password: state.primaryUser.password, sshKeys: primaryUserKeys, @@ -283,6 +275,7 @@ class UsersCubit extends ServerInstallationDependendCubit { userKeys.add(publicKey); final User updatedUser = User( login: user.login, + type: UserType.normal, isFoundOnServer: true, password: user.password, sshKeys: userKeys, @@ -302,22 +295,21 @@ class UsersCubit extends ServerInstallationDependendCubit { Future deleteSshKey(final User user, final String publicKey) async { // All keys are deleted via api.deleteUserSshKey - final ApiResponse result = - await api.deleteUserSshKey(user, publicKey); + final ApiResponse result = await api.deleteUserSshKey(user, publicKey); if (result.isSuccess) { // If it is root user, delete key from root keys // If it is primary user, update primary user // If it is not primary user, update user if (user.login == 'root') { - final List rootKeys = serverInstallationBox - .get(BNames.rootKeys, defaultValue: []) as List; + final List rootKeys = serverInstallationBox.get(BNames.rootKeys, defaultValue: []) as List; rootKeys.remove(publicKey); serverInstallationBox.put(BNames.rootKeys, rootKeys); emit( state.copyWith( rootUser: User( login: state.rootUser.login, + type: UserType.root, isFoundOnServer: true, password: state.rootUser.password, sshKeys: rootKeys, @@ -328,11 +320,11 @@ class UsersCubit extends ServerInstallationDependendCubit { return; } if (user.login == state.primaryUser.login) { - final List primaryUserKeys = - List.from(state.primaryUser.sshKeys); + final List primaryUserKeys = List.from(state.primaryUser.sshKeys); primaryUserKeys.remove(publicKey); final User updatedUser = User( login: state.primaryUser.login, + type: UserType.primary, isFoundOnServer: true, password: state.primaryUser.password, sshKeys: primaryUserKeys, @@ -350,6 +342,7 @@ class UsersCubit extends ServerInstallationDependendCubit { userKeys.remove(publicKey); final User updatedUser = User( login: user.login, + type: UserType.normal, isFoundOnServer: true, password: user.password, sshKeys: userKeys, @@ -369,8 +362,8 @@ class UsersCubit extends ServerInstallationDependendCubit { emit( const UsersState( [], - User(login: 'root'), - User(login: 'loading...'), + User(login: 'root', type: UserType.root), + User(login: 'loading...', type: UserType.primary), ), ); } diff --git a/lib/logic/models/hive/README.md b/lib/logic/models/hive/README.md index afdd6276..f8f9e14d 100644 --- a/lib/logic/models/hive/README.md +++ b/lib/logic/models/hive/README.md @@ -7,7 +7,8 @@ 5. ServerVolume 6. BackblazeBucket - ## Enums + 100. DnsProvider -101. ServerProvider \ No newline at end of file +101. ServerProvider +102. UserType diff --git a/lib/logic/models/hive/user.dart b/lib/logic/models/hive/user.dart index f140953d..042b2485 100644 --- a/lib/logic/models/hive/user.dart +++ b/lib/logic/models/hive/user.dart @@ -2,6 +2,7 @@ import 'dart:ui'; import 'package:equatable/equatable.dart'; import 'package:hive/hive.dart'; +import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/schema.graphql.dart'; import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/users.graphql.dart'; import 'package:selfprivacy/utils/color_utils.dart'; @@ -11,6 +12,7 @@ part 'user.g.dart'; class User extends Equatable { const User({ required this.login, + required this.type, this.password, this.sshKeys = const [], this.isFoundOnServer = true, @@ -20,6 +22,7 @@ class User extends Equatable { User.fromGraphQL(final Fragment$userFields user) : this( login: user.username, + type: UserType.fromGraphQL(user.userType), sshKeys: user.sshKeys, isFoundOnServer: true, ); @@ -39,6 +42,9 @@ class User extends Equatable { @HiveField(4) final String? note; + @HiveField(5, defaultValue: UserType.normal) + final UserType type; + @override List get props => [login, password, sshKeys, isFoundOnServer, note]; @@ -47,3 +53,26 @@ class User extends Equatable { @override String toString() => '$login, ${isFoundOnServer ? 'found' : 'not found'}, ${sshKeys.length} ssh keys, note: $note'; } + +@HiveType(typeId: 102) +enum UserType { + @HiveField(0) + root, + @HiveField(1) + primary, + @HiveField(2) + normal; + + factory UserType.fromGraphQL(final Enum$UserType type) { + switch (type) { + case Enum$UserType.ROOT: + return root; + case Enum$UserType.PRIMARY: + return primary; + case Enum$UserType.NORMAL: + return normal; + case Enum$UserType.$unknown: + return normal; + } + } +}