From 5fb8c5f2454cef3e2889852c6b894d8ae923e4dc Mon Sep 17 00:00:00 2001 From: Roland Osborne Date: Mon, 14 Feb 2022 15:00:41 -0800 Subject: [PATCH] testing subject field reference --- net/server/go.mod | 1 + net/server/go.sum | 2 + net/server/internal/api_attribute.go | 22 ------ .../internal/api_getArticleSubjectField.go | 69 +++++++++++++++++++ net/server/internal/ucShareAttribute_test.go | 27 +++++++- 5 files changed, 96 insertions(+), 25 deletions(-) delete mode 100644 net/server/internal/api_attribute.go create mode 100644 net/server/internal/api_getArticleSubjectField.go diff --git a/net/server/go.mod b/net/server/go.mod index 34a56ad9..ad847365 100644 --- a/net/server/go.mod +++ b/net/server/go.mod @@ -16,6 +16,7 @@ require ( github.com/rogpeppe/go-internal v1.6.1 // indirect github.com/stretchr/testify v1.7.0 // indirect github.com/theckman/go-securerandom v0.1.1 // indirect + github.com/valyala/fastjson v1.6.3 // indirect golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 // indirect gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect gorm.io/driver/sqlite v1.2.6 // indirect diff --git a/net/server/go.sum b/net/server/go.sum index b21c5f05..68c1409e 100644 --- a/net/server/go.sum +++ b/net/server/go.sum @@ -33,6 +33,8 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/theckman/go-securerandom v0.1.1 h1:5KctSyM0D5KKFK+bsypIyLq7yik0CEaI5i2fGcUGcsQ= github.com/theckman/go-securerandom v0.1.1/go.mod h1:bmkysLfBH6i891sBpcP4xRM3XIB7jMeiKJB31jlResI= +github.com/valyala/fastjson v1.6.3 h1:tAKFnnwmeMGPbwJ7IwxcTPCNr3uIzoIj3/Fh90ra4xc= +github.com/valyala/fastjson v1.6.3/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/net/server/internal/api_attribute.go b/net/server/internal/api_attribute.go deleted file mode 100644 index d042cfa0..00000000 --- a/net/server/internal/api_attribute.go +++ /dev/null @@ -1,22 +0,0 @@ -/* - * DataBag - * - * DataBag provides storage for decentralized identity based self-hosting apps. It is intended to support sharing of personal data and hosting group conversations. - * - * API version: 0.0.1 - * Contact: roland.osborne@gmail.com - * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) - */ -package databag - -import ( - "net/http" -) - - -func GetArticleSubjectField(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - - diff --git a/net/server/internal/api_getArticleSubjectField.go b/net/server/internal/api_getArticleSubjectField.go new file mode 100644 index 00000000..224bd28a --- /dev/null +++ b/net/server/internal/api_getArticleSubjectField.go @@ -0,0 +1,69 @@ +package databag + +import ( + "errors" + "strings" + "net/http" + "gorm.io/gorm" + "encoding/base64" + "github.com/gorilla/mux" + "databag/internal/store" + "github.com/valyala/fastjson" +) + +func GetArticleSubjectField(w http.ResponseWriter, r *http.Request) { + + // scan parameters + params := mux.Vars(r) + articleId := params["articleId"] + field := params["field"] + elements := strings.Split(field, ".") + + var act *store.Account + tokenType := r.Header.Get("TokenType") + if tokenType == APP_TOKENAPP { + account, code, err := BearerAppToken(r, false); + if err != nil { + ErrResponse(w, code, err) + return + } + act = account + } else if tokenType == APP_TOKENCONTACT { + card, code, err := BearerContactToken(r, true) + if err != nil { + ErrResponse(w, code, err) + return + } + act = &card.Account + } else { + ErrResponse(w, http.StatusBadRequest, errors.New("unknown token type")) + return + } + + // load article + var slot store.ArticleSlot + if err := store.DB.Preload("Article").Where("account_id = ? AND article_slot_id = ?", act.ID, articleId).First(&slot).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + ErrResponse(w, http.StatusNotFound, err) + } else { + ErrResponse(w, http.StatusInternalServerError, err) + } + return + } + if slot.Article == nil { + ErrResponse(w, http.StatusNotFound, errors.New("referenced article missing")) + return + } + + // decode data + strData := fastjson.GetString([]byte(slot.Article.Data), elements...) + binData, err := base64.StdEncoding.DecodeString(strData) + if err != nil { + ErrResponse(w, http.StatusNotFound, err) + return + } + + w.Header().Set("Content-Type", http.DetectContentType(binData)) + w.Write(binData) +} + diff --git a/net/server/internal/ucShareAttribute_test.go b/net/server/internal/ucShareAttribute_test.go index 104ee795..3dd93ae6 100644 --- a/net/server/internal/ucShareAttribute_test.go +++ b/net/server/internal/ucShareAttribute_test.go @@ -1,8 +1,10 @@ package databag import ( + "bytes" "testing" "strconv" + "encoding/base64" "github.com/stretchr/testify/assert" ) @@ -24,6 +26,7 @@ func TestShareAttribute(t *testing.T) { var bArticleRevision int64 var cArticleRevision int64 hdr := map[string][]string{} + var img []byte // setup testing group set, err := AddTestGroup("shareattribute") @@ -97,7 +100,8 @@ func TestShareAttribute(t *testing.T) { assert.Nil(t, (*articles)[0].Data) // update attribute - data := "{ \"nested\" : { \"image\" : \"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\" } }" + image := "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" + data := "{ \"nested\" : { \"image\" : \"" + image + "\" } }" subject = &Subject{ Data: data, DataType: "nestedimage" } param["articleId"] = article.Id article = &Article{} @@ -133,8 +137,25 @@ func TestShareAttribute(t *testing.T) { assert.NoError(t, ApiTestMsg(SetArticleGroup, "PUT", "/attribute/articles/{articleId}/groups/{groupId}", ¶m, nil, APP_TOKENAPP, set.A.Token, article, nil)) - // TODO A retrieve image - // TODO C retrieve image + // A retrieve image + param["articleId"] = article.Id + param["field"] = "nested.image" + aData, aType, aErr := ApiTestData(GetArticleSubjectField, "GET", "/attributes/articles/{articleId}/subject/{field}", + ¶m, nil, APP_TOKENAPP, set.A.Token) + assert.NoError(t, aErr) + assert.Equal(t, "image/png", aType["Content-Type"][0]) + img, _ = base64.StdEncoding.DecodeString(image) + assert.Zero(t, bytes.Compare(img, aData)) + + // C retrieve image + param["articleId"] = article.Id + param["field"] = "nested.image" + cData, cType, cErr := ApiTestData(GetArticleSubjectField, "GET", "/attributes/articles/{articleId}/subject/{field}", + ¶m, nil, APP_TOKENCONTACT, set.C.A.Token) + assert.NoError(t, cErr) + assert.Equal(t, "image/png", cType["Content-Type"][0]) + img, _ = base64.StdEncoding.DecodeString(image) + assert.Zero(t, bytes.Compare(img, cData)) // validate B & C view cards = &[]Card{}