Skip to content

Commit

Permalink
complete admin configs APIs [#628]
Browse files Browse the repository at this point in the history
  • Loading branch information
roberlander2 committed Feb 6, 2023
1 parent 0e4104a commit 775b914
Show file tree
Hide file tree
Showing 14 changed files with 295 additions and 61 deletions.
8 changes: 4 additions & 4 deletions .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -285,21 +285,21 @@
"filename": "driver/web/docs/gen/gen_types.go",
"hashed_secret": "c9739eab2dfa093cc0e450bf0ea81a43ae67b581",
"is_verified": false,
"line_number": 1389
"line_number": 1401
},
{
"type": "Secret Keyword",
"filename": "driver/web/docs/gen/gen_types.go",
"hashed_secret": "9afb15df443d57204a2a0f82e164a9c46749dec6",
"is_verified": false,
"line_number": 1783
"line_number": 1795
},
{
"type": "Secret Keyword",
"filename": "driver/web/docs/gen/gen_types.go",
"hashed_secret": "b296a47f167e06833104ebf060da1b4bbb4d619b",
"is_verified": false,
"line_number": 1786
"line_number": 1798
}
],
"driver/web/docs/resources/admin/auth/login.yaml": [
Expand Down Expand Up @@ -330,5 +330,5 @@
}
]
},
"generated_at": "2023-02-04T09:02:55Z"
"generated_at": "2023-02-06T22:57:57Z"
}
4 changes: 4 additions & 0 deletions core/apis.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,10 @@ func (s *administrationImpl) AdmGetConfig(id string, system bool) (*model.Config
return s.app.admGetConfig(id, system)
}

func (s *administrationImpl) AdmGetConfigs(configType *string, appID *string, orgID *string, system bool) ([]model.Config, error) {
return s.app.admGetConfigs(configType, appID, orgID, system)
}

func (s *administrationImpl) AdmCreateConfig(config model.Config, system bool) error {
return s.app.admCreateConfig(config, system)
}
Expand Down
65 changes: 50 additions & 15 deletions core/app_administration.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,13 +186,38 @@ func (app *application) adminGetAppConfig(appTypeIdentifier string, orgID *strin
}

func (app *application) admGetConfig(id string, system bool) (*model.Config, error) {
//TODO: handle system
// config, err := app.storage.FindConfig(id)
// if err != nil {
// return nil, errors.WrapErrorAction(logutils.ActionFind, model.TypeConfig, nil, err)
// }
// return config, nil
return nil, errors.New(logutils.Unimplemented)
config, err := app.storage.FindConfigByID(id)
if err != nil {
return nil, errors.WrapErrorAction(logutils.ActionFind, model.TypeConfig, nil, err)
}
if config == nil {
return nil, errors.ErrorData(logutils.StatusMissing, model.TypeConfig, &logutils.FieldArgs{"id": id})
}

if !system && config.System {
return nil, errors.ErrorData(logutils.StatusInvalid, "system claim", nil)
}

return config, nil
}

func (app *application) admGetConfigs(configType *string, appID *string, orgID *string, system bool) ([]model.Config, error) {
configs, err := app.storage.FindConfigs(configType, appID, orgID)
if err != nil {
return nil, errors.WrapErrorAction(logutils.ActionFind, model.TypeConfig, nil, err)
}

if !system {
allowedConfigs := make([]model.Config, 0)
for _, config := range configs {
if !config.System {
allowedConfigs = append(allowedConfigs, config)
}
}
return allowedConfigs, nil
}

return configs, nil
}

func (app *application) admCreateConfig(config model.Config, system bool) error {
Expand All @@ -215,7 +240,7 @@ func (app *application) admUpdateConfig(config model.Config, system bool) error
return errors.WrapErrorAction(logutils.ActionFind, model.TypeConfig, nil, err)
}
if oldConfig == nil {
return errors.ErrorData(logutils.StatusMissing, model.TypeConfig, nil)
return errors.ErrorData(logutils.StatusMissing, model.TypeConfig, &logutils.FieldArgs{"type": config.Type, "app_id": config.AppID, "org_id": config.OrgID})
}

if !system && (config.System || oldConfig.System) {
Expand All @@ -233,13 +258,23 @@ func (app *application) admUpdateConfig(config model.Config, system bool) error
}

func (app *application) admDeleteConfig(id string, system bool) error {
//TODO: handle system
// err := app.storage.DeleteConfig(id)
// if err != nil {
// return errors.WrapErrorAction(logutils.ActionDelete, model.TypeConfig, nil, err)
// }
// return nil
return errors.New(logutils.Unimplemented)
config, err := app.storage.FindConfigByID(id)
if err != nil {
return errors.WrapErrorAction(logutils.ActionFind, model.TypeConfig, nil, err)
}
if config == nil {
return errors.ErrorData(logutils.StatusMissing, model.TypeConfig, &logutils.FieldArgs{"id": id})
}

if !system && config.System {
return errors.ErrorData(logutils.StatusInvalid, "system claim", nil)
}

err = app.storage.DeleteConfig(id)
if err != nil {
return errors.WrapErrorAction(logutils.ActionDelete, model.TypeConfig, nil, err)
}
return nil
}

func (app *application) admGetApplications(orgID string) ([]model.Application, error) {
Expand Down
4 changes: 3 additions & 1 deletion core/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ type Administration interface {
AdmGetTestModel() string

AdmGetConfig(id string, system bool) (*model.Config, error)
AdmGetConfigs(configType *string, appID *string, orgID *string, system bool) ([]model.Config, error)
AdmCreateConfig(config model.Config, system bool) error
AdmUpdateConfig(config model.Config, system bool) error
AdmDeleteConfig(id string, system bool) error
Expand Down Expand Up @@ -181,7 +182,8 @@ type Storage interface {
DeleteDevice(context storage.TransactionContext, id string) error

FindConfig(configType string, appID string, orgID string) (*model.Config, error)
FindConfigs(configType string, appID *string, orgID *string) ([]model.Config, error)
FindConfigByID(id string) (*model.Config, error)
FindConfigs(configType *string, appID *string, orgID *string) ([]model.Config, error)
InsertConfig(config model.Config) error
UpdateConfig(config model.Config) error
DeleteConfig(id string) error
Expand Down
31 changes: 27 additions & 4 deletions core/mocks/Storage.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 37 additions & 9 deletions driven/storage/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,7 @@ func (sa *Adapter) setCachedConfigs(configs []model.Config) {
if err != nil {
sa.db.logger.Warn(err.Error())
}
sa.cachedConfigs.Store(config.ID, config)
sa.cachedConfigs.Store(fmt.Sprintf("%s_%s_%s", config.Type, config.AppID, config.OrgID), config)
}
}
Expand Down Expand Up @@ -764,41 +765,63 @@ func parseConfigsData(config *model.Config) error {
return nil
}

func (sa *Adapter) getCachedConfig(configType string, appID string, orgID string) (*model.Config, error) {
func (sa *Adapter) getCachedConfig(id string, configType string, appID string, orgID string) (*model.Config, error) {
sa.configsLock.RLock()
defer sa.configsLock.RUnlock()

errArgs := &logutils.FieldArgs{"type": configType, "app_id": appID, "org_id": orgID}
var item any
var errArgs logutils.FieldArgs
if id != "" {
errArgs = logutils.FieldArgs{"id": id}
item, _ = sa.cachedConfigs.Load(id)
} else {
errArgs = logutils.FieldArgs{"type": configType, "app_id": appID, "org_id": orgID}
item, _ = sa.cachedConfigs.Load(fmt.Sprintf("%s_%s_%s", configType, appID, orgID))
}

item, _ := sa.cachedConfigs.Load(fmt.Sprintf("%s_%s_%s", configType, appID, orgID))
if item != nil {
config, ok := item.(model.Config)
if !ok {
return nil, errors.ErrorAction(logutils.ActionCast, model.TypeConfig, errArgs)
return nil, errors.ErrorAction(logutils.ActionCast, model.TypeConfig, &errArgs)
}
return &config, nil
}
return nil, nil
}

func (sa *Adapter) getCachedConfigs(configType string, appID *string, orgID *string) ([]model.Config, error) {
func (sa *Adapter) getCachedConfigs(configType *string, appID *string, orgID *string) ([]model.Config, error) {
sa.configsLock.RLock()
defer sa.configsLock.RUnlock()

var err error
configList := make([]model.Config, 0)
sa.cachedConfigs.Range(func(key, item interface{}) bool {
if item == nil {
keyStr, ok := key.(string)
if !ok || item == nil {
return false
}
if !strings.Contains(keyStr, "_") {
return true
}

config, ok := item.(model.Config)
if !ok {
err = errors.ErrorAction(logutils.ActionCast, model.TypeConfig, &logutils.FieldArgs{"key": key})
return false
}

if config.Type == configType && (appID == nil || *appID == config.AppID) && (orgID == nil || *orgID == config.OrgID) {
match := true
if configType != nil && !strings.HasPrefix(keyStr, fmt.Sprintf("%s_", *configType)) {
match = false
}
if appID != nil && !strings.Contains(keyStr, fmt.Sprintf("_%s_", *appID)) {
match = false
}
if orgID != nil && !strings.HasSuffix(keyStr, fmt.Sprintf("_%s", *orgID)) {
match = false
}

if match {
configList = append(configList, config)
}
return true
Expand Down Expand Up @@ -3061,11 +3084,16 @@ func (sa *Adapter) loadConfigs() ([]model.Config, error) {

// FindConfig finds the config for the specified type, appID, and orgID
func (sa *Adapter) FindConfig(configType string, appID string, orgID string) (*model.Config, error) {
return sa.getCachedConfig(configType, appID, orgID)
return sa.getCachedConfig("", configType, appID, orgID)
}

// FindConfigByID finds the config for the specified ID
func (sa *Adapter) FindConfigByID(id string) (*model.Config, error) {
return sa.getCachedConfig(id, "", "", "")
}

// FindConfigs finds all configs for the specified type, nullable appID, and nullable orgID
func (sa *Adapter) FindConfigs(configType string, appID *string, orgID *string) ([]model.Config, error) {
func (sa *Adapter) FindConfigs(configType *string, appID *string, orgID *string) ([]model.Config, error) {
return sa.getCachedConfigs(configType, appID, orgID)
}

Expand Down
9 changes: 5 additions & 4 deletions driver/web/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,11 @@ func (we Adapter) Start() {
adminSubrouter.HandleFunc("/auth/verify-mfa", we.wrapFunc(we.adminApisHandler.verifyMFA, we.auth.admin.User)).Methods("POST")
adminSubrouter.HandleFunc("/auth/app-token", we.wrapFunc(we.adminApisHandler.getAppToken, we.auth.admin.User)).Methods("GET")

adminSubrouter.HandleFunc("/configs/{id}", we.wrapFunc(we.adminApisHandler.getConfig, we.auth.system.Permissions)).Methods("GET")
adminSubrouter.HandleFunc("/configs", we.wrapFunc(we.adminApisHandler.createConfig, we.auth.system.Permissions)).Methods("POST")
adminSubrouter.HandleFunc("/configs/{id}", we.wrapFunc(we.adminApisHandler.updateConfig, we.auth.system.Permissions)).Methods("PUT")
adminSubrouter.HandleFunc("/configs/{id}", we.wrapFunc(we.adminApisHandler.deleteConfig, we.auth.system.Permissions)).Methods("DELETE")
adminSubrouter.HandleFunc("/configs/{id}", we.wrapFunc(we.adminApisHandler.getConfig, we.auth.admin.Permissions)).Methods("GET")
adminSubrouter.HandleFunc("/configs", we.wrapFunc(we.adminApisHandler.getConfigs, we.auth.admin.Permissions)).Methods("GET")
adminSubrouter.HandleFunc("/configs", we.wrapFunc(we.adminApisHandler.createConfig, we.auth.admin.Permissions)).Methods("POST")
adminSubrouter.HandleFunc("/configs/{id}", we.wrapFunc(we.adminApisHandler.updateConfig, we.auth.admin.Permissions)).Methods("PUT")
adminSubrouter.HandleFunc("/configs/{id}", we.wrapFunc(we.adminApisHandler.deleteConfig, we.auth.admin.Permissions)).Methods("DELETE")

adminSubrouter.HandleFunc("/account", we.wrapFunc(we.adminApisHandler.getAccount, we.auth.admin.User)).Methods("GET")
adminSubrouter.HandleFunc("/account/mfa", we.wrapFunc(we.adminApisHandler.getMFATypes, we.auth.admin.User)).Methods("GET")
Expand Down
34 changes: 34 additions & 0 deletions driver/web/apis_admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,40 @@ func (h AdminApisHandler) getConfig(l *logs.Log, r *http.Request, claims *tokena
return l.HTTPResponseSuccessJSON(data)
}

// getConfig gets config by id
func (h AdminApisHandler) getConfigs(l *logs.Log, r *http.Request, claims *tokenauth.Claims) logs.HTTPResponse {
//type
var configType *string
typeParam := r.URL.Query().Get("type")
if len(typeParam) > 0 {
configType = &typeParam
}
//appID
var appID *string
appIDParam := r.URL.Query().Get("app_id")
if len(appIDParam) > 0 {
appID = &appIDParam
}
//orgID
var orgID *string
orgIDParam := r.URL.Query().Get("org_id")
if len(orgIDParam) > 0 {
orgID = &orgIDParam
}

configs, err := h.coreAPIs.Administration.AdmGetConfigs(configType, appID, orgID, claims.System)
if err != nil {
return l.HTTPResponseErrorAction(logutils.ActionGet, model.TypeConfig, nil, err, http.StatusInternalServerError, true)
}

data, err := json.Marshal(configListToDef(configs))
if err != nil {
return l.HTTPResponseErrorAction(logutils.ActionMarshal, model.TypeConfig, nil, err, http.StatusInternalServerError, false)
}

return l.HTTPResponseSuccessJSON(data)
}

// createConfig creates a config by id
func (h AdminApisHandler) createConfig(l *logs.Log, r *http.Request, claims *tokenauth.Claims) logs.HTTPResponse {
var requestData Def.Config
Expand Down
3 changes: 3 additions & 0 deletions driver/web/authorization_admin_policy.csv
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ p, get_test, /core/admin/test, (GET), Get test data
p, get_test-model, /core/admin/test-model, (GET), Get test models

p, all_core_configs, /core/admin/configs/*, (GET)|(POST)|(DELETE)|(PUT), All configs actions
p, all_core_configs, /core/admin/configs, (GET)|(POST),
p, get_core_configs, /core/admin/configs/*, (GET), Get configs
p, get_core_configs, /core/admin/configs, (GET),
p, update_core_configs, /core/admin/configs/*, (GET)|(PUT)|(POST), Update and create configs
p, update_core_configs, /core/admin/configs, (GET)|(POST),
p, delete_core_configs, /core/admin/configs/*, (DELETE), Delete configs

p, all_login-sessions, /core/admin/application/login-sessions, (GET), All login session actions
Expand Down
8 changes: 8 additions & 0 deletions driver/web/conversions_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ import (
"core-building-block/utils"
)

func configListToDef(items []model.Config) []Def.Config {
result := make([]Def.Config, len(items))
for i, item := range items {
result[i] = configToDef(item)
}
return result
}

func configToDef(item model.Config) Def.Config {
var dateUpdated *string
dateCreated := utils.FormatTime(&item.DateCreated)
Expand Down
Loading

0 comments on commit 775b914

Please sign in to comment.