diff --git a/api/http/handler/openamt/openamt.go b/api/http/handler/openamt/openamt.go index ee89bff3b..3255e0276 100644 --- a/api/http/handler/openamt/openamt.go +++ b/api/http/handler/openamt/openamt.go @@ -3,6 +3,7 @@ package openamt import ( "errors" "net/http" + "strconv" httperror "github.com/portainer/libhttp/error" "github.com/portainer/libhttp/request" @@ -73,7 +74,15 @@ func (handler *Handler) openAMTConfigureDefault(w http.ResponseWriter, r *http.R } if payload.EnableOpenAMT { - err := handler.OpenAMTService.ConfigureDefault(payload.CertFileText, payload.CertPassword, payload.DomainName, payload.UseWirelessConfig, payload.WifiAuthenticationMethod, payload.WifiEncryptionMethod, payload.WifiSSID, payload.WifiPskPass) + wifiAuthenticationMethod, err := strconv.Atoi(payload.WifiAuthenticationMethod) + if err != nil { + return &httperror.HandlerError{http.StatusBadRequest, "Invalid Wifi AuthenticationMethod value", err} + } + wifiEncryptionMethod, err := strconv.Atoi(payload.WifiEncryptionMethod) + if err != nil { + return &httperror.HandlerError{http.StatusBadRequest, "Invalid Wifi EncryptionMethod value", err} + } + err = handler.OpenAMTService.ConfigureDefault(payload.CertFileText, payload.CertPassword, payload.DomainName, payload.UseWirelessConfig, wifiAuthenticationMethod, wifiEncryptionMethod, payload.WifiSSID, payload.WifiPskPass) if err != nil { return &httperror.HandlerError{http.StatusInternalServerError, "error configuring OpenAMT server", err} } diff --git a/api/intel/openamt/authorization.go b/api/intel/openamt/authorization.go index 29e30cdbd..db3647491 100644 --- a/api/intel/openamt/authorization.go +++ b/api/intel/openamt/authorization.go @@ -9,7 +9,7 @@ import ( ) type authenticationResponse struct { - Token string `json:"token"` + Token string `json:"token"` } func (service *Service) executeAuthenticationRequest() (*authenticationResponse, error) { @@ -17,7 +17,7 @@ func (service *Service) executeAuthenticationRequest() (*authenticationResponse, payload := map[string]string{ "username": MpsServerAdminUser, - "password": "chelo.Port2021", // TODO prompt/autogenerate on deploy stack and save in datastore + "password": "mypassword", // TODO prompt/autogenerate on deploy stack and save in datastore } jsonValue, _ := json.Marshal(payload) diff --git a/api/intel/openamt/configDomain.go b/api/intel/openamt/configDomain.go index 7a41602ba..408dcd0be 100644 --- a/api/intel/openamt/configDomain.go +++ b/api/intel/openamt/configDomain.go @@ -16,7 +16,7 @@ type ( } ) -func (service *Service) createOrUpdateDomain(token string, domainName, domainSuffix, provisioningCert, provisioningCertPassword string) (*Domain, error) { +func (service *Service) createOrUpdateDomain(token string, domainName string, domainSuffix string, provisioningCert string, provisioningCertPassword string) (*Domain, error) { domain, err := service.getDomain(token, domainName) if err != nil { return nil, err @@ -53,13 +53,13 @@ func (service *Service) getDomain(token string, domainName string) (*Domain, err return &result, nil } -func (service *Service) saveDomain(method string, token string, domainName, domainSuffix, provisioningCert, provisioningCertPassword string) (*Domain, error) { +func (service *Service) saveDomain(method string, token string, domainName string, domainSuffix string, provisioningCert string, provisioningCertPassword string) (*Domain, error) { url := fmt.Sprintf("https://%v/rps/api/v1/admin/domains", MpsServerAddress) profile := Domain{ DomainName: domainName, DomainSuffix: domainSuffix, - ProvisioningCert: " ", // TODO do we prompt user or use own certificate? + ProvisioningCert: " ", // TODO do we prompt user or use own certificate? ProvisioningCertPassword: "certPass!1", // TODO what do we use here? ProvisioningCertStorageFormat: "string", } diff --git a/api/intel/openamt/configProfile.go b/api/intel/openamt/configProfile.go index 207b48833..67fc93639 100644 --- a/api/intel/openamt/configProfile.go +++ b/api/intel/openamt/configProfile.go @@ -8,24 +8,24 @@ import ( type ( Profile struct { - ProfileName string `json:"profileName"` - Activation string `json:"activation"` - CIRAConfigName *string `json:"ciraConfigName"` - GenerateRandomPassword bool `json:"generateRandomPassword"` - GenerateRandomMEBxPassword bool `json:"generateRandomMEBxPassword"` - Tags []string `json:"tags"` - DHCPEnabled bool `json:"dhcpEnabled"` - TenantId string `json:"tenantId"` - WIFIConfigs []WifiConfig `json:"wifiConfigs"` + ProfileName string `json:"profileName"` + Activation string `json:"activation"` + CIRAConfigName *string `json:"ciraConfigName"` + GenerateRandomPassword bool `json:"generateRandomPassword"` + GenerateRandomMEBxPassword bool `json:"generateRandomMEBxPassword"` + Tags []string `json:"tags"` + DHCPEnabled bool `json:"dhcpEnabled"` + TenantId string `json:"tenantId"` + WIFIConfigs []ProfileWifiConfig `json:"wifiConfigs"` } - WifiConfig struct { + ProfileWifiConfig struct { Priority int `json:"priority"` ProfileName string `json:"profileName"` } ) -func (service *Service) createOrUpdateAMTProfile(token, profileName string, ciraConfigName string, useWirelessConfig bool) (*Profile, error) { +func (service *Service) createOrUpdateAMTProfile(token string, profileName string, ciraConfigName string, wirelessConfig string) (*Profile, error) { profile, err := service.getAMTProfile(token, profileName) if err != nil { return nil, err @@ -36,7 +36,7 @@ func (service *Service) createOrUpdateAMTProfile(token, profileName string, cira method = http.MethodPatch } - profile, err = service.saveAMTProfile(method, token, profileName, ciraConfigName, useWirelessConfig) + profile, err = service.saveAMTProfile(method, token, profileName, ciraConfigName, wirelessConfig) if err != nil { return nil, err } @@ -62,7 +62,7 @@ func (service *Service) getAMTProfile(token string, profileName string) (*Profil return &result, nil } -func (service *Service) saveAMTProfile(method string, token string, profileName string, ciraConfigName string, useWirelessConfig bool) (*Profile, error) { +func (service *Service) saveAMTProfile(method string, token string, profileName string, ciraConfigName string, wirelessConfig string) (*Profile, error) { url := fmt.Sprintf("https://%v/rps/api/v1/admin/profiles", MpsServerAddress) profile := Profile{ @@ -74,8 +74,8 @@ func (service *Service) saveAMTProfile(method string, token string, profileName Tags: []string{}, DHCPEnabled: true, } - if useWirelessConfig { - profile.WIFIConfigs = []WifiConfig{ + if wirelessConfig != "" { + profile.WIFIConfigs = []ProfileWifiConfig{ { Priority: 1, ProfileName: DefaultWirelessConfigName, diff --git a/api/intel/openamt/configWireless.go b/api/intel/openamt/configWireless.go new file mode 100644 index 000000000..1738d362a --- /dev/null +++ b/api/intel/openamt/configWireless.go @@ -0,0 +1,79 @@ +package openamt + +import ( + "encoding/json" + "fmt" + "net/http" +) + +type ( + WirelessProfile struct { + ProfileName string `json:"profileName"` + AuthenticationMethod int `json:"authenticationMethod"` + EncryptionMethod int `json:"encryptionMethod"` + SSID string `json:"ssid"` + PSKPassphrase string `json:"pskPassphrase"` + } +) + +func (service *Service) createOrUpdateWirelessConfig(token string, configName string, authenticationMethod int, encryptionMethod int, ssid string, pskPass string) (*WirelessProfile, error) { + wirelessConfig, err := service.getWirelessConfig(token, configName) + if err != nil { + return nil, err + } + + method := http.MethodPost + if wirelessConfig != nil { + method = http.MethodPatch + } + + wirelessConfig, err = service.saveWirelessConfig(method, token, configName, authenticationMethod, encryptionMethod, ssid, pskPass) + if err != nil { + return nil, err + } + return wirelessConfig, nil +} + +func (service *Service) getWirelessConfig(token string, configName string) (*WirelessProfile, error) { + url := fmt.Sprintf("https://%v/rps/api/v1/admin/wirelessconfigs/%v", MpsServerAddress, configName) + + responseBody, err := service.executeGetRequest(url, token) + if err != nil { + return nil, err + } + if responseBody == nil { + return nil, nil + } + + var result WirelessProfile + err = json.Unmarshal(responseBody, &result) + if err != nil { + return nil, err + } + return &result, nil +} + +func (service *Service) saveWirelessConfig(method string, token string, configName string, authenticationMethod int, encryptionMethod int, ssid string, pskPassphrase string) (*WirelessProfile, error) { + url := fmt.Sprintf("https://%v/rps/api/v1/admin/wirelessconfigs", MpsServerAddress) + + config := WirelessProfile{ + ProfileName: configName, + AuthenticationMethod: authenticationMethod, + EncryptionMethod: encryptionMethod, + SSID: ssid, + PSKPassphrase: pskPassphrase, + } + payload, _ := json.Marshal(config) + + responseBody, err := service.executeSaveRequest(method, url, token, payload) + if err != nil { + return nil, err + } + + var result WirelessProfile + err = json.Unmarshal(responseBody, &result) + if err != nil { + return nil, err + } + return &result, nil +} diff --git a/api/intel/openamt/openamt.go b/api/intel/openamt/openamt.go index a2ed60478..e8dab2bb7 100644 --- a/api/intel/openamt/openamt.go +++ b/api/intel/openamt/openamt.go @@ -61,7 +61,7 @@ func parseError(responseBody []byte) error { return nil } -func (service *Service) ConfigureDefault(certFileText string, certPassword string, domainSuffix string, useWirelessConfig bool, wifiAuthenticationMethod string, wifiEncryptionMethod string, wifiSSID string, wifiPskPass string) error { +func (service *Service) ConfigureDefault(certFileText string, certPassword string, domainSuffix string, useWirelessConfig bool, wifiAuthenticationMethod int, wifiEncryptionMethod int, wifiSSID string, wifiPskPass string) error { token, err := service.executeAuthenticationRequest() if err != nil { return err @@ -72,9 +72,16 @@ func (service *Service) ConfigureDefault(certFileText string, certPassword strin return err } - //TODO wifi + wirelessConfigName := "" + if useWirelessConfig { + wirlessConfig, err := service.createOrUpdateWirelessConfig(token.Token, DefaultWirelessConfigName, wifiAuthenticationMethod, wifiEncryptionMethod, wifiSSID, wifiPskPass) + if err != nil { + return err + } + wirelessConfigName = wirlessConfig.ProfileName + } - profile, err := service.createOrUpdateAMTProfile(token.Token, DefaultProfileName, ciraConfig.ConfigName, useWirelessConfig) + profile, err := service.createOrUpdateAMTProfile(token.Token, DefaultProfileName, ciraConfig.ConfigName, wirelessConfigName) if err != nil { return err } @@ -91,7 +98,7 @@ func (service *Service) ConfigureDefault(certFileText string, certPassword strin return nil } -func (service *Service) executeSaveRequest(method, url, token string, payload []byte) ([]byte, error) { +func (service *Service) executeSaveRequest(method string, url string, token string, payload []byte) ([]byte, error) { req, err := http.NewRequest(method, url, bytes.NewBuffer(payload)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", fmt.Sprintf("Bearer %v", token)) @@ -116,7 +123,7 @@ func (service *Service) executeSaveRequest(method, url, token string, payload [] return responseBody, nil } -func (service *Service) executeGetRequest(url, token string) ([]byte, error) { +func (service *Service) executeGetRequest(url string, token string) ([]byte, error) { req, err := http.NewRequest(http.MethodGet, url, nil) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", fmt.Sprintf("Bearer %v", token)) @@ -142,4 +149,4 @@ func (service *Service) executeGetRequest(url, token string) ([]byte, error) { } return responseBody, nil -} \ No newline at end of file +} diff --git a/api/portainer.go b/api/portainer.go index 89fb5e90f..2e7cf096a 100644 --- a/api/portainer.go +++ b/api/portainer.go @@ -1259,7 +1259,7 @@ type ( // OpenAMTService represents a service for managing OpenAMT OpenAMTService interface { - ConfigureDefault(certFileText string, certPassword string, domainSuffix string, useWirelessConfig bool, wifiAuthenticationMethod string, wifiEncryptionMethod string, wifiSSID string, wifiPskPass string) error + ConfigureDefault(certFileText string, certPassword string, domainSuffix string, useWirelessConfig bool, wifiAuthenticationMethod int, wifiEncryptionMethod int, wifiSSID string, wifiPskPass string) error } // HelmUserRepositoryService represents a service to manage HelmUserRepositories diff --git a/app/portainer/settings/general/open-amt/open-amt.controller.js b/app/portainer/settings/general/open-amt/open-amt.controller.js index b28397011..7f3919e7c 100644 --- a/app/portainer/settings/general/open-amt/open-amt.controller.js +++ b/app/portainer/settings/general/open-amt/open-amt.controller.js @@ -45,8 +45,6 @@ class OpenAmtController { return this.$async(async () => { this.state.actionInProgress = true; try { - // eslint-disable-next-line no-debugger - debugger; this.formValues.certFileText = this.formValues.certFile ? await this.formValues.certFile.text() : null; await this.OpenAMTService.submit(this.formValues);