diff options
| author | jwijenbergh <jeroenwijenbergh@protonmail.com> | 2022-04-22 16:29:59 +0200 |
|---|---|---|
| committer | jwijenbergh <jeroenwijenbergh@protonmail.com> | 2022-04-22 16:29:59 +0200 |
| commit | b1d92b395322f2164ccfb44b0f7caebbaece6b62 (patch) | |
| tree | 2133e4045b4af4d07a98674b7ae3a234670f0305 /src/discovery.go | |
| parent | 3a4ae2942b43923ff98fd2eca8878c3cf145686c (diff) | |
Refactor: Restructure project
- Add an internal folder where all the internal code lives
- Make a state.go and state_test.go for the public interface
This gives a more clear separation between functions and modules. It
also makes this a more typical Go project setup.
Diffstat (limited to 'src/discovery.go')
| -rw-r--r-- | src/discovery.go | 165 |
1 files changed, 0 insertions, 165 deletions
diff --git a/src/discovery.go b/src/discovery.go deleted file mode 100644 index fa3cac6..0000000 --- a/src/discovery.go +++ /dev/null @@ -1,165 +0,0 @@ -package eduvpn - -import ( - "encoding/json" - "fmt" -) - -type DiscoFileError struct { - URL string - Err error -} - -func (e *DiscoFileError) Error() string { - return fmt.Sprintf("failed obtaining disco file %s with error %v", e.URL, e.Err) -} - -type DiscoSigFileError struct { - URL string - Err error -} - -func (e *DiscoSigFileError) Error() string { - return fmt.Sprintf("failed obtaining disco signature file %s with error %v", e.URL, e.Err) -} - -type DiscoVerifyError struct { - File string - Sigfile string - Err error -} - -func (e *DiscoVerifyError) Error() string { - return fmt.Sprintf("failed verifying file %s with signature %s due to error %v", e.File, e.Sigfile, e.Err) -} - -type DiscoJSONError struct { - Body string - Err error -} - -func (e *DiscoJSONError) Error() string { - return fmt.Sprintf("failed parsing JSON for contents %s with error %v", e.Body, e.Err) -} - -type OrganizationList struct { - JSON json.RawMessage `json:"organization_list"` - Version uint64 `json:"v"` - Timestamp int64 `json:"-"` -} - -type ServersList struct { - JSON json.RawMessage `json:"server_list"` - Version uint64 `json:"v"` - Timestamp int64 `json:"-"` -} - -type DiscoLists struct { - Organizations OrganizationList - Servers ServersList -} - -// Helper function that gets a disco json -func getDiscoFile(jsonFile string, previousVersion uint64, structure interface{}) error { - // Get json data - discoURL := "https://disco.eduvpn.org/v2/" - fileURL := discoURL + jsonFile - _, fileBody, fileErr := HTTPGet(fileURL) - - if fileErr != nil { - return &DiscoFileError{fileURL, fileErr} - } - - // Get signature - sigFile := jsonFile + ".minisig" - sigURL := discoURL + sigFile - _, sigBody, sigFileErr := HTTPGet(sigURL) - - if sigFileErr != nil { - return &DiscoSigFileError{URL: sigURL, Err: sigFileErr} - } - - // Verify signature - // Set this to true when we want to force prehash - forcePrehash := false - verifySuccess, verifyErr := Verify(string(sigBody), fileBody, jsonFile, previousVersion, forcePrehash) - - if !verifySuccess || verifyErr != nil { - return &DiscoVerifyError{File: jsonFile, Sigfile: sigFile, Err: verifyErr} - } - - // Parse JSON to extract version and list - jsonErr := json.Unmarshal(fileBody, structure) - - if jsonErr != nil { - return &DiscoJSONError{Body: string(fileBody), Err: jsonErr} - } - - return nil -} - -type GetListError struct { - File string - Err error -} - -func (e *GetListError) Error() string { - return fmt.Sprintf("failed getting disco list file %s with error %v", e.File, e.Err) -} - -// FIXME: Implement based on -// https://github.com/eduvpn/documentation/blob/v3/SERVER_DISCOVERY.md -// - [IMPLEMENTED] on "first launch" when offering the search for "Institute Access" and "Organizations"; -// - [TODO] when the user tries to add new server AND the user did NOT yet choose an organization before; -// - [TODO] when the authorization for the server associated with an already chosen organization is triggered, e.g. after expiry or revocation. -func (eduvpn *VPNState) DetermineOrganizationsUpdate() bool { - return string(eduvpn.DiscoList.Organizations.JSON) == "" -} - -// https://github.com/eduvpn/documentation/blob/v3/SERVER_DISCOVERY.md -// - [Implemented] The application MUST always fetch the server_list.json at application start. -// - The application MAY refresh the server_list.json periodically, e.g. once every hour. -func (eduvpn *VPNState) DetermineServersUpdate() bool { - // No servers, we should update - if string(eduvpn.DiscoList.Servers.JSON) == "" { - return true - } - // 1 hour from the last update - should_update_time := eduvpn.DiscoList.Servers.Timestamp + 3600 - now := GenerateTimeSeconds() - if now >= should_update_time { - return true - } - GetVPNState().Log(LOG_INFO, "No update needed for servers, 1h is not passed yet") - return false -} - -// Get the organization list -func (eduvpn *VPNState) GetOrganizationsList() (string, error) { - if !eduvpn.DetermineOrganizationsUpdate() { - return string(eduvpn.DiscoList.Organizations.JSON), nil - } - file := "organization_list.json" - err := getDiscoFile(file, eduvpn.DiscoList.Organizations.Version, &eduvpn.DiscoList.Organizations) - if err != nil { - // Return previous with an error - return string(eduvpn.DiscoList.Organizations.JSON), &GetListError{File: file, Err: err} - } - return string(eduvpn.DiscoList.Organizations.JSON), nil -} - -// Get the server list -func (eduvpn *VPNState) GetServersList() (string, error) { - if !eduvpn.DetermineServersUpdate() { - return string(eduvpn.DiscoList.Servers.JSON), nil - } - file := "server_list.json" - err := getDiscoFile(file, eduvpn.DiscoList.Servers.Version, &eduvpn.DiscoList.Servers) - if err != nil { - // Return previous with an error - return string(eduvpn.DiscoList.Servers.JSON), &GetListError{File: file, Err: err} - } - // Update servers timestamp - eduvpn.DiscoList.Servers.Timestamp = GenerateTimeSeconds() - return string(eduvpn.DiscoList.Servers.JSON), nil -} |
