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
109
110
111
112
113
114
115
116
|
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
Server *Server `json:"server"`
// The list of servers and organizations from disco
DiscoList *DiscoList `json:"disco"`
// 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 {
state.InitializeFSM()
if !state.InState(DEREGISTERED) {
return errors.New("app already registered")
}
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 {
if state.InState(DEREGISTERED) {
return errors.New("app already deregistered")
}
// Close the log file
state.CloseLog()
// Write the config
state.WriteConfig()
// Re-initialize the server and FSM
state.Server = &Server{}
state.InitializeFSM()
return nil
}
func (state *VPNState) Connect(url string) (string, error) {
if state.Server == nil || state.Server.BaseURL != url {
state.Server = &Server{}
}
initializeErr := state.Server.Initialize(url)
if initializeErr != nil {
return "", initializeErr
}
// Relogin with oauth
// This moves the state to authenticated
if state.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 := state.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
}
|