diff options
| -rw-r--r-- | exports/exports.go | 11 | ||||
| -rw-r--r-- | internal/discovery/discovery.go | 11 | ||||
| -rw-r--r-- | internal/fsm/fsm.go | 8 | ||||
| -rw-r--r-- | state.go | 16 | ||||
| -rw-r--r-- | wrappers/python/main.py | 11 | ||||
| -rw-r--r-- | wrappers/python/src/__init__.py | 1 | ||||
| -rw-r--r-- | wrappers/python/src/main.py | 30 |
7 files changed, 76 insertions, 12 deletions
diff --git a/exports/exports.go b/exports/exports.go index 6b33da6..2f5c357 100644 --- a/exports/exports.go +++ b/exports/exports.go @@ -176,6 +176,17 @@ func SetProfileID(name *C.char, data *C.char) *C.char { return C.CString(ErrorToString(profileErr)) } +//export SetSecureLocation +func SetSecureLocation(name *C.char, data *C.char) *C.char { + nameStr := C.GoString(name) + state, stateErr := GetVPNState(nameStr) + if stateErr != nil { + return C.CString(ErrorToString(stateErr)) + } + locationErr := state.SetSecureLocation(C.GoString(data)) + return C.CString(ErrorToString(locationErr)) +} + //export GetIdentifier func GetIdentifier(name *C.char) (*C.char, *C.char) { nameStr := C.GoString(name) diff --git a/internal/discovery/discovery.go b/internal/discovery/discovery.go index 2331491..b4163a8 100644 --- a/internal/discovery/discovery.go +++ b/internal/discovery/discovery.go @@ -73,14 +73,21 @@ func (discovery *Discovery) DetermineOrganizationsUpdate() bool { return discovery.Organizations.Timestamp == 0 } -func (discovery *Discovery) GetSecureLocationList() []string { +func (discovery *Discovery) GetSecureLocationList() (string, error) { var locations []string for _, server := range discovery.Servers.List { if server.Type == "secure_internet" { locations = append(locations, server.CountryCode) } } - return locations + + jsonBytes, jsonErr := json.Marshal(locations) + + if jsonErr != nil { + return "", &types.WrappedErrorMessage{Message: "failed getting Secure Internet locations list", Err: jsonErr} + } + + return string(jsonBytes), nil } func (discovery *Discovery) GetServerByURL(url string, _type string) (*types.DiscoveryServer, error) { diff --git a/internal/fsm/fsm.go b/internal/fsm/fsm.go index 2042977..1ba8133 100644 --- a/internal/fsm/fsm.go +++ b/internal/fsm/fsm.go @@ -36,6 +36,9 @@ const ( // 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 @@ -67,6 +70,8 @@ func (s FSMStateID) String() string { return "Deregistered" case NO_SERVER: return "No_Server" + case ASK_LOCATION: + return "Ask_Location" case SEARCH_SERVER: return "Search_Server" case CHOSEN_SERVER: @@ -113,7 +118,8 @@ type FSM struct { func (fsm *FSM) Init(name string, callback func(string, string, string), logger *log.FileLogger, directory string, debug bool) { fsm.States = FSMStates{ DEREGISTERED: {{NO_SERVER, "Client registers"}}, - NO_SERVER: {{CHOSEN_SERVER, "User chooses a server"}, {SEARCH_SERVER, "The user is trying to choose a Server in the UI"}}, + NO_SERVER: {{CHOSEN_SERVER, "User chooses a server"}, {SEARCH_SERVER, "The user is trying to choose a Server in the UI"}, {ASK_LOCATION, "User chooses a Secure Internet server but no location is configured"}}, + ASK_LOCATION: {{CHOSEN_SERVER, "Location chosen"}, {NO_SERVER, "Cancel or Error"}}, SEARCH_SERVER: {{CHOSEN_SERVER, "User clicks a server in the UI"}, {NO_SERVER, "Cancel or Error"}}, CHOSEN_SERVER: {{AUTHORIZED, "Found tokens in config"}, {OAUTH_STARTED, "No tokens found in config"}}, OAUTH_STARTED: {{AUTHORIZED, "User authorizes with browser"}, {NO_SERVER, "Cancel or Error"}}, @@ -133,16 +133,26 @@ func (state *VPNState) getConfig(chosenServer server.Server, forceTCP bool) (str return config, configType, nil } -func (state *VPNState) AskSecureLocation() error { - fmt.Println("locations: ", state.Discovery.GetSecureLocationList()) - server, serverErr := state.Discovery.GetServerByCountryCode("NL", "secure_internet") +func (state *VPNState) SetSecureLocation(countryCode string) error { + server, serverErr := state.Discovery.GetServerByCountryCode(countryCode, "secure_internet") if serverErr != nil { return &types.WrappedErrorMessage{Message: "failed asking secure location", Err: serverErr} } state.Servers.SetSecureLocation(server, &state.FSM, &state.Logger) + return nil +} + +func (state *VPNState) AskSecureLocation() error { + errorMessage := "failed asking Secure Internet location" + locations, locationsErr := state.Discovery.GetSecureLocationList() + if locationsErr != nil { + return &types.WrappedErrorMessage{Message: errorMessage, Err: locationsErr} + } + // Ask for the location in the callback + state.FSM.GoTransitionWithData(fsm.ASK_LOCATION, locations, false) return nil } diff --git a/wrappers/python/main.py b/wrappers/python/main.py index 5422d93..d75504f 100644 --- a/wrappers/python/main.py +++ b/wrappers/python/main.py @@ -1,6 +1,7 @@ import eduvpncommon.main as eduvpn import webbrowser import json +import sys # Asks the user for a profile index # It loops up until a valid input is given @@ -31,6 +32,11 @@ def setup_callbacks(_eduvpn: eduvpn.EduVPN) -> None: print(f"Got OAuth URL {url}, old state: {old_state}") webbrowser.open(url) + @_eduvpn.event.on("Ask_Location", eduvpn.StateType.Enter) + def ask_location(old_state: str, locations: str): + print("Locations: ", locations) + _eduvpn.set_secure_location("NL") + # The callback which asks the user for a profile @_eduvpn.event.on("Ask_Profile", eduvpn.StateType.Enter) def ask_profile(old_state: str, profiles: str): @@ -79,9 +85,12 @@ if __name__ == "__main__": # Get a Wireguard/OpenVPN config try: config, config_type = _eduvpn.get_config_custom_server(server) + print(f"Got a config with type: {config_type} and contents:\n{config}") except Exception as e: print("Failed to connect:", e) - print(f"Got a config with type: {config_type} and contents:\n{config}") + # Save and exit + _eduvpn.deregister() + sys.exit(1) # Set the internal FSM state to connected try: diff --git a/wrappers/python/src/__init__.py b/wrappers/python/src/__init__.py index f2ae66e..22d5406 100644 --- a/wrappers/python/src/__init__.py +++ b/wrappers/python/src/__init__.py @@ -75,6 +75,7 @@ lib.GetOrganizationsList.argtypes, lib.GetOrganizationsList.restype = [ lib.GetServersList.argtypes, lib.GetServersList.restype = [c_char_p], DataError lib.CancelOAuth.argtypes, lib.CancelOAuth.restype = [c_char_p], c_void_p lib.SetProfileID.argtypes, lib.SetProfileID.restype = [c_char_p, c_char_p], c_void_p +lib.SetSecureLocation.argtypes, lib.SetSecureLocation.restype = [c_char_p, c_char_p], c_void_p lib.SetConnected.argtypes, lib.SetConnected.restype = [c_char_p], c_void_p lib.SetDisconnected.argtypes, lib.SetDisconnected.restype = [c_char_p], c_void_p lib.GetIdentifier.argtypes, lib.GetIdentifier.restype = [c_char_p], DataError diff --git a/wrappers/python/src/main.py b/wrappers/python/src/main.py index dda3250..542fc54 100644 --- a/wrappers/python/src/main.py +++ b/wrappers/python/src/main.py @@ -38,12 +38,18 @@ class EduVPN(object): # The ask profile callback needs to wait for the UI thread to select a profile # This is stored in the profile_event self.profile_event: Optional[threading.Event] = None + self.location_event: Optional[threading.Event] = None @self.event.on("Ask_Profile", StateType.Wait) def wait_profile_event(old_state: str, profiles: str): if self.profile_event: self.profile_event.wait() + @self.event.on("Ask_Location", StateType.Wait) + def wait_location_event(old_state: str, locations: str): + if self.location_event: + self.location_event.wait() + def go_function(self, func, *args): # The functions all have at least one arg type which is the name of the client args_gen = encode_args(list(args), func.argtypes[1:]) @@ -102,11 +108,12 @@ class EduVPN(object): func, url, force_tcp ) + self.profile_event = None + self.location_event = None + if config_err: raise Exception(config_err) - self.profile_event = None - return config, config_type def get_config_custom_server( @@ -122,6 +129,7 @@ class EduVPN(object): def get_config_secure_internet( self, url: str, force_tcp: bool = False ) -> Tuple[str, str]: + self.location_event = threading.Event() return self.get_config(url, lib.GetConfigSecureInternet, force_tcp) def set_connected(self) -> None: @@ -173,10 +181,22 @@ class EduVPN(object): # Set the profile id profile_err = self.go_function(lib.SetProfileID, profile_id) - if profile_err: - raise Exception(profile_err) - # If there is a profile event, set it so that the wait callback finishes # And so that the Go code can move to the next state if self.profile_event: self.profile_event.set() + + if profile_err: + raise Exception(profile_err) + + def set_secure_location(self, country_code: str) -> None: + # Set the location by country code + location_err = self.go_function(lib.SetSecureLocation, country_code) + + # If there is a location event, set it so that the wait callback finishes + # And so that the Go code can move to the next state + if self.location_event: + self.location_event.set() + + if location_err: + raise Exception(location_err) |
