From a10c5ecd2b4bba6814fd66f0ec1997938d95bf92 Mon Sep 17 00:00:00 2001
From: "kali kaneko (leap communications)" <kali@leap.se>
Date: Mon, 17 Aug 2020 19:42:15 +0200
Subject: [PATCH] [feat] login feedback

- Resolves: #334
---
 branding/config/vendor.conf   |  2 +-
 gui/gui.qrc                   |  1 +
 gui/qml/LoginConfirmation.qml | 11 -----------
 gui/qml/LoginOKDialog.qml     | 23 +++++++++++++++++++++++
 gui/qml/main.qml              | 11 +++++++++++
 pkg/backend/api.go            |  9 ++++++---
 pkg/backend/status.go         |  1 +
 pkg/bitmask/bitmask.go        |  1 +
 pkg/bitmask/init.go           |  9 ++++++---
 pkg/config/config.go          |  4 ++--
 pkg/vpn/bonafide/bonafide.go  |  2 +-
 pkg/vpn/openvpn.go            | 16 ++++++++++++++++
 12 files changed, 69 insertions(+), 21 deletions(-)
 delete mode 100644 gui/qml/LoginConfirmation.qml
 create mode 100644 gui/qml/LoginOKDialog.qml

diff --git a/branding/config/vendor.conf b/branding/config/vendor.conf
index ac0f4b12..90ef36cf 100644
--- a/branding/config/vendor.conf
+++ b/branding/config/vendor.conf
@@ -72,7 +72,7 @@ binaryName          = demo-lib
 auth                = sip
 
 providerURL         = vpnlib.bitmask.net
-apiURL              = https://api.vpnlib.bitmask.net/
+apiURL              = https://api.vpnlib.bitmask.net:4430/
 caURL               = https://api.vpnlib.bitmask.net/ca.crt
 
 infoURL             = https://libraryvpn.org/
diff --git a/gui/gui.qrc b/gui/gui.qrc
index 28fcf7f4..6bc3d8de 100644
--- a/gui/gui.qrc
+++ b/gui/gui.qrc
@@ -4,6 +4,7 @@
         <file>qml/AboutDialog.qml</file>
         <file>qml/DonateDialog.qml</file>
         <file>qml/LoginDialog.qml</file>
+        <file>qml/LoginOKDialog.qml</file>
          
         <file>assets/icon/png/black/vpn_off.png</file>
         <file>assets/icon/png/black/vpn_on.png</file>
diff --git a/gui/qml/LoginConfirmation.qml b/gui/qml/LoginConfirmation.qml
deleted file mode 100644
index 618b8705..00000000
--- a/gui/qml/LoginConfirmation.qml
+++ /dev/null
@@ -1,11 +0,0 @@
-import QtQuick 2.0
-import QtQuick.Dialogs 1.2
-import QtQuick.Controls 1.4
-
-Dialog {
-    standardButtons: StandardButton.Ok
-    title: qsTr("Login Success")
-    text: qsTr("You are now logged in, connecting now")
-
-    visible: ctxSystray.loginConfirmationDialog == true
-}
diff --git a/gui/qml/LoginOKDialog.qml b/gui/qml/LoginOKDialog.qml
new file mode 100644
index 00000000..52b37701
--- /dev/null
+++ b/gui/qml/LoginOKDialog.qml
@@ -0,0 +1,23 @@
+import QtQuick 2.0
+import QtQuick.Dialogs 1.2
+import QtQuick.Controls 1.4
+
+Dialog {
+    standardButtons: StandardButton.Ok
+    title: qsTr("Login Successful")
+    Column {
+        anchors.fill: parent
+        Text {
+            text: qsTr("Login successful. You can now start the VPN.")
+        }
+    }
+
+    // TODO implement cleanNotifications on backend
+    function _loginOk() {
+        loginDone = true;
+    }
+
+    visible: false
+    onAccepted: _loginOk()
+    onRejected: _loginOk()
+}
diff --git a/gui/qml/main.qml b/gui/qml/main.qml
index 02424934..f22bdf36 100644
--- a/gui/qml/main.qml
+++ b/gui/qml/main.qml
@@ -10,6 +10,7 @@ ApplicationWindow {
     visible: false
 
     property var ctx
+    property var loginDone 
 
     Connections {
         target: jsonModel
@@ -23,6 +24,9 @@ ApplicationWindow {
                 console.debug(jsonModel.getJson())
                 login.visible = true
             }
+            if (ctx.loginOk == 'true' && loginDone == false) {
+                loginOk.visible = true
+            }
             if (ctx.errors ) {
                if ( ctx.errors  == "nohelpers" ) {
                    showInitFailure(qsTr("Could not find helpers. Check your installation"))
@@ -44,6 +48,8 @@ ApplicationWindow {
     }
 
     Component.onCompleted: {
+        loginDone = false;
+
         /* stupid as it sounds, windows doesn't like to have the systray icon
          not being attached to an actual application window.
          We can still use this quirk, and can use the AppWindow with deferred
@@ -228,6 +234,11 @@ ApplicationWindow {
         visible: false
     }
 
+    LoginOKDialog{
+        id: loginOk
+        visible: false
+    }
+
     MessageDialog {
         id: errorStartingVPN
         buttons: MessageDialog.Ok
diff --git a/pkg/backend/api.go b/pkg/backend/api.go
index 7b48906e..6609b1b7 100644
--- a/pkg/backend/api.go
+++ b/pkg/backend/api.go
@@ -16,16 +16,19 @@ import (
 func Login(username, password string) {
 	success, err := ctx.bm.DoLogin(username, password)
 	if err != nil {
-		// TODO
-		log.Printf("Error login: %v", err)
+		log.Printf("Error on login: %v", err)
+		ctx.Errors = "bad_auth_unknown"
 	} else if success {
-		// TODO: Notify success
 		log.Printf("Logged in as %s", username)
+		ctx.LoginOk = true
+		ctx.LoginDialog = false
 	} else {
 		// TODO: display login again with an err
 		log.Printf("Failed to login as %s", username)
 		ctx.LoginDialog = true
+		ctx.Errors = "bad_auth"
 	}
+	go ctx.updateStatus()
 }
 
 func SwitchOn() {
diff --git a/pkg/backend/status.go b/pkg/backend/status.go
index 5e9a0f80..f06d26df 100644
--- a/pkg/backend/status.go
+++ b/pkg/backend/status.go
@@ -38,6 +38,7 @@ type connectionCtx struct {
 	DonateDialog    bool   `json:"donateDialog"`
 	DonateURL       string `json:"donateURL"`
 	LoginDialog     bool   `json:"loginDialog"`
+	LoginOk         bool   `json:"loginOk"`
 	Version         string `json:"version"`
 	Errors          string `json:"errors"`
 	Status          status `json:"status"`
diff --git a/pkg/bitmask/bitmask.go b/pkg/bitmask/bitmask.go
index 927e4868..adfc8491 100644
--- a/pkg/bitmask/bitmask.go
+++ b/pkg/bitmask/bitmask.go
@@ -20,6 +20,7 @@ type Bitmask interface {
 	Close()
 	Version() (string, error)
 	StartVPN(provider string) error
+	CanStartVPN() bool
 	StopVPN() error
 	ReloadFirewall() error
 	GetStatus() (string, error)
diff --git a/pkg/bitmask/init.go b/pkg/bitmask/init.go
index a96ab870..b86deb82 100644
--- a/pkg/bitmask/init.go
+++ b/pkg/bitmask/init.go
@@ -131,7 +131,10 @@ func maybeStartVPN(b Bitmask, conf *config.Config) error {
 		return nil
 	}
 
-	err := b.StartVPN(config.Provider)
-	conf.SetUserStoppedVPN(false)
-	return err
+	if b.CanStartVPN() {
+		err := b.StartVPN(config.Provider)
+		conf.SetUserStoppedVPN(false)
+		return err
+	}
+	return nil
 }
diff --git a/pkg/config/config.go b/pkg/config/config.go
index e9866d26..f3f9e6e0 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -1,6 +1,6 @@
 // Code generated by go generate; DO NOT EDIT.
 // This file was generated by vendorize.py
-// At 2020-08-13 22:38:42
+// At 2020-08-15 20:39:01
 
 package config
 
@@ -15,7 +15,7 @@ const (
 	AskForDonations = "false"
 	HelpURL         = "https://libraryvpn.org/"
 	TosURL          = "https://libraryvpn.org/"
-	APIURL          = "https://api.vpnlib.bitmask.net/"
+	APIURL          = "https://api.vpnlib.bitmask.net:4430/"
 	GeolocationAPI  = "https://getmyip.vpnlib.bitmask.net/"
 )
 
diff --git a/pkg/vpn/bonafide/bonafide.go b/pkg/vpn/bonafide/bonafide.go
index 87801cca..dd8c597c 100644
--- a/pkg/vpn/bonafide/bonafide.go
+++ b/pkg/vpn/bonafide/bonafide.go
@@ -137,7 +137,7 @@ func (b *Bonafide) GetPemCertificate() ([]byte, error) {
 		log.Fatal("ERROR: bonafide did not initialize auth")
 	}
 	if b.auth.needsCredentials() && b.token == nil {
-		log.Println("BUG: expected token to be set, but is not there")
+		log.Println("Needs token, but token is empty")
 		return nil, errors.New("Needs to login, but it was not logged in. Please, restart the application and report it if it continues happening")
 	}
 
diff --git a/pkg/vpn/openvpn.go b/pkg/vpn/openvpn.go
index 31f87383..11bba69a 100644
--- a/pkg/vpn/openvpn.go
+++ b/pkg/vpn/openvpn.go
@@ -16,6 +16,7 @@
 package vpn
 
 import (
+	"errors"
 	"fmt"
 	"io/ioutil"
 	"log"
@@ -43,9 +44,23 @@ func (b *Bitmask) StartVPN(provider string) error {
 		}
 	}
 
+	if !b.CanStartVPN() {
+		return errors.New("BUG: cannot start vpn")
+	}
 	return b.startOpenVPN(proxy)
 }
 
+func (b *Bitmask) CanStartVPN() bool {
+	if !b.bonafide.NeedsCredentials() {
+		return true
+	}
+	_, err := b.getCert()
+	if err != nil {
+		return false
+	}
+	return true
+}
+
 func (b *Bitmask) startTransport() (proxy string, err error) {
 	proxy = "127.0.0.1:4430"
 	if b.shapes != nil {
@@ -150,6 +165,7 @@ func (b *Bitmask) getCert() (certPath string, err error) {
 	certPath = b.getCertPemPath()
 
 	if _, err := os.Stat(certPath); os.IsNotExist(err) {
+		log.Println("Cert does not exist in ", certPath, "...fetching")
 		cert, err := b.bonafide.GetPemCertificate()
 		if err != nil {
 			return "", err
-- 
GitLab