summaryrefslogtreecommitdiff
path: root/state.go
diff options
context:
space:
mode:
Diffstat (limited to 'state.go')
-rw-r--r--state.go143
1 files changed, 143 insertions, 0 deletions
diff --git a/state.go b/state.go
new file mode 100644
index 0000000..bafdfb9
--- /dev/null
+++ b/state.go
@@ -0,0 +1,143 @@
+package eduvpn
+
+import (
+ "errors"
+ "github.com/jwijenbergh/eduvpn-common/internal"
+)
+
+type VPNState struct {
+ // The chosen server
+ Servers internal.Servers `json:"servers"`
+
+ // The list of servers and organizations from disco
+ Discovery internal.Discovery `json:"-"`
+
+ // The fsm
+ FSM internal.FSM `json:"-"`
+
+ // The logger
+ Logger internal.FileLogger `json:"-"`
+
+ // The config
+ Config internal.Config `json:"-"`
+
+ // Whether to enable debugging
+ Debug bool `json:"-"`
+}
+
+var VPNStateInstance *VPNState
+
+func GetVPNState() *VPNState {
+ if VPNStateInstance == nil {
+ VPNStateInstance = &VPNState{}
+ }
+ return VPNStateInstance
+}
+
+func (state *VPNState) Register(name string, directory string, stateCallback func(string, string, string), debug bool) error {
+ if !state.FSM.InState(internal.DEREGISTERED) {
+ return errors.New("app already registered")
+ }
+ // Initialize the logger
+ logLevel := internal.LOG_WARNING
+
+ if debug {
+ logLevel = internal.LOG_INFO
+ }
+
+ loggerErr := state.Logger.Init(logLevel, name, directory)
+ if loggerErr != nil {
+ return errors.New("Failed to create a logger")
+ }
+
+ // Initialize the FSM
+ state.FSM.Init(stateCallback, &state.Logger, debug)
+ state.Debug = debug
+
+ // Initialize the Config
+ state.Config.Init(name, directory)
+
+ // Initialize Discovery
+ state.Discovery.Init(&state.FSM, &state.Logger)
+
+ // Try to load the previous configuration
+ if state.Config.Load(&state) != nil {
+ // This error can be safely ignored, as when the config does not load, the struct will not be filled
+ state.Logger.Log(internal.LOG_INFO, "Previous configuration not found")
+ }
+ state.FSM.GoTransition(internal.NO_SERVER)
+ return nil
+}
+
+func (state *VPNState) Deregister() error {
+ // Close the log file
+ state.Logger.Close()
+
+ // Save the config
+ state.Config.Save(&state)
+
+ // Empty out fsm
+ state.FSM = internal.FSM{}
+ return nil
+}
+
+func (state *VPNState) Connect(url string) (string, error) {
+ if state.FSM.InState(internal.DEREGISTERED) {
+ return "", errors.New("app not registered")
+ }
+ // New server chosen, ensure the server is fresh
+ server := state.Servers.EnsureServer(url, &state.FSM, &state.Logger)
+ // Make sure we are in the chosen state if available
+ state.FSM.GoTransition(internal.CHOSEN_SERVER)
+ // Relogin with oauth
+ // This moves the state to authenticated
+ if server.NeedsRelogin() {
+ loginErr := server.Login()
+
+ if loginErr != nil {
+ return "", loginErr
+ }
+ } else { // OAuth was valid, ensure we are in the authenticated state
+ state.FSM.GoTransition(internal.AUTHENTICATED)
+ }
+
+ state.FSM.GoTransition(internal.REQUEST_CONFIG)
+
+ config, configErr := server.GetConfig()
+
+ if configErr != nil {
+ return "", configErr
+ } else {
+ state.FSM.GoTransition(internal.HAS_CONFIG)
+ }
+
+ return config, nil
+}
+
+func (state *VPNState) GetDiscoOrganizations() (string, error) {
+ if state.FSM.InState(internal.DEREGISTERED) {
+ return "", errors.New("app not registered")
+ }
+ return state.Discovery.GetOrganizationsList()
+}
+
+
+func (state *VPNState) GetDiscoServers() (string, error) {
+ if state.FSM.InState(internal.DEREGISTERED) {
+ return "", errors.New("app not registered")
+ }
+ return state.Discovery.GetServersList()
+}
+
+func (state *VPNState) SetProfileID(profileID string) error {
+ if !state.FSM.InState(internal.ASK_PROFILE) {
+ return errors.New("Invalid state for setting a profile")
+ }
+
+ server, serverErr := state.Servers.GetCurrentServer()
+ if serverErr != nil {
+ return errors.New("No server found for setting a profile ID")
+ }
+ server.Profiles.Current = profileID
+ return nil
+}