175 lines
5.7 KiB
Dart
175 lines
5.7 KiB
Dart
import 'dart:convert' show jsonDecode, jsonEncode;
|
|
|
|
import 'package:fotodocumentation/dto/base_dto.dart';
|
|
import 'package:fotodocumentation/utils/di_container.dart';
|
|
import 'package:fotodocumentation/utils/http_client_utils.dart';
|
|
import 'package:fotodocumentation/utils/jwt_token_storage.dart';
|
|
import 'package:fotodocumentation/utils/url_utils.dart';
|
|
import 'package:http/http.dart' as http;
|
|
import 'package:http/http.dart' show Response;
|
|
|
|
import 'package:fotodocumentation/main.dart' show logger;
|
|
|
|
abstract class BaseController {
|
|
UrlUtils get uriUtils => DiContainer.get();
|
|
JwtTokenStorage get _jwtTokenStorage => DiContainer.get();
|
|
HttpClientUtils get httpClientUtils => DiContainer.get();
|
|
|
|
Future<Header> getAuthHeader() async {
|
|
final accessToken = await _jwtTokenStorage.getAccessToken();
|
|
|
|
if (accessToken != null && accessToken.isNotEmpty) {
|
|
// Use JWT Bearer token
|
|
return Header('Authorization', 'Bearer $accessToken');
|
|
} else {
|
|
return const Header("Accept-Language", "en-US");
|
|
}
|
|
}
|
|
|
|
Exception getServerError(Response response) {
|
|
return Exception("Error receiving data from server");
|
|
}
|
|
|
|
Future<List<T>> runGetListWithAuth<T>(String uriStr, List<T> Function(dynamic) convert) async {
|
|
http.Client client = httpClientUtils.client;
|
|
try {
|
|
Header cred = await getAuthHeader();
|
|
Uri uri = Uri.parse(uriStr);
|
|
var response = await client.get(uri, headers: {cred.name: cred.value});
|
|
if (response.statusCode == 200) {
|
|
String text = response.body;
|
|
var jsonArray = jsonDecode(text);
|
|
return convert(jsonArray);
|
|
} else {
|
|
throw ServerError(response.statusCode); // Exception("Failed to get server data ${response.statusCode}");
|
|
}
|
|
} catch (e) {
|
|
logger.e("exception $e");
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
Future<T?> runGetWithAuth<T>(String uriStr, T Function(dynamic) convert) async {
|
|
http.Client client = httpClientUtils.client;
|
|
try {
|
|
Header cred = await getAuthHeader();
|
|
Uri uri = Uri.parse(uriStr);
|
|
var response = await client.get(uri, headers: {cred.name: cred.value});
|
|
if (response.statusCode == 200) {
|
|
String text = response.body;
|
|
var jsonArray = jsonDecode(text);
|
|
return convert(jsonArray);
|
|
} else {
|
|
throw ServerError(response.statusCode); // Exception("Failed to get server data ${response.statusCode}");
|
|
}
|
|
} catch (e) {
|
|
logger.e("exception $e");
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
Future<bool> runDeleteWithAuth(String uriStr) async {
|
|
http.Client client = httpClientUtils.client;
|
|
Header cred = await getAuthHeader();
|
|
Uri uri = Uri.parse(uriStr);
|
|
var response = await client.delete(uri, headers: {cred.name: cred.value});
|
|
return response.statusCode == 200;
|
|
}
|
|
|
|
Future<bool> runPutWithAuth(String uriStr) async {
|
|
http.Client client = httpClientUtils.client;
|
|
Header cred = await getAuthHeader();
|
|
Uri uri = Uri.parse(uriStr);
|
|
var response = await client.put(uri, headers: {cred.name: cred.value});
|
|
return response.statusCode == 200;
|
|
}
|
|
|
|
Future<ServerReply<T>> runSaveNew<T extends DtoMapAble>(String uriStr, T dtoObj, Function(http.Response response, T dto) processReply) async {
|
|
http.Client client = httpClientUtils.client;
|
|
try {
|
|
Header cred = await getAuthHeader();
|
|
String body = jsonEncode(dtoObj.toMap());
|
|
|
|
Uri uri = Uri.parse(uriStr);
|
|
var response = await client.post(uri, headers: {cred.name: cred.value, "Accept": "application/json", "Content-Type": "application/json"}, body: body);
|
|
return processReply(response, dtoObj);
|
|
} catch (e) {
|
|
logger.e("exception $e");
|
|
}
|
|
return ServerReply(ServerState.error, dtoObj);
|
|
}
|
|
|
|
Future<ServerReply<T>> runSaveUpdate<T extends DtoMapAble>(String uriStr, T dtoObj, Function(http.Response response, T dto) processReply) async {
|
|
http.Client client = httpClientUtils.client;
|
|
try {
|
|
Header cred = await getAuthHeader();
|
|
String body = jsonEncode(dtoObj.toMap());
|
|
|
|
Uri uri = Uri.parse(uriStr);
|
|
var response = await client.put(uri, headers: {cred.name: cred.value, "Accept": "application/json", "Content-Type": "application/json"}, body: body);
|
|
|
|
return processReply(response, dtoObj);
|
|
} catch (e) {
|
|
logger.e("exception $e");
|
|
}
|
|
return ServerReply(ServerState.error, dtoObj);
|
|
}
|
|
|
|
ServerReply<T> processServerResponse<T>(Response response, T dto, T Function(Map<String, dynamic> json) fromJson) {
|
|
if (response.statusCode == 200) {
|
|
String text = response.body;
|
|
var json = jsonDecode(text);
|
|
var dto = fromJson(json);
|
|
return ServerReply(ServerState.ok, dto);
|
|
} else if (response.statusCode == 400 || response.statusCode == 409) {
|
|
String text = response.body;
|
|
try {
|
|
var json = jsonDecode(text);
|
|
var error = ErrorDto.fromJson(json);
|
|
|
|
return ServerReply(ServerState.duplicate, dto, error: error);
|
|
} catch (e) {
|
|
return ServerReply(ServerState.error, dto, error: ErrorDto(response.statusCode, text));
|
|
}
|
|
} else if (response.statusCode == 403) {
|
|
var error = ErrorDto(403, "Not allowed.");
|
|
return ServerReply(ServerState.error, dto, error: error);
|
|
}
|
|
return ServerReply(ServerState.error, dto, error: ErrorDto(response.statusCode, "Internal server error"));
|
|
}
|
|
}
|
|
|
|
class Header {
|
|
final String name;
|
|
final String value;
|
|
|
|
const Header(this.name, this.value);
|
|
|
|
@override
|
|
String toString() => '$runtimeType: $name, $value';
|
|
}
|
|
|
|
class ServerReply<T> {
|
|
ServerState state;
|
|
T entity;
|
|
ErrorDto? error;
|
|
|
|
ServerReply(this.state, this.entity, {this.error});
|
|
|
|
@override
|
|
String toString() => '$runtimeType: $state, $entity, $error';
|
|
}
|
|
|
|
class ServerError {
|
|
int statusCode;
|
|
|
|
ServerError(this.statusCode);
|
|
}
|
|
|
|
enum ServerState {
|
|
ok,
|
|
duplicate,
|
|
error,
|
|
;
|
|
}
|