Simplify customform handling in backend (let the frontend handle it)
This commit is contained in:
parent
90754b3050
commit
b4da1e0a69
35
api/form.go
35
api/form.go
|
@ -32,8 +32,6 @@
|
||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
|
||||||
"git.happydns.org/happydomain/config"
|
"git.happydns.org/happydomain/config"
|
||||||
|
@ -42,28 +40,15 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type FormState struct {
|
type FormState struct {
|
||||||
Id interface{} `json:"_id,omitempty"`
|
Id *happydns.Identifier `json:"_id,omitempty"`
|
||||||
Name string `json:"_comment"`
|
Name string `json:"_comment"`
|
||||||
State int32 `json:"state"`
|
State int32 `json:"state"`
|
||||||
Recall *int64 `json:"recall,omitempty"`
|
Recall string `json:"recall,omitempty"`
|
||||||
Redirect *string `json:"redirect,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type FormResponse struct {
|
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) {
|
||||||
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) {
|
|
||||||
session := c.MustGet("MySession").(*happydns.Session)
|
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)
|
csf, ok := data.(forms.CustomSettingsForm)
|
||||||
if !ok {
|
if !ok {
|
||||||
if fs.State == 1 {
|
if fs.State == 1 {
|
||||||
|
@ -73,14 +58,8 @@ func formDoState(cfg *config.Options, c *gin.Context, fs *FormState, data interf
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
return csf.DisplaySettingsForm(fs.State, cfg, session, func() int64 {
|
return csf.DisplaySettingsForm(fs.State, cfg, session, func() string {
|
||||||
key, recallid := session.FindNewKey("form-")
|
return fs.Recall
|
||||||
session.SetValue(key, data)
|
|
||||||
session.SetValue(key+"-id", fs.Id)
|
|
||||||
if fs.Redirect != nil {
|
|
||||||
session.SetValue(key+"-next", *fs.Redirect)
|
|
||||||
}
|
|
||||||
return recallid
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,8 +58,9 @@ type ProviderSettingsState struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProviderSettingsResponse struct {
|
type ProviderSettingsResponse struct {
|
||||||
FormResponse
|
Provider *happydns.Provider `json:"Provider,omitempty"`
|
||||||
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) {
|
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 != nil {
|
||||||
if err != forms.DoneForm {
|
if err != forms.DoneForm {
|
||||||
|
@ -104,14 +105,11 @@ func getProviderSettingsState(cfg *config.Options, c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, ProviderSettingsResponse{
|
c.JSON(http.StatusOK, s)
|
||||||
Provider: s,
|
|
||||||
FormResponse: FormResponse{Redirect: uss.Redirect},
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
// Update an existing Provider
|
// 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 {
|
if err != nil {
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()})
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()})
|
||||||
return
|
return
|
||||||
|
@ -125,15 +123,13 @@ func getProviderSettingsState(cfg *config.Options, c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, ProviderSettingsResponse{
|
c.JSON(http.StatusOK, s)
|
||||||
Provider: s,
|
|
||||||
FormResponse: FormResponse{Redirect: uss.Redirect},
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, ProviderSettingsResponse{
|
c.JSON(http.StatusOK, ProviderSettingsResponse{
|
||||||
FormResponse: FormResponse{From: form},
|
Form: form,
|
||||||
|
Values: p,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,6 @@ type ServiceSettingsState struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ServiceSettingsResponse struct {
|
type ServiceSettingsResponse struct {
|
||||||
FormResponse
|
|
||||||
Services map[string][]*happydns.ServiceCombined `json:"services,omitempty"`
|
Services map[string][]*happydns.ServiceCombined `json:"services,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +86,7 @@ func getServiceSettingsState(cfg *config.Options, c *gin.Context) {
|
||||||
return
|
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 != nil {
|
||||||
if err != forms.DoneForm {
|
if err != forms.DoneForm {
|
||||||
|
@ -99,7 +98,7 @@ func getServiceSettingsState(cfg *config.Options, c *gin.Context) {
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
// Update an existing Service
|
// 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 {
|
if err != nil {
|
||||||
|
@ -114,13 +113,13 @@ func getServiceSettingsState(cfg *config.Options, c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, ServiceSettingsResponse{
|
c.JSON(http.StatusOK, ServiceSettingsResponse{
|
||||||
Services: zone.Services,
|
Services: zone.Services,
|
||||||
FormResponse: FormResponse{Redirect: ups.Redirect},
|
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, ProviderSettingsResponse{
|
c.JSON(http.StatusOK, ProviderSettingsResponse{
|
||||||
FormResponse: FormResponse{From: form},
|
Form: form,
|
||||||
|
Values: p,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ package forms // import "happydns.org/forms"
|
||||||
|
|
||||||
import ()
|
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 {
|
type CustomForm struct {
|
||||||
// BeforeText is the text presented before the fields.
|
// BeforeText is the text presented before the fields.
|
||||||
BeforeText string `json:"beforeText,omitempty"`
|
BeforeText string `json:"beforeText,omitempty"`
|
||||||
|
|
|
@ -39,12 +39,12 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// GenRecallID
|
// 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.
|
// CustomSettingsForm are functions to declare when we want to display a custom user experience when asking for Source's settings.
|
||||||
type CustomSettingsForm interface {
|
type CustomSettingsForm interface {
|
||||||
// DisplaySettingsForm generates the CustomForm corresponding to the asked target state.
|
// 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 (
|
var (
|
||||||
|
|
|
@ -42,10 +42,6 @@ import (
|
||||||
"git.happydns.org/happydomain/model"
|
"git.happydns.org/happydomain/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
SESSION_CKEY = "ovh-consumerkey"
|
|
||||||
)
|
|
||||||
|
|
||||||
func settingsForm(edit bool) *forms.CustomForm {
|
func settingsForm(edit bool) *forms.CustomForm {
|
||||||
srcFields := []*forms.Field{
|
srcFields := []*forms.Field{
|
||||||
&forms.Field{
|
&forms.Field{
|
||||||
|
@ -75,56 +71,52 @@ func settingsForm(edit bool) *forms.CustomForm {
|
||||||
return form
|
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, "")
|
client, err := ovh.NewClient("ovh-eu", appKey, appSecret, "")
|
||||||
if err != nil {
|
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
|
// 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.AddRecursiveRules(ovh.ReadWrite, "/domain")
|
||||||
ckReq.AddRules(ovh.ReadOnly, "/me")
|
ckReq.AddRules(ovh.ReadOnly, "/me")
|
||||||
|
|
||||||
response, err := ckReq.Do()
|
response, err := ckReq.Do()
|
||||||
if err != nil {
|
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 some explanation to the user
|
||||||
return &forms.CustomForm{
|
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",
|
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",
|
NextButtonText: "Go to OVH",
|
||||||
PreviousButtonText: "< Previous",
|
PreviousButtonText: "< Previous",
|
||||||
NextButtonLink: response.ValidationURL,
|
NextButtonLink: response.ValidationURL,
|
||||||
PreviousButtonState: 0,
|
PreviousButtonState: 0,
|
||||||
}, nil
|
}, 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 {
|
switch state {
|
||||||
case 0:
|
case 0:
|
||||||
return settingsForm(s.ConsumerKey != ""), nil
|
return settingsForm(s.ConsumerKey != ""), nil, nil
|
||||||
case 1:
|
case 1:
|
||||||
if s.ConsumerKey == "" {
|
if s.ConsumerKey == "" {
|
||||||
recallid := genRecallId()
|
recallid := genRecallId()
|
||||||
return settingsAskCredentials(cfg, recallid, session)
|
return settingsAskCredentials(cfg, recallid, session)
|
||||||
} else {
|
} else {
|
||||||
return nil, forms.DoneForm
|
return nil, nil, forms.DoneForm
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
var consumerKey string
|
if s.ConsumerKey == "" {
|
||||||
if ok := session.GetValue(SESSION_CKEY, &consumerKey); !ok {
|
return nil, nil, errors.New("Something wierd has happend, as you were not in a consumer key registration process. Please retry.")
|
||||||
return nil, errors.New("Something wierd has happend, as you were not in a consumer key registration process. Please retry.")
|
|
||||||
} else {
|
} else {
|
||||||
s.ConsumerKey = consumerKey
|
return nil, nil, forms.DoneForm
|
||||||
session.DropKey(SESSION_CKEY)
|
|
||||||
return nil, forms.DoneForm
|
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return nil, forms.CancelForm
|
return nil, nil, forms.CancelForm
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user