3
0

Allow encoders to access system users during export

This commit is contained in:
Tomaž Jerman
2020-05-27 17:11:19 +02:00
committed by Denis Arh
parent 77b67acdf3
commit 6e05c2a6ab
3 changed files with 39 additions and 6 deletions

View File

@@ -1,5 +1,9 @@
package encoder
import (
syst "github.com/cortezaproject/corteza-server/system/types"
)
type (
multiple uint
@@ -17,14 +21,18 @@ type (
Encode(interface{}) error
}
userFinder func(ID uint64) (*syst.User, error)
flatWriter struct {
w FlatWriter
ff []field
u userFinder
}
structuredEncoder struct {
w StructuredEncoder
ff []field
u userFinder
}
)
@@ -45,10 +53,11 @@ func MultiValueField(name string) field {
return field{name: name, encodeAllMulti: true}
}
func NewFlatWriter(w FlatWriter, header bool, ff ...field) *flatWriter {
func NewFlatWriter(w FlatWriter, header bool, u userFinder, ff ...field) *flatWriter {
f := &flatWriter{
w: w,
ff: ff,
u: u,
}
if header {
@@ -71,10 +80,11 @@ func (enc flatWriter) writeHeader() {
_ = enc.w.Write(ss)
}
func NewStructuredEncoder(w StructuredEncoder, ff ...field) *structuredEncoder {
func NewStructuredEncoder(w StructuredEncoder, u userFinder, ff ...field) *structuredEncoder {
return &structuredEncoder{
w: w,
ff: ff,
u: u,
}
}

View File

@@ -12,14 +12,16 @@ type (
f *excelize.File
w io.Writer
ff []field
u userFinder
}
)
func NewExcelizeEncoder(w io.Writer, header bool, ff ...field) *excelizeEncoder {
func NewExcelizeEncoder(w io.Writer, header bool, u userFinder, ff ...field) *excelizeEncoder {
enc := &excelizeEncoder{
f: excelize.NewFile(),
w: w,
ff: ff,
u: u,
}
if header {

View File

@@ -23,6 +23,7 @@ import (
"github.com/cortezaproject/corteza-server/pkg/mime"
"github.com/cortezaproject/corteza-server/pkg/payload"
"github.com/cortezaproject/corteza-server/pkg/rh"
stypes "github.com/cortezaproject/corteza-server/system/types"
)
type (
@@ -40,6 +41,10 @@ type (
Set []*recordPayload `json:"set"`
}
userFinder interface {
FindByID(context.Context, uint64) (*stypes.User, error)
}
Record struct {
importSession service.ImportSessionService
record service.RecordService
@@ -47,6 +52,7 @@ type (
namespace service.NamespaceService
attachment service.AttachmentService
ac recordAccessController
userFinder userFinder
}
recordAccessController interface {
@@ -63,6 +69,7 @@ func (Record) New() *Record {
namespace: service.DefaultNamespace,
attachment: service.DefaultAttachment,
ac: service.DefaultAccessControl,
userFinder: service.DefaultSystemUser,
}
}
@@ -407,18 +414,32 @@ func (ctrl *Record) Export(ctx context.Context, r *request.RecordExport) (interf
http.Error(w, "no record value fields provided", http.StatusBadRequest)
}
// Custom user getter function for the underlying encoders.
users := map[uint64]*stypes.User{}
uf := func(ID uint64) (*stypes.User, error) {
if users[ID] != nil {
return users[ID], nil
}
u, err := ctrl.userFinder.FindByID(ctx, ID)
if err != nil {
return nil, err
}
users[ID] = u
return u, nil
}
switch strings.ToLower(r.Ext) {
case "json", "jsonl", "ldjson", "ndjson":
contentType = "application/jsonl"
recordEncoder = encoder.NewStructuredEncoder(json.NewEncoder(w), ff...)
recordEncoder = encoder.NewStructuredEncoder(json.NewEncoder(w), uf, ff...)
case "csv":
contentType = "text/csv"
recordEncoder = encoder.NewFlatWriter(csv.NewWriter(w), true, ff...)
recordEncoder = encoder.NewFlatWriter(csv.NewWriter(w), true, uf, ff...)
case "xlsx":
contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
recordEncoder = encoder.NewExcelizeEncoder(w, true, ff...)
recordEncoder = encoder.NewExcelizeEncoder(w, true, uf, ff...)
default:
http.Error(w, "unsupported format ("+r.Ext+")", http.StatusBadRequest)