fix: Implement better error messaging for providers token check

- Resolves #508
This commit is contained in:
NaiJi 2024-08-07 22:08:04 +04:00
parent d01df51296
commit b69e4ad7ff
10 changed files with 60 additions and 26 deletions

View file

@ -49,7 +49,7 @@ class CloudflareApi extends RestApiMap {
Future<GenericResult<bool>> isApiTokenValid(final String token) async { Future<GenericResult<bool>> isApiTokenValid(final String token) async {
bool isValid = false; bool isValid = false;
Response? response; Response? response;
String message = ''; String? message;
final Dio client = await getClient(); final Dio client = await getClient();
try { try {
response = await client.get( response = await client.get(
@ -77,9 +77,12 @@ class CloudflareApi extends RestApiMap {
); );
} }
message = response.statusMessage;
if (response.statusCode == HttpStatus.ok) { if (response.statusCode == HttpStatus.ok) {
isValid = true; isValid = true;
} else if (response.statusCode == HttpStatus.unauthorized) { } else if (response.statusCode == HttpStatus.unauthorized) {
message = 'initializing.provider_bad_key_error';
isValid = false; isValid = false;
} else { } else {
throw Exception('code: ${response.statusCode}'); throw Exception('code: ${response.statusCode}');
@ -88,7 +91,7 @@ class CloudflareApi extends RestApiMap {
return GenericResult( return GenericResult(
data: isValid, data: isValid,
success: true, success: true,
message: response.statusMessage, message: message,
); );
} }

View file

@ -49,7 +49,7 @@ class DesecApi extends RestApiMap {
Future<GenericResult<bool>> isApiTokenValid(final String token) async { Future<GenericResult<bool>> isApiTokenValid(final String token) async {
bool isValid = false; bool isValid = false;
Response? response; Response? response;
String message = ''; String? message;
final Dio client = await getClient(); final Dio client = await getClient();
try { try {
response = await client.get( response = await client.get(
@ -78,9 +78,12 @@ class DesecApi extends RestApiMap {
); );
} }
message = response.statusMessage;
if (response.statusCode == HttpStatus.ok) { if (response.statusCode == HttpStatus.ok) {
isValid = true; isValid = true;
} else if (response.statusCode == HttpStatus.unauthorized) { } else if (response.statusCode == HttpStatus.unauthorized) {
message = 'initializing.provider_bad_key_error';
isValid = false; isValid = false;
} else { } else {
throw Exception('code: ${response.statusCode}'); throw Exception('code: ${response.statusCode}');
@ -89,7 +92,7 @@ class DesecApi extends RestApiMap {
return GenericResult( return GenericResult(
data: isValid, data: isValid,
success: true, success: true,
message: response.statusMessage, message: message,
); );
} }

View file

@ -49,7 +49,7 @@ class DigitalOceanDnsApi extends RestApiMap {
Future<GenericResult<bool>> isApiTokenValid(final String token) async { Future<GenericResult<bool>> isApiTokenValid(final String token) async {
bool isValid = false; bool isValid = false;
Response? response; Response? response;
String message = ''; String? message;
final Dio client = await getClient(); final Dio client = await getClient();
try { try {
response = await client.get( response = await client.get(
@ -77,9 +77,12 @@ class DigitalOceanDnsApi extends RestApiMap {
); );
} }
message = response.statusMessage;
if (response.statusCode == HttpStatus.ok) { if (response.statusCode == HttpStatus.ok) {
isValid = true; isValid = true;
} else if (response.statusCode == HttpStatus.unauthorized) { } else if (response.statusCode == HttpStatus.unauthorized) {
message = 'initializing.provider_bad_key_error';
isValid = false; isValid = false;
} else { } else {
throw Exception('code: ${response.statusCode}'); throw Exception('code: ${response.statusCode}');
@ -88,7 +91,7 @@ class DigitalOceanDnsApi extends RestApiMap {
return GenericResult( return GenericResult(
data: isValid, data: isValid,
success: true, success: true,
message: response.statusMessage, message: message,
); );
} }

View file

@ -147,7 +147,7 @@ class DigitalOceanApi extends RestApiMap {
Future<GenericResult<bool>> isApiTokenValid(final String token) async { Future<GenericResult<bool>> isApiTokenValid(final String token) async {
bool isValid = false; bool isValid = false;
Response? response; Response? response;
String message = ''; String? message;
final Dio client = await getClient(); final Dio client = await getClient();
try { try {
response = await client.get( response = await client.get(
@ -175,9 +175,12 @@ class DigitalOceanApi extends RestApiMap {
); );
} }
message = response.statusMessage;
if (response.statusCode == HttpStatus.ok) { if (response.statusCode == HttpStatus.ok) {
isValid = true; isValid = true;
} else if (response.statusCode == HttpStatus.unauthorized) { } else if (response.statusCode == HttpStatus.unauthorized) {
message = 'initializing.provider_bad_key_error';
isValid = false; isValid = false;
} else { } else {
throw Exception('code: ${response.statusCode}'); throw Exception('code: ${response.statusCode}');
@ -186,7 +189,7 @@ class DigitalOceanApi extends RestApiMap {
return GenericResult( return GenericResult(
data: isValid, data: isValid,
success: true, success: true,
message: response.statusMessage, message: message,
); );
} }

View file

@ -195,7 +195,7 @@ class HetznerApi extends RestApiMap {
Future<GenericResult<bool>> isApiTokenValid(final String token) async { Future<GenericResult<bool>> isApiTokenValid(final String token) async {
bool isValid = false; bool isValid = false;
Response? response; Response? response;
String message = ''; String? message;
final Dio client = await getClient(); final Dio client = await getClient();
try { try {
response = await client.get( response = await client.get(
@ -223,9 +223,12 @@ class HetznerApi extends RestApiMap {
); );
} }
message = response.statusMessage;
if (response.statusCode == HttpStatus.ok) { if (response.statusCode == HttpStatus.ok) {
isValid = true; isValid = true;
} else if (response.statusCode == HttpStatus.unauthorized) { } else if (response.statusCode == HttpStatus.unauthorized) {
message = 'initializing.provider_bad_key_error';
isValid = false; isValid = false;
} else { } else {
throw Exception('code: ${response.statusCode}'); throw Exception('code: ${response.statusCode}');
@ -234,7 +237,7 @@ class HetznerApi extends RestApiMap {
return GenericResult( return GenericResult(
data: isValid, data: isValid,
success: true, success: true,
message: response.statusMessage, message: message,
); );
} }

View file

@ -41,7 +41,7 @@ class DnsProviderFormCubit extends FormCubit {
} }
if (!isKeyValid) { if (!isKeyValid) {
apiKey.setError('initializing.dns_provider_bad_key_error'.tr()); apiKey.setError('initializing.provider_bad_key_error'.tr());
} }
return isKeyValid; return isKeyValid;

View file

@ -92,11 +92,17 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
if (!apiResponse.success) { if (!apiResponse.success) {
getIt<NavigationService>().showSnackBar( getIt<NavigationService>().showSnackBar(
'initializing.could_not_connect'.tr(), apiResponse.message ?? 'initializing.could_not_connect'.tr(),
); );
return null; return null;
} }
if (!apiResponse.data) {
getIt<NavigationService>().showSnackBar(
(apiResponse.message ?? 'initializing.provider_bad_key_error').tr(),
);
}
return apiResponse.data; return apiResponse.data;
} }
@ -110,11 +116,17 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
if (!apiResponse.success) { if (!apiResponse.success) {
getIt<NavigationService>().showSnackBar( getIt<NavigationService>().showSnackBar(
'initializing.could_not_connect'.tr(), apiResponse.message ?? 'initializing.could_not_connect'.tr(),
); );
return null; return null;
} }
if (!apiResponse.data) {
getIt<NavigationService>().showSnackBar(
(apiResponse.message ?? 'initializing.provider_bad_key_error').tr(),
);
}
return apiResponse.data; return apiResponse.data;
} }
@ -800,11 +812,13 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
if (serverDomain == null) { if (serverDomain == null) {
return; return;
} }
final isTokenValid = final isTokenValidResult =
await repository.validateDnsToken(token, serverDomain.domainName); await repository.validateDnsToken(token, serverDomain.domainName);
if (!isTokenValid) { if (!isTokenValidResult.success) {
getIt<NavigationService>() getIt<NavigationService>().showSnackBar(
.showSnackBar('recovering.domain_not_available_on_token'.tr()); isTokenValidResult.message ??
'recovering.domain_not_available_on_token'.tr(),
);
return; return;
} }
final dnsProviderType = await ServerApi( final dnsProviderType = await ServerApi(

View file

@ -192,27 +192,34 @@ class ServerInstallationRepository {
return server; return server;
} }
Future<bool> validateDnsToken( Future<GenericResult<bool>> validateDnsToken(
final String token, final String token,
final String domain, final String domain,
) async { ) async {
final result = final result =
await ProvidersController.currentDnsProvider!.tryInitApiByToken(token); await ProvidersController.currentDnsProvider!.tryInitApiByToken(token);
if (!result.success) { if (!result.success) {
return false; return result;
} }
await setDnsApiToken(token); await setDnsApiToken(token);
final domainResult = final domainResult =
await ProvidersController.currentDnsProvider!.domainList(); await ProvidersController.currentDnsProvider!.domainList();
if (!domainResult.success || domainResult.data.isEmpty) { if (!domainResult.success || domainResult.data.isEmpty) {
return false; return GenericResult(
success: false,
data: false,
message: domainResult.message,
);
} }
await getIt<ResourcesModel>().removeDnsProviderToken( await getIt<ResourcesModel>().removeDnsProviderToken(
getIt<ResourcesModel>().dnsProviderCredentials.first, getIt<ResourcesModel>().dnsProviderCredentials.first,
); );
return domainResult.data.any( return GenericResult(
(final serverDomain) => serverDomain.domainName == domain, success: true,
data: domainResult.data.any(
(final serverDomain) => serverDomain.domainName == domain,
),
); );
} }

View file

@ -110,9 +110,8 @@ class ProviderInputDataPage extends StatelessWidget {
CubitFormTextField( CubitFormTextField(
autofocus: true, autofocus: true,
formFieldCubit: providerCubit.apiKey, formFieldCubit: providerCubit.apiKey,
textAlign: TextAlign.center,
scrollPadding: const EdgeInsets.only(bottom: 70),
decoration: const InputDecoration( decoration: const InputDecoration(
border: OutlineInputBorder(),
hintText: 'Provider API Token', hintText: 'Provider API Token',
), ),
), ),

View file

@ -118,9 +118,8 @@ class ProviderInputDataPage extends StatelessWidget {
CubitFormTextField( CubitFormTextField(
autofocus: true, autofocus: true,
formFieldCubit: providerCubit.apiKey, formFieldCubit: providerCubit.apiKey,
textAlign: TextAlign.center,
scrollPadding: const EdgeInsets.only(bottom: 70),
decoration: const InputDecoration( decoration: const InputDecoration(
border: OutlineInputBorder(),
hintText: 'Provider API Token', hintText: 'Provider API Token',
), ),
), ),