From 8b4f9fe3ed95ad187c09c7b84ec41d52ca0cb8dc Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Thu, 22 Dec 2022 12:56:24 +0100 Subject: [PATCH] Simplify customform handling in backend (let the frontend handle it) --- api/form.go | 35 ++++++----------------------- api/provider_settings.go | 22 ++++++++----------- api/service_settings.go | 11 +++++----- forms/custom.go | 2 +- forms/interface.go | 4 ++-- providers/ovh_settings.go | 46 ++++++++++++++++----------------------- 6 files changed, 43 insertions(+), 77 deletions(-) diff --git a/api/form.go b/api/form.go index 55c11d0..0391d33 100644 --- a/api/form.go +++ b/api/form.go @@ -32,8 +32,6 @@ package api import ( - "fmt" - "github.com/gin-gonic/gin" "git.happydns.org/happydomain/config" @@ -42,28 +40,15 @@ import ( ) type FormState struct { - Id interface{} `json:"_id,omitempty"` - Name string `json:"_comment"` - State int32 `json:"state"` - Recall *int64 `json:"recall,omitempty"` - Redirect *string `json:"redirect,omitempty"` + Id *happydns.Identifier `json:"_id,omitempty"` + Name string `json:"_comment"` + State int32 `json:"state"` + Recall string `json:"recall,omitempty"` } -type FormResponse struct { - From *forms.CustomForm `json:"form,omitempty"` - Redirect *string `json:"redirect,omitempty"` -} - -func formDoState(cfg *config.Options, c *gin.Context, fs *FormState, data interface{}, defaultForm func(interface{}) *forms.CustomForm) (form *forms.CustomForm, err error) { +func formDoState(cfg *config.Options, c *gin.Context, fs *FormState, data interface{}, defaultForm func(interface{}) *forms.CustomForm) (form *forms.CustomForm, d map[string]interface{}, err error) { session := c.MustGet("MySession").(*happydns.Session) - if fs.Recall != nil { - session.GetValue(fmt.Sprintf("form-%d", *fs.Recall), data) - session.GetValue(fmt.Sprintf("form-%d-name", *fs.Recall), &fs.Name) - session.GetValue(fmt.Sprintf("form-%d-id", *fs.Recall), &fs.Id) - session.GetValue(fmt.Sprintf("form-%d-next", *fs.Recall), &fs.Redirect) - } - csf, ok := data.(forms.CustomSettingsForm) if !ok { if fs.State == 1 { @@ -73,14 +58,8 @@ func formDoState(cfg *config.Options, c *gin.Context, fs *FormState, data interf } return } else { - return csf.DisplaySettingsForm(fs.State, cfg, session, func() int64 { - key, recallid := session.FindNewKey("form-") - session.SetValue(key, data) - session.SetValue(key+"-id", fs.Id) - if fs.Redirect != nil { - session.SetValue(key+"-next", *fs.Redirect) - } - return recallid + return csf.DisplaySettingsForm(fs.State, cfg, session, func() string { + return fs.Recall }) } } diff --git a/api/provider_settings.go b/api/provider_settings.go index d608af8..4c6e720 100644 --- a/api/provider_settings.go +++ b/api/provider_settings.go @@ -58,8 +58,9 @@ type ProviderSettingsState struct { } type ProviderSettingsResponse struct { - FormResponse - happydns.Provider `json:"Provider,omitempty"` + Provider *happydns.Provider `json:"Provider,omitempty"` + Values map[string]interface{} `json:"values,omitempty"` + Form *forms.CustomForm `json:"form,omitempty"` } func getProviderSettingsState(cfg *config.Options, c *gin.Context) { @@ -87,7 +88,7 @@ func getProviderSettingsState(cfg *config.Options, c *gin.Context) { } - form, err := formDoState(cfg, c, &uss.FormState, src, forms.GenDefaultSettingsForm) + form, p, err := formDoState(cfg, c, &uss.FormState, src, forms.GenDefaultSettingsForm) if err != nil { if err != forms.DoneForm { @@ -104,14 +105,11 @@ func getProviderSettingsState(cfg *config.Options, c *gin.Context) { return } - c.JSON(http.StatusOK, ProviderSettingsResponse{ - Provider: s, - FormResponse: FormResponse{Redirect: uss.Redirect}, - }) + c.JSON(http.StatusOK, s) return } else { // Update an existing Provider - s, err := storage.MainStore.GetProvider(user, uss.Id.(happydns.Identifier)) + s, err := storage.MainStore.GetProvider(user, *uss.Id) if err != nil { c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()}) return @@ -125,15 +123,13 @@ func getProviderSettingsState(cfg *config.Options, c *gin.Context) { return } - c.JSON(http.StatusOK, ProviderSettingsResponse{ - Provider: s, - FormResponse: FormResponse{Redirect: uss.Redirect}, - }) + c.JSON(http.StatusOK, s) return } } c.JSON(http.StatusOK, ProviderSettingsResponse{ - FormResponse: FormResponse{From: form}, + Form: form, + Values: p, }) } diff --git a/api/service_settings.go b/api/service_settings.go index be3f4ce..59f14e3 100644 --- a/api/service_settings.go +++ b/api/service_settings.go @@ -57,7 +57,6 @@ type ServiceSettingsState struct { } type ServiceSettingsResponse struct { - FormResponse Services map[string][]*happydns.ServiceCombined `json:"services,omitempty"` } @@ -87,7 +86,7 @@ func getServiceSettingsState(cfg *config.Options, c *gin.Context) { return } - form, err := formDoState(cfg, c, &ups.FormState, ups.Service, forms.GenDefaultSettingsForm) + form, p, err := formDoState(cfg, c, &ups.FormState, ups.Service, forms.GenDefaultSettingsForm) if err != nil { if err != forms.DoneForm { @@ -99,7 +98,7 @@ func getServiceSettingsState(cfg *config.Options, c *gin.Context) { return } else { // Update an existing Service - err = zone.EraseServiceWithoutMeta(subdomain, domain.DomainName, ups.Id.([]byte), ups) + err = zone.EraseServiceWithoutMeta(subdomain, domain.DomainName, *ups.Id, ups) } if err != nil { @@ -114,13 +113,13 @@ func getServiceSettingsState(cfg *config.Options, c *gin.Context) { } c.JSON(http.StatusOK, ServiceSettingsResponse{ - Services: zone.Services, - FormResponse: FormResponse{Redirect: ups.Redirect}, + Services: zone.Services, }) return } c.JSON(http.StatusOK, ProviderSettingsResponse{ - FormResponse: FormResponse{From: form}, + Form: form, + Values: p, }) } diff --git a/forms/custom.go b/forms/custom.go index 6fa87c4..1beb9cf 100644 --- a/forms/custom.go +++ b/forms/custom.go @@ -33,7 +33,7 @@ package forms // import "happydns.org/forms" import () -// CustomForm is used to create a form with several steps when creating or updating source's settings. +// CustomForm is used to create a form with several steps when creating or updating provider's settings. type CustomForm struct { // BeforeText is the text presented before the fields. BeforeText string `json:"beforeText,omitempty"` diff --git a/forms/interface.go b/forms/interface.go index 84be2b2..cdd35ff 100644 --- a/forms/interface.go +++ b/forms/interface.go @@ -39,12 +39,12 @@ import ( ) // GenRecallID -type GenRecallID func() int64 +type GenRecallID func() string // CustomSettingsForm are functions to declare when we want to display a custom user experience when asking for Source's settings. type CustomSettingsForm interface { // DisplaySettingsForm generates the CustomForm corresponding to the asked target state. - DisplaySettingsForm(int32, *config.Options, *happydns.Session, GenRecallID) (*CustomForm, error) + DisplaySettingsForm(int32, *config.Options, *happydns.Session, GenRecallID) (*CustomForm, map[string]interface{}, error) } var ( diff --git a/providers/ovh_settings.go b/providers/ovh_settings.go index 5da3dbf..152aa47 100644 --- a/providers/ovh_settings.go +++ b/providers/ovh_settings.go @@ -42,10 +42,6 @@ import ( "git.happydns.org/happydomain/model" ) -const ( - SESSION_CKEY = "ovh-consumerkey" -) - func settingsForm(edit bool) *forms.CustomForm { srcFields := []*forms.Field{ &forms.Field{ @@ -75,56 +71,52 @@ func settingsForm(edit bool) *forms.CustomForm { return form } -func settingsAskCredentials(cfg *config.Options, recallid int64, session *happydns.Session) (*forms.CustomForm, error) { +func settingsAskCredentials(cfg *config.Options, recallid string, session *happydns.Session) (*forms.CustomForm, map[string]interface{}, error) { client, err := ovh.NewClient("ovh-eu", appKey, appSecret, "") if err != nil { - return nil, fmt.Errorf("Unable to generate Consumer key, as OVH client can't be created: %w", err) + return nil, nil, fmt.Errorf("Unable to generate Consumer key, as OVH client can't be created: %w", err) } // Generate customer key - ckReq := client.NewCkRequestWithRedirection(cfg.BuildURL_noescape("/providers/new/OVHAPI/2?recall=%d", recallid)) + ckReq := client.NewCkRequestWithRedirection(cfg.BuildURL_noescape("/providers/new/OVHAPI/2?nsprvid=%s", recallid)) ckReq.AddRecursiveRules(ovh.ReadWrite, "/domain") ckReq.AddRules(ovh.ReadOnly, "/me") response, err := ckReq.Do() if err != nil { - return nil, fmt.Errorf("Unable to generate Consumer key; OVH returns: %w", err) + return nil, nil, fmt.Errorf("Unable to generate Consumer key; OVH returns: %w", err) } - // Store the key in user's session - session.SetValue(SESSION_CKEY, response.ConsumerKey) - // Return some explanation to the user return &forms.CustomForm{ - BeforeText: "In order allows happyDomain to get and update yours domains, you have to let us access them. To avoid storing your credentials, we will store a unique token that will be associated with your account. For this purpose, you will be redirected to an OVH login screen. The registration will automatically continue", - NextButtonText: "Go to OVH", - PreviousButtonText: "< Previous", - NextButtonLink: response.ValidationURL, - PreviousButtonState: 0, - }, nil + BeforeText: "In order allows happyDomain to get and update yours domains, you have to let us access them. To avoid storing your credentials, we will store a unique token that will be associated with your account. For this purpose, you will be redirected to an OVH login screen. The registration will automatically continue", + NextButtonText: "Go to OVH", + PreviousButtonText: "< Previous", + NextButtonLink: response.ValidationURL, + PreviousButtonState: 0, + }, map[string]interface{}{ + "consumerkey": response.ConsumerKey, + }, nil } -func (s *OVHAPI) DisplaySettingsForm(state int32, cfg *config.Options, session *happydns.Session, genRecallId forms.GenRecallID) (*forms.CustomForm, error) { +func (s *OVHAPI) DisplaySettingsForm(state int32, cfg *config.Options, session *happydns.Session, genRecallId forms.GenRecallID) (*forms.CustomForm, map[string]interface{}, error) { switch state { case 0: - return settingsForm(s.ConsumerKey != ""), nil + return settingsForm(s.ConsumerKey != ""), nil, nil case 1: if s.ConsumerKey == "" { recallid := genRecallId() return settingsAskCredentials(cfg, recallid, session) } else { - return nil, forms.DoneForm + return nil, nil, forms.DoneForm } case 2: - var consumerKey string - if ok := session.GetValue(SESSION_CKEY, &consumerKey); !ok { - return nil, errors.New("Something wierd has happend, as you were not in a consumer key registration process. Please retry.") + if s.ConsumerKey == "" { + return nil, nil, errors.New("Something wierd has happend, as you were not in a consumer key registration process. Please retry.") } else { - s.ConsumerKey = consumerKey - session.DropKey(SESSION_CKEY) - return nil, forms.DoneForm + return nil, nil, forms.DoneForm } default: - return nil, forms.CancelForm + return nil, nil, forms.CancelForm } }