summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjwijenbergh <jeroenwijenbergh@protonmail.com>2022-09-07 18:41:01 +0200
committerjwijenbergh <jeroenwijenbergh@protonmail.com>2022-09-07 18:41:01 +0200
commit7f7b6884d11e0e2b891814b84eb906db284a50b0 (patch)
treeed3f2ec29b5efda3fbb628a09628464d98fce336
parent809bc265d11b508903313f5b0a8c1a04add7209b (diff)
Refactor: Define FSM state constants inside the public package
-rw-r--r--cmd/cli/main.go14
-rw-r--r--exports/exports.go8
-rw-r--r--fsm.go237
-rw-r--r--internal/fsm/fsm.go238
-rw-r--r--state.go129
-rw-r--r--state_test.go19
6 files changed, 334 insertions, 311 deletions
diff --git a/cmd/cli/main.go b/cmd/cli/main.go
index e900585..4561517 100644
--- a/cmd/cli/main.go
+++ b/cmd/cli/main.go
@@ -11,7 +11,6 @@ import (
"strings"
"github.com/jwijenbergh/eduvpn-common"
- "github.com/jwijenbergh/eduvpn-common/internal/fsm"
"github.com/jwijenbergh/eduvpn-common/internal/server"
)
@@ -94,16 +93,15 @@ func sendProfile(state *eduvpn.VPNState, data interface{}) {
// Note that this has an additional argument, the vpn state which was wrapped into this callback function below
func stateCallback(
state *eduvpn.VPNState,
- oldState eduvpn.StateID,
- newState eduvpn.StateID,
+ oldState eduvpn.FSMStateID,
+ newState eduvpn.FSMStateID,
data interface{},
) {
- // TODO: Remove internal usage of fsm
- if newState == fsm.OAUTH_STARTED {
+ if newState == eduvpn.STATE_OAUTH_STARTED {
openBrowser(data)
}
- if newState == fsm.ASK_PROFILE {
+ if newState == eduvpn.STATE_ASK_PROFILE {
sendProfile(state, data)
}
}
@@ -177,7 +175,7 @@ func getSecureInternetAll(homeURL string) {
state.Register(
"org.eduvpn.app.linux",
"configs",
- func(old eduvpn.StateID, new eduvpn.StateID, data interface{}) {
+ func(old eduvpn.FSMStateID, new eduvpn.FSMStateID, data interface{}) {
stateCallback(state, old, new, data)
},
true,
@@ -223,7 +221,7 @@ func printConfig(url string, serverType ServerTypes) {
state.Register(
"org.eduvpn.app.linux",
"configs",
- func(old eduvpn.StateID, new eduvpn.StateID, data interface{}) {
+ func(old eduvpn.FSMStateID, new eduvpn.FSMStateID, data interface{}) {
stateCallback(state, old, new, data)
},
true,
diff --git a/exports/exports.go b/exports/exports.go
index e2b02a1..daf84bb 100644
--- a/exports/exports.go
+++ b/exports/exports.go
@@ -28,8 +28,8 @@ var VPNStates map[string]*eduvpn.VPNState
func StateCallback(
name string,
- old_state eduvpn.StateID,
- new_state eduvpn.StateID,
+ old_state eduvpn.FSMStateID,
+ new_state eduvpn.FSMStateID,
data interface{},
) {
P_StateCallback, exists := P_StateCallbacks[name]
@@ -86,7 +86,7 @@ func Register(
registerErr := state.Register(
nameStr,
C.GoString(config_directory),
- func(old eduvpn.StateID, new eduvpn.StateID, data interface{}) {
+ func(old eduvpn.FSMStateID, new eduvpn.FSMStateID, data interface{}) {
StateCallback(nameStr, old, new, data)
},
debug != 0,
@@ -367,7 +367,7 @@ func InFSMState(name *C.char, checkState C.int) C.int {
if stateErr != nil {
return C.int(0)
}
- inStateBool := state.InFSMState(eduvpn.StateID(checkState))
+ inStateBool := state.InFSMState(eduvpn.FSMStateID(checkState))
if inStateBool {
return C.int(1)
}
diff --git a/fsm.go b/fsm.go
new file mode 100644
index 0000000..31ed30b
--- /dev/null
+++ b/fsm.go
@@ -0,0 +1,237 @@
+package eduvpn
+
+import (
+ "errors"
+ "fmt"
+ "github.com/jwijenbergh/eduvpn-common/internal/fsm"
+ "github.com/jwijenbergh/eduvpn-common/internal/types"
+)
+
+type FSMStateID = fsm.FSMStateID
+type FSMStates = fsm.FSMStates
+type FSMState = fsm.FSMState
+type FSMTransition = fsm.FSMTransition
+
+const (
+ // Deregistered means the app is not registered with the wrapper
+ STATE_DEREGISTERED FSMStateID = iota
+
+ // No Server means the user has not chosen a server yet
+ STATE_NO_SERVER
+
+ // The user selected a Secure Internet server but needs to choose a location
+ STATE_ASK_LOCATION
+
+ // The user is currently selecting a server in the UI
+ STATE_SEARCH_SERVER
+
+ // We are loading the server details
+ STATE_LOADING_SERVER
+
+ // Chosen Server means the user has chosen a server to connect to
+ STATE_CHOSEN_SERVER
+
+ // OAuth Started means the OAuth process has started
+ STATE_OAUTH_STARTED
+
+ // Authorized means the OAuth process has finished and the user is now authorized with the server
+ STATE_AUTHORIZED
+
+ // Requested config means the user has requested a config for connecting
+ STATE_REQUEST_CONFIG
+
+ // Ask profile means the go code is asking for a profile selection from the UI
+ STATE_ASK_PROFILE
+
+ // Disconnected means the user has gotten a config for a server but is not connected yet
+ STATE_DISCONNECTED
+
+ // Disconnecting means the OS is disconnecting and the Go code is doing the /disconnect
+ STATE_DISCONNECTING
+
+ // Connecting means the OS is establishing a connection to the server
+ STATE_CONNECTING
+
+ // Connected means the user has been connected to the server
+ STATE_CONNECTED
+)
+
+func GetStateName(s FSMStateID) string {
+ switch s {
+ case STATE_DEREGISTERED:
+ return "Deregistered"
+ case STATE_NO_SERVER:
+ return "No_Server"
+ case STATE_ASK_LOCATION:
+ return "Ask_Location"
+ case STATE_SEARCH_SERVER:
+ return "Search_Server"
+ case STATE_LOADING_SERVER:
+ return "Loading_Server"
+ case STATE_CHOSEN_SERVER:
+ return "Chosen_Server"
+ case STATE_OAUTH_STARTED:
+ return "OAuth_Started"
+ case STATE_DISCONNECTED:
+ return "Disconnected"
+ case STATE_REQUEST_CONFIG:
+ return "Request_Config"
+ case STATE_ASK_PROFILE:
+ return "Ask_Profile"
+ case STATE_AUTHORIZED:
+ return "Authorized"
+ case STATE_DISCONNECTING:
+ return "Disconnecting"
+ case STATE_CONNECTING:
+ return "Connecting"
+ case STATE_CONNECTED:
+ return "Connected"
+ default:
+ panic("unknown conversion of state to string")
+ }
+}
+
+func newFSM(name string, callback func(FSMStateID, FSMStateID, interface{}), directory string, debug bool) fsm.FSM {
+ states := FSMStates{
+ STATE_DEREGISTERED: FSMState{Transitions: []FSMTransition{{STATE_NO_SERVER, "Client registers"}}},
+ STATE_NO_SERVER: FSMState{
+ Transitions: []FSMTransition{
+ {STATE_NO_SERVER, "Reload list"},
+ {STATE_CHOSEN_SERVER, "User chooses a server"},
+ {STATE_SEARCH_SERVER, "The user is trying to choose a Server in the UI"},
+ {STATE_CONNECTED, "The user is already connected"},
+ {STATE_ASK_LOCATION, "Change the location in the main screen"},
+ },
+ },
+ STATE_SEARCH_SERVER: FSMState{
+ Transitions: []FSMTransition{
+ {STATE_LOADING_SERVER, "User clicks a server in the UI"},
+ {STATE_NO_SERVER, "Cancel or Error"},
+ },
+ BackState: STATE_NO_SERVER,
+ },
+ STATE_ASK_LOCATION: FSMState{
+ Transitions: []FSMTransition{
+ {STATE_CHOSEN_SERVER, "Location chosen"},
+ {STATE_NO_SERVER, "Go back or Error"},
+ {STATE_SEARCH_SERVER, "Cancel or Error"},
+ },
+ },
+ STATE_LOADING_SERVER: FSMState{
+ Transitions: []FSMTransition{
+ {STATE_CHOSEN_SERVER, "Server info loaded"},
+ {
+ STATE_ASK_LOCATION,
+ "User chooses a Secure Internet server but no location is configured",
+ },
+ {STATE_NO_SERVER, "Go back or Error"},
+ },
+ BackState: STATE_NO_SERVER,
+ },
+ STATE_CHOSEN_SERVER: FSMState{
+ Transitions: []FSMTransition{
+ {STATE_AUTHORIZED, "Found tokens in config"},
+ {STATE_OAUTH_STARTED, "No tokens found in config"},
+ },
+ },
+ STATE_OAUTH_STARTED: FSMState{
+ Transitions: []FSMTransition{
+ {STATE_AUTHORIZED, "User authorizes with browser"},
+ {STATE_NO_SERVER, "Cancel or Error"},
+ {STATE_SEARCH_SERVER, "Cancel or Error"},
+ },
+ BackState: STATE_NO_SERVER,
+ },
+ STATE_AUTHORIZED: FSMState{
+ Transitions: []FSMTransition{
+ {STATE_OAUTH_STARTED, "Re-authorize with OAuth"},
+ {STATE_REQUEST_CONFIG, "Client requests a config"},
+ },
+ },
+ STATE_REQUEST_CONFIG: FSMState{
+ Transitions: []FSMTransition{
+ {STATE_ASK_PROFILE, "Multiple profiles found and no profile chosen"},
+ {STATE_DISCONNECTED, "Only one profile or profile already chosen"},
+ {STATE_NO_SERVER, "Cancel or Error"},
+ {STATE_OAUTH_STARTED, "Re-authorize"},
+ },
+ },
+ STATE_ASK_PROFILE: FSMState{
+ Transitions: []FSMTransition{
+ {STATE_DISCONNECTED, "User chooses profile"},
+ {STATE_NO_SERVER, "Cancel or Error"},
+ {STATE_SEARCH_SERVER, "Cancel or Error"},
+ },
+ },
+ STATE_DISCONNECTED: FSMState{
+ Transitions: []FSMTransition{
+ {STATE_CONNECTING, "OS reports it is trying to connect"},
+ {STATE_REQUEST_CONFIG, "User reconnects"},
+ {STATE_NO_SERVER, "User wants to choose a new server"},
+ {STATE_OAUTH_STARTED, "Re-authorize with OAuth"},
+ },
+ BackState: STATE_NO_SERVER,
+ },
+ STATE_DISCONNECTING: FSMState{
+ Transitions: []FSMTransition{
+ {STATE_DISCONNECTED, "Cancel or Error"},
+ {STATE_DISCONNECTED, "Done disconnecting"},
+ },
+ },
+ STATE_CONNECTING: FSMState{
+ Transitions: []FSMTransition{
+ {STATE_DISCONNECTED, "Cancel or Error"},
+ {STATE_CONNECTED, "Done connecting"},
+ },
+ },
+ STATE_CONNECTED: FSMState{
+ Transitions: []FSMTransition{{STATE_DISCONNECTING, "App wants to disconnect"}},
+ },
+ }
+ returnedFSM := fsm.FSM{}
+ returnedFSM.Init(name, STATE_DEREGISTERED, states, callback, directory, GetStateName, debug)
+ return returnedFSM
+}
+
+type FSMDeregisteredError struct{}
+
+func (e FSMDeregisteredError) CustomError() *types.WrappedErrorMessage {
+ return &types.WrappedErrorMessage{
+ Message: "Client not registered with the GO library",
+ Err: errors.New(
+ "the current FSM state is deregistered, but the function needs a state that is not deregistered",
+ ),
+ }
+}
+
+type FSMWrongStateTransitionError struct {
+ Got FSMStateID
+ Want FSMStateID
+}
+
+func (e FSMWrongStateTransitionError) CustomError() *types.WrappedErrorMessage {
+ return &types.WrappedErrorMessage{
+ Message: "Wrong FSM transition",
+ Err: errors.New(
+ fmt.Sprintf(
+ "wrong FSM state, got: %s, want: a state with a transition to: %s",
+ GetStateName(e.Got),
+ GetStateName(e.Want),
+ ),
+ ),
+ }
+}
+
+type FSMWrongStateError struct {
+ Got FSMStateID
+ Want FSMStateID
+}
+
+func (e FSMWrongStateError) CustomError() *types.WrappedErrorMessage {
+ return &types.WrappedErrorMessage{
+ Message: "Wrong FSM State",
+ Err: errors.New(
+ fmt.Sprintf("wrong FSM state, got: %s, want: %s", GetStateName(e.Got), GetStateName(e.Want)),
+ ),
+ }
+}
diff --git a/internal/fsm/fsm.go b/internal/fsm/fsm.go
index 6178af9..63c9ac2 100644
--- a/internal/fsm/fsm.go
+++ b/internal/fsm/fsm.go
@@ -1,14 +1,11 @@
package fsm
import (
- "errors"
- "fmt"
"os"
"os/exec"
+ "fmt"
"path"
"sort"
-
- "github.com/jwijenbergh/eduvpn-common/internal/types"
)
type (
@@ -28,85 +25,6 @@ func (v FSMStateIDSlice) Swap(i, j int) {
v[i], v[j] = v[j], v[i]
}
-const (
- // Deregistered means the app is not registered with the wrapper
- DEREGISTERED FSMStateID = iota
-
- // No Server means the user has not chosen a server yet
- NO_SERVER
-
- // The user selected a Secure Internet server but needs to choose a location
- ASK_LOCATION
-
- // The user is currently selecting a server in the UI
- SEARCH_SERVER
-
- // We are loading the server details
- LOADING_SERVER
-
- // Chosen Server means the user has chosen a server to connect to
- CHOSEN_SERVER
-
- // OAuth Started means the OAuth process has started
- OAUTH_STARTED
-
- // Authorized means the OAuth process has finished and the user is now authorized with the server
- AUTHORIZED
-
- // Requested config means the user has requested a config for connecting
- REQUEST_CONFIG
-
- // Ask profile means the go code is asking for a profile selection from the UI
- ASK_PROFILE
-
- // Disconnected means the user has gotten a config for a server but is not connected yet
- DISCONNECTED
-
- // Disconnecting means the OS is disconnecting and the Go code is doing the /disconnect
- DISCONNECTING
-
- // Connecting means the OS is establishing a connection to the server
- CONNECTING
-
- // Connected means the user has been connected to the server
- CONNECTED
-)
-
-func (s FSMStateID) String() string {
- switch s {
- case DEREGISTERED:
- return "Deregistered"
- case NO_SERVER:
- return "No_Server"
- case ASK_LOCATION:
- return "Ask_Location"
- case SEARCH_SERVER:
- return "Search_Server"
- case LOADING_SERVER:
- return "Loading_Server"
- case CHOSEN_SERVER:
- return "Chosen_Server"
- case OAUTH_STARTED:
- return "OAuth_Started"
- case DISCONNECTED:
- return "Disconnected"
- case REQUEST_CONFIG:
- return "Request_Config"
- case ASK_PROFILE:
- return "Ask_Profile"
- case AUTHORIZED:
- return "Authorized"
- case DISCONNECTING:
- return "Disconnecting"
- case CONNECTING:
- return "Connecting"
- case CONNECTED:
- return "Connected"
- default:
- panic("unknown conversion of state to string")
- }
-}
-
type FSMTransition struct {
To FSMStateID
Description string
@@ -132,114 +50,24 @@ type FSM struct {
StateCallback func(FSMStateID, FSMStateID, interface{})
Directory string
Debug bool
+ GetName func(FSMStateID) string
}
func (fsm *FSM) Init(
name string,
+ current FSMStateID,
+ states map[FSMStateID]FSMState,
callback func(FSMStateID, FSMStateID, interface{}),
directory string,
+ nameGen func(FSMStateID) string,
debug bool,
) {
- fsm.States = FSMStates{
- DEREGISTERED: FSMState{Transitions: []FSMTransition{{NO_SERVER, "Client registers"}}},
- NO_SERVER: FSMState{
- Transitions: []FSMTransition{
- {NO_SERVER, "Reload list"},
- {CHOSEN_SERVER, "User chooses a server"},
- {SEARCH_SERVER, "The user is trying to choose a Server in the UI"},
- {CONNECTED, "The user is already connected"},
- {ASK_LOCATION, "Change the location in the main screen"},
- },
- },
- SEARCH_SERVER: FSMState{
- Transitions: []FSMTransition{
- {LOADING_SERVER, "User clicks a server in the UI"},
- {NO_SERVER, "Cancel or Error"},
- },
- BackState: NO_SERVER,
- },
- ASK_LOCATION: FSMState{
- Transitions: []FSMTransition{
- {CHOSEN_SERVER, "Location chosen"},
- {NO_SERVER, "Go back or Error"},
- {SEARCH_SERVER, "Cancel or Error"},
- },
- },
- LOADING_SERVER: FSMState{
- Transitions: []FSMTransition{
- {CHOSEN_SERVER, "Server info loaded"},
- {
- ASK_LOCATION,
- "User chooses a Secure Internet server but no location is configured",
- },
- {NO_SERVER, "Go back or Error"},
- },
- BackState: NO_SERVER,
- },
- CHOSEN_SERVER: FSMState{
- Transitions: []FSMTransition{
- {AUTHORIZED, "Found tokens in config"},
- {OAUTH_STARTED, "No tokens found in config"},
- },
- },
- OAUTH_STARTED: FSMState{
- Transitions: []FSMTransition{
- {AUTHORIZED, "User authorizes with browser"},
- {NO_SERVER, "Cancel or Error"},
- {SEARCH_SERVER, "Cancel or Error"},
- },
- BackState: NO_SERVER,
- },
- AUTHORIZED: FSMState{
- Transitions: []FSMTransition{
- {OAUTH_STARTED, "Re-authorize with OAuth"},
- {REQUEST_CONFIG, "Client requests a config"},
- },
- },
- REQUEST_CONFIG: FSMState{
- Transitions: []FSMTransition{
- {ASK_PROFILE, "Multiple profiles found and no profile chosen"},
- {DISCONNECTED, "Only one profile or profile already chosen"},
- {NO_SERVER, "Cancel or Error"},
- {OAUTH_STARTED, "Re-authorize"},
- },
- },
- ASK_PROFILE: FSMState{
- Transitions: []FSMTransition{
- {DISCONNECTED, "User chooses profile"},
- {NO_SERVER, "Cancel or Error"},
- {SEARCH_SERVER, "Cancel or Error"},
- },
- },
- DISCONNECTED: FSMState{
- Transitions: []FSMTransition{
- {CONNECTING, "OS reports it is trying to connect"},
- {REQUEST_CONFIG, "User reconnects"},
- {NO_SERVER, "User wants to choose a new server"},
- {OAUTH_STARTED, "Re-authorize with OAuth"},
- },
- BackState: NO_SERVER,
- },
- DISCONNECTING: FSMState{
- Transitions: []FSMTransition{
- {DISCONNECTED, "Cancel or Error"},
- {DISCONNECTED, "Done disconnecting"},
- },
- },
- CONNECTING: FSMState{
- Transitions: []FSMTransition{
- {DISCONNECTED, "Cancel or Error"},
- {CONNECTED, "Done connecting"},
- },
- },
- CONNECTED: FSMState{
- Transitions: []FSMTransition{{DISCONNECTING, "App wants to disconnect"}},
- },
- }
- fsm.Current = DEREGISTERED
+ fsm.States = states
+ fsm.Current = current
fsm.Name = name
fsm.StateCallback = callback
fsm.Directory = directory
+ fsm.GetName = nameGen
fsm.Debug = debug
}
@@ -317,59 +145,21 @@ func (fsm *FSM) generateMermaidGraph() string {
transitions := fsm.States[state].Transitions
for _, transition := range transitions {
if state == fsm.Current {
- graph += "\nstyle " + state.String() + " fill:cyan\n"
+ graph += "\nstyle " + fsm.GetName(state) + " fill:cyan\n"
} else {
- graph += "\nstyle " + state.String() + " fill:white\n"
+ graph += "\nstyle " + fsm.GetName(state) + " fill:white\n"
}
- graph += state.String() + "(" + state.String() + ") " + "-->|" + transition.Description + "| " + transition.To.String() + "\n"
+ graph += fsm.GetName(state) + "(" + fsm.GetName(state) + ") " + "-->|" + transition.Description + "| " + fsm.GetName(transition.To) + "\n"
}
}
return graph
}
func (fsm *FSM) GenerateGraph() string {
- return fsm.generateMermaidGraph()
-}
-
-type DeregisteredError struct{}
-
-func (e DeregisteredError) CustomError() *types.WrappedErrorMessage {
- return &types.WrappedErrorMessage{
- Message: "Client not registered with the GO library",
- Err: errors.New(
- "the current FSM state is deregistered, but the function needs a state that is not deregistered",
- ),
+ if fsm.GetName != nil {
+ return fsm.generateMermaidGraph()
}
-}
-
-type WrongStateTransitionError struct {
- Got FSMStateID
- Want FSMStateID
-}
-
-func (e WrongStateTransitionError) CustomError() *types.WrappedErrorMessage {
- return &types.WrappedErrorMessage{
- Message: "Wrong FSM transition",
- Err: errors.New(
- fmt.Sprintf(
- "wrong FSM state, got: %s, want: a state with a transition to: %s",
- e.Got.String(),
- e.Want.String(),
- ),
- ),
- }
-}
-type WrongStateError struct {
- Got FSMStateID
- Want FSMStateID
+ return ""
}
-func (e WrongStateError) CustomError() *types.WrappedErrorMessage {
- return &types.WrappedErrorMessage{
- Message: "Wrong FSM State",
- Err: errors.New(
- fmt.Sprintf("wrong FSM state, got: %s, want: %s", e.Got.String(), e.Want.String()),
- ),
- }
-}
diff --git a/state.go b/state.go
index 7f2691a..d77d1b6 100644
--- a/state.go
+++ b/state.go
@@ -15,7 +15,6 @@ import (
)
type ServerInfo = server.ServerInfoScreen
-type StateID = fsm.FSMStateID
type VPNState struct {
// The chosen server
@@ -44,14 +43,14 @@ func (state *VPNState) GetSavedServers() *server.ServersConfiguredScreen {
func (state *VPNState) Register(
name string,
directory string,
- stateCallback func(StateID, StateID, interface{}),
+ stateCallback func(FSMStateID, FSMStateID, interface{}),
debug bool,
) error {
errorMessage := "failed to register with the GO library"
- if !state.InFSMState(fsm.DEREGISTERED) {
+ if !state.InFSMState(STATE_DEREGISTERED) {
return &types.WrappedErrorMessage{
Message: errorMessage,
- Err: fsm.DeregisteredError{}.CustomError(),
+ Err: FSMDeregisteredError{}.CustomError(),
}
}
// Initialize the logger
@@ -67,7 +66,7 @@ func (state *VPNState) Register(
}
// Initialize the FSM
- state.FSM.Init(name, stateCallback, directory, debug)
+ state.FSM = newFSM(name, stateCallback, directory, debug)
state.Debug = debug
// Initialize the Config
@@ -95,7 +94,7 @@ func (state *VPNState) Register(
return &types.WrappedErrorMessage{Message: errorMessage, Err: discoOrgsErr}
}
// Go to the No Server state with the saved servers
- state.FSM.GoTransitionWithData(fsm.NO_SERVER, state.GetSavedServers(), true)
+ state.FSM.GoTransitionWithData(STATE_NO_SERVER, state.GetSavedServers(), true)
return nil
}
@@ -113,21 +112,21 @@ func (state *VPNState) Deregister() error {
func (state *VPNState) GoBack() error {
errorMessage := "failed to go back"
- if state.InFSMState(fsm.DEREGISTERED) {
+ if state.InFSMState(STATE_DEREGISTERED) {
return &types.WrappedErrorMessage{
Message: errorMessage,
- Err: fsm.DeregisteredError{}.CustomError(),
+ Err: FSMDeregisteredError{}.CustomError(),
}
}
// FIXME: Abitrary back transitions don't work because we need the approriate data
- state.FSM.GoTransitionWithData(fsm.NO_SERVER, state.GetSavedServers(), false)
+ state.FSM.GoTransitionWithData(STATE_NO_SERVER, state.GetSavedServers(), false)
// state.FSM.GoBack()
return nil
}
func (state *VPNState) doAuth(authURL string) error {
- state.FSM.GoTransitionWithData(fsm.OAUTH_STARTED, authURL, true)
+ state.FSM.GoTransitionWithData(STATE_OAUTH_STARTED, authURL, true)
return nil
}
@@ -145,7 +144,7 @@ func (state *VPNState) ensureLogin(chosenServer server.Server) error {
}
}
// OAuth was valid, ensure we are in the authorized state
- state.FSM.GoTransition(fsm.AUTHORIZED)
+ state.FSM.GoTransition(STATE_AUTHORIZED)
return nil
}
@@ -154,7 +153,7 @@ func (state *VPNState) getConfigAuth(chosenServer server.Server, forceTCP bool)
if loginErr != nil {
return "", "", loginErr
}
- state.FSM.GoTransition(fsm.REQUEST_CONFIG)
+ state.FSM.GoTransition(STATE_REQUEST_CONFIG)
validProfile, profileErr := server.HasValidProfile(chosenServer)
if profileErr != nil {
@@ -198,10 +197,10 @@ func (state *VPNState) getConfig(
forceTCP bool,
) (string, string, error) {
errorMessage := "failed to get a configuration for OpenVPN/Wireguard"
- if state.InFSMState(fsm.DEREGISTERED) {
+ if state.InFSMState(STATE_DEREGISTERED) {
return "", "", &types.WrappedErrorMessage{
Message: errorMessage,
- Err: fsm.DeregisteredError{}.CustomError(),
+ Err: FSMDeregisteredError{}.CustomError(),
}
}
@@ -214,7 +213,7 @@ func (state *VPNState) getConfig(
}
// Signal the server display info
- state.FSM.GoTransitionWithData(fsm.DISCONNECTED, state.getServerInfoData(), false)
+ state.FSM.GoTransitionWithData(STATE_DISCONNECTED, state.getServerInfoData(), false)
// Save the config
state.Config.Save(&state)
@@ -243,7 +242,7 @@ func (state *VPNState) askProfile(chosenServer server.Server) error {
if baseErr != nil {
return &types.WrappedErrorMessage{Message: "failed asking for profiles", Err: baseErr}
}
- state.FSM.GoTransitionWithData(fsm.ASK_PROFILE, &base.Profiles, false)
+ state.FSM.GoTransitionWithData(STATE_ASK_PROFILE, &base.Profiles, false)
return nil
}
@@ -251,10 +250,10 @@ func (state *VPNState) askSecureLocation() error {
locations := state.Discovery.GetSecureLocationList()
// Ask for the location in the callback
- state.FSM.GoTransitionWithData(fsm.ASK_LOCATION, locations, false)
+ state.FSM.GoTransitionWithData(STATE_ASK_LOCATION, locations, false)
// The state has changed, meaning setting the secure location was not successful
- if state.FSM.Current != fsm.ASK_LOCATION {
+ if state.FSM.Current != STATE_ASK_LOCATION {
// TODO: maybe a custom type for this errors.new?
return &types.WrappedErrorMessage{Message: "failed setting secure location", Err: errors.New("failed setting secure location due to state change")}
}
@@ -296,45 +295,45 @@ func (state *VPNState) addSecureInternetHomeServer(orgID string) (server.Server,
}
func (state *VPNState) RemoveSecureInternet() error {
- if state.InFSMState(fsm.DEREGISTERED) {
+ if state.InFSMState(STATE_DEREGISTERED) {
return &types.WrappedErrorMessage{
Message: "failed to remove Secure Internet",
- Err: fsm.DeregisteredError{}.CustomError(),
+ Err: FSMDeregisteredError{}.CustomError(),
}
}
// No error because we can only have one secure internet server and if there are no secure internet servers, this is a NO-OP
state.Servers.RemoveSecureInternet()
- state.FSM.GoTransitionWithData(fsm.NO_SERVER, state.GetSavedServers(), false)
+ state.FSM.GoTransitionWithData(STATE_NO_SERVER, state.GetSavedServers(), false)
// Save the config
state.Config.Save(&state)
return nil
}
func (state *VPNState) RemoveInstituteAccess(url string) error {
- if state.InFSMState(fsm.DEREGISTERED) {
+ if state.InFSMState(STATE_DEREGISTERED) {
return &types.WrappedErrorMessage{
Message: "failed to remove Institute Access",
- Err: fsm.DeregisteredError{}.CustomError(),
+ Err: FSMDeregisteredError{}.CustomError(),
}
}
// No error because this is a NO-OP if the server doesn't exist
state.Servers.RemoveInstituteAccess(url)
- state.FSM.GoTransitionWithData(fsm.NO_SERVER, state.GetSavedServers(), false)
+ state.FSM.GoTransitionWithData(STATE_NO_SERVER, state.GetSavedServers(), false)
// Save the config
state.Config.Save(&state)
return nil
}
func (state *VPNState) RemoveCustomServer(url string) error {
- if state.InFSMState(fsm.DEREGISTERED) {
+ if state.InFSMState(STATE_DEREGISTERED) {
return &types.WrappedErrorMessage{
Message: "failed to remove Custom Server",
- Err: fsm.DeregisteredError{}.CustomError(),
+ Err: FSMDeregisteredError{}.CustomError(),
}
}
// No error because this is a NO-OP if the server doesn't exist
state.Servers.RemoveCustomServer(url)
- state.FSM.GoTransitionWithData(fsm.NO_SERVER, state.GetSavedServers(), false)
+ state.FSM.GoTransitionWithData(STATE_NO_SERVER, state.GetSavedServers(), false)
// Save the config
state.Config.Save(&state)
return nil
@@ -348,7 +347,7 @@ func (state *VPNState) GetConfigSecureInternet(
"failed getting a configuration for Secure Internet organization %s",
orgID,
)
- state.FSM.GoTransition(fsm.LOADING_SERVER)
+ state.FSM.GoTransition(STATE_LOADING_SERVER)
server, serverErr := state.addSecureInternetHomeServer(orgID)
if serverErr != nil {
@@ -356,7 +355,7 @@ func (state *VPNState) GetConfigSecureInternet(
return "", "", &types.WrappedErrorMessage{Message: errorMessage, Err: serverErr}
}
- state.FSM.GoTransition(fsm.CHOSEN_SERVER)
+ state.FSM.GoTransition(STATE_CHOSEN_SERVER)
return state.getConfig(server, forceTCP)
}
@@ -374,7 +373,7 @@ func (state *VPNState) addInstituteServer(url string) (server.Server, error) {
return nil, &types.WrappedErrorMessage{Message: errorMessage, Err: serverErr}
}
- state.FSM.GoTransition(fsm.CHOSEN_SERVER)
+ state.FSM.GoTransition(STATE_CHOSEN_SERVER)
return server, nil
}
@@ -402,14 +401,14 @@ func (state *VPNState) addCustomServer(url string) (server.Server, error) {
return nil, &types.WrappedErrorMessage{Message: errorMessage, Err: serverErr}
}
- state.FSM.GoTransition(fsm.CHOSEN_SERVER)
+ state.FSM.GoTransition(STATE_CHOSEN_SERVER)
return server, nil
}
func (state *VPNState) GetConfigInstituteAccess(url string, forceTCP bool) (string, string, error) {
errorMessage := fmt.Sprintf("failed getting a configuration for Institute Access %s", url)
- state.FSM.GoTransition(fsm.LOADING_SERVER)
+ state.FSM.GoTransition(STATE_LOADING_SERVER)
server, serverErr := state.addInstituteServer(url)
if serverErr != nil {
@@ -422,7 +421,7 @@ func (state *VPNState) GetConfigInstituteAccess(url string, forceTCP bool) (stri
func (state *VPNState) GetConfigCustomServer(url string, forceTCP bool) (string, string, error) {
errorMessage := fmt.Sprintf("failed getting a configuration for custom server %s", url)
- state.FSM.GoTransition(fsm.LOADING_SERVER)
+ state.FSM.GoTransition(STATE_LOADING_SERVER)
server, serverErr := state.addCustomServer(url)
if serverErr != nil {
@@ -436,12 +435,12 @@ func (state *VPNState) GetConfigCustomServer(url string, forceTCP bool) (string,
func (state *VPNState) CancelOAuth() error {
errorMessage := "failed to cancel OAuth"
- if !state.InFSMState(fsm.OAUTH_STARTED) {
+ if !state.InFSMState(STATE_OAUTH_STARTED) {
return &types.WrappedErrorMessage{
Message: errorMessage,
- Err: fsm.WrongStateError{
+ Err: FSMWrongStateError{
Got: state.FSM.Current,
- Want: fsm.OAUTH_STARTED,
+ Want: STATE_OAUTH_STARTED,
}.CustomError(),
}
}
@@ -458,10 +457,10 @@ func (state *VPNState) CancelOAuth() error {
func (state *VPNState) ChangeSecureLocation() error {
errorMessage := "failed to change location from the main screen"
- if !state.InFSMState(fsm.NO_SERVER) {
+ if !state.InFSMState(STATE_NO_SERVER) {
return &types.WrappedErrorMessage{
Message: errorMessage,
- Err: fsm.WrongStateError{Got: state.FSM.Current, Want: fsm.NO_SERVER}.CustomError(),
+ Err: FSMWrongStateError{Got: state.FSM.Current, Want: STATE_NO_SERVER}.CustomError(),
}
}
@@ -472,7 +471,7 @@ func (state *VPNState) ChangeSecureLocation() error {
}
// Go back to the main screen
- state.FSM.GoTransitionWithData(fsm.NO_SERVER, state.GetSavedServers(), false)
+ state.FSM.GoTransitionWithData(STATE_NO_SERVER, state.GetSavedServers(), false)
return nil
}
@@ -502,17 +501,17 @@ func (state *VPNState) SetProfileID(profileID string) error {
}
func (state *VPNState) SetSearchServer() error {
- if !state.FSM.HasTransition(fsm.SEARCH_SERVER) {
+ if !state.FSM.HasTransition(STATE_SEARCH_SERVER) {
return &types.WrappedErrorMessage{
Message: "failed to set search server",
- Err: fsm.WrongStateTransitionError{
+ Err: FSMWrongStateTransitionError{
Got: state.FSM.Current,
- Want: fsm.CONNECTED,
+ Want: STATE_CONNECTED,
}.CustomError(),
}
}
- state.FSM.GoTransition(fsm.SEARCH_SERVER)
+ state.FSM.GoTransition(STATE_SEARCH_SERVER)
return nil
}
@@ -523,74 +522,74 @@ func (state *VPNState) getServerInfoData() *server.ServerInfoScreen {
}
func (state *VPNState) SetConnected() error {
- if state.InFSMState(fsm.CONNECTED) {
+ if state.InFSMState(STATE_CONNECTED) {
// already connected, show no error
return nil
}
- if !state.FSM.HasTransition(fsm.CONNECTED) {
+ if !state.FSM.HasTransition(STATE_CONNECTED) {
return &types.WrappedErrorMessage{
Message: "failed to set connected",
- Err: fsm.WrongStateTransitionError{
+ Err: FSMWrongStateTransitionError{
Got: state.FSM.Current,
- Want: fsm.CONNECTED,
+ Want: STATE_CONNECTED,
}.CustomError(),
}
}
- state.FSM.GoTransitionWithData(fsm.CONNECTED, state.getServerInfoData(), false)
+ state.FSM.GoTransitionWithData(STATE_CONNECTED, state.getServerInfoData(), false)
return nil
}
func (state *VPNState) SetConnecting() error {
- if state.InFSMState(fsm.CONNECTING) {
+ if state.InFSMState(STATE_CONNECTING) {
// already loading connection, show no error
return nil
}
- if !state.FSM.HasTransition(fsm.CONNECTING) {
+ if !state.FSM.HasTransition(STATE_CONNECTING) {
return &types.WrappedErrorMessage{
Message: "failed to set connecting",
- Err: fsm.WrongStateTransitionError{
+ Err: FSMWrongStateTransitionError{
Got: state.FSM.Current,
- Want: fsm.CONNECTING,
+ Want: STATE_CONNECTING,
}.CustomError(),
}
}
- state.FSM.GoTransition(fsm.CONNECTING)
+ state.FSM.GoTransition(STATE_CONNECTING)
return nil
}
func (state *VPNState) SetDisconnecting() error {
- if state.InFSMState(fsm.DISCONNECTING) {
+ if state.InFSMState(STATE_DISCONNECTING) {
// already disconnecting, show no error
return nil
}
- if !state.FSM.HasTransition(fsm.DISCONNECTING) {
+ if !state.FSM.HasTransition(STATE_DISCONNECTING) {
return &types.WrappedErrorMessage{
Message: "failed to set disconnecting",
- Err: fsm.WrongStateTransitionError{
+ Err: FSMWrongStateTransitionError{
Got: state.FSM.Current,
- Want: fsm.DISCONNECTING,
+ Want: STATE_DISCONNECTING,
}.CustomError(),
}
}
- state.FSM.GoTransitionWithData(fsm.DISCONNECTING, state.getServerInfoData(), false)
+ state.FSM.GoTransitionWithData(STATE_DISCONNECTING, state.getServerInfoData(), false)
return nil
}
func (state *VPNState) SetDisconnected(cleanup bool) error {
errorMessage := "failed to set disconnected"
- if state.InFSMState(fsm.DISCONNECTED) {
+ if state.InFSMState(STATE_DISCONNECTED) {
// already disconnected, show no error
return nil
}
- if !state.FSM.HasTransition(fsm.DISCONNECTED) {
+ if !state.FSM.HasTransition(STATE_DISCONNECTED) {
return &types.WrappedErrorMessage{
Message: errorMessage,
- Err: fsm.WrongStateTransitionError{
+ Err: FSMWrongStateTransitionError{
Got: state.FSM.Current,
- Want: fsm.DISCONNECTED,
+ Want: STATE_DISCONNECTED,
}.CustomError(),
}
}
@@ -605,7 +604,7 @@ func (state *VPNState) SetDisconnected(cleanup bool) error {
server.Disconnect(currentServer)
}
- state.FSM.GoTransitionWithData(fsm.DISCONNECTED, state.getServerInfoData(), false)
+ state.FSM.GoTransitionWithData(STATE_DISCONNECTED, state.getServerInfoData(), false)
return nil
}
@@ -630,7 +629,7 @@ func (state *VPNState) RenewSession() error {
}
func (state *VPNState) ShouldRenewButton() bool {
- if !state.InFSMState(fsm.CONNECTED) && !state.InFSMState(fsm.CONNECTING) && !state.InFSMState(fsm.DISCONNECTED) && !state.InFSMState(fsm.DISCONNECTING) {
+ if !state.InFSMState(STATE_CONNECTED) && !state.InFSMState(STATE_CONNECTING) && !state.InFSMState(STATE_DISCONNECTED) && !state.InFSMState(STATE_DISCONNECTING) {
return false
}
@@ -650,7 +649,7 @@ func (state *VPNState) ShouldRenewButton() bool {
return server.ShouldRenewButton(currentServer)
}
-func (state *VPNState) InFSMState(checkState StateID) bool {
+func (state *VPNState) InFSMState(checkState FSMStateID) bool {
return state.FSM.InState(checkState)
}
diff --git a/state_test.go b/state_test.go
index 2106f40..b87b1ef 100644
--- a/state_test.go
+++ b/state_test.go
@@ -11,7 +11,6 @@ import (
"testing"
"time"
- "github.com/jwijenbergh/eduvpn-common/internal/fsm"
httpw "github.com/jwijenbergh/eduvpn-common/internal/http"
"github.com/jwijenbergh/eduvpn-common/internal/oauth"
"github.com/jwijenbergh/eduvpn-common/internal/server"
@@ -63,12 +62,12 @@ func loginOAuthSelenium(t *testing.T, url string, state *VPNState) {
func stateCallback(
t *testing.T,
- oldState StateID,
- newState StateID,
+ oldState FSMStateID,
+ newState FSMStateID,
data interface{},
state *VPNState,
) {
- if newState == fsm.OAUTH_STARTED {
+ if newState == STATE_OAUTH_STARTED {
url, ok := data.(string)
if !ok {
@@ -86,7 +85,7 @@ func Test_server(t *testing.T) {
state.Register(
"org.eduvpn.app.linux",
"configstest",
- func(old StateID, new StateID, data interface{}) {
+ func(old FSMStateID, new FSMStateID, data interface{}) {
stateCallback(t, old, new, data, state)
},
false,
@@ -111,8 +110,8 @@ func test_connect_oauth_parameter(
state.Register(
"org.eduvpn.app.linux",
configDirectory,
- func(oldState StateID, newState StateID, data interface{}) {
- if newState == fsm.OAUTH_STARTED {
+ func(oldState FSMStateID, newState FSMStateID, data interface{}) {
+ if newState == STATE_OAUTH_STARTED {
baseURL := "http://127.0.0.1:8000/callback"
url, err := httpw.HTTPConstructURL(baseURL, parameters)
if err != nil {
@@ -190,7 +189,7 @@ func Test_token_expired(t *testing.T) {
state.Register(
"org.eduvpn.app.linux",
"configsexpired",
- func(old StateID, new StateID, data interface{}) {
+ func(old FSMStateID, new FSMStateID, data interface{}) {
stateCallback(t, old, new, data, state)
},
false,
@@ -243,7 +242,7 @@ func Test_token_invalid(t *testing.T) {
state.Register(
"org.eduvpn.app.linux",
"configsinvalid",
- func(old StateID, new StateID, data interface{}) {
+ func(old FSMStateID, new FSMStateID, data interface{}) {
stateCallback(t, old, new, data, state)
},
false,
@@ -293,7 +292,7 @@ func Test_invalid_profile_corrected(t *testing.T) {
state.Register(
"org.eduvpn.app.linux",
"configscancelprofile",
- func(old StateID, new StateID, data interface{}) {
+ func(old FSMStateID, new FSMStateID, data interface{}) {
stateCallback(t, old, new, data, state)
},
false,