snapshot of https://github.com/cortezaproject/corteza.git (2024.9.x, 2026-09-18; blobs > 131072B omitted)
Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s

This commit is contained in:
upstream-mirror
2026-09-18 01:22:23 +05:00
commit 7e385fc126
8391 changed files with 1766236 additions and 0 deletions

4255
server/automation/rest/eventTypes.gen.go generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,45 @@
package rest
import (
"context"
"github.com/cortezaproject/corteza/server/automation/rest/request"
"github.com/cortezaproject/corteza/server/automation/service"
)
type (
EventTypes struct {
reg interface {
Types() []string
}
}
eventTypePayload struct {
Set []eventTypeDef `json:"set"`
}
eventTypeDef struct {
ResourceType string `json:"resourceType"`
EventType string `json:"eventType"`
Properties []eventTypePropertyDef `json:"properties"`
Constraints []eventTypeConstraintDef `json:"constraints"`
}
eventTypePropertyDef struct {
Name string `json:"name"`
Type string `json:"type"`
Immutable bool `json:"immutable"`
}
eventTypeConstraintDef struct {
Name string `json:"name"`
}
)
func (EventTypes) New() *EventTypes {
ctrl := &EventTypes{reg: service.Registry()}
return ctrl
}
func (ctrl EventTypes) List(_ context.Context, _ *request.EventTypesList) (interface{}, error) {
return eventTypePayload{Set: getEventTypeDefinitions()}, nil
}

View File

@@ -0,0 +1,29 @@
package rest
import (
"context"
"github.com/cortezaproject/corteza/server/automation/rest/request"
"github.com/cortezaproject/corteza/server/automation/service"
"github.com/cortezaproject/corteza/server/automation/types"
)
type (
Function struct {
reg interface {
Functions() []*types.Function
}
}
functionSetPayload struct {
Set []*types.Function `json:"set"`
}
)
func (Function) New() *Function {
ctrl := &Function{reg: service.Registry()}
return ctrl
}
func (ctrl Function) List(_ context.Context, _ *request.FunctionList) (interface{}, error) {
return functionSetPayload{Set: ctrl.reg.Functions()}, nil
}

View File

@@ -0,0 +1,57 @@
package handlers
// This file is auto-generated.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Definitions file that controls how this file is generated:
//
import (
"context"
"github.com/cortezaproject/corteza/server/automation/rest/request"
"github.com/cortezaproject/corteza/server/pkg/api"
"github.com/go-chi/chi/v5"
"net/http"
)
type (
// Internal API interface
EventTypesAPI interface {
List(context.Context, *request.EventTypesList) (interface{}, error)
}
// HTTP API interface
EventTypes struct {
List func(http.ResponseWriter, *http.Request)
}
)
func NewEventTypes(h EventTypesAPI) *EventTypes {
return &EventTypes{
List: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewEventTypesList()
if err := params.Fill(r); err != nil {
api.Send(w, r, err)
return
}
value, err := h.List(r.Context(), params)
if err != nil {
api.Send(w, r, err)
return
}
api.Send(w, r, value)
},
}
}
func (h EventTypes) MountRoutes(r chi.Router, middlewares ...func(http.Handler) http.Handler) {
r.Group(func(r chi.Router) {
r.Use(middlewares...)
r.Get("/event-types/", h.List)
})
}

View File

@@ -0,0 +1,57 @@
package handlers
// This file is auto-generated.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Definitions file that controls how this file is generated:
//
import (
"context"
"github.com/cortezaproject/corteza/server/automation/rest/request"
"github.com/cortezaproject/corteza/server/pkg/api"
"github.com/go-chi/chi/v5"
"net/http"
)
type (
// Internal API interface
FunctionAPI interface {
List(context.Context, *request.FunctionList) (interface{}, error)
}
// HTTP API interface
Function struct {
List func(http.ResponseWriter, *http.Request)
}
)
func NewFunction(h FunctionAPI) *Function {
return &Function{
List: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewFunctionList()
if err := params.Fill(r); err != nil {
api.Send(w, r, err)
return
}
value, err := h.List(r.Context(), params)
if err != nil {
api.Send(w, r, err)
return
}
api.Send(w, r, value)
},
}
}
func (h Function) MountRoutes(r chi.Router, middlewares ...func(http.Handler) http.Handler) {
r.Group(func(r chi.Router) {
r.Use(middlewares...)
r.Get("/functions/", h.List)
})
}

View File

@@ -0,0 +1,152 @@
package handlers
// This file is auto-generated.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Definitions file that controls how this file is generated:
//
import (
"context"
"github.com/cortezaproject/corteza/server/automation/rest/request"
"github.com/cortezaproject/corteza/server/pkg/api"
"github.com/go-chi/chi/v5"
"net/http"
)
type (
// Internal API interface
PermissionsAPI interface {
List(context.Context, *request.PermissionsList) (interface{}, error)
Effective(context.Context, *request.PermissionsEffective) (interface{}, error)
Trace(context.Context, *request.PermissionsTrace) (interface{}, error)
Read(context.Context, *request.PermissionsRead) (interface{}, error)
Delete(context.Context, *request.PermissionsDelete) (interface{}, error)
Update(context.Context, *request.PermissionsUpdate) (interface{}, error)
}
// HTTP API interface
Permissions struct {
List func(http.ResponseWriter, *http.Request)
Effective func(http.ResponseWriter, *http.Request)
Trace func(http.ResponseWriter, *http.Request)
Read func(http.ResponseWriter, *http.Request)
Delete func(http.ResponseWriter, *http.Request)
Update func(http.ResponseWriter, *http.Request)
}
)
func NewPermissions(h PermissionsAPI) *Permissions {
return &Permissions{
List: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewPermissionsList()
if err := params.Fill(r); err != nil {
api.Send(w, r, err)
return
}
value, err := h.List(r.Context(), params)
if err != nil {
api.Send(w, r, err)
return
}
api.Send(w, r, value)
},
Effective: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewPermissionsEffective()
if err := params.Fill(r); err != nil {
api.Send(w, r, err)
return
}
value, err := h.Effective(r.Context(), params)
if err != nil {
api.Send(w, r, err)
return
}
api.Send(w, r, value)
},
Trace: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewPermissionsTrace()
if err := params.Fill(r); err != nil {
api.Send(w, r, err)
return
}
value, err := h.Trace(r.Context(), params)
if err != nil {
api.Send(w, r, err)
return
}
api.Send(w, r, value)
},
Read: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewPermissionsRead()
if err := params.Fill(r); err != nil {
api.Send(w, r, err)
return
}
value, err := h.Read(r.Context(), params)
if err != nil {
api.Send(w, r, err)
return
}
api.Send(w, r, value)
},
Delete: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewPermissionsDelete()
if err := params.Fill(r); err != nil {
api.Send(w, r, err)
return
}
value, err := h.Delete(r.Context(), params)
if err != nil {
api.Send(w, r, err)
return
}
api.Send(w, r, value)
},
Update: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewPermissionsUpdate()
if err := params.Fill(r); err != nil {
api.Send(w, r, err)
return
}
value, err := h.Update(r.Context(), params)
if err != nil {
api.Send(w, r, err)
return
}
api.Send(w, r, value)
},
}
}
func (h Permissions) MountRoutes(r chi.Router, middlewares ...func(http.Handler) http.Handler) {
r.Group(func(r chi.Router) {
r.Use(middlewares...)
r.Get("/permissions/", h.List)
r.Get("/permissions/effective", h.Effective)
r.Get("/permissions/trace", h.Trace)
r.Get("/permissions/{roleID}/rules", h.Read)
r.Delete("/permissions/{roleID}/rules", h.Delete)
r.Patch("/permissions/{roleID}/rules", h.Update)
})
}

View File

@@ -0,0 +1,133 @@
package handlers
// This file is auto-generated.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Definitions file that controls how this file is generated:
//
import (
"context"
"github.com/cortezaproject/corteza/server/automation/rest/request"
"github.com/cortezaproject/corteza/server/pkg/api"
"github.com/go-chi/chi/v5"
"net/http"
)
type (
// Internal API interface
SessionAPI interface {
List(context.Context, *request.SessionList) (interface{}, error)
Read(context.Context, *request.SessionRead) (interface{}, error)
Cancel(context.Context, *request.SessionCancel) (interface{}, error)
ListPrompts(context.Context, *request.SessionListPrompts) (interface{}, error)
ResumeState(context.Context, *request.SessionResumeState) (interface{}, error)
}
// HTTP API interface
Session struct {
List func(http.ResponseWriter, *http.Request)
Read func(http.ResponseWriter, *http.Request)
Cancel func(http.ResponseWriter, *http.Request)
ListPrompts func(http.ResponseWriter, *http.Request)
ResumeState func(http.ResponseWriter, *http.Request)
}
)
func NewSession(h SessionAPI) *Session {
return &Session{
List: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewSessionList()
if err := params.Fill(r); err != nil {
api.Send(w, r, err)
return
}
value, err := h.List(r.Context(), params)
if err != nil {
api.Send(w, r, err)
return
}
api.Send(w, r, value)
},
Read: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewSessionRead()
if err := params.Fill(r); err != nil {
api.Send(w, r, err)
return
}
value, err := h.Read(r.Context(), params)
if err != nil {
api.Send(w, r, err)
return
}
api.Send(w, r, value)
},
Cancel: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewSessionCancel()
if err := params.Fill(r); err != nil {
api.Send(w, r, err)
return
}
value, err := h.Cancel(r.Context(), params)
if err != nil {
api.Send(w, r, err)
return
}
api.Send(w, r, value)
},
ListPrompts: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewSessionListPrompts()
if err := params.Fill(r); err != nil {
api.Send(w, r, err)
return
}
value, err := h.ListPrompts(r.Context(), params)
if err != nil {
api.Send(w, r, err)
return
}
api.Send(w, r, value)
},
ResumeState: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewSessionResumeState()
if err := params.Fill(r); err != nil {
api.Send(w, r, err)
return
}
value, err := h.ResumeState(r.Context(), params)
if err != nil {
api.Send(w, r, err)
return
}
api.Send(w, r, value)
},
}
}
func (h Session) MountRoutes(r chi.Router, middlewares ...func(http.Handler) http.Handler) {
r.Group(func(r chi.Router) {
r.Use(middlewares...)
r.Get("/sessions/", h.List)
r.Get("/sessions/{sessionID}", h.Read)
r.Post("/sessions/{sessionID}/cancel", h.Cancel)
r.Get("/sessions/prompts", h.ListPrompts)
r.Post("/sessions/{sessionID}/state/{stateID}", h.ResumeState)
})
}

View File

@@ -0,0 +1,152 @@
package handlers
// This file is auto-generated.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Definitions file that controls how this file is generated:
//
import (
"context"
"github.com/cortezaproject/corteza/server/automation/rest/request"
"github.com/cortezaproject/corteza/server/pkg/api"
"github.com/go-chi/chi/v5"
"net/http"
)
type (
// Internal API interface
TriggerAPI interface {
List(context.Context, *request.TriggerList) (interface{}, error)
Create(context.Context, *request.TriggerCreate) (interface{}, error)
Update(context.Context, *request.TriggerUpdate) (interface{}, error)
Read(context.Context, *request.TriggerRead) (interface{}, error)
Delete(context.Context, *request.TriggerDelete) (interface{}, error)
Undelete(context.Context, *request.TriggerUndelete) (interface{}, error)
}
// HTTP API interface
Trigger struct {
List func(http.ResponseWriter, *http.Request)
Create func(http.ResponseWriter, *http.Request)
Update func(http.ResponseWriter, *http.Request)
Read func(http.ResponseWriter, *http.Request)
Delete func(http.ResponseWriter, *http.Request)
Undelete func(http.ResponseWriter, *http.Request)
}
)
func NewTrigger(h TriggerAPI) *Trigger {
return &Trigger{
List: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewTriggerList()
if err := params.Fill(r); err != nil {
api.Send(w, r, err)
return
}
value, err := h.List(r.Context(), params)
if err != nil {
api.Send(w, r, err)
return
}
api.Send(w, r, value)
},
Create: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewTriggerCreate()
if err := params.Fill(r); err != nil {
api.Send(w, r, err)
return
}
value, err := h.Create(r.Context(), params)
if err != nil {
api.Send(w, r, err)
return
}
api.Send(w, r, value)
},
Update: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewTriggerUpdate()
if err := params.Fill(r); err != nil {
api.Send(w, r, err)
return
}
value, err := h.Update(r.Context(), params)
if err != nil {
api.Send(w, r, err)
return
}
api.Send(w, r, value)
},
Read: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewTriggerRead()
if err := params.Fill(r); err != nil {
api.Send(w, r, err)
return
}
value, err := h.Read(r.Context(), params)
if err != nil {
api.Send(w, r, err)
return
}
api.Send(w, r, value)
},
Delete: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewTriggerDelete()
if err := params.Fill(r); err != nil {
api.Send(w, r, err)
return
}
value, err := h.Delete(r.Context(), params)
if err != nil {
api.Send(w, r, err)
return
}
api.Send(w, r, value)
},
Undelete: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewTriggerUndelete()
if err := params.Fill(r); err != nil {
api.Send(w, r, err)
return
}
value, err := h.Undelete(r.Context(), params)
if err != nil {
api.Send(w, r, err)
return
}
api.Send(w, r, value)
},
}
}
func (h Trigger) MountRoutes(r chi.Router, middlewares ...func(http.Handler) http.Handler) {
r.Group(func(r chi.Router) {
r.Use(middlewares...)
r.Get("/triggers/", h.List)
r.Post("/triggers/", h.Create)
r.Put("/triggers/{triggerID}", h.Update)
r.Get("/triggers/{triggerID}", h.Read)
r.Delete("/triggers/{triggerID}", h.Delete)
r.Post("/triggers/{triggerID}/undelete", h.Undelete)
})
}

View File

@@ -0,0 +1,57 @@
package handlers
// This file is auto-generated.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Definitions file that controls how this file is generated:
//
import (
"context"
"github.com/cortezaproject/corteza/server/automation/rest/request"
"github.com/cortezaproject/corteza/server/pkg/api"
"github.com/go-chi/chi/v5"
"net/http"
)
type (
// Internal API interface
TypeAPI interface {
List(context.Context, *request.TypeList) (interface{}, error)
}
// HTTP API interface
Type struct {
List func(http.ResponseWriter, *http.Request)
}
)
func NewType(h TypeAPI) *Type {
return &Type{
List: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewTypeList()
if err := params.Fill(r); err != nil {
api.Send(w, r, err)
return
}
value, err := h.List(r.Context(), params)
if err != nil {
api.Send(w, r, err)
return
}
api.Send(w, r, value)
},
}
}
func (h Type) MountRoutes(r chi.Router, middlewares ...func(http.Handler) http.Handler) {
r.Group(func(r chi.Router) {
r.Use(middlewares...)
r.Get("/types/", h.List)
})
}

View File

@@ -0,0 +1,190 @@
package handlers
// This file is auto-generated.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Definitions file that controls how this file is generated:
//
import (
"context"
"github.com/cortezaproject/corteza/server/automation/rest/request"
"github.com/cortezaproject/corteza/server/pkg/api"
"github.com/go-chi/chi/v5"
"net/http"
)
type (
// Internal API interface
WorkflowAPI interface {
List(context.Context, *request.WorkflowList) (interface{}, error)
Create(context.Context, *request.WorkflowCreate) (interface{}, error)
Update(context.Context, *request.WorkflowUpdate) (interface{}, error)
Read(context.Context, *request.WorkflowRead) (interface{}, error)
Delete(context.Context, *request.WorkflowDelete) (interface{}, error)
Undelete(context.Context, *request.WorkflowUndelete) (interface{}, error)
Test(context.Context, *request.WorkflowTest) (interface{}, error)
Exec(context.Context, *request.WorkflowExec) (interface{}, error)
}
// HTTP API interface
Workflow struct {
List func(http.ResponseWriter, *http.Request)
Create func(http.ResponseWriter, *http.Request)
Update func(http.ResponseWriter, *http.Request)
Read func(http.ResponseWriter, *http.Request)
Delete func(http.ResponseWriter, *http.Request)
Undelete func(http.ResponseWriter, *http.Request)
Test func(http.ResponseWriter, *http.Request)
Exec func(http.ResponseWriter, *http.Request)
}
)
func NewWorkflow(h WorkflowAPI) *Workflow {
return &Workflow{
List: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewWorkflowList()
if err := params.Fill(r); err != nil {
api.Send(w, r, err)
return
}
value, err := h.List(r.Context(), params)
if err != nil {
api.Send(w, r, err)
return
}
api.Send(w, r, value)
},
Create: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewWorkflowCreate()
if err := params.Fill(r); err != nil {
api.Send(w, r, err)
return
}
value, err := h.Create(r.Context(), params)
if err != nil {
api.Send(w, r, err)
return
}
api.Send(w, r, value)
},
Update: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewWorkflowUpdate()
if err := params.Fill(r); err != nil {
api.Send(w, r, err)
return
}
value, err := h.Update(r.Context(), params)
if err != nil {
api.Send(w, r, err)
return
}
api.Send(w, r, value)
},
Read: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewWorkflowRead()
if err := params.Fill(r); err != nil {
api.Send(w, r, err)
return
}
value, err := h.Read(r.Context(), params)
if err != nil {
api.Send(w, r, err)
return
}
api.Send(w, r, value)
},
Delete: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewWorkflowDelete()
if err := params.Fill(r); err != nil {
api.Send(w, r, err)
return
}
value, err := h.Delete(r.Context(), params)
if err != nil {
api.Send(w, r, err)
return
}
api.Send(w, r, value)
},
Undelete: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewWorkflowUndelete()
if err := params.Fill(r); err != nil {
api.Send(w, r, err)
return
}
value, err := h.Undelete(r.Context(), params)
if err != nil {
api.Send(w, r, err)
return
}
api.Send(w, r, value)
},
Test: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewWorkflowTest()
if err := params.Fill(r); err != nil {
api.Send(w, r, err)
return
}
value, err := h.Test(r.Context(), params)
if err != nil {
api.Send(w, r, err)
return
}
api.Send(w, r, value)
},
Exec: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewWorkflowExec()
if err := params.Fill(r); err != nil {
api.Send(w, r, err)
return
}
value, err := h.Exec(r.Context(), params)
if err != nil {
api.Send(w, r, err)
return
}
api.Send(w, r, value)
},
}
}
func (h Workflow) MountRoutes(r chi.Router, middlewares ...func(http.Handler) http.Handler) {
r.Group(func(r chi.Router) {
r.Use(middlewares...)
r.Get("/workflows/", h.List)
r.Post("/workflows/", h.Create)
r.Put("/workflows/{workflowID}", h.Update)
r.Get("/workflows/{workflowID}", h.Read)
r.Delete("/workflows/{workflowID}", h.Delete)
r.Post("/workflows/{workflowID}/undelete", h.Undelete)
r.Post("/workflows/{workflowID}/test", h.Test)
r.Post("/workflows/{workflowID}/exec", h.Exec)
})
}

View File

@@ -0,0 +1,69 @@
package rest
import (
"context"
"github.com/cortezaproject/corteza/server/automation/rest/request"
"github.com/cortezaproject/corteza/server/automation/service"
"github.com/cortezaproject/corteza/server/automation/types"
"github.com/cortezaproject/corteza/server/pkg/api"
"github.com/cortezaproject/corteza/server/pkg/rbac"
)
type (
Permissions struct {
ac permissionsAccessController
}
permissionsAccessController interface {
Effective(context.Context, ...rbac.Resource) rbac.EffectiveSet
Trace(context.Context, uint64, []uint64, ...string) ([]*rbac.Trace, error)
List() []map[string]string
FindRulesByRoleID(context.Context, uint64) (rbac.RuleSet, error)
FindRules(ctx context.Context, roleID uint64, rr ...string) (rbac.RuleSet, error)
Grant(ctx context.Context, rr ...*rbac.Rule) error
}
)
func (Permissions) New() *Permissions {
return &Permissions{
ac: service.DefaultAccessControl,
}
}
func (ctrl Permissions) Effective(ctx context.Context, r *request.PermissionsEffective) (interface{}, error) {
return ctrl.ac.Effective(ctx, types.Component{}), nil
}
func (ctrl Permissions) Trace(ctx context.Context, r *request.PermissionsTrace) (interface{}, error) {
return ctrl.ac.Trace(ctx, r.UserID, r.RoleID, r.Resource...)
}
func (ctrl Permissions) List(ctx context.Context, r *request.PermissionsList) (interface{}, error) {
return ctrl.ac.List(), nil
}
func (ctrl Permissions) Read(ctx context.Context, r *request.PermissionsRead) (interface{}, error) {
return ctrl.ac.FindRules(ctx, r.RoleID, r.Resource...)
}
func (ctrl Permissions) Delete(ctx context.Context, r *request.PermissionsDelete) (interface{}, error) {
rr, err := ctrl.ac.FindRulesByRoleID(ctx, r.RoleID)
if err != nil {
return nil, err
}
for _, r := range rr {
r.Access = rbac.Inherit
}
return api.OK(), ctrl.ac.Grant(ctx, rr...)
}
func (ctrl Permissions) Update(ctx context.Context, r *request.PermissionsUpdate) (interface{}, error) {
for _, rule := range r.Rules {
// Make sure everything is properly set
rule.RoleID = r.RoleID
}
return api.OK(), ctrl.ac.Grant(ctx, r.Rules...)
}

View File

@@ -0,0 +1,54 @@
package request
// This file is auto-generated.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Definitions file that controls how this file is generated:
//
import (
"encoding/json"
"fmt"
"github.com/cortezaproject/corteza/server/pkg/payload"
"github.com/go-chi/chi/v5"
"io"
"mime/multipart"
"net/http"
"strings"
)
// dummy vars to prevent
// unused imports complain
var (
_ = chi.URLParam
_ = multipart.ErrMessageTooLarge
_ = payload.ParseUint64s
_ = strings.ToLower
_ = io.EOF
_ = fmt.Errorf
_ = json.NewEncoder
)
type (
// Internal API interface
EventTypesList struct {
}
)
// NewEventTypesList request
func NewEventTypesList() *EventTypesList {
return &EventTypesList{}
}
// Auditable returns all auditable/loggable parameters
func (r EventTypesList) Auditable() map[string]interface{} {
return map[string]interface{}{}
}
// Fill processes request and fills internal variables
func (r *EventTypesList) Fill(req *http.Request) (err error) {
return err
}

View File

@@ -0,0 +1,54 @@
package request
// This file is auto-generated.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Definitions file that controls how this file is generated:
//
import (
"encoding/json"
"fmt"
"github.com/cortezaproject/corteza/server/pkg/payload"
"github.com/go-chi/chi/v5"
"io"
"mime/multipart"
"net/http"
"strings"
)
// dummy vars to prevent
// unused imports complain
var (
_ = chi.URLParam
_ = multipart.ErrMessageTooLarge
_ = payload.ParseUint64s
_ = strings.ToLower
_ = io.EOF
_ = fmt.Errorf
_ = json.NewEncoder
)
type (
// Internal API interface
FunctionList struct {
}
)
// NewFunctionList request
func NewFunctionList() *FunctionList {
return &FunctionList{}
}
// Auditable returns all auditable/loggable parameters
func (r FunctionList) Auditable() map[string]interface{} {
return map[string]interface{}{}
}
// Fill processes request and fills internal variables
func (r *FunctionList) Fill(req *http.Request) (err error) {
return err
}

View File

@@ -0,0 +1,384 @@
package request
// This file is auto-generated.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Definitions file that controls how this file is generated:
//
import (
"encoding/json"
"fmt"
"github.com/cortezaproject/corteza/server/pkg/payload"
"github.com/cortezaproject/corteza/server/pkg/rbac"
"github.com/go-chi/chi/v5"
"io"
"mime/multipart"
"net/http"
"strings"
)
// dummy vars to prevent
// unused imports complain
var (
_ = chi.URLParam
_ = multipart.ErrMessageTooLarge
_ = payload.ParseUint64s
_ = strings.ToLower
_ = io.EOF
_ = fmt.Errorf
_ = json.NewEncoder
)
type (
// Internal API interface
PermissionsList struct {
}
PermissionsEffective struct {
// Resource GET parameter
//
// Show only rules for a specific resource
Resource string
}
PermissionsTrace struct {
// Resource GET parameter
//
// Show only rules for a specific resource
Resource []string
// UserID GET parameter
//
//
UserID uint64 `json:",string"`
// RoleID GET parameter
//
//
RoleID []uint64
}
PermissionsRead struct {
// RoleID PATH parameter
//
// Role ID
RoleID uint64 `json:",string"`
// Resource GET parameter
//
// Show only rules for a specific resource
Resource []string
}
PermissionsDelete struct {
// RoleID PATH parameter
//
// Role ID
RoleID uint64 `json:",string"`
}
PermissionsUpdate struct {
// RoleID PATH parameter
//
// Role ID
RoleID uint64 `json:",string"`
// Rules POST parameter
//
// List of permission rules to set
Rules rbac.RuleSet
}
)
// NewPermissionsList request
func NewPermissionsList() *PermissionsList {
return &PermissionsList{}
}
// Auditable returns all auditable/loggable parameters
func (r PermissionsList) Auditable() map[string]interface{} {
return map[string]interface{}{}
}
// Fill processes request and fills internal variables
func (r *PermissionsList) Fill(req *http.Request) (err error) {
return err
}
// NewPermissionsEffective request
func NewPermissionsEffective() *PermissionsEffective {
return &PermissionsEffective{}
}
// Auditable returns all auditable/loggable parameters
func (r PermissionsEffective) Auditable() map[string]interface{} {
return map[string]interface{}{
"resource": r.Resource,
}
}
// Auditable returns all auditable/loggable parameters
func (r PermissionsEffective) GetResource() string {
return r.Resource
}
// Fill processes request and fills internal variables
func (r *PermissionsEffective) Fill(req *http.Request) (err error) {
{
// GET params
tmp := req.URL.Query()
if val, ok := tmp["resource"]; ok && len(val) > 0 {
r.Resource, err = val[0], nil
if err != nil {
return err
}
}
}
return err
}
// NewPermissionsTrace request
func NewPermissionsTrace() *PermissionsTrace {
return &PermissionsTrace{}
}
// Auditable returns all auditable/loggable parameters
func (r PermissionsTrace) Auditable() map[string]interface{} {
return map[string]interface{}{
"resource": r.Resource,
"userID": r.UserID,
"roleID": r.RoleID,
}
}
// Auditable returns all auditable/loggable parameters
func (r PermissionsTrace) GetResource() []string {
return r.Resource
}
// Auditable returns all auditable/loggable parameters
func (r PermissionsTrace) GetUserID() uint64 {
return r.UserID
}
// Auditable returns all auditable/loggable parameters
func (r PermissionsTrace) GetRoleID() []uint64 {
return r.RoleID
}
// Fill processes request and fills internal variables
func (r *PermissionsTrace) Fill(req *http.Request) (err error) {
{
// GET params
tmp := req.URL.Query()
if val, ok := tmp["resource[]"]; ok {
r.Resource, err = val, nil
if err != nil {
return err
}
} else if val, ok := tmp["resource"]; ok {
r.Resource, err = val, nil
if err != nil {
return err
}
}
if val, ok := tmp["userID"]; ok && len(val) > 0 {
r.UserID, err = payload.ParseUint64(val[0]), nil
if err != nil {
return err
}
}
if val, ok := tmp["roleID[]"]; ok {
r.RoleID, err = payload.ParseUint64s(val), nil
if err != nil {
return err
}
} else if val, ok := tmp["roleID"]; ok {
r.RoleID, err = payload.ParseUint64s(val), nil
if err != nil {
return err
}
}
}
return err
}
// NewPermissionsRead request
func NewPermissionsRead() *PermissionsRead {
return &PermissionsRead{}
}
// Auditable returns all auditable/loggable parameters
func (r PermissionsRead) Auditable() map[string]interface{} {
return map[string]interface{}{
"roleID": r.RoleID,
"resource": r.Resource,
}
}
// Auditable returns all auditable/loggable parameters
func (r PermissionsRead) GetRoleID() uint64 {
return r.RoleID
}
// Auditable returns all auditable/loggable parameters
func (r PermissionsRead) GetResource() []string {
return r.Resource
}
// Fill processes request and fills internal variables
func (r *PermissionsRead) Fill(req *http.Request) (err error) {
{
// GET params
tmp := req.URL.Query()
if val, ok := tmp["resource[]"]; ok {
r.Resource, err = val, nil
if err != nil {
return err
}
} else if val, ok := tmp["resource"]; ok {
r.Resource, err = val, nil
if err != nil {
return err
}
}
}
{
var val string
// path params
val = chi.URLParam(req, "roleID")
r.RoleID, err = payload.ParseUint64(val), nil
if err != nil {
return err
}
}
return err
}
// NewPermissionsDelete request
func NewPermissionsDelete() *PermissionsDelete {
return &PermissionsDelete{}
}
// Auditable returns all auditable/loggable parameters
func (r PermissionsDelete) Auditable() map[string]interface{} {
return map[string]interface{}{
"roleID": r.RoleID,
}
}
// Auditable returns all auditable/loggable parameters
func (r PermissionsDelete) GetRoleID() uint64 {
return r.RoleID
}
// Fill processes request and fills internal variables
func (r *PermissionsDelete) Fill(req *http.Request) (err error) {
{
var val string
// path params
val = chi.URLParam(req, "roleID")
r.RoleID, err = payload.ParseUint64(val), nil
if err != nil {
return err
}
}
return err
}
// NewPermissionsUpdate request
func NewPermissionsUpdate() *PermissionsUpdate {
return &PermissionsUpdate{}
}
// Auditable returns all auditable/loggable parameters
func (r PermissionsUpdate) Auditable() map[string]interface{} {
return map[string]interface{}{
"roleID": r.RoleID,
"rules": r.Rules,
}
}
// Auditable returns all auditable/loggable parameters
func (r PermissionsUpdate) GetRoleID() uint64 {
return r.RoleID
}
// Auditable returns all auditable/loggable parameters
func (r PermissionsUpdate) GetRules() rbac.RuleSet {
return r.Rules
}
// Fill processes request and fills internal variables
func (r *PermissionsUpdate) Fill(req *http.Request) (err error) {
if strings.HasPrefix(strings.ToLower(req.Header.Get("content-type")), "application/json") {
err = json.NewDecoder(req.Body).Decode(r)
switch {
case err == io.EOF:
err = nil
case err != nil:
return fmt.Errorf("error parsing http request body: %w", err)
}
}
{
// Caching 32MB to memory, the rest to disk
if err = req.ParseMultipartForm(32 << 20); err != nil && err != http.ErrNotMultipart {
return err
} else if err == nil {
// Multipart params
}
}
{
if err = req.ParseForm(); err != nil {
return err
}
// POST params
//if val, ok := req.Form["rules[]"]; ok && len(val) > 0 {
// r.Rules, err = rbac.RuleSet(val), nil
// if err != nil {
// return err
// }
//}
}
{
var val string
// path params
val = chi.URLParam(req, "roleID")
r.RoleID, err = payload.ParseUint64(val), nil
if err != nil {
return err
}
}
return err
}

View File

@@ -0,0 +1,494 @@
package request
// This file is auto-generated.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Definitions file that controls how this file is generated:
//
import (
"encoding/json"
"fmt"
"github.com/cortezaproject/corteza/server/automation/types"
"github.com/cortezaproject/corteza/server/pkg/expr"
"github.com/cortezaproject/corteza/server/pkg/payload"
"github.com/go-chi/chi/v5"
"io"
"mime/multipart"
"net/http"
"strings"
)
// dummy vars to prevent
// unused imports complain
var (
_ = chi.URLParam
_ = multipart.ErrMessageTooLarge
_ = payload.ParseUint64s
_ = strings.ToLower
_ = io.EOF
_ = fmt.Errorf
_ = json.NewEncoder
)
type (
// Internal API interface
SessionList struct {
// SessionID GET parameter
//
// Filter by session ID
SessionID []string
// WorkflowID GET parameter
//
// Filter by workflow ID
WorkflowID []string
// CreatedBy GET parameter
//
// Filter by creators ID
CreatedBy []string
// Completed GET parameter
//
// Exclude (0, default), include (1) or return only (2) completed sessions
Completed uint
// Status GET parameter
//
// Filter by status: started (0), prompted (1), suspended (2), failed (3) and completed (4)
Status []uint
// EventType GET parameter
//
// Filter event type
EventType string
// ResourceType GET parameter
//
// Filter resource type
ResourceType string
// Limit GET parameter
//
// Limit
Limit uint
// IncTotal GET parameter
//
// Include total rows counter
IncTotal bool
// PageCursor GET parameter
//
// Page cursor
PageCursor string
// Sort GET parameter
//
// Sort items
Sort string
}
SessionRead struct {
// SessionID PATH parameter
//
// Session ID
SessionID uint64 `json:",string"`
}
SessionCancel struct {
// SessionID PATH parameter
//
// Session ID
SessionID uint64 `json:",string"`
}
SessionListPrompts struct {
}
SessionResumeState struct {
// SessionID PATH parameter
//
// Session ID
SessionID uint64 `json:",string"`
// StateID PATH parameter
//
// State ID
StateID uint64 `json:",string"`
// Input POST parameter
//
// Prompt variables
Input *expr.Vars
}
)
// NewSessionList request
func NewSessionList() *SessionList {
return &SessionList{}
}
// Auditable returns all auditable/loggable parameters
func (r SessionList) Auditable() map[string]interface{} {
return map[string]interface{}{
"sessionID": r.SessionID,
"workflowID": r.WorkflowID,
"createdBy": r.CreatedBy,
"completed": r.Completed,
"status": r.Status,
"eventType": r.EventType,
"resourceType": r.ResourceType,
"limit": r.Limit,
"incTotal": r.IncTotal,
"pageCursor": r.PageCursor,
"sort": r.Sort,
}
}
// Auditable returns all auditable/loggable parameters
func (r SessionList) GetSessionID() []string {
return r.SessionID
}
// Auditable returns all auditable/loggable parameters
func (r SessionList) GetWorkflowID() []string {
return r.WorkflowID
}
// Auditable returns all auditable/loggable parameters
func (r SessionList) GetCreatedBy() []string {
return r.CreatedBy
}
// Auditable returns all auditable/loggable parameters
func (r SessionList) GetCompleted() uint {
return r.Completed
}
// Auditable returns all auditable/loggable parameters
func (r SessionList) GetStatus() []uint {
return r.Status
}
// Auditable returns all auditable/loggable parameters
func (r SessionList) GetEventType() string {
return r.EventType
}
// Auditable returns all auditable/loggable parameters
func (r SessionList) GetResourceType() string {
return r.ResourceType
}
// Auditable returns all auditable/loggable parameters
func (r SessionList) GetLimit() uint {
return r.Limit
}
// Auditable returns all auditable/loggable parameters
func (r SessionList) GetIncTotal() bool {
return r.IncTotal
}
// Auditable returns all auditable/loggable parameters
func (r SessionList) GetPageCursor() string {
return r.PageCursor
}
// Auditable returns all auditable/loggable parameters
func (r SessionList) GetSort() string {
return r.Sort
}
// Fill processes request and fills internal variables
func (r *SessionList) Fill(req *http.Request) (err error) {
{
// GET params
tmp := req.URL.Query()
if val, ok := tmp["sessionID[]"]; ok {
r.SessionID, err = val, nil
if err != nil {
return err
}
} else if val, ok := tmp["sessionID"]; ok {
r.SessionID, err = val, nil
if err != nil {
return err
}
}
if val, ok := tmp["workflowID[]"]; ok {
r.WorkflowID, err = val, nil
if err != nil {
return err
}
} else if val, ok := tmp["workflowID"]; ok {
r.WorkflowID, err = val, nil
if err != nil {
return err
}
}
if val, ok := tmp["createdBy[]"]; ok {
r.CreatedBy, err = val, nil
if err != nil {
return err
}
} else if val, ok := tmp["createdBy"]; ok {
r.CreatedBy, err = val, nil
if err != nil {
return err
}
}
if val, ok := tmp["completed"]; ok && len(val) > 0 {
r.Completed, err = payload.ParseUint(val[0]), nil
if err != nil {
return err
}
}
if val, ok := tmp["status[]"]; ok {
r.Status, err = payload.ParseUints(val), nil
if err != nil {
return err
}
} else if val, ok := tmp["status"]; ok {
r.Status, err = payload.ParseUints(val), nil
if err != nil {
return err
}
}
if val, ok := tmp["eventType"]; ok && len(val) > 0 {
r.EventType, err = val[0], nil
if err != nil {
return err
}
}
if val, ok := tmp["resourceType"]; ok && len(val) > 0 {
r.ResourceType, err = val[0], nil
if err != nil {
return err
}
}
if val, ok := tmp["limit"]; ok && len(val) > 0 {
r.Limit, err = payload.ParseUint(val[0]), nil
if err != nil {
return err
}
}
if val, ok := tmp["incTotal"]; ok && len(val) > 0 {
r.IncTotal, err = payload.ParseBool(val[0]), nil
if err != nil {
return err
}
}
if val, ok := tmp["pageCursor"]; ok && len(val) > 0 {
r.PageCursor, err = val[0], nil
if err != nil {
return err
}
}
if val, ok := tmp["sort"]; ok && len(val) > 0 {
r.Sort, err = val[0], nil
if err != nil {
return err
}
}
}
return err
}
// NewSessionRead request
func NewSessionRead() *SessionRead {
return &SessionRead{}
}
// Auditable returns all auditable/loggable parameters
func (r SessionRead) Auditable() map[string]interface{} {
return map[string]interface{}{
"sessionID": r.SessionID,
}
}
// Auditable returns all auditable/loggable parameters
func (r SessionRead) GetSessionID() uint64 {
return r.SessionID
}
// Fill processes request and fills internal variables
func (r *SessionRead) Fill(req *http.Request) (err error) {
{
var val string
// path params
val = chi.URLParam(req, "sessionID")
r.SessionID, err = payload.ParseUint64(val), nil
if err != nil {
return err
}
}
return err
}
// NewSessionCancel request
func NewSessionCancel() *SessionCancel {
return &SessionCancel{}
}
// Auditable returns all auditable/loggable parameters
func (r SessionCancel) Auditable() map[string]interface{} {
return map[string]interface{}{
"sessionID": r.SessionID,
}
}
// Auditable returns all auditable/loggable parameters
func (r SessionCancel) GetSessionID() uint64 {
return r.SessionID
}
// Fill processes request and fills internal variables
func (r *SessionCancel) Fill(req *http.Request) (err error) {
{
var val string
// path params
val = chi.URLParam(req, "sessionID")
r.SessionID, err = payload.ParseUint64(val), nil
if err != nil {
return err
}
}
return err
}
// NewSessionListPrompts request
func NewSessionListPrompts() *SessionListPrompts {
return &SessionListPrompts{}
}
// Auditable returns all auditable/loggable parameters
func (r SessionListPrompts) Auditable() map[string]interface{} {
return map[string]interface{}{}
}
// Fill processes request and fills internal variables
func (r *SessionListPrompts) Fill(req *http.Request) (err error) {
return err
}
// NewSessionResumeState request
func NewSessionResumeState() *SessionResumeState {
return &SessionResumeState{}
}
// Auditable returns all auditable/loggable parameters
func (r SessionResumeState) Auditable() map[string]interface{} {
return map[string]interface{}{
"sessionID": r.SessionID,
"stateID": r.StateID,
"input": r.Input,
}
}
// Auditable returns all auditable/loggable parameters
func (r SessionResumeState) GetSessionID() uint64 {
return r.SessionID
}
// Auditable returns all auditable/loggable parameters
func (r SessionResumeState) GetStateID() uint64 {
return r.StateID
}
// Auditable returns all auditable/loggable parameters
func (r SessionResumeState) GetInput() *expr.Vars {
return r.Input
}
// Fill processes request and fills internal variables
func (r *SessionResumeState) Fill(req *http.Request) (err error) {
if strings.HasPrefix(strings.ToLower(req.Header.Get("content-type")), "application/json") {
err = json.NewDecoder(req.Body).Decode(r)
switch {
case err == io.EOF:
err = nil
case err != nil:
return fmt.Errorf("error parsing http request body: %w", err)
}
}
{
// Caching 32MB to memory, the rest to disk
if err = req.ParseMultipartForm(32 << 20); err != nil && err != http.ErrNotMultipart {
return err
} else if err == nil {
// Multipart params
if val, ok := req.MultipartForm.Value["input[]"]; ok {
r.Input, err = types.ParseWorkflowVariables(val)
if err != nil {
return err
}
} else if val, ok := req.MultipartForm.Value["input"]; ok {
r.Input, err = types.ParseWorkflowVariables(val)
if err != nil {
return err
}
}
}
}
{
if err = req.ParseForm(); err != nil {
return err
}
// POST params
if val, ok := req.Form["input[]"]; ok {
r.Input, err = types.ParseWorkflowVariables(val)
if err != nil {
return err
}
} else if val, ok := req.Form["input"]; ok {
r.Input, err = types.ParseWorkflowVariables(val)
if err != nil {
return err
}
}
}
{
var val string
// path params
val = chi.URLParam(req, "sessionID")
r.SessionID, err = payload.ParseUint64(val), nil
if err != nil {
return err
}
val = chi.URLParam(req, "stateID")
r.StateID, err = payload.ParseUint64(val), nil
if err != nil {
return err
}
}
return err
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,54 @@
package request
// This file is auto-generated.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Definitions file that controls how this file is generated:
//
import (
"encoding/json"
"fmt"
"github.com/cortezaproject/corteza/server/pkg/payload"
"github.com/go-chi/chi/v5"
"io"
"mime/multipart"
"net/http"
"strings"
)
// dummy vars to prevent
// unused imports complain
var (
_ = chi.URLParam
_ = multipart.ErrMessageTooLarge
_ = payload.ParseUint64s
_ = strings.ToLower
_ = io.EOF
_ = fmt.Errorf
_ = json.NewEncoder
)
type (
// Internal API interface
TypeList struct {
}
)
// NewTypeList request
func NewTypeList() *TypeList {
return &TypeList{}
}
// Auditable returns all auditable/loggable parameters
func (r TypeList) Auditable() map[string]interface{} {
return map[string]interface{}{}
}
// Fill processes request and fills internal variables
func (r *TypeList) Fill(req *http.Request) (err error) {
return err
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,25 @@
package rest
import (
"github.com/go-chi/chi/v5"
"github.com/cortezaproject/corteza/server/automation/rest/handlers"
"github.com/cortezaproject/corteza/server/pkg/auth"
)
func MountRoutes() func(r chi.Router) {
return func(r chi.Router) {
// Protect all _private_ routes
r.Group(func(r chi.Router) {
r.Use(auth.HttpTokenValidator("api"))
handlers.NewWorkflow(Workflow{}.New()).MountRoutes(r)
handlers.NewTrigger(Trigger{}.New()).MountRoutes(r)
handlers.NewSession(Session{}.New()).MountRoutes(r)
handlers.NewFunction(Function{}.New()).MountRoutes(r)
handlers.NewType(Type{}.New()).MountRoutes(r)
handlers.NewPermissions(Permissions{}.New()).MountRoutes(r)
handlers.NewEventTypes(EventTypes{}.New()).MountRoutes(r)
})
}
}

View File

@@ -0,0 +1,161 @@
package rest
import (
"context"
"fmt"
"github.com/cortezaproject/corteza/server/automation/rest/request"
"github.com/cortezaproject/corteza/server/automation/service"
"github.com/cortezaproject/corteza/server/automation/types"
"github.com/cortezaproject/corteza/server/compose/automation"
cmpService "github.com/cortezaproject/corteza/server/compose/service"
cmpTypes "github.com/cortezaproject/corteza/server/compose/types"
"github.com/cortezaproject/corteza/server/pkg/api"
"github.com/cortezaproject/corteza/server/pkg/auth"
"github.com/cortezaproject/corteza/server/pkg/expr"
"github.com/cortezaproject/corteza/server/pkg/filter"
"github.com/cortezaproject/corteza/server/pkg/wfexec"
)
type (
Session struct {
svc sessionService
// cross-link with compose service to load module on resolved records
svcModule interface {
FindByID(ctx context.Context, namespaceID, moduleID uint64) (*cmpTypes.Module, error)
}
}
sessionService interface {
Search(ctx context.Context, filter types.SessionFilter) (types.SessionSet, types.SessionFilter, error)
LookupByID(ctx context.Context, sessionID uint64) (*types.Session, error)
Resume(sessionID, stateID uint64, i auth.Identifiable, input *expr.Vars) error
PendingPrompts(context.Context) []*wfexec.PendingPrompt
Cancel(context.Context, uint64) error
}
sessionSetPayload struct {
Filter types.SessionFilter `json:"filter"`
Set []*sessionSetItem `json:"set"`
}
sessionSetItem struct {
*types.Session
// Make sure stacktrace is not included in the list
Stacktrace *struct{} `json:"stacktrace,omitempty"`
// Make sure output values are not included in the list
Output *struct{} `json:"output,omitempty"`
// Make sure input values are not included in the list
Input *struct{} `json:"input,omitempty"`
}
)
func (Session) New() *Session {
ctrl := &Session{}
ctrl.svc = service.DefaultSession
ctrl.svcModule = cmpService.DefaultModule
return ctrl
}
func (ctrl Session) List(ctx context.Context, r *request.SessionList) (interface{}, error) {
var (
err error
f = types.SessionFilter{
WorkflowID: r.WorkflowID,
SessionID: r.SessionID,
CreatedBy: r.CreatedBy,
EventType: r.EventType,
ResourceType: r.ResourceType,
Completed: filter.State(r.Completed),
Status: r.Status,
}
)
if f.Paging, err = filter.NewPaging(r.Limit, r.PageCursor); err != nil {
return nil, err
}
// fixes issue with sorting of status column and pagination
// need to improve on cursor for this
if f.Paging.PageCursor != nil {
for _, status := range r.Status {
f.Paging.PageCursor.Set("status", status, false)
}
}
f.IncTotal = r.IncTotal
if f.Sorting, err = filter.NewSorting(r.Sort); err != nil {
return nil, err
}
set, filter, err := ctrl.svc.Search(ctx, f)
return ctrl.makeFilterPayload(ctx, set, filter, err)
}
func (ctrl Session) Read(ctx context.Context, r *request.SessionRead) (interface{}, error) {
return ctrl.svc.LookupByID(ctx, r.SessionID)
}
func (ctrl Session) Cancel(ctx context.Context, r *request.SessionCancel) (interface{}, error) {
return true, ctrl.svc.Cancel(ctx, r.SessionID)
}
func (ctrl Session) ListPrompts(ctx context.Context, r *request.SessionListPrompts) (interface{}, error) {
return struct {
Set []*wfexec.PendingPrompt `json:"set"`
}{
Set: ctrl.svc.PendingPrompts(ctx),
}, nil
}
func (ctrl Session) ResumeState(ctx context.Context, r *request.SessionResumeState) (_ interface{}, err error) {
if r.Input != nil {
if err = r.Input.ResolveTypes(service.Registry().Type); err != nil {
return nil, err
}
}
// Now when all types are resolved we have to load modules and link them to records
//
// Very naive approach for now.
//
// @note copied from https://github.com/cortezaproject/corteza/blob/2023.9.x/server/automation/rest/workflow.go#L189
// copied to reduce the need for some dependency; should be good enough for now
r.Input.Each(func(k string, v expr.TypedValue) error {
switch c := v.(type) {
case *automation.ComposeRecord:
rec := c.GetValue()
if rec == nil {
return nil
}
mod, err := ctrl.svcModule.FindByID(ctx, rec.NamespaceID, rec.ModuleID)
if err != nil {
return fmt.Errorf("failed to resolve ComposeRecord type: %w", err)
}
c.GetValue().SetModule(mod)
}
return nil
})
return api.OK(), ctrl.svc.Resume(r.SessionID, r.StateID, auth.GetIdentityFromContext(ctx), r.Input)
}
func (ctrl Session) makeFilterPayload(ctx context.Context, ss types.SessionSet, f types.SessionFilter, err error) (*sessionSetPayload, error) {
if err != nil {
return nil, err
}
out := &sessionSetPayload{Filter: f, Set: make([]*sessionSetItem, len(ss))}
for i, s := range ss {
s.Stacktrace = nil
out.Set[i] = &sessionSetItem{Session: s}
}
return out, nil
}

View File

@@ -0,0 +1,121 @@
package rest
import (
"context"
"github.com/cortezaproject/corteza/server/automation/rest/request"
"github.com/cortezaproject/corteza/server/automation/service"
"github.com/cortezaproject/corteza/server/automation/types"
"github.com/cortezaproject/corteza/server/pkg/api"
"github.com/cortezaproject/corteza/server/pkg/filter"
)
type (
Trigger struct {
svc interface {
Search(ctx context.Context, filter types.TriggerFilter) (types.TriggerSet, types.TriggerFilter, error)
LookupByID(ctx context.Context, triggerID uint64) (*types.Trigger, error)
Create(ctx context.Context, new *types.Trigger) (*types.Trigger, error)
Update(ctx context.Context, upd *types.Trigger) (*types.Trigger, error)
DeleteByID(ctx context.Context, triggerID uint64) error
UndeleteByID(ctx context.Context, triggerID uint64) error
}
}
triggerSetPayload struct {
Filter types.TriggerFilter `json:"filter"`
Set types.TriggerSet `json:"set"`
}
)
func (Trigger) New() *Trigger {
ctrl := &Trigger{}
ctrl.svc = service.DefaultTrigger
return ctrl
}
func (ctrl Trigger) List(ctx context.Context, r *request.TriggerList) (interface{}, error) {
var (
err error
f = types.TriggerFilter{
WorkflowID: r.WorkflowID,
TriggerID: r.TriggerID,
EventType: r.EventType,
ResourceType: r.ResourceType,
Labels: r.Labels,
Deleted: filter.State(r.Deleted),
Disabled: filter.State(r.Disabled),
}
)
if f.Paging, err = filter.NewPaging(r.Limit, r.PageCursor); err != nil {
return nil, err
}
if f.Sorting, err = filter.NewSorting(r.Sort); err != nil {
return nil, err
}
set, filter, err := ctrl.svc.Search(ctx, f)
return ctrl.makeFilterPayload(ctx, set, filter, err)
}
func (ctrl Trigger) Create(ctx context.Context, r *request.TriggerCreate) (interface{}, error) {
trigger := &types.Trigger{
Enabled: r.Enabled,
WorkflowID: r.WorkflowID,
StepID: r.WorkflowStepID,
ResourceType: r.ResourceType,
EventType: r.EventType,
Constraints: r.Constraints,
Input: r.Input,
Labels: r.Labels,
OwnedBy: r.OwnedBy,
Meta: r.Meta,
}
return ctrl.svc.Create(ctx, trigger)
}
func (ctrl Trigger) Update(ctx context.Context, r *request.TriggerUpdate) (interface{}, error) {
trigger := &types.Trigger{
ID: r.TriggerID,
Enabled: r.Enabled,
WorkflowID: r.WorkflowID,
StepID: r.WorkflowStepID,
ResourceType: r.ResourceType,
EventType: r.EventType,
Constraints: r.Constraints,
Input: r.Input,
Labels: r.Labels,
OwnedBy: r.OwnedBy,
Meta: r.Meta,
UpdatedAt: r.UpdatedAt,
}
return ctrl.svc.Update(ctx, trigger)
}
func (ctrl Trigger) Read(ctx context.Context, r *request.TriggerRead) (interface{}, error) {
return ctrl.svc.LookupByID(ctx, r.TriggerID)
}
func (ctrl Trigger) Delete(ctx context.Context, r *request.TriggerDelete) (interface{}, error) {
return api.OK(), ctrl.svc.DeleteByID(ctx, r.TriggerID)
}
func (ctrl Trigger) Undelete(ctx context.Context, r *request.TriggerUndelete) (interface{}, error) {
return api.OK(), ctrl.svc.UndeleteByID(ctx, r.TriggerID)
}
func (ctrl Trigger) makeFilterPayload(ctx context.Context, uu types.TriggerSet, f types.TriggerFilter, err error) (*triggerSetPayload, error) {
if err != nil {
return nil, err
}
if len(uu) == 0 {
uu = make([]*types.Trigger, 0)
}
return &triggerSetPayload{Filter: f, Set: uu}, nil
}

View File

@@ -0,0 +1,28 @@
package rest
import (
"context"
"github.com/cortezaproject/corteza/server/automation/rest/request"
"github.com/cortezaproject/corteza/server/automation/service"
)
type (
Type struct {
reg interface {
Types() []string
}
}
typeSetPayload struct {
Set []string `json:"set"`
}
)
func (Type) New() *Type {
ctrl := &Type{reg: service.Registry()}
return ctrl
}
func (ctrl Type) List(_ context.Context, _ *request.TypeList) (interface{}, error) {
return typeSetPayload{Set: ctrl.reg.Types()}, nil
}

View File

@@ -0,0 +1,249 @@
package rest
import (
"context"
"fmt"
"github.com/cortezaproject/corteza/server/automation/rest/request"
"github.com/cortezaproject/corteza/server/automation/service"
"github.com/cortezaproject/corteza/server/automation/types"
"github.com/cortezaproject/corteza/server/compose/automation"
cmpService "github.com/cortezaproject/corteza/server/compose/service"
cmpTypes "github.com/cortezaproject/corteza/server/compose/types"
"github.com/cortezaproject/corteza/server/pkg/api"
"github.com/cortezaproject/corteza/server/pkg/expr"
"github.com/cortezaproject/corteza/server/pkg/filter"
)
type (
Workflow struct {
svc interface {
Search(ctx context.Context, filter types.WorkflowFilter) (types.WorkflowSet, types.WorkflowFilter, error)
LookupByID(ctx context.Context, workflowID uint64) (*types.Workflow, error)
Create(ctx context.Context, new *types.Workflow) (*types.Workflow, error)
Update(ctx context.Context, upd *types.Workflow) (*types.Workflow, error)
DeleteByID(ctx context.Context, workflowID uint64) error
UndeleteByID(ctx context.Context, workflowID uint64) error
Exec(ctx context.Context, workflowID uint64, p types.WorkflowExecParams) (*expr.Vars, uint64, types.Stacktrace, error)
}
// cross-link with compose service to load module on resolved records
svcModule interface {
FindByID(ctx context.Context, namespaceID, moduleID uint64) (*cmpTypes.Module, error)
}
ac workflowAccessControl
}
workflowAccessControl interface {
CanGrant(context.Context) bool
CanUpdateWorkflow(context.Context, *types.Workflow) bool
CanDeleteWorkflow(context.Context, *types.Workflow) bool
CanUndeleteWorkflow(context.Context, *types.Workflow) bool
CanExecuteWorkflow(context.Context, *types.Workflow) bool
CanManageTriggersOnWorkflow(context.Context, *types.Workflow) bool
CanManageSessionsOnWorkflow(context.Context, *types.Workflow) bool
}
workflowPayload struct {
*types.Workflow
CanGrant bool `json:"canGrant"`
CanUpdateWorkflow bool `json:"canUpdateWorkflow"`
CanDeleteWorkflow bool `json:"canDeleteWorkflow"`
CanUndeleteWorkflow bool `json:"canUndeleteWorkflow"`
CanExecuteWorkflow bool `json:"canExecuteWorkflow"`
CanManageWorkflowTriggers bool `json:"canManageWorkflowTriggers"`
CanManageWorkflowSessions bool `json:"canManageWorkflowSessions"`
}
workflowSetPayload struct {
Filter types.WorkflowFilter `json:"filter"`
Set []*workflowPayload `json:"set"`
}
workflowExecPayload struct {
Results *expr.Vars `json:"results"`
Trace types.Stacktrace `json:"trace,omitempty"`
SessionID uint64 `json:"sessionID,string,omitempty"`
Error string `json:"error,omitempty"`
}
)
func (Workflow) New() *Workflow {
ctrl := &Workflow{}
ctrl.svc = service.DefaultWorkflow
ctrl.svcModule = cmpService.DefaultModule
ctrl.ac = service.DefaultAccessControl
return ctrl
}
func (ctrl Workflow) List(ctx context.Context, r *request.WorkflowList) (interface{}, error) {
var (
err error
f = types.WorkflowFilter{
WorkflowID: r.WorkflowID,
Query: r.Query,
Labels: r.Labels,
Deleted: filter.State(r.Deleted),
Disabled: filter.State(r.Disabled),
SubWorkflow: filter.State(r.SubWorkflow),
}
)
if f.Paging, err = filter.NewPaging(r.Limit, r.PageCursor); err != nil {
return nil, err
}
f.IncTotal = r.IncTotal
if f.Sorting, err = filter.NewSorting(r.Sort); err != nil {
return nil, err
}
set, filter, err := ctrl.svc.Search(ctx, f)
return ctrl.makeFilterPayload(ctx, set, filter, err)
}
func (ctrl Workflow) Create(ctx context.Context, r *request.WorkflowCreate) (interface{}, error) {
workflow := &types.Workflow{
Handle: r.Handle,
Labels: r.Labels,
Meta: r.Meta,
Enabled: r.Enabled,
Trace: r.Trace,
KeepSessions: r.KeepSessions,
Scope: r.Scope,
Steps: r.Steps,
Paths: r.Paths,
RunAs: r.RunAs,
OwnedBy: r.OwnedBy,
}
wf, err := ctrl.svc.Create(ctx, workflow)
return ctrl.makePayload(ctx, wf, err)
}
func (ctrl Workflow) Update(ctx context.Context, r *request.WorkflowUpdate) (interface{}, error) {
workflow := &types.Workflow{
ID: r.WorkflowID,
Handle: r.Handle,
Labels: r.Labels,
Meta: r.Meta,
Enabled: r.Enabled,
Trace: r.Trace,
KeepSessions: r.KeepSessions,
Scope: r.Scope,
Steps: r.Steps,
Paths: r.Paths,
RunAs: r.RunAs,
OwnedBy: r.OwnedBy,
UpdatedAt: r.UpdatedAt,
}
wf, err := ctrl.svc.Update(ctx, workflow)
return ctrl.makePayload(ctx, wf, err)
}
func (ctrl Workflow) Read(ctx context.Context, r *request.WorkflowRead) (interface{}, error) {
wf, err := ctrl.svc.LookupByID(ctx, r.WorkflowID)
return ctrl.makePayload(ctx, wf, err)
}
func (ctrl Workflow) Test(ctx context.Context, r *request.WorkflowTest) (interface{}, error) {
return nil, fmt.Errorf("not implemented")
}
func (ctrl Workflow) Delete(ctx context.Context, r *request.WorkflowDelete) (interface{}, error) {
return api.OK(), ctrl.svc.DeleteByID(ctx, r.WorkflowID)
}
func (ctrl Workflow) Undelete(ctx context.Context, r *request.WorkflowUndelete) (interface{}, error) {
return api.OK(), ctrl.svc.UndeleteByID(ctx, r.WorkflowID)
}
func (ctrl Workflow) Exec(ctx context.Context, r *request.WorkflowExec) (interface{}, error) {
var (
wep = &workflowExecPayload{}
err error
execParams = types.WorkflowExecParams{
StepID: r.StepID,
Trace: r.Trace,
Input: r.Input,
Async: r.Async,
Wait: r.Wait,
}
)
if execParams.Input != nil {
if err = execParams.Input.ResolveTypes(service.Registry().Type); err != nil {
return nil, err
}
}
// Now when all types are resolved we have to load modules and link them to records
//
// Very naive approach for now.
execParams.Input.Each(func(k string, v expr.TypedValue) error {
switch c := v.(type) {
case *automation.ComposeRecord:
rec := c.GetValue()
if rec == nil {
return nil
}
mod, err := ctrl.svcModule.FindByID(ctx, rec.NamespaceID, rec.ModuleID)
if err != nil {
return fmt.Errorf("failed to resolve ComposeRecord type: %w", err)
}
c.GetValue().SetModule(mod)
}
return nil
})
wep.Results, wep.SessionID, wep.Trace, err = ctrl.svc.Exec(ctx, r.WorkflowID, execParams)
if err != nil && wep.Trace != nil && r.Trace {
// in case of an error & trace enabled (and stacktrace present)
// we'll suppress the error
wep.Error = err.Error()
return wep, nil
}
return wep, err
}
func (ctrl Workflow) makeFilterPayload(ctx context.Context, set types.WorkflowSet, f types.WorkflowFilter, err error) (*workflowSetPayload, error) {
if err != nil {
return nil, err
}
wfsp := &workflowSetPayload{Filter: f, Set: make([]*workflowPayload, len(set))}
for i, wf := range set {
wfsp.Set[i], _ = ctrl.makePayload(ctx, wf, nil)
}
return wfsp, nil
}
func (ctrl Workflow) makePayload(ctx context.Context, wf *types.Workflow, err error) (*workflowPayload, error) {
if err != nil {
return nil, err
}
return &workflowPayload{
Workflow: wf,
CanGrant: ctrl.ac.CanGrant(ctx),
CanUpdateWorkflow: ctrl.ac.CanUpdateWorkflow(ctx, wf),
CanDeleteWorkflow: ctrl.ac.CanDeleteWorkflow(ctx, wf),
CanUndeleteWorkflow: ctrl.ac.CanUndeleteWorkflow(ctx, wf),
CanExecuteWorkflow: ctrl.ac.CanExecuteWorkflow(ctx, wf),
CanManageWorkflowTriggers: ctrl.ac.CanManageTriggersOnWorkflow(ctx, wf),
CanManageWorkflowSessions: ctrl.ac.CanManageSessionsOnWorkflow(ctx, wf),
}, nil
}