summaryrefslogtreecommitdiff
path: root/src/state.go
blob: c0e512fb8124c6e4a1e4e54598dfa86e308b7e01 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package eduvpn

import (
	"errors"
)

type VPNState struct {
	// Info passed by the client
	ConfigDirectory   string                       `json:"-"`
	Name              string                       `json:"-"`
	StateCallback     func(string, string, string) `json:"-"`
	StateCallbackData string                       `json:"-"`

	// The chosen server
	Servers Servers `json:"servers"`

	// The list of servers and organizations from disco
	DiscoList DiscoLists `json:"-"`

	// The file we keep open for logging
	LogFile FileLogger `json:"-"`

	// The fsm
	FSM FSM `json:"-"`

	// Whether to enable debugging
	Debug bool `json:"-"`
}

func (state *VPNState) Register(name string, directory string, stateCallback func(string, string, string), debug bool) error {
	if !state.InState(DEREGISTERED) {
		return errors.New("app already registered")
	}
	state.InitializeFSM()
	state.Name = name
	state.ConfigDirectory = directory
	state.StateCallback = stateCallback
	state.Debug = debug

	LogLevel := LOG_WARNING

	if debug {
		LogLevel = LOG_INFO
	}

	// Initialize the logger
	state.InitLog(LogLevel)

	// Try to load the previous configuration
	if state.LoadConfig() != nil {
		// This error can be safely ignored, as when the config does not load, the struct will not be filled
		state.Log(LOG_INFO, "Previous configuration not found")
	}
	state.GoTransition(NO_SERVER)
	return nil
}

func (state *VPNState) Deregister() error {
	// Close the log file
	state.CloseLog()

	// Write the config
	state.WriteConfig()

	// Re-initialize the servers and FSM
	state.Servers = Servers{}
	state.InitializeFSM()
	return nil
}

func (state *VPNState) Connect(url string) (string, error) {
	// New server chosen, ensure the server is fresh
	server := state.Servers.EnsureServer(url)
	// Make sure we are in the chosen state if available
	state.GoTransition(CHOSEN_SERVER)
	// Relogin with oauth
	// This moves the state to authenticated
	if server.NeedsRelogin() {
		loginErr := state.LoginOAuth()

		if loginErr != nil {
			return "", loginErr
		}
	} else { // OAuth was valid, ensure we are in the authenticated state
		state.GoTransition(AUTHENTICATED)
	}

	state.GoTransition(REQUEST_CONFIG)

	config, configErr := server.GetConfig()

	if configErr != nil {
		return "", configErr
	} else {
		state.GoTransition(HAS_CONFIG)
	}

	return config, nil
}

var VPNStateInstance *VPNState

func GetVPNState() *VPNState {
	if VPNStateInstance == nil {
		VPNStateInstance = &VPNState{}
	}
	return VPNStateInstance
}