summaryrefslogtreecommitdiff
path: root/internal/server
diff options
context:
space:
mode:
authorjwijenbergh <jeroenwijenbergh@protonmail.com>2022-07-19 08:30:46 +0200
committerjwijenbergh <jeroenwijenbergh@protonmail.com>2022-07-19 08:30:46 +0200
commit3f7a95dea59ce05ff9cd620fd51a25dd72b3827b (patch)
tree9cc27b0b2f2ccc62c094ca3de879b270c21691c0 /internal/server
parentb3b78558e3d5d369f76a696e7f1b30559a16d3c7 (diff)
Server: Split CustomServer and split types into multiple files
Diffstat (limited to 'internal/server')
-rw-r--r--internal/server/common.go (renamed from internal/server/server.go)431
-rw-r--r--internal/server/instituteaccess.go56
-rw-r--r--internal/server/secureinternet.go134
3 files changed, 336 insertions, 285 deletions
diff --git a/internal/server/server.go b/internal/server/common.go
index 149867f..c4a9702 100644
--- a/internal/server/server.go
+++ b/internal/server/common.go
@@ -27,54 +27,90 @@ type ServerBase struct {
FSM *fsm.FSM `json:"-"`
}
-// An instute access server
-type InstituteAccessServer struct {
- // An instute access server has its own OAuth
- OAuth oauth.OAuth `json:"oauth"`
+type ServerType int8
- // Embed the server base
- Base ServerBase `json:"base"`
+const (
+ CustomServerType ServerType = iota
+ InstituteAccessServerType
+ SecureInternetServerType
+)
+
+type Servers struct {
+ // A custom server is just an institute access server under the hood
+ CustomServers InstituteAccessServers `json:"custom_servers"`
+ InstituteServers InstituteAccessServers `json:"institute_servers"`
+ SecureInternetHomeServer SecureInternetHomeServer `json:"secure_internet_home"`
+ IsType ServerType `json:"is_secure_internet"`
}
-// A secure internet server which has its own OAuth tokens
-// It specifies the current location url it is connected to
-type SecureInternetHomeServer struct {
- DisplayName map[string]string `json:"display_name"`
- OAuth oauth.OAuth `json:"oauth"`
+type Server interface {
+ // Gets the current OAuth object
+ GetOAuth() *oauth.OAuth
- // The home server has a list of info for each configured server location
- BaseMap map[string]*ServerBase `json:"base_map"`
+ // Get the authorization URL template function
+ GetTemplateAuth() func(string) string
- // We have the authorization URL template, the home organization ID and the current location
- AuthorizationTemplate string `json:"authorization_template"`
- HomeOrganizationID string `json:"home_organization_id"`
- CurrentLocation string `json:"current_location"`
+ // Gets the server base
+ GetBase() (*ServerBase, error)
}
-type InstituteServers struct {
- Map map[string]*InstituteAccessServer `json:"map"`
- CurrentURL string `json:"current_url"`
+type ServerProfile struct {
+ ID string `json:"profile_id"`
+ DisplayName string `json:"display_name"`
+ VPNProtoList []string `json:"vpn_proto_list"`
+ DefaultGateway bool `json:"default_gateway"`
+}
+
+type ServerProfileInfo struct {
+ Current string `json:"current_profile"`
+ Info struct {
+ ProfileList []ServerProfile `json:"profile_list"`
+ } `json:"info"`
+}
+
+type ServerEndpointList struct {
+ API string `json:"api_endpoint"`
+ Authorization string `json:"authorization_endpoint"`
+ Token string `json:"token_endpoint"`
+}
+
+// Struct that defines the json format for /.well-known/vpn-user-portal"
+type ServerEndpoints struct {
+ API struct {
+ V2 ServerEndpointList `json:"http://eduvpn.org/api#2"`
+ V3 ServerEndpointList `json:"http://eduvpn.org/api#3"`
+ } `json:"api"`
+ V string `json:"v"`
}
+// Make this a var which we can overwrite in the tests
+var WellKnownPath string = ".well-known/vpn-user-portal"
+
func (servers *Servers) GetCurrentServer() (Server, error) {
errorMessage := "failed getting current server"
- if servers.IsSecureInternet {
+ if servers.IsType == SecureInternetServerType {
if !servers.HasSecureLocation() {
return nil, &types.WrappedErrorMessage{Message: errorMessage, Err: &ServerGetCurrentNotFoundError{}}
}
return &servers.SecureInternetHomeServer, nil
}
- currentInstitute := servers.InstituteServers.CurrentURL
- institutes := servers.InstituteServers.Map
- if institutes == nil {
+
+ serversStruct := &servers.InstituteServers
+
+ if servers.IsType == CustomServerType {
+ serversStruct = &servers.CustomServers
+ }
+ currentServerURL := serversStruct.CurrentURL
+ bases := serversStruct.Map
+ if bases == nil {
return nil, &types.WrappedErrorMessage{Message: errorMessage, Err: &ServerGetCurrentNoMapError{}}
}
- institute, exists := institutes[currentInstitute]
+ server, exists := bases[currentServerURL]
- if !exists || institute == nil {
+ if !exists || server == nil {
return nil, &types.WrappedErrorMessage{Message: errorMessage, Err: &ServerGetCurrentNotFoundError{}}
}
- return institute, nil
+ return server, nil
}
func (servers *Servers) GetJSON() (string, error) {
@@ -87,141 +123,123 @@ func (servers *Servers) GetJSON() (string, error) {
return string(bytes), nil
}
-type Servers struct {
- InstituteServers InstituteServers `json:"institute_servers"`
- SecureInternetHomeServer SecureInternetHomeServer `json:"secure_internet_home"`
- IsSecureInternet bool `json:"is_secure_internet"`
+type ServerInfoScreen struct {
+ Identifier string `json:"identifier"`
+ DisplayName map[string]string `json:"display_name"`
+ CountryCode string `json:"country_code,omitempty"`
+ SupportContact []string `json:"support_contact"`
+ ProfilesRaw string `json:"profiles"`
+ ExpireTime int64 `json:"expire_time"`
+ Type string `json:"server_type"`
}
-type Server interface {
- // Gets the current OAuth object
- GetOAuth() *oauth.OAuth
+func (servers *Servers) GetCurrentServerInfoJSON() (string, error) {
+ errorMessage := "failed getting JSON for server"
- // Get the authorization URL template function
- GetTemplateAuth() func(string) string
+ currentServer, currentServerErr := servers.GetCurrentServer()
+ if currentServerErr != nil {
+ return "{}", &types.WrappedErrorMessage{Message: errorMessage, Err: currentServerErr}
+ }
- // Gets the server base
- GetBase() (*ServerBase, error)
-}
+ serverInfoScreen := &ServerInfoScreen{}
-// For an institute, we can simply get the OAuth
-func (institute *InstituteAccessServer) GetOAuth() *oauth.OAuth {
- return &institute.OAuth
-}
+ base, baseErr := currentServer.GetBase()
-func (secure *SecureInternetHomeServer) GetOAuth() *oauth.OAuth {
- return &secure.OAuth
-}
+ if baseErr != nil {
+ return "{}", &types.WrappedErrorMessage{Message: errorMessage, Err: baseErr}
+ }
-func (institute *InstituteAccessServer) GetTemplateAuth() func(string) string {
- return func(authURL string) string {
- return authURL
+ serverInfoScreen.Identifier = base.URL
+ serverInfoScreen.DisplayName = base.DisplayName
+ serverInfoScreen.SupportContact = base.SupportContact
+ serverInfoScreen.ProfilesRaw = base.ProfilesRaw
+ serverInfoScreen.ExpireTime = base.EndTime
+ serverInfoScreen.Type = base.Type
+
+ if servers.IsType == SecureInternetServerType {
+ serverInfoScreen.Identifier = servers.SecureInternetHomeServer.HomeOrganizationID
+ serverInfoScreen.CountryCode = servers.SecureInternetHomeServer.CurrentLocation
}
-}
-func (secure *SecureInternetHomeServer) GetTemplateAuth() func(string) string {
- return func(authURL string) string {
- return util.ReplaceWAYF(secure.AuthorizationTemplate, authURL, secure.HomeOrganizationID)
+ bytes, bytesErr := json.Marshal(serverInfoScreen)
+
+ if bytesErr != nil {
+ return "{}", &types.WrappedErrorMessage{Message: errorMessage, Err: bytesErr}
}
-}
-func (institute *InstituteAccessServer) GetBase() (*ServerBase, error) {
- return &institute.Base, nil
+ return string(bytes), nil
}
-func (server *SecureInternetHomeServer) GetBase() (*ServerBase, error) {
- errorMessage := "failed getting current secure internet home base"
- if server.BaseMap == nil {
- return nil, &types.WrappedErrorMessage{Message: errorMessage, Err: &ServerSecureInternetMapNotFoundError{}}
+func (servers *Servers) addInstituteAndCustom(discoServer *types.DiscoveryServer, isCustom bool, fsm *fsm.FSM, logger *log.FileLogger) (Server, error) {
+ url := discoServer.BaseURL
+ errorMessage := fmt.Sprintf("failed adding institute access server: %s", url)
+ toAddServers := &servers.InstituteServers
+ serverType := InstituteAccessServerType
+
+ if isCustom {
+ toAddServers = &servers.CustomServers
+ serverType = CustomServerType
+ }
+
+ if toAddServers.Map == nil {
+ toAddServers.Map = make(map[string]*InstituteAccessServer)
}
- base, exists := server.BaseMap[server.CurrentLocation]
+ server, exists := toAddServers.Map[url]
+ // initialize the server if it doesn't exist yet
if !exists {
- return nil, &types.WrappedErrorMessage{Message: errorMessage, Err: &ServerSecureInternetBaseNotFoundError{Current: server.CurrentLocation}}
+ server = &InstituteAccessServer{}
}
- return base, nil
-}
-func (institute *InstituteAccessServer) init(url string, displayName map[string]string, serverType string, supportContact []string, fsm *fsm.FSM, logger *log.FileLogger) error {
- errorMessage := fmt.Sprintf("failed initializing institute server %s", url)
- institute.Base.URL = url
- institute.Base.DisplayName = displayName
- institute.Base.SupportContact = supportContact
- institute.Base.FSM = fsm
- institute.Base.Logger = logger
- institute.Base.Type = serverType
- endpoints, endpointsErr := APIGetEndpoints(url)
- if endpointsErr != nil {
- return &types.WrappedErrorMessage{Message: errorMessage, Err: endpointsErr}
+ // Set the current server
+ toAddServers.CurrentURL = url
+ instituteInitErr := server.init(url, discoServer.DisplayName, discoServer.Type, discoServer.SupportContact, fsm, logger)
+ if instituteInitErr != nil {
+ return nil, &types.WrappedErrorMessage{Message: errorMessage, Err: instituteInitErr}
}
- institute.OAuth.Init(endpoints.API.V3.Authorization, endpoints.API.V3.Token, fsm, logger)
- institute.Base.Endpoints = *endpoints
- return nil
+ toAddServers.Map[url] = server
+ servers.IsType = serverType
+ return server, nil
}
-func (servers *Servers) HasSecureLocation() bool {
- return servers.SecureInternetHomeServer.CurrentLocation != ""
+func (servers *Servers) AddInstituteAccessServer(instituteServer *types.DiscoveryServer, fsm *fsm.FSM, logger *log.FileLogger) (Server, error) {
+ return servers.addInstituteAndCustom(instituteServer, false, fsm, logger)
}
-func (secure *SecureInternetHomeServer) addLocation(locationServer *types.DiscoveryServer, fsm *fsm.FSM, logger *log.FileLogger) (*ServerBase, error) {
- errorMessage := "failed adding a location"
- // Initialize the base map if it is non-nil
- if secure.BaseMap == nil {
- secure.BaseMap = make(map[string]*ServerBase)
- }
-
- // Add the location to the base map
- base, exists := secure.BaseMap[locationServer.CountryCode]
-
- if !exists || base == nil {
- // Create the base to be added to the map
- base = &ServerBase{}
- base.URL = locationServer.BaseURL
- base.DisplayName = secure.DisplayName
- base.SupportContact = locationServer.SupportContact
- base.Type = "secure_internet"
- endpoints, endpointsErr := APIGetEndpoints(locationServer.BaseURL)
- if endpointsErr != nil {
- return nil, &types.WrappedErrorMessage{Message: errorMessage, Err: endpointsErr}
- }
- base.Endpoints = *endpoints
- }
-
- // Pass the fsm and logger
- base.FSM = fsm
- base.Logger = logger
+func (servers *Servers) AddCustomServer(customServer *types.DiscoveryServer, fsm *fsm.FSM, logger *log.FileLogger) (Server, error) {
+ return servers.addInstituteAndCustom(customServer, true, fsm, logger)
+}
- // Ensure it is in the map
- secure.BaseMap[locationServer.CountryCode] = base
- return base, nil
+func (servers *Servers) GetSecureLocation() string {
+ return servers.SecureInternetHomeServer.CurrentLocation
}
-// Initializes the home server and adds its own location
-func (secure *SecureInternetHomeServer) init(homeOrg *types.DiscoveryOrganization, homeLocation *types.DiscoveryServer, fsm *fsm.FSM, logger *log.FileLogger) error {
- errorMessage := "failed initializing secure internet home server"
+func (servers *Servers) SetSecureLocation(chosenLocationServer *types.DiscoveryServer, fsm *fsm.FSM, logger *log.FileLogger) error {
+ errorMessage := "failed to set secure location"
+ // Make sure to add the current location
+ _, addLocationErr := servers.SecureInternetHomeServer.addLocation(chosenLocationServer, fsm, logger)
- if secure.HomeOrganizationID != homeOrg.OrgId {
- // New home organisation, clear everything
- *secure = SecureInternetHomeServer{}
+ if addLocationErr != nil {
+ return &types.WrappedErrorMessage{Message: errorMessage, Err: addLocationErr}
}
- // Make sure to set the organization ID
- secure.HomeOrganizationID = homeOrg.OrgId
- secure.DisplayName = homeOrg.DisplayName
-
- // Make sure to set the authorization URL template
- secure.AuthorizationTemplate = homeLocation.AuthenticationURLTemplate
+ servers.SecureInternetHomeServer.CurrentLocation = chosenLocationServer.CountryCode
+ return nil
+}
- base, baseErr := secure.addLocation(homeLocation, fsm, logger)
+func (servers *Servers) AddSecureInternet(secureOrg *types.DiscoveryOrganization, secureServer *types.DiscoveryServer, fsm *fsm.FSM, logger *log.FileLogger) (Server, error) {
+ errorMessage := "failed adding secure internet server"
+ // If we have specified an organization ID
+ // We also need to get an authorization template
+ initErr := servers.SecureInternetHomeServer.init(secureOrg, secureServer, fsm, logger)
- if baseErr != nil {
- return &types.WrappedErrorMessage{Message: errorMessage, Err: baseErr}
+ if initErr != nil {
+ return nil, &types.WrappedErrorMessage{Message: errorMessage, Err: initErr}
}
- // Make sure oauth contains our endpoints
- secure.OAuth.Init(base.Endpoints.API.V3.Authorization, base.Endpoints.API.V3.Token, fsm, logger)
- return nil
+ servers.IsType = SecureInternetServerType
+ return &servers.SecureInternetHomeServer, nil
}
func ShouldRenewButton(server Server) bool {
@@ -286,96 +304,6 @@ func CancelOAuth(server Server) {
server.GetOAuth().Cancel()
}
-func (servers *Servers) AddInstituteAccess(instituteServer *types.DiscoveryServer, fsm *fsm.FSM, logger *log.FileLogger) (Server, error) {
- url := instituteServer.BaseURL
- errorMessage := fmt.Sprintf("failed adding institute access server: %s", url)
- instituteServers := &servers.InstituteServers
-
- if instituteServers.Map == nil {
- instituteServers.Map = make(map[string]*InstituteAccessServer)
- }
-
- institute, exists := instituteServers.Map[url]
-
- // initialize the server if it doesn't exist yet
- if !exists {
- institute = &InstituteAccessServer{}
- }
-
- // Set the current server
- instituteServers.CurrentURL = url
- instituteInitErr := institute.init(url, instituteServer.DisplayName, instituteServer.Type, instituteServer.SupportContact, fsm, logger)
- if instituteInitErr != nil {
- return nil, &types.WrappedErrorMessage{Message: errorMessage, Err: instituteInitErr}
- }
- instituteServers.Map[url] = institute
- servers.IsSecureInternet = false
- return institute, nil
-}
-
-func (servers *Servers) GetSecureLocation() string {
- return servers.SecureInternetHomeServer.CurrentLocation
-}
-
-func (servers *Servers) SetSecureLocation(chosenLocationServer *types.DiscoveryServer, fsm *fsm.FSM, logger *log.FileLogger) error {
- errorMessage := "failed to set secure location"
- // Make sure to add the current location
- _, addLocationErr := servers.SecureInternetHomeServer.addLocation(chosenLocationServer, fsm, logger)
-
- if addLocationErr != nil {
- return &types.WrappedErrorMessage{Message: errorMessage, Err: addLocationErr}
- }
-
- servers.SecureInternetHomeServer.CurrentLocation = chosenLocationServer.CountryCode
- return nil
-}
-
-func (servers *Servers) AddSecureInternet(secureOrg *types.DiscoveryOrganization, secureServer *types.DiscoveryServer, fsm *fsm.FSM, logger *log.FileLogger) (Server, error) {
- errorMessage := "failed adding secure internet server"
- // If we have specified an organization ID
- // We also need to get an authorization template
- initErr := servers.SecureInternetHomeServer.init(secureOrg, secureServer, fsm, logger)
-
- if initErr != nil {
- return nil, &types.WrappedErrorMessage{Message: errorMessage, Err: initErr}
- }
-
- servers.IsSecureInternet = true
- return &servers.SecureInternetHomeServer, nil
-}
-
-type ServerProfile struct {
- ID string `json:"profile_id"`
- DisplayName string `json:"display_name"`
- VPNProtoList []string `json:"vpn_proto_list"`
- DefaultGateway bool `json:"default_gateway"`
-}
-
-type ServerProfileInfo struct {
- Current string `json:"current_profile"`
- Info struct {
- ProfileList []ServerProfile `json:"profile_list"`
- } `json:"info"`
-}
-
-type ServerEndpointList struct {
- API string `json:"api_endpoint"`
- Authorization string `json:"authorization_endpoint"`
- Token string `json:"token_endpoint"`
-}
-
-// Struct that defines the json format for /.well-known/vpn-user-portal"
-type ServerEndpoints struct {
- API struct {
- V2 ServerEndpointList `json:"http://eduvpn.org/api#2"`
- V3 ServerEndpointList `json:"http://eduvpn.org/api#3"`
- } `json:"api"`
- V string `json:"v"`
-}
-
-// Make this a var which we can overwrite in the tests
-var WellKnownPath string = ".well-known/vpn-user-portal"
-
func (profile *ServerProfile) supportsProtocol(protocol string) bool {
for _, proto := range profile.VPNProtoList {
if proto == protocol {
@@ -525,53 +453,6 @@ func askForProfileID(server Server) error {
return nil
}
-type ServerInfoScreen struct {
- Identifier string `json:"identifier"`
- DisplayName map[string]string `json:"display_name"`
- CountryCode string `json:"country_code,omitempty"`
- SupportContact []string `json:"support_contact"`
- ProfilesRaw string `json:"profiles"`
- ExpireTime int64 `json:"expire_time"`
- Type string `json:"server_type"`
-}
-
-func (servers *Servers) GetCurrentServerInfoJSON() (string, error) {
- errorMessage := "failed getting JSON for server"
-
- currentServer, currentServerErr := servers.GetCurrentServer()
- if currentServerErr != nil {
- return "{}", &types.WrappedErrorMessage{Message: errorMessage, Err: currentServerErr}
- }
-
- serverInfoScreen := &ServerInfoScreen{}
-
- base, baseErr := currentServer.GetBase()
-
- if baseErr != nil {
- return "{}", &types.WrappedErrorMessage{Message: errorMessage, Err: baseErr}
- }
-
- serverInfoScreen.Identifier = base.URL
- serverInfoScreen.DisplayName = base.DisplayName
- serverInfoScreen.SupportContact = base.SupportContact
- serverInfoScreen.ProfilesRaw = base.ProfilesRaw
- serverInfoScreen.ExpireTime = base.EndTime
- serverInfoScreen.Type = base.Type
-
- if servers.IsSecureInternet {
- serverInfoScreen.Identifier = servers.SecureInternetHomeServer.HomeOrganizationID
- serverInfoScreen.CountryCode = servers.SecureInternetHomeServer.CurrentLocation
- }
-
- bytes, bytesErr := json.Marshal(serverInfoScreen)
-
- if bytesErr != nil {
- return "{}", &types.WrappedErrorMessage{Message: errorMessage, Err: bytesErr}
- }
-
- return string(bytes), nil
-}
-
func GetConfig(server Server, forceTCP bool) (string, string, error) {
errorMessage := "failed getting an OpenVPN/WireGuard configuration"
base, baseErr := server.GetBase()
@@ -631,12 +512,6 @@ func (e *ServerGetConfigForceTCPError) Error() string {
return fmt.Sprintf("failed to get config, force TCP is on but the server does not support OpenVPN")
}
-type ServerGetSecureInternetHomeError struct{}
-
-func (e *ServerGetSecureInternetHomeError) Error() string {
- return "failed to get secure internet home server, not found"
-}
-
type ServerEnsureServerEmptyURLError struct{}
func (e *ServerEnsureServerEmptyURLError) Error() string {
@@ -654,17 +529,3 @@ type ServerGetCurrentNotFoundError struct{}
func (e *ServerGetCurrentNotFoundError) Error() string {
return "failed getting current server, not found"
}
-
-type ServerSecureInternetMapNotFoundError struct{}
-
-func (e *ServerSecureInternetMapNotFoundError) Error() string {
- return "secure internet map not found"
-}
-
-type ServerSecureInternetBaseNotFoundError struct {
- Current string
-}
-
-func (e *ServerSecureInternetBaseNotFoundError) Error() string {
- return fmt.Sprintf("secure internet base not found with current location: %s", e.Current)
-}
diff --git a/internal/server/instituteaccess.go b/internal/server/instituteaccess.go
new file mode 100644
index 0000000..9e712bd
--- /dev/null
+++ b/internal/server/instituteaccess.go
@@ -0,0 +1,56 @@
+package server
+
+import (
+ "fmt"
+
+ "github.com/jwijenbergh/eduvpn-common/internal/fsm"
+ "github.com/jwijenbergh/eduvpn-common/internal/log"
+ "github.com/jwijenbergh/eduvpn-common/internal/oauth"
+ "github.com/jwijenbergh/eduvpn-common/internal/types"
+)
+
+// An instute access server
+type InstituteAccessServer struct {
+ // An instute access server has its own OAuth
+ OAuth oauth.OAuth `json:"oauth"`
+
+ // Embed the server base
+ Base ServerBase `json:"base"`
+}
+
+type InstituteAccessServers struct {
+ Map map[string]*InstituteAccessServer `json:"map"`
+ CurrentURL string `json:"current_url"`
+}
+
+// For an institute, we can simply get the OAuth
+func (institute *InstituteAccessServer) GetOAuth() *oauth.OAuth {
+ return &institute.OAuth
+}
+
+func (institute *InstituteAccessServer) GetTemplateAuth() func(string) string {
+ return func(authURL string) string {
+ return authURL
+ }
+}
+
+func (institute *InstituteAccessServer) GetBase() (*ServerBase, error) {
+ return &institute.Base, nil
+}
+
+func (institute *InstituteAccessServer) init(url string, displayName map[string]string, serverType string, supportContact []string, fsm *fsm.FSM, logger *log.FileLogger) error {
+ errorMessage := fmt.Sprintf("failed initializing institute server %s", url)
+ institute.Base.URL = url
+ institute.Base.DisplayName = displayName
+ institute.Base.SupportContact = supportContact
+ institute.Base.FSM = fsm
+ institute.Base.Logger = logger
+ institute.Base.Type = serverType
+ endpoints, endpointsErr := APIGetEndpoints(url)
+ if endpointsErr != nil {
+ return &types.WrappedErrorMessage{Message: errorMessage, Err: endpointsErr}
+ }
+ institute.OAuth.Init(endpoints.API.V3.Authorization, endpoints.API.V3.Token, fsm, logger)
+ institute.Base.Endpoints = *endpoints
+ return nil
+}
diff --git a/internal/server/secureinternet.go b/internal/server/secureinternet.go
new file mode 100644
index 0000000..95c14a6
--- /dev/null
+++ b/internal/server/secureinternet.go
@@ -0,0 +1,134 @@
+package server
+
+import (
+ "fmt"
+
+ "github.com/jwijenbergh/eduvpn-common/internal/fsm"
+ "github.com/jwijenbergh/eduvpn-common/internal/log"
+ "github.com/jwijenbergh/eduvpn-common/internal/oauth"
+ "github.com/jwijenbergh/eduvpn-common/internal/types"
+ "github.com/jwijenbergh/eduvpn-common/internal/util"
+)
+
+// A secure internet server which has its own OAuth tokens
+// It specifies the current location url it is connected to
+type SecureInternetHomeServer struct {
+ DisplayName map[string]string `json:"display_name"`
+ OAuth oauth.OAuth `json:"oauth"`
+
+ // The home server has a list of info for each configured server location
+ BaseMap map[string]*ServerBase `json:"base_map"`
+
+ // We have the authorization URL template, the home organization ID and the current location
+ AuthorizationTemplate string `json:"authorization_template"`
+ HomeOrganizationID string `json:"home_organization_id"`
+ CurrentLocation string `json:"current_location"`
+}
+
+func (secure *SecureInternetHomeServer) GetOAuth() *oauth.OAuth {
+ return &secure.OAuth
+}
+
+func (secure *SecureInternetHomeServer) GetTemplateAuth() func(string) string {
+ return func(authURL string) string {
+ return util.ReplaceWAYF(secure.AuthorizationTemplate, authURL, secure.HomeOrganizationID)
+ }
+}
+
+func (server *SecureInternetHomeServer) GetBase() (*ServerBase, error) {
+ errorMessage := "failed getting current secure internet home base"
+ if server.BaseMap == nil {
+ return nil, &types.WrappedErrorMessage{Message: errorMessage, Err: &ServerSecureInternetMapNotFoundError{}}
+ }
+
+ base, exists := server.BaseMap[server.CurrentLocation]
+
+ if !exists {
+ return nil, &types.WrappedErrorMessage{Message: errorMessage, Err: &ServerSecureInternetBaseNotFoundError{Current: server.CurrentLocation}}
+ }
+ return base, nil
+}
+
+func (servers *Servers) HasSecureLocation() bool {
+ return servers.SecureInternetHomeServer.CurrentLocation != ""
+}
+
+func (secure *SecureInternetHomeServer) addLocation(locationServer *types.DiscoveryServer, fsm *fsm.FSM, logger *log.FileLogger) (*ServerBase, error) {
+ errorMessage := "failed adding a location"
+ // Initialize the base map if it is non-nil
+ if secure.BaseMap == nil {
+ secure.BaseMap = make(map[string]*ServerBase)
+ }
+
+ // Add the location to the base map
+ base, exists := secure.BaseMap[locationServer.CountryCode]
+
+ if !exists || base == nil {
+ // Create the base to be added to the map
+ base = &ServerBase{}
+ base.URL = locationServer.BaseURL
+ base.DisplayName = secure.DisplayName
+ base.SupportContact = locationServer.SupportContact
+ base.Type = "secure_internet"
+ endpoints, endpointsErr := APIGetEndpoints(locationServer.BaseURL)
+ if endpointsErr != nil {
+ return nil, &types.WrappedErrorMessage{Message: errorMessage, Err: endpointsErr}
+ }
+ base.Endpoints = *endpoints
+ }
+
+ // Pass the fsm and logger
+ base.FSM = fsm
+ base.Logger = logger
+
+ // Ensure it is in the map
+ secure.BaseMap[locationServer.CountryCode] = base
+ return base, nil
+}
+
+// Initializes the home server and adds its own location
+func (secure *SecureInternetHomeServer) init(homeOrg *types.DiscoveryOrganization, homeLocation *types.DiscoveryServer, fsm *fsm.FSM, logger *log.FileLogger) error {
+ errorMessage := "failed initializing secure internet home server"
+
+ if secure.HomeOrganizationID != homeOrg.OrgId {
+ // New home organisation, clear everything
+ *secure = SecureInternetHomeServer{}
+ }
+
+ // Make sure to set the organization ID
+ secure.HomeOrganizationID = homeOrg.OrgId
+ secure.DisplayName = homeOrg.DisplayName
+
+ // Make sure to set the authorization URL template
+ secure.AuthorizationTemplate = homeLocation.AuthenticationURLTemplate
+
+ base, baseErr := secure.addLocation(homeLocation, fsm, logger)
+
+ if baseErr != nil {
+ return &types.WrappedErrorMessage{Message: errorMessage, Err: baseErr}
+ }
+
+ // Make sure oauth contains our endpoints
+ secure.OAuth.Init(base.Endpoints.API.V3.Authorization, base.Endpoints.API.V3.Token, fsm, logger)
+ return nil
+}
+
+type ServerGetSecureInternetHomeError struct{}
+
+func (e *ServerGetSecureInternetHomeError) Error() string {
+ return "failed to get secure internet home server, not found"
+}
+
+type ServerSecureInternetMapNotFoundError struct{}
+
+func (e *ServerSecureInternetMapNotFoundError) Error() string {
+ return "secure internet map not found"
+}
+
+type ServerSecureInternetBaseNotFoundError struct {
+ Current string
+}
+
+func (e *ServerSecureInternetBaseNotFoundError) Error() string {
+ return fmt.Sprintf("secure internet base not found with current location: %s", e.Current)
+}