diff --git a/lib/api.dart b/lib/api.dart index 628eb92d..d2607897 100644 --- a/lib/api.dart +++ b/lib/api.dart @@ -8,6 +8,8 @@ import 'package:http/http.dart' as http; class InvenTreeAPI { + static const _URL_GET_TOKEN = "user/token/"; + // Ensure we only ever create a single instance of the API class static final InvenTreeAPI _api = new InvenTreeAPI._internal(); @@ -56,6 +58,11 @@ class InvenTreeAPI { // Construct an API URL String _makeUrl(String url) { + + if (url.startsWith('/')) { + url = url.substring(1); + } + return path.join(_base_url, url); } @@ -65,50 +72,113 @@ class InvenTreeAPI { // Request the raw /api/ endpoing to see if there is an InvenTree server listening void _tryConnection() async { - final response = get(""); + + print("Testing connection to server"); + + final response = await get("").then((http.Response response) { + print("response!"); + print(response.body); + }).catchError((error) { + print("Error trying connection"); + }); + + // TODO - Add timeout handler } // Request an API token from the server. // A valid username/password combination must be provided void _secureToken() async { - if (_token.isNotEmpty) { print("Discarding old token - " + _token); } _token = ""; - var _url = _makeUrl("user/token/"); - final response = await http.post(_url, + var response = post(_URL_GET_TOKEN, body: { "username": _username, - "password": _password - }); + "password": _password, + }); - if (response.statusCode != 200) { - print("Invalid status code:" + String.fromCharCode(response.statusCode)); - } else { - var _json = json.decode(response.body); + response.then((http.Response response) { + if (response.statusCode != 200) { + print("Invalid status code: " + response.statusCode.toString()); + } else { + var _json = json.decode(response.body); - if (_json["token"] != null) { - _token = _json["token"]; - print("Received token: " + _token); + if (_json["token"] != null) { + _token = _json["token"]; + print("Received token: " + _token); + } } - } + }).catchError((error) { + print("Error retrieving token"); + }); } - Future get(String url) async { - var _url = _makeUrl(url); - final response = await http.get(_url, - headers: { - HttpHeaders.authorizationHeader: "Token: " + _token - } - ); + // Perform a PATCH request + Future patch(String url, {Map body}) async { - print("Making request to " + _url); - print(response.statusCode); - print(response.body); + var _url = _makeUrl(url); + var _headers = _defaultHeaders(); + var _body = Map(); + + // Copy across provided data + body.forEach((K, V) => _body[K] = V); + + print("PATCH: " + _url); + + final response = await http.patch(_url, + headers: _headers, + body: _body, + ); return response; } + // Perform a POST request + Future post(String url, {Map body}) async { + + var _url = _makeUrl(url); + var _headers = _defaultHeaders(); + var _body = Map(); + + // Copy across provided data + body.forEach((K, V) => _body[K] = V); + + print("POST: " + _url); + + final response = await http.post(_url, + headers: _headers, + body: _body, + ); + + return response; + } + + // Perform a GET request + Future get(String url) async { + + var _url = _makeUrl(url); + var _headers = _defaultHeaders(); + + print("GET: " + _url); + + final response = await http.get(_url, + headers: _headers, + ); + + return response; + } + + Map _defaultHeaders() { + + var headers = Map(); + + if (_token.isNotEmpty) { + headers[HttpHeaders.authorizationHeader] = "Token " + _token; + } + + return headers; + } + } \ No newline at end of file diff --git a/lib/login_settings.dart b/lib/login_settings.dart index 5f6bffef..a346796a 100644 --- a/lib/login_settings.dart +++ b/lib/login_settings.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'api.dart'; +import 'preferences.dart'; class InvenTreeLoginSettingsWidget extends StatefulWidget { @@ -133,13 +134,9 @@ class _InvenTreeLoginSettingsState extends State { if (_formKey.currentState.validate()) { _formKey.currentState.save(); - SharedPreferences prefs = await SharedPreferences.getInstance(); + await InvenTreeUserPreferences().saveLoginDetails(_addr, _user, _pass); - await prefs.setString('server', _addr); - await prefs.setString('username', _user); - await prefs.setString('password', _pass); - - InvenTreeAPI().connect(_addr, _user, _pass); + print("Saved"); } } } \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index a266a119..af8cbabb 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -2,11 +2,13 @@ import 'package:flutter/material.dart'; import 'settings.dart'; import 'api.dart'; +import 'preferences.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { // This widget is the root of your application. + @override Widget build(BuildContext context) { return MaterialApp( @@ -21,7 +23,7 @@ class MyApp extends StatelessWidget { // or simply save your changes to "hot reload" in a Flutter IDE). // Notice that the counter didn't reset back to zero; the application // is not restarted. - primarySwatch: Colors.blue, + primarySwatch: Colors.lightGreen, ), home: MyHomePage(title: 'InvenTree'), ); diff --git a/lib/preferences.dart b/lib/preferences.dart new file mode 100644 index 00000000..616c7f09 --- /dev/null +++ b/lib/preferences.dart @@ -0,0 +1,41 @@ +import 'package:shared_preferences/shared_preferences.dart'; +import 'api.dart'; + + +class InvenTreeUserPreferences { + + static const String _SERVER = 'server'; + static const String _USERNAME = 'username'; + static const String _PASSWORD = 'password'; + + // Ensure we only ever create a single instance of the preferences class + static final InvenTreeUserPreferences _api = new InvenTreeUserPreferences._internal(); + + factory InvenTreeUserPreferences() { + return _api; + } + + InvenTreeUserPreferences._internal(); + + // Load saved login details, and attempt connection + void loadLoginDetails() async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + + var server = prefs.getString(_SERVER); + var username = prefs.getString(_USERNAME); + var password = prefs.getString(_PASSWORD); + + await InvenTreeAPI().connect(server, username, password); + } + + void saveLoginDetails(String server, String username, String password) async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + + await prefs.setString(_SERVER, server); + await prefs.setString(_USERNAME, username); + await prefs.setString(_PASSWORD, password); + + // Reconnect the API + await InvenTreeAPI().connect(server, username, password); + } +} \ No newline at end of file