diff options
| author | jwijenbergh <jeroenwijenbergh@protonmail.com> | 2024-02-12 19:18:05 +0100 |
|---|---|---|
| committer | Jeroen Wijenbergh <46386452+jwijenbergh@users.noreply.github.com> | 2024-02-19 14:15:07 +0100 |
| commit | 74e36f0ead717105f26087c2cab08b41ba5a7ce8 (patch) | |
| tree | 1eb2b7516bea705c9b5a50ce0965e170414ed880 /internal/api | |
| parent | 682d70091af2044ff6d8b350da9dff13163232e2 (diff) | |
All: Document everything to pass revive lint
Diffstat (limited to 'internal/api')
| -rw-r--r-- | internal/api/api.go | 32 | ||||
| -rw-r--r-- | internal/api/endpoints/endpoints.go | 17 | ||||
| -rw-r--r-- | internal/api/profiles/profiles.go | 39 |
3 files changed, 72 insertions, 16 deletions
diff --git a/internal/api/api.go b/internal/api/api.go index a9ea0c0..2268357 100644 --- a/internal/api/api.go +++ b/internal/api/api.go @@ -1,3 +1,4 @@ +// Package api implements version 3 of the eduVPN api: https://docs.eduvpn.org/server/v3/api.html package api import ( @@ -21,12 +22,18 @@ import ( "github.com/eduvpn/eduvpn-common/types/server" ) +// Callbacks is the API callback interface +// It is used to trigger authorization and forward token updates type Callbacks interface { + // TriggerAuth is called when authorization should be triggered TriggerAuth(context.Context, string, bool) (string, error) + // AuthDone is called when authorization has just completed AuthDone(string, server.Type) + // TokensUpdates is called when tokens are updated TokensUpdated(string, server.Type, eduoauth.Token) } +// ServerData is the data for a server that is passed to the API struct type ServerData struct { // ID is the identifier for the server ID string @@ -44,6 +51,7 @@ type ServerData struct { DisableAuthorize bool } +// API is the top-level struct that each method is defined on type API struct { cb Callbacks // oauth is the oauth object @@ -91,6 +99,7 @@ func NewAPI(ctx context.Context, clientID string, sd ServerData, cb Callbacks, t return api, nil } +// ErrAuthorizeDisabled is returned when authorization is disabled but is needed to complete var ErrAuthorizeDisabled = errors.New("cannot authorize as re-authorization is disabled") func (a *API) authorize(ctx context.Context) (err error) { @@ -168,11 +177,14 @@ func (a *API) authorizedRetry(ctx context.Context, method string, endpoint strin return h, body, err } +// Disconnect disconnects a client from the server by sending a /disconnect API call +// This cleans up resources such as WireGuard IP allocation func (a *API) Disconnect(ctx context.Context) error { _, _, err := a.authorized(ctx, http.MethodPost, "/disconnect", &httpw.OptionalParams{Timeout: 5 * time.Second}) return err } +// Info does the /info API call func (a *API) Info(ctx context.Context) (*profiles.Info, error) { _, body, err := a.authorizedRetry(ctx, http.MethodGet, "/info", nil) if err != nil { @@ -185,16 +197,16 @@ func (a *API) Info(ctx context.Context) (*profiles.Info, error) { return &p, nil } -type Proxy struct { - Listen string - Peer string -} - +// ConnectData is the data that is returned when the /connect call completes without error type ConnectData struct { + // Configuration is the VPN configuration Configuration string - Protocol protocol.Protocol - Expires time.Time - Proxy *wireguard.Proxy + // Protocol tells us what protocol it is, OpenVPN or WireGuard (proxied or not) + Protocol protocol.Protocol + // Expires tells us when this configuration expires + Expires time.Time + // Proxy is filled when WireGuard is proxied + Proxy *wireguard.Proxy } // see https://github.com/eduvpn/documentation/blob/v3/API.md#request-1 @@ -345,12 +357,16 @@ func refreshEndpoints(ctx context.Context, sd ServerData) (*endpoints.List, *end return &ep.API.V3, &epauth.API.V3, err } +// OAuthLogger is defined here to update the internal logger +// for the eduoauth library type OAuthLogger struct{} +// Logf logs a message with parameters func (ol *OAuthLogger) Logf(msg string, params ...interface{}) { log.Logger.Debugf(msg, params...) } +// Log logs a message func (ol *OAuthLogger) Log(msg string) { log.Logger.Debugf("%s", msg) } diff --git a/internal/api/endpoints/endpoints.go b/internal/api/endpoints/endpoints.go index 11e244b..c98d2c7 100644 --- a/internal/api/endpoints/endpoints.go +++ b/internal/api/endpoints/endpoints.go @@ -1,3 +1,5 @@ +// Package endpoints defines a wrapper around the various +// endpoints returned by an eduVPN server in well-known package endpoints import ( @@ -5,21 +7,30 @@ import ( "net/url" ) +// List is the list of endpoints as returned by the eduVPN server type List struct { - API string `json:"api_endpoint"` + // API is the API endpoint which we use for calls such as /info, /connect, ... + API string `json:"api_endpoint"` + // Authorization is the authorization endpoint for OAuth Authorization string `json:"authorization_endpoint"` - Token string `json:"token_endpoint"` + // Token is the token endpoint for OAuth + Token string `json:"token_endpoint"` } +// Versions is the endpoints separated by API version type Versions struct { + // V2 is the legacy V2 API, this is not used V2 List `json:"http://eduvpn.org/api#2"` + // V3 is the newest API, which we use V3 List `json:"http://eduvpn.org/api#3"` } // Endpoints defines the json format for /.well-known/vpn-user-portal". type Endpoints struct { + // API defines the API endpoints, split by version API Versions `json:"api"` - V string `json:"v"` + // V is the version string for the server + V string `json:"v"` } // Validate validates the endpoints by parsing them and checking the scheme is HTTP diff --git a/internal/api/profiles/profiles.go b/internal/api/profiles/profiles.go index 111a835..d31bbcc 100644 --- a/internal/api/profiles/profiles.go +++ b/internal/api/profiles/profiles.go @@ -1,3 +1,5 @@ +// Package profiles defines a wrapper around the various profiles +// returned by the /info endpoint package profiles import ( @@ -5,27 +7,43 @@ import ( "github.com/eduvpn/eduvpn-common/types/server" ) +// Profile is the information for a profile type Profile struct { - ID string `json:"profile_id"` - DisplayName string `json:"display_name"` - VPNProtoList []string `json:"vpn_proto_list"` + // ID is the identifier of the profile + // Used to select a profile + ID string `json:"profile_id"` + // DisplayName defines the UI friendly name for the profile + DisplayName string `json:"display_name"` + // VPNProtoList defines the list of VPN protocols + // E.g. wireguard, openvpn + VPNProtoList []string `json:"vpn_proto_list"` + // VPNProtoTransportList defines the list of VPN protocols including their transport values + // E.g. wireguard+udp, openvpn+tcp VPNProtoTransportList []string `json:"vpn_proto_transport_list"` - DefaultGateway bool `json:"default_gateway"` - DNSSearchDomains []string `json:"dns_search_domain_list"` + // DefaultGateway specifies whether or not this profile is a default gateway profile + DefaultGateway bool `json:"default_gateway"` + // DNSSearchDomains specifies the list of dns search domains + // This is provided for a Linux client issue + // See: https://github.com/eduvpn/python-eduvpn-client/issues/550 + DNSSearchDomains []string `json:"dns_search_domain_list"` } +// ListInfo is the struct that has the profile list type ListInfo struct { ProfileList []Profile `json:"profile_list"` } +// Info is the top-level struct for the info endpoint type Info struct { Info ListInfo `json:"info"` } +// Len returns the length of the profile list func (i Info) Len() int { return len(i.Info.ProfileList) } +// Get returns a profile with id `id`, it returns nil if it is not found func (i Info) Get(id string) *Profile { for _, p := range i.Info.ProfileList { if p.ID == id { @@ -35,6 +53,8 @@ func (i Info) Get(id string) *Profile { return nil } +// MustIndex gets a profile by index +// This index must be in the bounds func (i Info) MustIndex(n int) Profile { return i.Info.ProfileList[n] } @@ -48,6 +68,11 @@ func hasProtocol(protos []string, proto protocol.Protocol) bool { return false } +// ShouldFailover returns whether or not this VPN profile should start a failover procedure +// This is true when the profile supports a TCP connection +// If we cannot determine whether it supports a TCP connection +// (because the server doesn't provide the VPN transport list function yet), +// we will just check if it supports OpenVPN func (p *Profile) ShouldFailover() bool { // old servers don't support it, only failover in case OpenVPN is supported if len(p.VPNProtoTransportList) == 0 { @@ -65,14 +90,17 @@ func (p *Profile) ShouldFailover() bool { return false } +// HasOpenVPN returns whether or not the profile has OpenVPN support func (p *Profile) HasOpenVPN() bool { return hasProtocol(p.VPNProtoList, protocol.OpenVPN) } +// HasWireGuard returns whether or not the profile has WireGuard support func (p *Profile) HasWireGuard() bool { return hasProtocol(p.VPNProtoList, protocol.WireGuard) } +// FilterWireGuard gets a profile list but without WireGuard profiles func (i Info) FilterWireGuard() *Info { var ret []Profile for _, p := range i.Info.ProfileList { @@ -87,6 +115,7 @@ func (i Info) FilterWireGuard() *Info { } } +// Public gets the server list as a structure that we return to clients func (i Info) Public() server.Profiles { m := make(map[string]server.Profile) for _, p := range i.Info.ProfileList { |
