2
0
mirror of https://github.com/inventree/inventree-app.git synced 2025-04-28 13:36:50 +00:00

Driving the refactor tractor

- Separated get into getRequest and get
- Improved login error messages
This commit is contained in:
Oliver Walters 2021-04-20 10:32:01 +10:00
parent f5e1f25dd0
commit 8a6be4142a
2 changed files with 110 additions and 74 deletions

View File

@ -165,21 +165,27 @@ class InvenTreeAPI {
InvenTreeAPI._internal();
/**
* Connect to the remote InvenTree server:
*
* - Check that the InvenTree server exists
* - Request user token from the server
* - Request user roles from the server
*/
Future<bool> _connect(BuildContext context) async {
/* Address is the base address for the InvenTree server,
* e.g. http://127.0.0.1:8000
*/
if (profile == null) return false;
var ctx = OneContext().context;
String address = profile.server.trim();
String username = profile.username.trim();
String password = profile.password.trim();
if (address.isEmpty || username.isEmpty || password.isEmpty) {
showSnackIcon(
"Incomplete server details",
"Incomplete profile details",
icon: FontAwesomeIcons.exclamationCircle,
success: false
);
@ -189,28 +195,36 @@ class InvenTreeAPI {
if (!address.endsWith('/')) {
address = address + '/';
}
// TODO - Better URL validation
/*
/* TODO: Better URL validation
* - If not a valid URL, return error
* - If no port supplied, append a default port
*/
_BASE_URL = address;
print("Connecting to ${apiUrl} -> ${username}:${password}");
print("Connecting to ${apiUrl} -> username=${username}");
// Request the /api/ endpoint - response is a json object
var response = await get("");
HttpClientResponse response;
dynamic data;
response = await getResponse("");
// Null response means something went horribly wrong!
// Most likely, the server cannot be contacted
if (response == null) {
// An error message has already been displayed!
return false;
}
if (response.statusCode != 200) {
showStatusCodeError(response.statusCode);
return false;
}
data = await responseToJson(response);
// We expect certain response from the server
if (!response.containsKey("server") || !response.containsKey("version") || !response.containsKey("instance")) {
if (data == null || !data.containsKey("server") || !data.containsKey("version") || !data.containsKey("instance")) {
showServerError(
"Missing Data",
@ -221,16 +235,14 @@ class InvenTreeAPI {
}
// Record server information
_version = response["version"];
instance = response['instance'] ?? '';
_version = data["version"];
instance = data['instance'] ?? '';
// Default API version is 1 if not provided
_apiVersion = response['apiVersion'] as int ?? 1;
_apiVersion = data['apiVersion'] as int ?? 1;
if (_apiVersion < _minApiVersion) {
BuildContext ctx = OneContext().context;
String message = I18N.of(ctx).serverApiVersion + ": ${_apiVersion}";
message += "\n";
@ -248,23 +260,43 @@ class InvenTreeAPI {
return false;
}
/**
* Request user token information from the server
* This is the stage that we check username:password credentials!
*/
// Clear the existing token value
_token = "";
print("Requesting token from server");
response = await get(_URL_GET_TOKEN);
response = await getResponse(_URL_GET_TOKEN);
// A "null" response means that the request was unsuccessful
if (response == null) {
return false;
}
if (response.statusCode != 200) {
switch (response.statusCode) {
case 401:
case 403:
showServerError(
I18N.of(OneContext().context).tokenError,
"Error requesting access token from server"
I18N.of(ctx).serverAuthenticationError,
"Incorrect username:password combination"
);
break;
default:
showStatusCodeError(response.statusCode);
break;
}
return false;
}
if (!response.containsKey("token")) {
data = await responseToJson(response);
if (data == null || !data.containsKey("token")) {
showServerError(
I18N.of(OneContext().context).tokenMissing,
"Access token missing from response"
@ -274,7 +306,7 @@ class InvenTreeAPI {
}
// Return the received token
_token = response["token"];
_token = data["token"];
print("Received token - $_token");
// Request user role information
@ -420,7 +452,7 @@ class InvenTreeAPI {
});
// Request could not be made
if (request = null) {
if (request == null) {
return null;
}
@ -474,7 +506,9 @@ class InvenTreeAPI {
return null;
}
return response;
var responseData = await responseToJson(response);
return responseData;
}
/*
@ -591,25 +625,9 @@ class InvenTreeAPI {
return null;
}
// Convert the body of the response to a JSON object
String responseData = await response.transform(utf8.decoder).join();
var responseData = await responseToJson(response);
try {
var data = json.decode(responseData);
return data;
} on FormatException {
print("JSON format exception!");
print("${responseData}");
showServerError(
"Format Exception",
"JSON data format exception:\n${responseData}"
);
return null;
}
return responseData;
}
HttpClient createClient(bool allowBadCert) {
@ -641,10 +659,11 @@ class InvenTreeAPI {
}
/**
* Perform a HTTP GET request
* Returns a json object (or null if did not complete)
* Perform a HTTP GET request,
* and return the Response object
* (or null if the request fails)
*/
Future<dynamic> get(String url, {Map<String, String> params, int expectedStatusCode=200}) async {
Future<HttpClientResponse> getResponse(String url, {Map<String, String> params}) async {
var _url = makeApiUrl(url);
print("GET: ${_url}");
@ -700,8 +719,6 @@ class InvenTreeAPI {
request.headers.set(HttpHeaders.contentTypeHeader, 'application/json');
request.headers.set(HttpHeaders.authorizationHeader, _authorizationHeader());
print("Attempting connection");
HttpClientResponse response = await request.close()
.timeout(Duration(seconds: 10))
.catchError((error) {
@ -728,28 +745,21 @@ class InvenTreeAPI {
return null;
});
print("got here");
return response;
}
dynamic responseToJson(HttpClientResponse response) async {
// A null response means something has gone wrong...
if (response == null) {
print("null response from GET ${_url}");
return null;
}
// Check the status code of the response
if (response.statusCode != expectedStatusCode) {
showStatusCodeError(response.statusCode);
return null;
}
// Convert the body of the response to a JSON object
String body = await response.transform(utf8.decoder).join();
try {
var data = json.decode(body);
return data;
} on FormatException {
print("JSON format exception!");
@ -761,6 +771,32 @@ class InvenTreeAPI {
);
return null;
}
}
/**
* Perform a HTTP GET request
* Returns a json object (or null if did not complete)
*/
Future<dynamic> get(String url, {Map<String, String> params, int expectedStatusCode=200}) async {
var response = await getResponse(url, params: params);
// A null response means something has gone wrong...
if (response == null) {
print("null response from GET ${url}");
return null;
}
// Check the status code of the response
if (response.statusCode != expectedStatusCode) {
showStatusCodeError(response.statusCode);
return null;
}
var data = await responseToJson(response);
return data;
}
Map<String, String> defaultHeaders() {

@ -1 +1 @@
Subproject commit 385c15b1e3275140c1b8a4e59de9513a6241dd9b
Subproject commit 8c2bf9e993d5c618a0a7b5cb94d189b89d70cbe9