From d5649af2f9f8d4228e5445bd31bf9bd0a727f1b8 Mon Sep 17 00:00:00 2001
From: Oliver Walters <oliver.henry.walters@gmail.com>
Date: Mon, 8 Feb 2021 22:03:14 +1100
Subject: [PATCH] Server login now references the UserProfile class

---
 lib/api.dart               | 42 ++++++++++-------
 lib/preferences.dart       | 10 +----
 lib/settings/login.dart    | 92 ++------------------------------------
 lib/settings/settings.dart | 21 +--------
 lib/widget/home.dart       | 24 +++++-----
 pubspec.lock               |  7 ---
 pubspec.yaml               |  3 +-
 7 files changed, 45 insertions(+), 154 deletions(-)

diff --git a/lib/api.dart b/lib/api.dart
index ed721c28..d66a7c56 100644
--- a/lib/api.dart
+++ b/lib/api.dart
@@ -2,6 +2,7 @@ import 'dart:async';
 import 'dart:convert';
 import 'dart:io';
 
+import 'package:InvenTree/user_profile.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
 import 'package:cached_network_image/cached_network_image.dart';
@@ -108,8 +109,7 @@ class InvenTreeAPI {
 
   String makeUrl(String endpoint) => _makeUrl(endpoint);
 
-  String _username = "";
-  String _password = "";
+  UserProfile _profile;
 
   // Authentication token (initially empty, must be requested)
   String _token = "";
@@ -168,25 +168,34 @@ class InvenTreeAPI {
   InvenTreeAPI._internal();
 
   Future<bool> connect(BuildContext context) async {
-    var prefs = await SharedPreferences.getInstance();
 
-    String server = prefs.getString("server");
-    String username = prefs.getString("username");
-    String password = prefs.getString("password");
+    _profile = await UserProfileDBManager().getSelectedProfile();
 
-    return connectToServer(context, server, username, password);
+    if (_profile == null) {
+      await showErrorDialog(
+          context,
+          "Select Profile",
+          "User profile not selected"
+      );
+      return false;
+    }
+
+    return connectToServer(context);
   }
 
-  Future<bool> connectToServer(BuildContext context, String address, String username, String password) async {
+  Future<bool> connectToServer(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;
+
     String errorMessage = "";
 
-    address = address.trim();
-    username = username.trim();
+    String address = _profile.server.trim();
+    String username = _profile.username.trim();
+    String password = _profile.password.trim();
 
     if (address.isEmpty || username.isEmpty || password.isEmpty) {
       await showErrorDialog(
@@ -211,14 +220,13 @@ class InvenTreeAPI {
      */
 
     _BASE_URL = address;
-    _username = username;
-    _password = password;
-
     _connected = false;
 
     print("Connecting to " + apiUrl + " -> " + username + ":" + password);
 
-    var response = await get("").timeout(Duration(seconds: 10)).catchError((error) {
+    var response = await get("").timeout(Duration(seconds: 5)).catchError((error) {
+
+      print("Error connecting to server: ${error.toString()}");
 
       if (error is SocketException) {
         errorMessage = "Could not connect to server";
@@ -397,7 +405,7 @@ class InvenTreeAPI {
   Map<String, String> defaultHeaders() {
     var headers = Map<String, String>();
 
-    headers[HttpHeaders.authorizationHeader] = _authorizationHeader();
+    headers[HttpHeaders.authorizationHeader] = _authorizationHeader(_profile.username, _profile.password);
 
     return headers;
   }
@@ -408,11 +416,11 @@ class InvenTreeAPI {
     return headers;
   }
 
-  String _authorizationHeader() {
+  String _authorizationHeader(String username, String password) {
     if (_token.isNotEmpty) {
       return "Token $_token";
     } else {
-      return "Basic " + base64Encode(utf8.encode('$_username:$_password'));
+      return "Basic " + base64Encode(utf8.encode('${username}:${password}'));
     }
   }
 
diff --git a/lib/preferences.dart b/lib/preferences.dart
index 201f4c27..b4512d30 100644
--- a/lib/preferences.dart
+++ b/lib/preferences.dart
@@ -89,13 +89,7 @@ class InvenTreePreferences {
 
     print("Loading login details");
 
-    SharedPreferences prefs = await SharedPreferences.getInstance();
-
-    var server = prefs.getString(_SERVER) ?? '';
-    var username = prefs.getString(_USERNAME) ?? '';
-    var password = prefs.getString(_PASSWORD) ?? '';
-
-    await InvenTreeAPI().connectToServer(context, server, username, password);
+    await InvenTreeAPI().connectToServer(context);
   }
 
   void saveLoginDetails(BuildContext context, String server, String username, String password) async {
@@ -107,6 +101,6 @@ class InvenTreePreferences {
     await prefs.setString(_PASSWORD, password);
 
     // Reconnect the API
-    await InvenTreeAPI().connectToServer(context, server, username, password);
+    await InvenTreeAPI().connectToServer(context);
   }
 }
\ No newline at end of file
diff --git a/lib/settings/login.dart b/lib/settings/login.dart
index 0733710a..06b99ed9 100644
--- a/lib/settings/login.dart
+++ b/lib/settings/login.dart
@@ -1,10 +1,6 @@
-import 'dart:ffi';
-
 import 'package:InvenTree/widget/dialogs.dart';
 import 'package:InvenTree/widget/fields.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_speed_dial/flutter_speed_dial.dart';
-import 'package:shared_preferences/shared_preferences.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
 import 'package:font_awesome_flutter/font_awesome_flutter.dart';
 
@@ -14,14 +10,12 @@ import '../user_profile.dart';
 
 class InvenTreeLoginSettingsWidget extends StatefulWidget {
 
-  final SharedPreferences _preferences;
-
   final List<UserProfile> _profiles;
 
-  InvenTreeLoginSettingsWidget(this._profiles, this._preferences) : super();
+  InvenTreeLoginSettingsWidget(this._profiles) : super();
 
   @override
-  _InvenTreeLoginSettingsState createState() => _InvenTreeLoginSettingsState(_profiles, _preferences);
+  _InvenTreeLoginSettingsState createState() => _InvenTreeLoginSettingsState(_profiles);
 }
 
 
@@ -31,18 +25,10 @@ class _InvenTreeLoginSettingsState extends State<InvenTreeLoginSettingsWidget> {
 
   final GlobalKey<FormState> _addProfileKey = new GlobalKey<FormState>();
 
-  final SharedPreferences _preferences;
-
   List<UserProfile> profiles;
 
-  String _server = '';
-  String _username = '';
-  String _password = '';
+  _InvenTreeLoginSettingsState(this.profiles) {
 
-  _InvenTreeLoginSettingsState(this.profiles, this._preferences) : super() {
-    _server = _preferences.getString('server') ?? '';
-    _username = _preferences.getString('username') ?? '';
-    _password = _preferences.getString('password') ?? '';
   }
 
   void _reload() async {
@@ -99,7 +85,6 @@ class _InvenTreeLoginSettingsState extends State<InvenTreeLoginSettingsWidget> {
         ),
         StringField(
           label: I18N.of(context).server,
-          initial: "http://127.0.0.1:8000",
           hint: "http[s]://<server>:<port>",
           validator: _validateServer,
           onSaved: (value) => _server = value,
@@ -162,16 +147,6 @@ class _InvenTreeLoginSettingsState extends State<InvenTreeLoginSettingsWidget> {
     return null;
   }
 
-  void _save(BuildContext context) async {
-    if (_formKey.currentState.validate()) {
-      _formKey.currentState.save();
-
-      // TODO
-      await InvenTreePreferences().saveLoginDetails(context, _server, _username, _password);
-
-    }
-  }
-
   void _selectProfile(UserProfile profile) async {
 
     // Mark currently selected profile as unselected
@@ -287,66 +262,5 @@ class _InvenTreeLoginSettingsState extends State<InvenTreeLoginSettingsWidget> {
         },
       )
     );
-
-    return Scaffold(
-      appBar: AppBar(
-        title: Text("Login Settings"),
-      ),
-      body: new Container(
-        padding: new EdgeInsets.all(20.0),
-        child: new Form(
-          key: _formKey,
-          child: new ListView(
-            children: <Widget>[
-              Text(I18N.of(context).serverAddress),
-              new TextFormField(
-                initialValue: _server,
-                decoration: InputDecoration(
-                  hintText: "127.0.0.1:8000",
-                ),
-                validator: _validateServer,
-                onSaved: (String value) {
-                  _server = value;
-                },
-              ),
-              Divider(),
-              Text(I18N.of(context).accountDetails),
-              TextFormField(
-                initialValue: _username,
-                decoration: InputDecoration(
-                  hintText: I18N.of(context).username,
-                  labelText: I18N.of(context).username,
-                ),
-                validator: _validateUsername,
-                onSaved: (String value) {
-                  _username = value;
-                }
-              ),
-              TextFormField(
-                initialValue: _password,
-                obscureText: true,
-                decoration: InputDecoration(
-                  hintText: I18N.of(context).password,
-                  labelText: I18N.of(context).password,
-                ),
-                validator: _validatePassword,
-                onSaved: (String value) {
-                  _password = value;
-                },
-              ),
-              Container(
-                width: screenSize.width,
-                child: RaisedButton(
-                  child: Text(I18N.of(context).save),
-                  onPressed: () {
-                    _save(context);
-                  }
-                )
-              )
-            ],
-          )
-        )
-      )
-    );
   }
 }
\ No newline at end of file
diff --git a/lib/settings/settings.dart b/lib/settings/settings.dart
index 387ff4f4..ffd2731a 100644
--- a/lib/settings/settings.dart
+++ b/lib/settings/settings.dart
@@ -60,25 +60,6 @@ class _InvenTreeSettingsState extends State<InvenTreeSettingsWidget> {
               leading: FaIcon(FontAwesomeIcons.bug),
               onTap: null,
             ),
-            ListTile(
-              title: Text("Throw Error"),
-              onTap: () {
-                throw("My custom error");
-              },
-            ),
-            ListTile(
-              title: Text("add profile"),
-              onTap: () {
-                UserProfileDBManager().addProfile(
-                  UserProfile(
-                    name: "My Profile",
-                    server: "https://127.0.0.1:8000",
-                    username: "Oliver",
-                    password: "hunter2",
-                  )
-                );
-              },
-            )
           ],
         )
       )
@@ -91,7 +72,7 @@ class _InvenTreeSettingsState extends State<InvenTreeSettingsWidget> {
 
     List<UserProfile> profiles = await UserProfileDBManager().getAllProfiles();
 
-    Navigator.push(context, MaterialPageRoute(builder: (context) => InvenTreeLoginSettingsWidget(profiles, prefs)));
+    Navigator.push(context, MaterialPageRoute(builder: (context) => InvenTreeLoginSettingsWidget(profiles)));
   }
 
   void _about() async {
diff --git a/lib/widget/home.dart b/lib/widget/home.dart
index 0a2d0129..c1bc56c6 100644
--- a/lib/widget/home.dart
+++ b/lib/widget/home.dart
@@ -1,10 +1,10 @@
+import 'package:InvenTree/user_profile.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
 
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
 
 import 'package:font_awesome_flutter/font_awesome_flutter.dart';
-import 'package:shared_preferences/shared_preferences.dart';
 
 import 'package:InvenTree/barcode.dart';
 import 'package:InvenTree/api.dart';
@@ -27,8 +27,6 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> {
   _InvenTreeHomePageState() : super() {
   }
 
-  String _serverAddress = "";
-
   String _serverStatus = "Connecting to server";
 
   String _serverMessage = "";
@@ -39,20 +37,28 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> {
 
   Color _serverStatusColor = Color.fromARGB(255, 50, 50, 250);
 
-  void onConnectSuccess(String msg) {
+  void onConnectSuccess(String msg) async {
+
+    final profile = await UserProfileDBManager().getSelectedProfile();
+
+    String address = profile?.server ?? 'unknown server address';
+
     _serverConnection = true;
     _serverMessage = msg;
-    _serverStatus = "Connected to $_serverAddress";
+    _serverStatus = "Connected to ${address}";
     _serverStatusColor = Color.fromARGB(255, 50, 250, 50);
     _serverIcon = new FaIcon(FontAwesomeIcons.checkCircle, color: _serverStatusColor);
 
     setState(() {});
   }
 
-  void onConnectFailure(String msg) {
+  void onConnectFailure(String msg) async {
+
+    final profile = await UserProfileDBManager().getSelectedProfile();
+
     _serverConnection = false;
     _serverMessage = msg;
-    _serverStatus = "Could not connect to $_serverAddress";
+    _serverStatus = "Could not connect to ${profile?.server}";
     _serverStatusColor = Color.fromARGB(255, 250, 50, 50);
     _serverIcon = new FaIcon(FontAwesomeIcons.timesCircle, color: _serverStatusColor);
 
@@ -64,10 +70,6 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> {
    */
   void _checkServerConnection(BuildContext context) async {
 
-    var prefs = await SharedPreferences.getInstance();
-
-    _serverAddress = prefs.getString("server");
-
     // Reset the connection status variables
     _serverStatus = "Connecting to server";
     _serverMessage = "";
diff --git a/pubspec.lock b/pubspec.lock
index cd28fab8..8d39f12c 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -385,13 +385,6 @@ packages:
       url: "https://pub.dartlang.org"
     source: hosted
     version: "1.0.3"
-  preferences:
-    dependency: "direct main"
-    description:
-      name: preferences
-      url: "https://pub.dartlang.org"
-    source: hosted
-    version: "5.2.1"
   process:
     dependency: transitive
     description:
diff --git a/pubspec.yaml b/pubspec.yaml
index c212ecc8..0902d4da 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -11,7 +11,7 @@ description: InvenTree stock management
 # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
 # Read more about iOS versioning at
 # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
-version: 0.1.0+1
+version: 0.1.0+2
 
 environment:
   sdk: ">=2.1.0 <3.0.0"
@@ -30,7 +30,6 @@ dependencies:
   shared_preferences: ^0.5.7
 
   cached_network_image: ^2.5.0
-  preferences: ^5.2.0                     # Persistent settings storage
   qr_code_scanner: ^0.0.13
   package_info: ^0.4.0                    # App information introspection
   device_info: ^1.0.0                     # Information about the device