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
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:
295
server/system/rest/dal_connection.go
Normal file
295
server/system/rest/dal_connection.go
Normal file
@@ -0,0 +1,295 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
federationService "github.com/cortezaproject/corteza/server/federation/service"
|
||||
federationTypes "github.com/cortezaproject/corteza/server/federation/types"
|
||||
"github.com/cortezaproject/corteza/server/pkg/api"
|
||||
"github.com/cortezaproject/corteza/server/pkg/filter"
|
||||
"github.com/cortezaproject/corteza/server/pkg/handle"
|
||||
"github.com/cortezaproject/corteza/server/pkg/id"
|
||||
"github.com/cortezaproject/corteza/server/system/rest/request"
|
||||
"github.com/cortezaproject/corteza/server/system/service"
|
||||
"github.com/cortezaproject/corteza/server/system/types"
|
||||
"github.com/modern-go/reflect2"
|
||||
)
|
||||
|
||||
type (
|
||||
DalConnection struct {
|
||||
svc connectionService
|
||||
federationSvc federationNodeService
|
||||
|
||||
connectionAc connectionAccessController
|
||||
}
|
||||
|
||||
connectionPayload struct {
|
||||
*types.DalConnection
|
||||
|
||||
CanGrant bool `json:"canGrant"`
|
||||
CanUpdateConnection bool `json:"canUpdateConnection"`
|
||||
CanDeleteConnection bool `json:"canDeleteConnection"`
|
||||
CanManageDalConfig bool `json:"canManageDalConfig"`
|
||||
}
|
||||
|
||||
connectionSetPayload struct {
|
||||
Filter types.DalConnectionFilter `json:"filter"`
|
||||
Set []*connectionPayload `json:"set"`
|
||||
}
|
||||
|
||||
connectionAccessController interface {
|
||||
CanGrant(context.Context) bool
|
||||
CanCreateDalConnection(context.Context) bool
|
||||
CanUpdateDalConnection(context.Context, *types.DalConnection) bool
|
||||
CanDeleteDalConnection(context.Context, *types.DalConnection) bool
|
||||
CanManageDalConfigOnDalConnection(context.Context, *types.DalConnection) bool
|
||||
}
|
||||
|
||||
connectionService interface {
|
||||
FindByID(ctx context.Context, ID uint64) (*types.DalConnection, error)
|
||||
Create(ctx context.Context, new *types.DalConnection) (*types.DalConnection, error)
|
||||
Update(ctx context.Context, upd *types.DalConnection) (*types.DalConnection, error)
|
||||
DeleteByID(ctx context.Context, ID uint64) error
|
||||
UndeleteByID(ctx context.Context, ID uint64) error
|
||||
Search(ctx context.Context, filter types.DalConnectionFilter) (types.DalConnectionSet, types.DalConnectionFilter, error)
|
||||
}
|
||||
|
||||
federationNodeService interface {
|
||||
Search(ctx context.Context, filter federationTypes.NodeFilter) (set federationTypes.NodeSet, f federationTypes.NodeFilter, err error)
|
||||
}
|
||||
)
|
||||
|
||||
func (DalConnection) New() *DalConnection {
|
||||
return &DalConnection{
|
||||
svc: service.DefaultDalConnection,
|
||||
federationSvc: federationService.DefaultNode,
|
||||
|
||||
connectionAc: service.DefaultAccessControl,
|
||||
}
|
||||
}
|
||||
|
||||
func (ctrl DalConnection) List(ctx context.Context, r *request.DalConnectionList) (interface{}, error) {
|
||||
var (
|
||||
err error
|
||||
dalConnections types.DalConnectionSet
|
||||
|
||||
f = types.DalConnectionFilter{
|
||||
DalConnectionID: r.ConnectionID,
|
||||
Handle: r.Handle,
|
||||
Type: r.Type,
|
||||
|
||||
Deleted: filter.State(r.Deleted),
|
||||
}
|
||||
)
|
||||
|
||||
if f.Deleted == 0 {
|
||||
f.Deleted = filter.StateExcluded
|
||||
}
|
||||
|
||||
f.IncTotal = r.IncTotal
|
||||
|
||||
dalConnections, f, err = ctrl.collectConnections(ctx, f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ctrl.makeFilterPayload(ctx, dalConnections, f)
|
||||
}
|
||||
|
||||
func (ctrl DalConnection) Create(ctx context.Context, r *request.DalConnectionCreate) (interface{}, error) {
|
||||
connection := &types.DalConnection{
|
||||
Handle: r.Handle,
|
||||
Type: r.Type,
|
||||
Meta: r.Meta,
|
||||
Config: r.Config,
|
||||
}
|
||||
|
||||
res, err := ctrl.svc.Create(ctx, connection)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ctrl.makePayload(ctx, res), nil
|
||||
}
|
||||
|
||||
func (ctrl DalConnection) Update(ctx context.Context, r *request.DalConnectionUpdate) (interface{}, error) {
|
||||
connection := &types.DalConnection{
|
||||
ID: r.ConnectionID,
|
||||
Handle: r.Handle,
|
||||
Type: r.Type,
|
||||
Meta: r.Meta,
|
||||
Config: r.Config,
|
||||
UpdatedAt: r.UpdatedAt,
|
||||
}
|
||||
|
||||
res, err := ctrl.svc.Update(ctx, connection)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ctrl.makePayload(ctx, res), nil
|
||||
}
|
||||
|
||||
func (ctrl DalConnection) Read(ctx context.Context, r *request.DalConnectionRead) (interface{}, error) {
|
||||
res, err := ctrl.svc.FindByID(ctx, r.ConnectionID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ctrl.makePayload(ctx, res), nil
|
||||
}
|
||||
|
||||
func (ctrl DalConnection) Delete(ctx context.Context, r *request.DalConnectionDelete) (interface{}, error) {
|
||||
return api.OK(), ctrl.svc.DeleteByID(ctx, r.ConnectionID)
|
||||
}
|
||||
|
||||
func (ctrl DalConnection) Undelete(ctx context.Context, r *request.DalConnectionUndelete) (interface{}, error) {
|
||||
return api.OK(), ctrl.svc.UndeleteByID(ctx, r.ConnectionID)
|
||||
}
|
||||
|
||||
func (ctrl DalConnection) makeFilterPayload(ctx context.Context, connections types.DalConnectionSet, f types.DalConnectionFilter) (out *connectionSetPayload, err error) {
|
||||
out = &connectionSetPayload{
|
||||
Filter: f,
|
||||
Set: make([]*connectionPayload, 0, len(connections)),
|
||||
}
|
||||
|
||||
for _, c := range connections {
|
||||
out.Set = append(out.Set, ctrl.makePayload(ctx, c))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Make payload for dal-connection
|
||||
//
|
||||
// # Payload is without connection params on the config prop
|
||||
//
|
||||
// An explicit call to /params
|
||||
func (ctrl DalConnection) makePayload(ctx context.Context, c *types.DalConnection) *connectionPayload {
|
||||
return &connectionPayload{
|
||||
DalConnection: c,
|
||||
|
||||
CanGrant: ctrl.connectionAc.CanGrant(ctx),
|
||||
CanUpdateConnection: ctrl.connectionAc.CanUpdateDalConnection(ctx, c),
|
||||
CanDeleteConnection: ctrl.connectionAc.CanDeleteDalConnection(ctx, c),
|
||||
CanManageDalConfig: ctrl.connectionAc.CanManageDalConfigOnDalConnection(ctx, c),
|
||||
}
|
||||
}
|
||||
|
||||
func (ctrl DalConnection) federatedNodeToConnection(f *federationTypes.Node) *types.DalConnection {
|
||||
h, _ := handle.Cast(nil, f.Name)
|
||||
|
||||
return &types.DalConnection{
|
||||
ID: f.ID,
|
||||
|
||||
Meta: types.ConnectionMeta{
|
||||
Name: f.Name,
|
||||
Ownership: f.Contact,
|
||||
},
|
||||
|
||||
Handle: h,
|
||||
Type: federationTypes.NodeResourceType,
|
||||
|
||||
//Config: types.ConnectionConfig{
|
||||
// Connection: dal.NewFederatedNodeConnection(f.BaseURL, f.PairToken, f.AuthToken),
|
||||
//},
|
||||
|
||||
CreatedAt: f.CreatedAt,
|
||||
CreatedBy: f.CreatedBy,
|
||||
UpdatedAt: f.UpdatedAt,
|
||||
UpdatedBy: f.UpdatedBy,
|
||||
DeletedAt: f.DeletedAt,
|
||||
DeletedBy: f.DeletedBy,
|
||||
}
|
||||
}
|
||||
|
||||
func (ctrl DalConnection) collectConnections(ctx context.Context, filter types.DalConnectionFilter) (out types.DalConnectionSet, f types.DalConnectionFilter, err error) {
|
||||
var (
|
||||
dalConnections types.DalConnectionSet
|
||||
federatedNodes federationTypes.NodeSet
|
||||
)
|
||||
|
||||
if dalConnections, f, err = ctrl.svc.Search(ctx, filter); err != nil {
|
||||
return nil, f, err
|
||||
}
|
||||
|
||||
if !reflect2.IsNil(ctrl.federationSvc) {
|
||||
if federatedNodes, _, err = ctrl.federationSvc.Search(ctx, federationTypes.NodeFilter{
|
||||
// @todo IDs?
|
||||
Deleted: f.Deleted,
|
||||
}); err != nil {
|
||||
return nil, f, err
|
||||
}
|
||||
}
|
||||
|
||||
out = append(out, dalConnections...)
|
||||
|
||||
// We're converting federation nodes to DAL connection structs so that we have
|
||||
// a unified output.
|
||||
//
|
||||
// Eventually federation nodes will become connections, so this is ok
|
||||
for _, nn := range federatedNodes {
|
||||
out = append(out, ctrl.federatedNodeToConnection(nn))
|
||||
}
|
||||
|
||||
out = ctrl.filterConnections(out, f)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (ctrl DalConnection) filterConnections(baseConnections types.DalConnectionSet, f types.DalConnectionFilter) (out types.DalConnectionSet) {
|
||||
for _, conn := range baseConnections {
|
||||
include := true
|
||||
|
||||
if len(f.DalConnectionID) > 0 {
|
||||
include = include && ctrl.inIDSet(id.Uints(f.DalConnectionID...), conn.ID)
|
||||
}
|
||||
|
||||
if f.Handle != "" {
|
||||
include = include && f.Handle == conn.Handle
|
||||
}
|
||||
|
||||
if f.Type != "" {
|
||||
include = include && f.Type == conn.Type
|
||||
}
|
||||
|
||||
{
|
||||
if f.Deleted == filter.StateExcluded {
|
||||
include = include && conn.DeletedAt == nil
|
||||
}
|
||||
|
||||
if f.Deleted == filter.StateExclusive {
|
||||
include = include && conn.DeletedAt != nil
|
||||
}
|
||||
}
|
||||
|
||||
if include {
|
||||
out = append(out, conn)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (ctrl DalConnection) inIDSet(set []uint64, target uint64) (out bool) {
|
||||
for _, id := range set {
|
||||
out = out || id == target
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (ctrl DalConnection) serve(ctx context.Context, fn string, archive io.ReadSeeker, err error) (interface{}, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return func(w http.ResponseWriter, req *http.Request) {
|
||||
w.Header().Add("Content-Disposition", "attachment; filename="+fn)
|
||||
|
||||
http.ServeContent(w, req, fn, time.Now(), archive)
|
||||
}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user