diff --git a/api/compose/spec.json b/api/compose/spec.json index c7cdb34a3..01f8941a9 100644 --- a/api/compose/spec.json +++ b/api/compose/spec.json @@ -1886,25 +1886,26 @@ "authentication": [], "struct": [{ "imports": [ - "sqlxTypes github.com/jmoiron/sqlx/types" + "github.com/cortezaproject/corteza-server/pkg/settings" ] }], - "apis": [{ - "name": "list", - "method": "GET", - "title": "List settings", - "path": "/", - "parameters": { - "get": [ - { - "name": "prefix", - "type": "string", - "title": "Key prefix" + "apis": [ + { + "name": "list", + "method": "GET", + "title": "List settings", + "path": "/", + "parameters": { + "get": [ + { + "name": "prefix", + "type": "string", + "title": "Key prefix" + } + ] } - ] - } - }, - { + }, + { "name": "update", "method": "PATCH", "title": "Update settings", @@ -1912,7 +1913,7 @@ "parameters": { "post": [{ "name": "values", - "type": "sqlxTypes.JSONText", + "type": "settings.ValueSet", "title": "Array of new settings: `[{ name: ..., value: ... }]`. Omit value to remove setting", "required": true }] @@ -1938,30 +1939,10 @@ } }, { - "name": "set", - "method": "PUT", - "title": "Set a value for a key", - "path": "/{key}", - "parameters": { - "path": [{ - "name": "key", - "type": "string", - "title": "Setting key", - "required": true - }], - "post": [{ - "name": "ownerID", - "type": "uint64", - "title": "Owner" - }, - { - "name": "value", - "type": "sqlxTypes.JSONText", - "required": true, - "title": "Setting value" - } - ] - } + "name": "current", + "method": "GET", + "title": "Current compose settings", + "path": "/current" } ] } diff --git a/api/compose/spec/settings.json b/api/compose/spec/settings.json index 12884045d..7366a0b39 100644 --- a/api/compose/spec/settings.json +++ b/api/compose/spec/settings.json @@ -4,7 +4,7 @@ "Struct": [ { "imports": [ - "sqlxTypes github.com/jmoiron/sqlx/types" + "github.com/cortezaproject/corteza-server/pkg/settings" ] } ], @@ -39,7 +39,7 @@ "name": "values", "required": true, "title": "Array of new settings: `[{ name: ..., value: ... }]`. Omit value to remove setting", - "type": "sqlxTypes.JSONText" + "type": "settings.ValueSet" } ] } @@ -68,33 +68,11 @@ } }, { - "Name": "set", - "Method": "PUT", - "Title": "Set a value for a key", - "Path": "/{key}", - "Parameters": { - "path": [ - { - "name": "key", - "required": true, - "title": "Setting key", - "type": "string" - } - ], - "post": [ - { - "name": "ownerID", - "title": "Owner", - "type": "uint64" - }, - { - "name": "value", - "required": true, - "title": "Setting value", - "type": "sqlxTypes.JSONText" - } - ] - } + "Name": "current", + "Method": "GET", + "Title": "Current compose settings", + "Path": "/current", + "Parameters": null } ] } \ No newline at end of file diff --git a/api/messaging/spec.json b/api/messaging/spec.json index 102f41275..c1787d9d4 100644 --- a/api/messaging/spec.json +++ b/api/messaging/spec.json @@ -1253,25 +1253,26 @@ "authentication": [], "struct": [{ "imports": [ - "sqlxTypes github.com/jmoiron/sqlx/types" + "github.com/cortezaproject/corteza-server/pkg/settings" ] }], - "apis": [{ - "name": "list", - "method": "GET", - "title": "List settings", - "path": "/", - "parameters": { - "get": [ - { - "name": "prefix", - "type": "string", - "title": "Key prefix" + "apis": [ + { + "name": "list", + "method": "GET", + "title": "List settings", + "path": "/", + "parameters": { + "get": [ + { + "name": "prefix", + "type": "string", + "title": "Key prefix" + } + ] } - ] - } - }, - { + }, + { "name": "update", "method": "PATCH", "title": "Update settings", @@ -1279,7 +1280,7 @@ "parameters": { "post": [{ "name": "values", - "type": "sqlxTypes.JSONText", + "type": "settings.ValueSet", "title": "Array of new settings: `[{ name: ..., value: ... }]`. Omit value to remove setting", "required": true }] @@ -1305,30 +1306,10 @@ } }, { - "name": "set", - "method": "PUT", - "title": "Set a value for a key", - "path": "/{key}", - "parameters": { - "path": [{ - "name": "key", - "type": "string", - "title": "Setting key", - "required": true - }], - "post": [{ - "name": "ownerID", - "type": "uint64", - "title": "Owner" - }, - { - "name": "value", - "type": "sqlxTypes.JSONText", - "required": true, - "title": "Setting value" - } - ] - } + "name": "current", + "method": "GET", + "title": "Current compose settings", + "path": "/current" } ] } diff --git a/api/messaging/spec/settings.json b/api/messaging/spec/settings.json index 12884045d..7366a0b39 100644 --- a/api/messaging/spec/settings.json +++ b/api/messaging/spec/settings.json @@ -4,7 +4,7 @@ "Struct": [ { "imports": [ - "sqlxTypes github.com/jmoiron/sqlx/types" + "github.com/cortezaproject/corteza-server/pkg/settings" ] } ], @@ -39,7 +39,7 @@ "name": "values", "required": true, "title": "Array of new settings: `[{ name: ..., value: ... }]`. Omit value to remove setting", - "type": "sqlxTypes.JSONText" + "type": "settings.ValueSet" } ] } @@ -68,33 +68,11 @@ } }, { - "Name": "set", - "Method": "PUT", - "Title": "Set a value for a key", - "Path": "/{key}", - "Parameters": { - "path": [ - { - "name": "key", - "required": true, - "title": "Setting key", - "type": "string" - } - ], - "post": [ - { - "name": "ownerID", - "title": "Owner", - "type": "uint64" - }, - { - "name": "value", - "required": true, - "title": "Setting value", - "type": "sqlxTypes.JSONText" - } - ] - } + "Name": "current", + "Method": "GET", + "Title": "Current compose settings", + "Path": "/current", + "Parameters": null } ] } \ No newline at end of file diff --git a/api/system/spec.json b/api/system/spec.json index 4ae055f14..3bf927c78 100644 --- a/api/system/spec.json +++ b/api/system/spec.json @@ -217,13 +217,11 @@ "path": "/settings", "entrypoint": "settings", "authentication": [], - "struct": [ - { - "imports": [ - "sqlxTypes github.com/jmoiron/sqlx/types" - ] - } - ], + "struct": [{ + "imports": [ + "github.com/cortezaproject/corteza-server/pkg/settings" + ] + }], "apis": [ { "name": "list", @@ -246,67 +244,38 @@ "title": "Update settings", "path": "/", "parameters": { - "post": [ - { - "name": "values", - "type": "sqlxTypes.JSONText", - "title": "Array of new settings: `[{ name: ..., value: ... }]`. Omit value to remove setting", - "required": true - } - ] + "post": [{ + "name": "values", + "type": "settings.ValueSet", + "title": "Array of new settings: `[{ name: ..., value: ... }]`. Omit value to remove setting", + "required": true + }] } }, { "name": "get", "method": "GET", - "title": "Check JWT token", + "title": "Get a value for a key", "path": "/{key}", "parameters": { - "path": [ - { - "name": "key", - "type": "string", - "title": "Setting key", - "required": true - } - ], - "get": [ - { - "name": "ownerID", - "type": "uint64", - "title": "Owner ID" - } - ] + "path": [{ + "name": "key", + "type": "string", + "title": "Setting key", + "required": true + }], + "get": [{ + "name": "ownerID", + "type": "uint64", + "title": "Owner ID" + }] } }, { - "name": "set", - "method": "PUT", - "title": "Set a value for a key", - "path": "/{key}", - "parameters": { - "path": [ - { - "name": "key", - "type": "string", - "title": "Setting key", - "required": true - } - ], - "post": [ - { - "name": "ownerID", - "type": "uint64", - "title": "Owner" - }, - { - "name": "value", - "type": "sqlxTypes.JSONText", - "required": true, - "title": "Setting value" - } - ] - } + "name": "current", + "method": "GET", + "title": "Current compose settings", + "path": "/current" } ] }, diff --git a/api/system/spec/settings.json b/api/system/spec/settings.json index 116a47865..7366a0b39 100644 --- a/api/system/spec/settings.json +++ b/api/system/spec/settings.json @@ -4,7 +4,7 @@ "Struct": [ { "imports": [ - "sqlxTypes github.com/jmoiron/sqlx/types" + "github.com/cortezaproject/corteza-server/pkg/settings" ] } ], @@ -39,7 +39,7 @@ "name": "values", "required": true, "title": "Array of new settings: `[{ name: ..., value: ... }]`. Omit value to remove setting", - "type": "sqlxTypes.JSONText" + "type": "settings.ValueSet" } ] } @@ -47,7 +47,7 @@ { "Name": "get", "Method": "GET", - "Title": "Check JWT token", + "Title": "Get a value for a key", "Path": "/{key}", "Parameters": { "get": [ @@ -68,33 +68,11 @@ } }, { - "Name": "set", - "Method": "PUT", - "Title": "Set a value for a key", - "Path": "/{key}", - "Parameters": { - "path": [ - { - "name": "key", - "required": true, - "title": "Setting key", - "type": "string" - } - ], - "post": [ - { - "name": "ownerID", - "title": "Owner", - "type": "uint64" - }, - { - "name": "value", - "required": true, - "title": "Setting value", - "type": "sqlxTypes.JSONText" - } - ] - } + "Name": "current", + "Method": "GET", + "Title": "Current compose settings", + "Path": "/current", + "Parameters": null } ] } \ No newline at end of file diff --git a/compose/rest/handlers/settings.go b/compose/rest/handlers/settings.go index f0e266bf9..6f46b1ca3 100644 --- a/compose/rest/handlers/settings.go +++ b/compose/rest/handlers/settings.go @@ -32,15 +32,15 @@ type SettingsAPI interface { List(context.Context, *request.SettingsList) (interface{}, error) Update(context.Context, *request.SettingsUpdate) (interface{}, error) Get(context.Context, *request.SettingsGet) (interface{}, error) - Set(context.Context, *request.SettingsSet) (interface{}, error) + Current(context.Context, *request.SettingsCurrent) (interface{}, error) } // HTTP API interface type Settings struct { - List func(http.ResponseWriter, *http.Request) - Update func(http.ResponseWriter, *http.Request) - Get func(http.ResponseWriter, *http.Request) - Set func(http.ResponseWriter, *http.Request) + List func(http.ResponseWriter, *http.Request) + Update func(http.ResponseWriter, *http.Request) + Get func(http.ResponseWriter, *http.Request) + Current func(http.ResponseWriter, *http.Request) } func NewSettings(h SettingsAPI) *Settings { @@ -105,22 +105,22 @@ func NewSettings(h SettingsAPI) *Settings { resputil.JSON(w, value) } }, - Set: func(w http.ResponseWriter, r *http.Request) { + Current: func(w http.ResponseWriter, r *http.Request) { defer r.Body.Close() - params := request.NewSettingsSet() + params := request.NewSettingsCurrent() if err := params.Fill(r); err != nil { - logger.LogParamError("Settings.Set", r, err) + logger.LogParamError("Settings.Current", r, err) resputil.JSON(w, err) return } - value, err := h.Set(r.Context(), params) + value, err := h.Current(r.Context(), params) if err != nil { - logger.LogControllerError("Settings.Set", r, err, params.Auditable()) + logger.LogControllerError("Settings.Current", r, err, params.Auditable()) resputil.JSON(w, err) return } - logger.LogControllerCall("Settings.Set", r, params.Auditable()) + logger.LogControllerCall("Settings.Current", r, params.Auditable()) if !serveHTTP(value, w, r) { resputil.JSON(w, value) } @@ -134,6 +134,6 @@ func (h Settings) MountRoutes(r chi.Router, middlewares ...func(http.Handler) ht r.Get("/settings/", h.List) r.Patch("/settings/", h.Update) r.Get("/settings/{key}", h.Get) - r.Put("/settings/{key}", h.Set) + r.Get("/settings/current", h.Current) }) } diff --git a/compose/rest/request/settings.go b/compose/rest/request/settings.go index 368166e14..321f85ffd 100644 --- a/compose/rest/request/settings.go +++ b/compose/rest/request/settings.go @@ -26,7 +26,7 @@ import ( "github.com/go-chi/chi" "github.com/pkg/errors" - sqlxTypes "github.com/jmoiron/sqlx/types" + "github.com/cortezaproject/corteza-server/pkg/settings" ) var _ = chi.URLParam @@ -87,7 +87,7 @@ var _ RequestFiller = NewSettingsList() // Settings update request parameters type SettingsUpdate struct { - Values sqlxTypes.JSONText + Values settings.ValueSet } func NewSettingsUpdate() *SettingsUpdate { @@ -129,13 +129,6 @@ func (r *SettingsUpdate) Fill(req *http.Request) (err error) { post[name] = string(param[0]) } - if val, ok := post["values"]; ok { - - if r.Values, err = parseJSONTextWithErr(val); err != nil { - return err - } - } - return err } @@ -197,28 +190,21 @@ func (r *SettingsGet) Fill(req *http.Request) (err error) { var _ RequestFiller = NewSettingsGet() -// Settings set request parameters -type SettingsSet struct { - Key string - OwnerID uint64 `json:",string"` - Value sqlxTypes.JSONText +// Settings current request parameters +type SettingsCurrent struct { } -func NewSettingsSet() *SettingsSet { - return &SettingsSet{} +func NewSettingsCurrent() *SettingsCurrent { + return &SettingsCurrent{} } -func (r SettingsSet) Auditable() map[string]interface{} { +func (r SettingsCurrent) Auditable() map[string]interface{} { var out = map[string]interface{}{} - out["key"] = r.Key - out["ownerID"] = r.OwnerID - out["value"] = r.Value - return out } -func (r *SettingsSet) Fill(req *http.Request) (err error) { +func (r *SettingsCurrent) Fill(req *http.Request) (err error) { if strings.ToLower(req.Header.Get("content-type")) == "application/json" { err = json.NewDecoder(req.Body).Decode(r) @@ -245,18 +231,7 @@ func (r *SettingsSet) Fill(req *http.Request) (err error) { post[name] = string(param[0]) } - r.Key = chi.URLParam(req, "key") - if val, ok := post["ownerID"]; ok { - r.OwnerID = parseUInt64(val) - } - if val, ok := post["value"]; ok { - - if r.Value, err = parseJSONTextWithErr(val); err != nil { - return err - } - } - return err } -var _ RequestFiller = NewSettingsSet() +var _ RequestFiller = NewSettingsCurrent() diff --git a/compose/rest/settings.go b/compose/rest/settings.go index 7964da17d..be93f6cb6 100644 --- a/compose/rest/settings.go +++ b/compose/rest/settings.go @@ -4,11 +4,9 @@ import ( "context" "github.com/pkg/errors" - "github.com/titpetric/factory/resputil" "github.com/cortezaproject/corteza-server/compose/rest/request" "github.com/cortezaproject/corteza-server/compose/service" - "github.com/cortezaproject/corteza-server/pkg/settings" ) var _ = errors.Wrap @@ -37,11 +35,7 @@ func (ctrl *Settings) List(ctx context.Context, r *request.SettingsList) (interf } func (ctrl *Settings) Update(ctx context.Context, r *request.SettingsUpdate) (interface{}, error) { - values := settings.ValueSet{} - - if err := r.Values.Unmarshal(&values); err != nil { - return nil, err - } else if err := ctrl.svc.settings.With(ctx).BulkSet(values); err != nil { + if err := ctrl.svc.settings.With(ctx).BulkSet(r.Values); err != nil { return nil, err } else { return true, nil @@ -56,6 +50,6 @@ func (ctrl *Settings) Get(ctx context.Context, r *request.SettingsGet) (interfac } } -func (ctrl *Settings) Set(ctx context.Context, r *request.SettingsSet) (interface{}, error) { - return resputil.OK(), errors.New("Not implemented: Settings.set") +func (ctrl *Settings) Current(ctx context.Context, r *request.SettingsCurrent) (interface{}, error) { + return service.CurrentSettings, nil } diff --git a/compose/types/settings.go b/compose/types/settings.go index 7673a210a..4f5b6c6bf 100644 --- a/compose/types/settings.go +++ b/compose/types/settings.go @@ -1,6 +1,11 @@ package types type ( + // Settings type is structured representation of current compose settings + // + // Raw settings keys are hypen (kebab) case, separated with a dot (.) that indicates sub-level + // JSON properties for settings are NOT converted (lower-cased, etc...) + // Use `json:"-"` tag to hide settings on REST endpoint Settings struct { // UI related settings UI struct { diff --git a/docs/compose/README.md b/docs/compose/README.md index f7f78732a..d8f7c276f 100644 --- a/docs/compose/README.md +++ b/docs/compose/README.md @@ -1199,7 +1199,7 @@ Compose records | `GET` | `/settings/` | List settings | | `PATCH` | `/settings/` | Update settings | | `GET` | `/settings/{key}` | Get a value for a key | -| `PUT` | `/settings/{key}` | Set a value for a key | +| `GET` | `/settings/current` | Current compose settings | ## List settings @@ -1227,7 +1227,7 @@ Compose records | Parameter | Type | Method | Description | Default | Required? | | --------- | ---- | ------ | ----------- | ------- | --------- | -| values | sqlxTypes.JSONText | POST | Array of new settings: `[{ name: ..., value: ... }]`. Omit value to remove setting | N/A | YES | +| values | settings.ValueSet | POST | Array of new settings: `[{ name: ..., value: ... }]`. Omit value to remove setting | N/A | YES | ## Get a value for a key @@ -1244,20 +1244,17 @@ Compose records | ownerID | uint64 | GET | Owner ID | N/A | NO | | key | string | PATH | Setting key | N/A | YES | -## Set a value for a key +## Current compose settings #### Method | URI | Protocol | Method | Authentication | | --- | -------- | ------ | -------------- | -| `/settings/{key}` | HTTP/S | PUT | | +| `/settings/current` | HTTP/S | GET | | #### Request parameters | Parameter | Type | Method | Description | Default | Required? | | --------- | ---- | ------ | ----------- | ------- | --------- | -| key | string | PATH | Setting key | N/A | YES | -| ownerID | uint64 | POST | Owner | N/A | NO | -| value | sqlxTypes.JSONText | POST | Setting value | N/A | YES | --- \ No newline at end of file diff --git a/docs/messaging/README.md b/docs/messaging/README.md index a43adf030..1fb6f9ff4 100644 --- a/docs/messaging/README.md +++ b/docs/messaging/README.md @@ -658,7 +658,7 @@ A channel is a representation of a sequence of messages. It has meta data like c | `GET` | `/settings/` | List settings | | `PATCH` | `/settings/` | Update settings | | `GET` | `/settings/{key}` | Get a value for a key | -| `PUT` | `/settings/{key}` | Set a value for a key | +| `GET` | `/settings/current` | Current compose settings | ## List settings @@ -686,7 +686,7 @@ A channel is a representation of a sequence of messages. It has meta data like c | Parameter | Type | Method | Description | Default | Required? | | --------- | ---- | ------ | ----------- | ------- | --------- | -| values | sqlxTypes.JSONText | POST | Array of new settings: `[{ name: ..., value: ... }]`. Omit value to remove setting | N/A | YES | +| values | settings.ValueSet | POST | Array of new settings: `[{ name: ..., value: ... }]`. Omit value to remove setting | N/A | YES | ## Get a value for a key @@ -703,21 +703,18 @@ A channel is a representation of a sequence of messages. It has meta data like c | ownerID | uint64 | GET | Owner ID | N/A | NO | | key | string | PATH | Setting key | N/A | YES | -## Set a value for a key +## Current compose settings #### Method | URI | Protocol | Method | Authentication | | --- | -------- | ------ | -------------- | -| `/settings/{key}` | HTTP/S | PUT | | +| `/settings/current` | HTTP/S | GET | | #### Request parameters | Parameter | Type | Method | Description | Default | Required? | | --------- | ---- | ------ | ----------- | ------- | --------- | -| key | string | PATH | Setting key | N/A | YES | -| ownerID | uint64 | POST | Owner | N/A | NO | -| value | sqlxTypes.JSONText | POST | Setting value | N/A | YES | --- diff --git a/docs/system/README.md b/docs/system/README.md index 52d664e43..55ed0f0a5 100644 --- a/docs/system/README.md +++ b/docs/system/README.md @@ -1018,8 +1018,8 @@ An organisation may have many roles. Roles may have many channels available. Acc | ------ | -------- | ------- | | `GET` | `/settings/` | List settings | | `PATCH` | `/settings/` | Update settings | -| `GET` | `/settings/{key}` | Check JWT token | -| `PUT` | `/settings/{key}` | Set a value for a key | +| `GET` | `/settings/{key}` | Get a value for a key | +| `GET` | `/settings/current` | Current compose settings | ## List settings @@ -1047,9 +1047,9 @@ An organisation may have many roles. Roles may have many channels available. Acc | Parameter | Type | Method | Description | Default | Required? | | --------- | ---- | ------ | ----------- | ------- | --------- | -| values | sqlxTypes.JSONText | POST | Array of new settings: `[{ name: ..., value: ... }]`. Omit value to remove setting | N/A | YES | +| values | settings.ValueSet | POST | Array of new settings: `[{ name: ..., value: ... }]`. Omit value to remove setting | N/A | YES | -## Check JWT token +## Get a value for a key #### Method @@ -1064,21 +1064,18 @@ An organisation may have many roles. Roles may have many channels available. Acc | ownerID | uint64 | GET | Owner ID | N/A | NO | | key | string | PATH | Setting key | N/A | YES | -## Set a value for a key +## Current compose settings #### Method | URI | Protocol | Method | Authentication | | --- | -------- | ------ | -------------- | -| `/settings/{key}` | HTTP/S | PUT | | +| `/settings/current` | HTTP/S | GET | | #### Request parameters | Parameter | Type | Method | Description | Default | Required? | | --------- | ---- | ------ | ----------- | ------- | --------- | -| key | string | PATH | Setting key | N/A | YES | -| ownerID | uint64 | POST | Owner | N/A | NO | -| value | sqlxTypes.JSONText | POST | Setting value | N/A | YES | --- diff --git a/messaging/rest/handlers/settings.go b/messaging/rest/handlers/settings.go index 4339affaa..776d8403b 100644 --- a/messaging/rest/handlers/settings.go +++ b/messaging/rest/handlers/settings.go @@ -32,15 +32,15 @@ type SettingsAPI interface { List(context.Context, *request.SettingsList) (interface{}, error) Update(context.Context, *request.SettingsUpdate) (interface{}, error) Get(context.Context, *request.SettingsGet) (interface{}, error) - Set(context.Context, *request.SettingsSet) (interface{}, error) + Current(context.Context, *request.SettingsCurrent) (interface{}, error) } // HTTP API interface type Settings struct { - List func(http.ResponseWriter, *http.Request) - Update func(http.ResponseWriter, *http.Request) - Get func(http.ResponseWriter, *http.Request) - Set func(http.ResponseWriter, *http.Request) + List func(http.ResponseWriter, *http.Request) + Update func(http.ResponseWriter, *http.Request) + Get func(http.ResponseWriter, *http.Request) + Current func(http.ResponseWriter, *http.Request) } func NewSettings(h SettingsAPI) *Settings { @@ -105,22 +105,22 @@ func NewSettings(h SettingsAPI) *Settings { resputil.JSON(w, value) } }, - Set: func(w http.ResponseWriter, r *http.Request) { + Current: func(w http.ResponseWriter, r *http.Request) { defer r.Body.Close() - params := request.NewSettingsSet() + params := request.NewSettingsCurrent() if err := params.Fill(r); err != nil { - logger.LogParamError("Settings.Set", r, err) + logger.LogParamError("Settings.Current", r, err) resputil.JSON(w, err) return } - value, err := h.Set(r.Context(), params) + value, err := h.Current(r.Context(), params) if err != nil { - logger.LogControllerError("Settings.Set", r, err, params.Auditable()) + logger.LogControllerError("Settings.Current", r, err, params.Auditable()) resputil.JSON(w, err) return } - logger.LogControllerCall("Settings.Set", r, params.Auditable()) + logger.LogControllerCall("Settings.Current", r, params.Auditable()) if !serveHTTP(value, w, r) { resputil.JSON(w, value) } @@ -134,6 +134,6 @@ func (h Settings) MountRoutes(r chi.Router, middlewares ...func(http.Handler) ht r.Get("/settings/", h.List) r.Patch("/settings/", h.Update) r.Get("/settings/{key}", h.Get) - r.Put("/settings/{key}", h.Set) + r.Get("/settings/current", h.Current) }) } diff --git a/messaging/rest/request/settings.go b/messaging/rest/request/settings.go index 368166e14..321f85ffd 100644 --- a/messaging/rest/request/settings.go +++ b/messaging/rest/request/settings.go @@ -26,7 +26,7 @@ import ( "github.com/go-chi/chi" "github.com/pkg/errors" - sqlxTypes "github.com/jmoiron/sqlx/types" + "github.com/cortezaproject/corteza-server/pkg/settings" ) var _ = chi.URLParam @@ -87,7 +87,7 @@ var _ RequestFiller = NewSettingsList() // Settings update request parameters type SettingsUpdate struct { - Values sqlxTypes.JSONText + Values settings.ValueSet } func NewSettingsUpdate() *SettingsUpdate { @@ -129,13 +129,6 @@ func (r *SettingsUpdate) Fill(req *http.Request) (err error) { post[name] = string(param[0]) } - if val, ok := post["values"]; ok { - - if r.Values, err = parseJSONTextWithErr(val); err != nil { - return err - } - } - return err } @@ -197,28 +190,21 @@ func (r *SettingsGet) Fill(req *http.Request) (err error) { var _ RequestFiller = NewSettingsGet() -// Settings set request parameters -type SettingsSet struct { - Key string - OwnerID uint64 `json:",string"` - Value sqlxTypes.JSONText +// Settings current request parameters +type SettingsCurrent struct { } -func NewSettingsSet() *SettingsSet { - return &SettingsSet{} +func NewSettingsCurrent() *SettingsCurrent { + return &SettingsCurrent{} } -func (r SettingsSet) Auditable() map[string]interface{} { +func (r SettingsCurrent) Auditable() map[string]interface{} { var out = map[string]interface{}{} - out["key"] = r.Key - out["ownerID"] = r.OwnerID - out["value"] = r.Value - return out } -func (r *SettingsSet) Fill(req *http.Request) (err error) { +func (r *SettingsCurrent) Fill(req *http.Request) (err error) { if strings.ToLower(req.Header.Get("content-type")) == "application/json" { err = json.NewDecoder(req.Body).Decode(r) @@ -245,18 +231,7 @@ func (r *SettingsSet) Fill(req *http.Request) (err error) { post[name] = string(param[0]) } - r.Key = chi.URLParam(req, "key") - if val, ok := post["ownerID"]; ok { - r.OwnerID = parseUInt64(val) - } - if val, ok := post["value"]; ok { - - if r.Value, err = parseJSONTextWithErr(val); err != nil { - return err - } - } - return err } -var _ RequestFiller = NewSettingsSet() +var _ RequestFiller = NewSettingsCurrent() diff --git a/messaging/rest/settings.go b/messaging/rest/settings.go index 88e306b8b..18a2ef661 100644 --- a/messaging/rest/settings.go +++ b/messaging/rest/settings.go @@ -4,11 +4,9 @@ import ( "context" "github.com/pkg/errors" - "github.com/titpetric/factory/resputil" "github.com/cortezaproject/corteza-server/messaging/rest/request" "github.com/cortezaproject/corteza-server/messaging/service" - "github.com/cortezaproject/corteza-server/pkg/settings" ) var _ = errors.Wrap @@ -37,11 +35,7 @@ func (ctrl *Settings) List(ctx context.Context, r *request.SettingsList) (interf } func (ctrl *Settings) Update(ctx context.Context, r *request.SettingsUpdate) (interface{}, error) { - values := settings.ValueSet{} - - if err := r.Values.Unmarshal(&values); err != nil { - return nil, err - } else if err := ctrl.svc.settings.With(ctx).BulkSet(values); err != nil { + if err := ctrl.svc.settings.With(ctx).BulkSet(r.Values); err != nil { return nil, err } else { return true, nil @@ -56,6 +50,6 @@ func (ctrl *Settings) Get(ctx context.Context, r *request.SettingsGet) (interfac } } -func (ctrl *Settings) Set(ctx context.Context, r *request.SettingsSet) (interface{}, error) { - return resputil.OK(), errors.New("Not implemented: Settings.set") +func (ctrl *Settings) Current(ctx context.Context, r *request.SettingsCurrent) (interface{}, error) { + return service.CurrentSettings, nil } diff --git a/messaging/types/settings.go b/messaging/types/settings.go index dc25573f5..837d23ec6 100644 --- a/messaging/types/settings.go +++ b/messaging/types/settings.go @@ -1,6 +1,11 @@ package types type ( + // Settings type is structured representation of current messaging settings + // + // Raw settings keys are hypen (kebab) case, separated with a dot (.) that indicates sub-level + // JSON properties for settings are NOT converted (lower-cased, etc...) + // Use `json:"-"` tag to hide settings on REST endpoint Settings struct { // UI related settings UI struct { diff --git a/system/rest/handlers/settings.go b/system/rest/handlers/settings.go index d850eb6b2..a40ce8d59 100644 --- a/system/rest/handlers/settings.go +++ b/system/rest/handlers/settings.go @@ -32,15 +32,15 @@ type SettingsAPI interface { List(context.Context, *request.SettingsList) (interface{}, error) Update(context.Context, *request.SettingsUpdate) (interface{}, error) Get(context.Context, *request.SettingsGet) (interface{}, error) - Set(context.Context, *request.SettingsSet) (interface{}, error) + Current(context.Context, *request.SettingsCurrent) (interface{}, error) } // HTTP API interface type Settings struct { - List func(http.ResponseWriter, *http.Request) - Update func(http.ResponseWriter, *http.Request) - Get func(http.ResponseWriter, *http.Request) - Set func(http.ResponseWriter, *http.Request) + List func(http.ResponseWriter, *http.Request) + Update func(http.ResponseWriter, *http.Request) + Get func(http.ResponseWriter, *http.Request) + Current func(http.ResponseWriter, *http.Request) } func NewSettings(h SettingsAPI) *Settings { @@ -105,22 +105,22 @@ func NewSettings(h SettingsAPI) *Settings { resputil.JSON(w, value) } }, - Set: func(w http.ResponseWriter, r *http.Request) { + Current: func(w http.ResponseWriter, r *http.Request) { defer r.Body.Close() - params := request.NewSettingsSet() + params := request.NewSettingsCurrent() if err := params.Fill(r); err != nil { - logger.LogParamError("Settings.Set", r, err) + logger.LogParamError("Settings.Current", r, err) resputil.JSON(w, err) return } - value, err := h.Set(r.Context(), params) + value, err := h.Current(r.Context(), params) if err != nil { - logger.LogControllerError("Settings.Set", r, err, params.Auditable()) + logger.LogControllerError("Settings.Current", r, err, params.Auditable()) resputil.JSON(w, err) return } - logger.LogControllerCall("Settings.Set", r, params.Auditable()) + logger.LogControllerCall("Settings.Current", r, params.Auditable()) if !serveHTTP(value, w, r) { resputil.JSON(w, value) } @@ -134,6 +134,6 @@ func (h Settings) MountRoutes(r chi.Router, middlewares ...func(http.Handler) ht r.Get("/settings/", h.List) r.Patch("/settings/", h.Update) r.Get("/settings/{key}", h.Get) - r.Put("/settings/{key}", h.Set) + r.Get("/settings/current", h.Current) }) } diff --git a/system/rest/request/settings.go b/system/rest/request/settings.go index 368166e14..321f85ffd 100644 --- a/system/rest/request/settings.go +++ b/system/rest/request/settings.go @@ -26,7 +26,7 @@ import ( "github.com/go-chi/chi" "github.com/pkg/errors" - sqlxTypes "github.com/jmoiron/sqlx/types" + "github.com/cortezaproject/corteza-server/pkg/settings" ) var _ = chi.URLParam @@ -87,7 +87,7 @@ var _ RequestFiller = NewSettingsList() // Settings update request parameters type SettingsUpdate struct { - Values sqlxTypes.JSONText + Values settings.ValueSet } func NewSettingsUpdate() *SettingsUpdate { @@ -129,13 +129,6 @@ func (r *SettingsUpdate) Fill(req *http.Request) (err error) { post[name] = string(param[0]) } - if val, ok := post["values"]; ok { - - if r.Values, err = parseJSONTextWithErr(val); err != nil { - return err - } - } - return err } @@ -197,28 +190,21 @@ func (r *SettingsGet) Fill(req *http.Request) (err error) { var _ RequestFiller = NewSettingsGet() -// Settings set request parameters -type SettingsSet struct { - Key string - OwnerID uint64 `json:",string"` - Value sqlxTypes.JSONText +// Settings current request parameters +type SettingsCurrent struct { } -func NewSettingsSet() *SettingsSet { - return &SettingsSet{} +func NewSettingsCurrent() *SettingsCurrent { + return &SettingsCurrent{} } -func (r SettingsSet) Auditable() map[string]interface{} { +func (r SettingsCurrent) Auditable() map[string]interface{} { var out = map[string]interface{}{} - out["key"] = r.Key - out["ownerID"] = r.OwnerID - out["value"] = r.Value - return out } -func (r *SettingsSet) Fill(req *http.Request) (err error) { +func (r *SettingsCurrent) Fill(req *http.Request) (err error) { if strings.ToLower(req.Header.Get("content-type")) == "application/json" { err = json.NewDecoder(req.Body).Decode(r) @@ -245,18 +231,7 @@ func (r *SettingsSet) Fill(req *http.Request) (err error) { post[name] = string(param[0]) } - r.Key = chi.URLParam(req, "key") - if val, ok := post["ownerID"]; ok { - r.OwnerID = parseUInt64(val) - } - if val, ok := post["value"]; ok { - - if r.Value, err = parseJSONTextWithErr(val); err != nil { - return err - } - } - return err } -var _ RequestFiller = NewSettingsSet() +var _ RequestFiller = NewSettingsCurrent() diff --git a/system/rest/settings.go b/system/rest/settings.go index 7d0c1964f..deec5c6fa 100644 --- a/system/rest/settings.go +++ b/system/rest/settings.go @@ -4,9 +4,7 @@ import ( "context" "github.com/pkg/errors" - "github.com/titpetric/factory/resputil" - "github.com/cortezaproject/corteza-server/pkg/settings" "github.com/cortezaproject/corteza-server/system/rest/request" "github.com/cortezaproject/corteza-server/system/service" ) @@ -17,6 +15,7 @@ type ( Settings struct { svc struct { settings service.SettingsService + auth service.AuthService } } ) @@ -24,6 +23,7 @@ type ( func (Settings) New() *Settings { ctrl := &Settings{} ctrl.svc.settings = service.DefaultSettings + ctrl.svc.auth = service.DefaultAuth return ctrl } @@ -37,11 +37,7 @@ func (ctrl *Settings) List(ctx context.Context, r *request.SettingsList) (interf } func (ctrl *Settings) Update(ctx context.Context, r *request.SettingsUpdate) (interface{}, error) { - values := settings.ValueSet{} - - if err := r.Values.Unmarshal(&values); err != nil { - return nil, err - } else if err := ctrl.svc.settings.With(ctx).BulkSet(values); err != nil { + if err := ctrl.svc.settings.With(ctx).BulkSet(r.Values); err != nil { return nil, err } else { return true, nil @@ -56,6 +52,11 @@ func (ctrl *Settings) Get(ctx context.Context, r *request.SettingsGet) (interfac } } -func (ctrl *Settings) Set(ctx context.Context, r *request.SettingsSet) (interface{}, error) { - return resputil.OK(), errors.New("Not implemented: Settings.set") +func (ctrl *Settings) Current(ctx context.Context, r *request.SettingsCurrent) (interface{}, error) { + if err := ctrl.svc.auth.With(ctx).CanRegister(); err != nil { + // Append signup warning to current settings + service.CurrentSettings.Auth.SignupWarning = err.Error() + } + + return service.CurrentSettings, nil } diff --git a/system/types/settings.go b/system/types/settings.go index 34bb5fdb6..7fe6d99d5 100644 --- a/system/types/settings.go +++ b/system/types/settings.go @@ -9,7 +9,11 @@ import ( ) type ( - // Settings structured representation of current system settings + // Settings type is structured representation of current system settings + // + // Raw settings keys are hypen (kebab) case, separated with a dot (.) that indicates sub-level + // JSON properties for settings are NOT converted (lower-cased, etc...) + // Use `json:"-"` tag to hide settings on REST endpoint Settings struct { Privacy struct { Mask struct { @@ -19,7 +23,7 @@ type ( // Enable masking of user's name (value replaced with ######) Name bool } - } + } `json:"-"` General struct { Mail struct { @@ -27,9 +31,14 @@ type ( Header string `kv:"header.en"` Footer string `kv:"footer.en"` } - } + } `json:"-"` Auth struct { + // Not a setting, only a holder for potential + // warning for from subscription + SignupWarning string `json:",omitempty", kv:"-"` + + Internal struct { // Is internal authentication (username + password) enabled Enabled bool @@ -51,13 +60,13 @@ type ( Enabled bool // Where to redirect (url used for registration) - RedirectUrl string `kv:"redirect-url"` + RedirectUrl string `json:"-" kv:"redirect-url"` // session secret to use - SessionStoreSecret string `kv:"session-store-secret"` + SessionStoreSecret string `json:"-" kv:"session-store-secret"` // session store should be secure - SessionStoreSecure bool `kv:"session-store-secure"` + SessionStoreSecure bool `json:"-" kv:"session-store-secure"` // all external providers we know Providers ExternalAuthProviderSet @@ -92,7 +101,7 @@ type ( Subject string `kv:"subject.en"` Body string `kv:"body.en"` } `kv:"password-reset"` - } + } `json:"-"` } }