mirror of
https://github.com/balzack/databag.git
synced 2025-02-12 03:29:16 +00:00
removed label based endpoints
This commit is contained in:
parent
a74b2ee74b
commit
d90df5f170
136
doc/api.oa3
136
doc/api.oa3
@ -43,12 +43,12 @@ paths:
|
||||
'200':
|
||||
description: Awaiting announce
|
||||
|
||||
/admin/available:
|
||||
/admin/status:
|
||||
get:
|
||||
tags:
|
||||
- admin
|
||||
description: Check if portal params have been set
|
||||
operationId: get-node-available
|
||||
operationId: get-node-status
|
||||
responses:
|
||||
'200':
|
||||
description: success
|
||||
@ -58,13 +58,11 @@ paths:
|
||||
type: boolean
|
||||
'500':
|
||||
description: internal server error
|
||||
|
||||
/admin/claim:
|
||||
post:
|
||||
put:
|
||||
tags:
|
||||
- admin
|
||||
description: Set admin password and node domain
|
||||
operationId: set-node-claim
|
||||
operationId: set-node-status
|
||||
security:
|
||||
- basicCredentials: []
|
||||
parameters:
|
||||
@ -269,12 +267,12 @@ paths:
|
||||
type: string
|
||||
format: binary
|
||||
|
||||
/account/public/available:
|
||||
/account/public/status:
|
||||
get:
|
||||
tags:
|
||||
- account
|
||||
description: Check if a public account can be created.
|
||||
operationId: get-public-available
|
||||
operationId: get-public-status
|
||||
responses:
|
||||
'200':
|
||||
description: success
|
||||
@ -1041,6 +1039,30 @@ paths:
|
||||
required: false # required for connected
|
||||
schema:
|
||||
type: string
|
||||
- name: profileRevision
|
||||
in: query
|
||||
description: profile revision of contact
|
||||
required: false # required for connected
|
||||
schema:
|
||||
type: string
|
||||
- name: articleRevision
|
||||
in: query
|
||||
description: article revision of contact
|
||||
required: false # required for connected
|
||||
schema:
|
||||
type: string
|
||||
- name: channelRevision
|
||||
in: query
|
||||
description: channel revision of contact
|
||||
required: false # required for connected
|
||||
schema:
|
||||
type: string
|
||||
- name: viewRevision
|
||||
in: query
|
||||
description: view revision of contact
|
||||
required: false # required for connected
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: success
|
||||
@ -1159,18 +1181,6 @@ paths:
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required:
|
||||
- status
|
||||
properties:
|
||||
token:
|
||||
type: string
|
||||
status:
|
||||
type: string
|
||||
enum: [ pending, confirmed, requested, connecting, connected ]
|
||||
'400':
|
||||
description: invalid data message
|
||||
'410':
|
||||
@ -1474,12 +1484,36 @@ paths:
|
||||
type: integer
|
||||
format: int64
|
||||
|
||||
/contact/content/revision:
|
||||
/contact/article/revision:
|
||||
put:
|
||||
tags:
|
||||
- contact
|
||||
description: Set content revision for contact. This is intend to be invoked automatically anytime a contact updates their content or sharing. Access granted to contact tokens.
|
||||
operationId: set-content-revision
|
||||
description: Set artcile revision for contact. This is intend to be invoked automatically anytime a contact updates their content or sharing. Access granted to contact tokens.
|
||||
operationId: set-article-revision
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
'200':
|
||||
description: revision set
|
||||
'401':
|
||||
description: not authorized
|
||||
'410':
|
||||
description: account disabled
|
||||
'500':
|
||||
description: internal server error
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
|
||||
/contact/channel/revision:
|
||||
put:
|
||||
tags:
|
||||
- contact
|
||||
description: Set channel revision for contact. This is intend to be invoked automatically anytime a contact updates their content or sharing. Access granted to contact tokens.
|
||||
operationId: set-channel-revision
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
@ -1692,15 +1726,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required:
|
||||
- type
|
||||
- data
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
data:
|
||||
type: string
|
||||
$ref: '#/components/schemas/Subject'
|
||||
|
||||
/attribute/articles/{articleId}/groups/{groupId}:
|
||||
put:
|
||||
@ -2341,15 +2367,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required:
|
||||
- type
|
||||
- data
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
data:
|
||||
type: string
|
||||
$ref: '#/components/schemas/Subject'
|
||||
|
||||
/content/channels/{channelId}/topics/{topicId}/assets:
|
||||
get:
|
||||
@ -2804,7 +2822,7 @@ components:
|
||||
type: object
|
||||
required:
|
||||
- profile
|
||||
- attribute
|
||||
- article
|
||||
- group
|
||||
- channel
|
||||
- card
|
||||
@ -2955,7 +2973,7 @@ components:
|
||||
id:
|
||||
type: string
|
||||
revision:
|
||||
type: number
|
||||
type: integer
|
||||
format: int64
|
||||
data:
|
||||
$ref: '#/components/schemas/CardData'
|
||||
@ -2966,7 +2984,7 @@ components:
|
||||
- detailRevision
|
||||
- profileRevision
|
||||
- notifiedProfile
|
||||
- notifiedContent
|
||||
- notifiedArticle
|
||||
- notifiedChannel
|
||||
- notifiedView
|
||||
properties:
|
||||
@ -2979,7 +2997,7 @@ components:
|
||||
notifiedProfile:
|
||||
type: integer
|
||||
format: int64
|
||||
notifiedContent:
|
||||
notifiedArticle:
|
||||
type: integer
|
||||
format: int64
|
||||
notifiedChannel:
|
||||
@ -3038,7 +3056,7 @@ components:
|
||||
required:
|
||||
- id
|
||||
- revision
|
||||
- ata
|
||||
- data
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
@ -3162,7 +3180,8 @@ components:
|
||||
id:
|
||||
type: string
|
||||
revision:
|
||||
type: string
|
||||
type: integer
|
||||
format: int64
|
||||
data:
|
||||
$ref: '#/components/schemas/TopicData'
|
||||
|
||||
@ -3232,7 +3251,8 @@ components:
|
||||
id:
|
||||
type: string
|
||||
revision:
|
||||
type: string
|
||||
type: integer
|
||||
format: int64
|
||||
data:
|
||||
$ref: '#/components/schemas/TagData'
|
||||
|
||||
@ -3268,7 +3288,8 @@ components:
|
||||
id:
|
||||
type: string
|
||||
revision:
|
||||
type: string
|
||||
type: integer
|
||||
format: int64
|
||||
data:
|
||||
$ref: '#/components/schemas/ArticleData'
|
||||
|
||||
@ -3378,12 +3399,15 @@ components:
|
||||
viewRevision:
|
||||
type: integer
|
||||
format: int64
|
||||
contentRevision:
|
||||
articleRevision:
|
||||
type: integer
|
||||
format: int64
|
||||
profileRevision:
|
||||
type: integer
|
||||
format: int64
|
||||
channelRevision:
|
||||
type: integer
|
||||
format: int64
|
||||
handle:
|
||||
type: string
|
||||
name:
|
||||
@ -3435,6 +3459,18 @@ components:
|
||||
properties:
|
||||
token:
|
||||
type: string
|
||||
profileRevision:
|
||||
type: integer
|
||||
format: int64
|
||||
articleRevision:
|
||||
type: integer
|
||||
format: int64
|
||||
channelRevision:
|
||||
type: integer
|
||||
format: int64
|
||||
viewRevision:
|
||||
type: integer
|
||||
format: int64
|
||||
status:
|
||||
type: string
|
||||
enum: [ pending, confirmed, requested, connecting, connected ]
|
||||
|
@ -53,7 +53,17 @@ func GetAccountStatus(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetPublicClaimable(w http.ResponseWriter, r *http.Request) {
|
||||
func GetAccountToken(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetAccountUsername(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetPublicStatus(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
@ -1,103 +0,0 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"time"
|
||||
"errors"
|
||||
"net/http"
|
||||
"gorm.io/gorm"
|
||||
"github.com/google/uuid"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func AddArticle(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
account, code, err := BearerAppToken(r, false)
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
|
||||
var articleAccess ArticleAccess
|
||||
if err := ParseRequest(r, w, &articleAccess); err != nil {
|
||||
ErrResponse(w, http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
var groupSlots []store.GroupSlot
|
||||
if err := store.DB.Preload("Group").Where("group_slot_id IN ?", articleAccess.Groups).Find(&groupSlots).Error; err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
var groups []store.Group
|
||||
for _, slot := range groupSlots {
|
||||
if slot.Group != nil {
|
||||
groups = append(groups, *slot.Group)
|
||||
}
|
||||
}
|
||||
|
||||
var labelSlots []store.LabelSlot
|
||||
if err := store.DB.Preload("Label").Where("label_slot_id IN ?", articleAccess.Labels).Find(&labelSlots).Error; err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
var labels []store.Label
|
||||
for _, slot := range labelSlots {
|
||||
if slot.Label != nil {
|
||||
labels = append(labels, *slot.Label)
|
||||
}
|
||||
}
|
||||
|
||||
// save data and apply transaction
|
||||
var slot *store.ArticleSlot
|
||||
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
||||
|
||||
article := &store.Article{
|
||||
Status: APP_ARTICLEUNCONFIRMED,
|
||||
TagUpdated: time.Now().Unix(),
|
||||
TagRevision: 1,
|
||||
TagCount: 0,
|
||||
Groups: groups,
|
||||
Labels: labels,
|
||||
};
|
||||
if res := tx.Save(article).Error; res != nil {
|
||||
return res;
|
||||
}
|
||||
|
||||
if res := tx.Where("article_id = 0 AND account_id = ?", account.ID).First(&slot).Error; res != nil {
|
||||
if errors.Is(res, gorm.ErrRecordNotFound) {
|
||||
slot = &store.ArticleSlot{
|
||||
ArticleSlotId: uuid.New().String(),
|
||||
AccountID: account.ID,
|
||||
Revision: 1,
|
||||
ArticleID: article.ID,
|
||||
Article: article,
|
||||
}
|
||||
if ret := tx.Save(slot).Error; ret != nil {
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
return res
|
||||
}
|
||||
}
|
||||
if ret := tx.Model(slot).Update("article_id", article.ID).Error; ret != nil {
|
||||
return ret;
|
||||
}
|
||||
if ret := tx.Preload("Article.Labels.Groups").Where("id = ?", article.ID).First(slot).Error; ret != nil {
|
||||
return ret;
|
||||
}
|
||||
if ret := tx.Model(&account).Update("content_revision", account.ContentRevision + 1).Error; ret != nil {
|
||||
return ret
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
SetContentNotification(account)
|
||||
SetStatus(account)
|
||||
WriteResponse(w, getArticleModel(slot, false, true))
|
||||
}
|
||||
|
||||
|
@ -1,71 +0,0 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"errors"
|
||||
"gorm.io/gorm"
|
||||
"github.com/google/uuid"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func AddLabel(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
account, code, err := BearerAppToken(r, false)
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
|
||||
var subject Subject
|
||||
if err := ParseRequest(r, w, &subject); err != nil {
|
||||
ErrResponse(w, http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
slot := &store.LabelSlot{}
|
||||
label := &store.Label{}
|
||||
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
||||
|
||||
data := &store.LabelData{
|
||||
Data: subject.Data,
|
||||
}
|
||||
if res := tx.Save(data).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
|
||||
label.LabelDataID = data.ID
|
||||
label.LabelData = *data
|
||||
label.DataType = subject.DataType
|
||||
if res := tx.Save(label).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
|
||||
if res := tx.Where("account_id = ? AND label_id = 0", account.ID).First(slot).Error; res != nil {
|
||||
if errors.Is(res, gorm.ErrRecordNotFound) {
|
||||
slot.LabelSlotId = uuid.New().String()
|
||||
slot.AccountID = account.ID
|
||||
} else {
|
||||
return res
|
||||
}
|
||||
}
|
||||
slot.LabelID = label.ID
|
||||
slot.Revision = account.LabelRevision + 1
|
||||
slot.Label = label
|
||||
if res := tx.Save(slot).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Model(&account).Update("label_revision", account.LabelRevision + 1).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
SetStatus(account)
|
||||
WriteResponse(w, getLabelModel(slot, true, true))
|
||||
}
|
||||
|
||||
|
30
net/server/internal/api_alias.go
Normal file
30
net/server/internal/api_alias.go
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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 GetGroups(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func RemoveGroup(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func UpdateGroup(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
50
net/server/internal/api_attribute.go
Normal file
50
net/server/internal/api_attribute.go
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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 AddArticle(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func ClearArticleGroup(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetArticleSubjectField(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetArticles(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func RemoveArticle(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func SetArticleGroup(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func SetArticleSubject(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
@ -1,3 +1,12 @@
|
||||
/*
|
||||
* 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 (
|
||||
@ -5,30 +14,7 @@ import (
|
||||
)
|
||||
|
||||
func Authorize(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
account, code, res := BearerAppToken(r, true);
|
||||
if res != nil {
|
||||
ErrResponse(w, code, res)
|
||||
return
|
||||
}
|
||||
detail := account.AccountDetail
|
||||
|
||||
// extract token from body
|
||||
var token string
|
||||
res = ParseRequest(r, w, &token)
|
||||
if res != nil {
|
||||
ErrResponse(w, http.StatusBadRequest, res)
|
||||
return
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
// generate auth DataMessage
|
||||
auth := Authenticate{ Token: token }
|
||||
msg, res := WriteDataMessage(detail.PrivateKey, detail.PublicKey, detail.KeyType,
|
||||
APP_SIGNPKCS1V15, account.Guid, APP_MSGAUTHENTICATE, &auth)
|
||||
if res != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, res)
|
||||
return
|
||||
}
|
||||
|
||||
WriteResponse(w, msg)
|
||||
}
|
||||
|
@ -1,64 +0,0 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"gorm.io/gorm"
|
||||
"github.com/gorilla/mux"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func ClearCardNotes(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
account, code, err := BearerAppToken(r, false);
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
|
||||
// scan parameters
|
||||
params := mux.Vars(r)
|
||||
cardId := params["cardId"]
|
||||
|
||||
// load referenced card
|
||||
var slot store.CardSlot
|
||||
if err := store.DB.Preload("Card").Where("account_id = ? AND card_slot_id = ?", account.ID, cardId).First(&slot).Error; err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
} else {
|
||||
ErrResponse(w, http.StatusNotFound, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if slot.Card == nil {
|
||||
ErrResponse(w, http.StatusNotFound, errors.New("card has been deleted"))
|
||||
return
|
||||
}
|
||||
|
||||
// update card
|
||||
slot.Revision = account.CardRevision + 1
|
||||
slot.Card.DetailRevision += 1
|
||||
slot.Card.Notes = ""
|
||||
|
||||
// save and update contact revision
|
||||
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if res := tx.Save(&slot.Card).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Preload("Card").Save(&slot).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Model(&account).Update("card_revision", account.CardRevision + 1).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
SetStatus(account)
|
||||
WriteResponse(w, getCardDetailModel(&slot));
|
||||
}
|
||||
|
@ -18,12 +18,7 @@ func ClearCardGroup(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetCardDetail(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetCardProfile(w http.ResponseWriter, r *http.Request) {
|
||||
func ClearCardNotes(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
@ -33,6 +28,11 @@ func GetCardProfileImage(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetCards(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetCloseMessage(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
@ -43,6 +43,16 @@ func RemoveCard(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func SetCardNotes(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func SetCardProfile(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func SetCloseMessage(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
@ -13,107 +13,132 @@ import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func AddArticleAsset(w http.ResponseWriter, r *http.Request) {
|
||||
func AddChannel(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func AddArticleTag(w http.ResponseWriter, r *http.Request) {
|
||||
func AddChannelAsset(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func ClearArticleGroup(w http.ResponseWriter, r *http.Request) {
|
||||
func AddChannelTopic(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func ClearArticleLabel(w http.ResponseWriter, r *http.Request) {
|
||||
func AddChannelTopicTag(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func ClearLabelGroup(w http.ResponseWriter, r *http.Request) {
|
||||
func ClearChannelGroup(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetArticle(w http.ResponseWriter, r *http.Request) {
|
||||
func GetChannelAsset(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetArticleAsset(w http.ResponseWriter, r *http.Request) {
|
||||
func GetChannelAssets(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetArticleAssets(w http.ResponseWriter, r *http.Request) {
|
||||
func GetChannelDetail(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetArticleSubjectField(w http.ResponseWriter, r *http.Request) {
|
||||
func GetChannelSize(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetArticleTag(w http.ResponseWriter, r *http.Request) {
|
||||
func GetChannelSubjectField(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetArticleTagBlockView(w http.ResponseWriter, r *http.Request) {
|
||||
func GetChannelTopicDetail(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetArticleTagSubjectField(w http.ResponseWriter, r *http.Request) {
|
||||
func GetChannelTopicSize(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetArticleTagView(w http.ResponseWriter, r *http.Request) {
|
||||
func GetChannelTopicSubjectField(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetArticleTags(w http.ResponseWriter, r *http.Request) {
|
||||
func GetChannelTopicTagSubjectField(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func RemoveArticleAsset(w http.ResponseWriter, r *http.Request) {
|
||||
func GetChannelTopicTags(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func RemoveArticleTag(w http.ResponseWriter, r *http.Request) {
|
||||
func GetChannelTopics(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func SetArticleConfirmed(w http.ResponseWriter, r *http.Request) {
|
||||
func GetChannels(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func SetArticleExpiration(w http.ResponseWriter, r *http.Request) {
|
||||
func RemoveChannel(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func SetArticleGroup(w http.ResponseWriter, r *http.Request) {
|
||||
func RemoveChannelAsset(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func SetArticleSubject(w http.ResponseWriter, r *http.Request) {
|
||||
func RemoveChannelTopic(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func UpdateLabel(w http.ResponseWriter, r *http.Request) {
|
||||
func RemoveChannelTopicTag(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func SetChannelConfirmed(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func SetChannelGroup(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func SetChannelSubject(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func SetChannelTopicSubject(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func SetChannelTopicTagSubject(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
@ -1,174 +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 AddDialogue(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func AddDialogueInsight(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func AddDialogueTopic(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func AddInsightDialogue(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func AddTopicAsset(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func AddTopicTag(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func ConversationDialoguesDialogueIdTopicsTopicIdConfirmedPut(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetDialogueTopic(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetDialogueTopicSubjectField(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetDialogues(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetInsights(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetTopicAsset(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetTopicAssets(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetTopicBlock(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetTopicBlockView(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetTopicTag(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetTopicTagBlockView(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetTopicTagSubjectField(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetTopicTagView(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetTopicTags(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetTopicViews(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func RemoveDialogue(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func RemoveDialogueInsight(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func RemoveDialogueTopic(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func RemoveTopicAsset(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func RemoveTopicTag(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func SetDialogueActive(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func SetDialogueInsightStatus(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func SetDialogueSubject(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func SetInsightDialogue(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func SetInsightStatus(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func SetTopicSubject(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
@ -1,125 +0,0 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
"net/http"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func GetArticles(w http.ResponseWriter, r *http.Request) {
|
||||
var res error
|
||||
var viewRevision int64
|
||||
var contentRevision int64
|
||||
var revisionSet bool
|
||||
|
||||
view := r.FormValue("viewRevision")
|
||||
if view != "" {
|
||||
if viewRevision, res = strconv.ParseInt(view, 10, 64); res != nil {
|
||||
ErrResponse(w, http.StatusBadRequest, res)
|
||||
return
|
||||
}
|
||||
}
|
||||
content := r.FormValue("contentRevision")
|
||||
if content != "" {
|
||||
if contentRevision, res = strconv.ParseInt(content, 10, 64); res != nil {
|
||||
ErrResponse(w, http.StatusBadRequest, res)
|
||||
return
|
||||
}
|
||||
revisionSet = true
|
||||
}
|
||||
|
||||
tokenType := r.Header.Get("TokenType")
|
||||
var response []*Article
|
||||
if tokenType == APP_TOKENAPP {
|
||||
|
||||
account, code, err := BearerAppToken(r, false)
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
|
||||
var articles []store.ArticleSlot
|
||||
if err := getAccountArticles(account, contentRevision, &articles); err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, article := range articles {
|
||||
response = append(response, getArticleModel(&article, false, true))
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Revision", strconv.FormatInt(account.ContentRevision, 10))
|
||||
} else if tokenType == APP_TOKENCONTACT {
|
||||
|
||||
card, code, err := BearerContactToken(r, false)
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
|
||||
if viewRevision != card.ViewRevision {
|
||||
if revisionSet {
|
||||
ErrResponse(w, http.StatusGone, errors.New("article view unavailable"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var articles []store.ArticleSlot
|
||||
if err := getContactArticles(card, contentRevision, &articles); err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, article := range articles {
|
||||
if isArticleShared(&article, card.Guid) {
|
||||
response = append(response, getArticleModel(&article, true, true))
|
||||
} else if revisionSet {
|
||||
response = append(response, getArticleModel(&article, true, false))
|
||||
}
|
||||
}
|
||||
|
||||
w.Header().Set("View-Revision", strconv.FormatInt(card.ViewRevision, 10))
|
||||
w.Header().Set("Content-Revision", strconv.FormatInt(card.Account.ContentRevision, 10))
|
||||
} else {
|
||||
ErrResponse(w, http.StatusBadRequest, errors.New("invalid token type"))
|
||||
}
|
||||
|
||||
WriteResponse(w, response)
|
||||
}
|
||||
|
||||
// better if this filtering was done in gorm or sql
|
||||
func isArticleShared(slot *store.ArticleSlot, guid string) bool {
|
||||
if slot.Article == nil {
|
||||
return false
|
||||
}
|
||||
for _, group := range slot.Article.Groups {
|
||||
for _, card := range group.Cards {
|
||||
if card.Guid == guid {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, label := range slot.Article.Labels {
|
||||
for _, group := range label.Groups {
|
||||
for _, card := range group.Cards {
|
||||
if card.Guid == guid {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func getAccountArticles(account *store.Account, revision int64, articles *[]store.ArticleSlot) error {
|
||||
return store.DB.Preload("Article.Labels.LabelSlot").Preload("Article.Groups.GroupSlot").Preload("Article.Labels.Groups.GroupSlot").Where("account_id = ? AND revision > ?", account.ID, revision).Find(articles).Error
|
||||
}
|
||||
|
||||
func getContactArticles(card *store.Card, revision int64, articles *[]store.ArticleSlot) error {
|
||||
return store.DB.Preload("Article.Labels.LabelSlot").Preload("Article.Groups.Cards").Preload("Article.Labels.Groups.Cards").Where("account_id = ? AND revision > ?", card.Account.ID, revision).Find(articles).Error
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func GetCard(w http.ResponseWriter, r *http.Request) {
|
||||
func GetCardDetail(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
account, code, err := BearerAppToken(r, false);
|
||||
if err != nil {
|
||||
@ -26,7 +26,11 @@ func GetCard(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
WriteResponse(w, getCardModel(&slot))
|
||||
if slot.Card == nil {
|
||||
ErrResponse(w, http.StatusNotFound, errors.New("referenced empty card slot"))
|
||||
return
|
||||
}
|
||||
|
||||
WriteResponse(w, getCardDetailModel(&slot))
|
||||
}
|
||||
|
36
net/server/internal/api_getCardProfile.go
Normal file
36
net/server/internal/api_getCardProfile.go
Normal file
@ -0,0 +1,36 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"gorm.io/gorm"
|
||||
"github.com/gorilla/mux"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func GetCardProfile(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
account, code, err := BearerAppToken(r, false);
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
cardId := mux.Vars(r)["cardId"]
|
||||
|
||||
var slot store.CardSlot
|
||||
if err := store.DB.Preload("Card.Groups").Where("account_id = ? AND card_slot_id = ?", account.ID, cardId).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.Card == nil {
|
||||
ErrResponse(w, http.StatusNotFound, errors.New("referenced empty card slot"))
|
||||
return
|
||||
}
|
||||
|
||||
WriteResponse(w, getCardProfileModel(&slot))
|
||||
}
|
||||
|
@ -1,40 +0,0 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"net/http"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func GetCards(w http.ResponseWriter, r *http.Request) {
|
||||
var res error
|
||||
var cardRevision int64
|
||||
|
||||
card := r.FormValue("cardRevision")
|
||||
if card != "" {
|
||||
if cardRevision, res = strconv.ParseInt(card, 10, 64); res != nil {
|
||||
ErrResponse(w, http.StatusBadRequest, res)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
account, code, err := BearerAppToken(r, false);
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
|
||||
var slots []store.CardSlot
|
||||
if err := store.DB.Preload("Card.Groups.GroupSlot").Where("account_id = ? AND revision > ?", account.ID, cardRevision).Find(&slots).Error; err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
var response []*Card
|
||||
for _, slot := range slots {
|
||||
response = append(response, getCardModel(&slot))
|
||||
}
|
||||
|
||||
w.Header().Set("Card-Revision", strconv.FormatInt(account.CardRevision, 10))
|
||||
WriteResponse(w, response)
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"net/http"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func GetGroups(w http.ResponseWriter, r *http.Request) {
|
||||
var res error
|
||||
var groupRevision int64
|
||||
|
||||
group := r.FormValue("groupRevision")
|
||||
if group != "" {
|
||||
if groupRevision, res = strconv.ParseInt(group, 10, 64); res != nil {
|
||||
ErrResponse(w, http.StatusBadRequest, res)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
account, code, err := BearerAppToken(r, false)
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
|
||||
var slots []store.GroupSlot
|
||||
if err := store.DB.Preload("Group").Where("account_id = ? AND revision > ?", account.ID, groupRevision).Find(&slots).Error; err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
var groups []*Group
|
||||
for _, slot := range slots {
|
||||
groups = append(groups, getGroupModel(&slot))
|
||||
}
|
||||
|
||||
w.Header().Set("Group-Revision", strconv.FormatInt(account.GroupRevision, 10))
|
||||
WriteResponse(w, groups)
|
||||
}
|
||||
|
@ -1,116 +0,0 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
"net/http"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func GetLabels(w http.ResponseWriter, r *http.Request) {
|
||||
var res error
|
||||
var viewRevision int64
|
||||
var labelRevision int64
|
||||
var revisionSet bool
|
||||
|
||||
view := r.FormValue("viewRevision")
|
||||
if view != "" {
|
||||
if viewRevision, res = strconv.ParseInt(view, 10, 64); res != nil {
|
||||
ErrResponse(w, http.StatusBadRequest, res)
|
||||
return
|
||||
}
|
||||
}
|
||||
label := r.FormValue("labelRevision")
|
||||
if label != "" {
|
||||
if labelRevision, res = strconv.ParseInt(label, 10, 64); res != nil {
|
||||
ErrResponse(w, http.StatusBadRequest, res)
|
||||
return
|
||||
}
|
||||
revisionSet = true
|
||||
}
|
||||
|
||||
tokenType := r.Header.Get("TokenType")
|
||||
var response []*Label
|
||||
if tokenType == APP_TOKENAPP {
|
||||
|
||||
account, code, err := BearerAppToken(r, false)
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
|
||||
var labels []store.LabelSlot
|
||||
if err := getAccountLabels(account, labelRevision, &labels); err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, label := range labels {
|
||||
response = append(response, getLabelModel(&label, false, true))
|
||||
}
|
||||
|
||||
w.Header().Set("Label-Revision", strconv.FormatInt(account.LabelRevision, 10))
|
||||
} else if tokenType == APP_TOKENCONTACT {
|
||||
|
||||
card, code, err := BearerContactToken(r, false)
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
|
||||
if viewRevision != card.ViewRevision {
|
||||
if revisionSet {
|
||||
ErrResponse(w, http.StatusGone, errors.New("label view unavailable"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var labels []store.LabelSlot
|
||||
if err := getContactLabels(card, labelRevision, &labels); err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, label := range labels {
|
||||
if isLabelShared(&label, card.Guid) {
|
||||
response = append(response, getLabelModel(&label, true, true))
|
||||
} else if revisionSet {
|
||||
response = append(response, getLabelModel(&label, true, false))
|
||||
}
|
||||
}
|
||||
|
||||
w.Header().Set("View-Revision", strconv.FormatInt(card.ViewRevision, 10))
|
||||
w.Header().Set("Label-Revision", strconv.FormatInt(card.Account.LabelRevision, 10))
|
||||
} else {
|
||||
ErrResponse(w, http.StatusBadRequest, errors.New("invalid token type"))
|
||||
}
|
||||
|
||||
WriteResponse(w, response)
|
||||
}
|
||||
|
||||
// better if this filtering was done in gorm or sql
|
||||
func isLabelShared(slot *store.LabelSlot, guid string) bool {
|
||||
if slot.Label == nil {
|
||||
return false
|
||||
}
|
||||
for _, group := range slot.Label.Groups {
|
||||
for _, card := range group.Cards {
|
||||
if card.Guid == guid {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func getAccountLabels(account *store.Account, revision int64, labels *[]store.LabelSlot) error {
|
||||
return store.DB.Preload("Label.Groups.GroupSlot").Where("account_id = ? AND revision > ?", account.ID, revision).Find(labels).Error
|
||||
}
|
||||
|
||||
func getContactLabels(card *store.Card, revision int64, labels *[]store.LabelSlot) error {
|
||||
return store.DB.Preload("Label.Groups.Cards").Where("account_id = ? AND revision > ?", card.Account.ID, revision).Find(labels).Error
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func GetNodeClaimable(w http.ResponseWriter, r *http.Request) {
|
||||
func GetNodeStatus(w http.ResponseWriter, r *http.Request) {
|
||||
var config store.Config
|
||||
err := store.DB.Where("config_id = ?", CONFIG_CONFIGURED).First(&config).Error
|
||||
if err != nil {
|
@ -40,10 +40,10 @@ func GetOpenMessage(w http.ResponseWriter, r *http.Request) {
|
||||
connect := &Connect{
|
||||
Contact: slot.Card.Guid,
|
||||
Token: slot.Card.InToken,
|
||||
ContentRevision: account.ContentRevision,
|
||||
ArticleRevision: account.ArticleRevision,
|
||||
ProfileRevision: account.ProfileRevision,
|
||||
ViewRevision: slot.Card.ViewRevision,
|
||||
LabelRevision: account.LabelRevision,
|
||||
ChannelRevision: account.ChannelRevision,
|
||||
Handle: account.Username,
|
||||
Name: detail.Name,
|
||||
Description: detail.Description,
|
||||
|
@ -1,30 +0,0 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func GetProfile(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
account, code, err := BearerAppToken(r, true);
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
detail := account.AccountDetail
|
||||
|
||||
// send profile data
|
||||
profile := Profile {
|
||||
Guid: account.Guid,
|
||||
Handle: account.Username,
|
||||
Name: detail.Name,
|
||||
Description: detail.Description,
|
||||
Location: detail.Location,
|
||||
Image: detail.Image,
|
||||
Revision: account.ProfileRevision,
|
||||
Version: APP_VERSION,
|
||||
Node: "https://" + getStrConfigValue(CONFIG_DOMAIN, "") + "/",
|
||||
}
|
||||
WriteResponse(w, profile)
|
||||
}
|
||||
|
@ -13,11 +13,21 @@ import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func GetProfile(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func GetProfileImage(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func SetProfile(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func SetProfileImage(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
@ -1,63 +0,0 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"gorm.io/gorm"
|
||||
"github.com/gorilla/mux"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func RemoveArticle(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
account, code, err := BearerAppToken(r, false)
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
|
||||
params := mux.Vars(r)
|
||||
articleId := params["articleId"]
|
||||
|
||||
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
||||
var slot store.ArticleSlot
|
||||
if res := store.DB.Preload("Article").Where("account_id = ? AND article_slot_id = ?", account.ID, articleId).First(&slot).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if slot.Article == nil {
|
||||
return nil
|
||||
}
|
||||
if res := tx.Model(slot.Article).Association("Groups").Clear(); res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Model(slot.Article).Association("Labels").Clear(); res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Delete(slot.Article).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
slot.ArticleID = 0
|
||||
slot.Revision = account.ContentRevision + 1
|
||||
slot.Article = nil
|
||||
if res := tx.Save(&slot).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Model(&account).Update("content_revision", account.ContentRevision + 1).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
ErrResponse(w, http.StatusNotFound, err)
|
||||
} else {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
SetContentNotification(account)
|
||||
SetStatus(account)
|
||||
WriteResponse(w, nil)
|
||||
}
|
||||
|
@ -1,68 +0,0 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"gorm.io/gorm"
|
||||
"github.com/gorilla/mux"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func RemoveGroup(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
account, code, err := BearerAppToken(r, false)
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
params := mux.Vars(r)
|
||||
groupId := params["groupId"]
|
||||
|
||||
var slot store.GroupSlot
|
||||
if err := store.DB.Preload("Group.GroupData").Preload("Group.Cards").Where("account_id = ? AND group_slot_id = ?", account.ID, groupId).First(&slot).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
ErrResponse(w, http.StatusNotFound, err)
|
||||
} else {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
cards := slot.Group.Cards
|
||||
notify := []*store.Card{}
|
||||
|
||||
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if res := tx.Model(slot.Group).Association("Cards").Clear(); res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Delete(&slot.Group.GroupData).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Delete(&slot.Group).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
for _, card := range cards {
|
||||
if res := tx.Model(&card).Update("ViewRevision", card.ViewRevision + 1).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
notify = append(notify, &card)
|
||||
}
|
||||
slot.GroupID = 0
|
||||
slot.Group = nil
|
||||
slot.Revision = account.GroupRevision + 1
|
||||
if res := tx.Save(&slot).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, card := range notify {
|
||||
SetContactViewNotification(account, card)
|
||||
}
|
||||
SetStatus(account)
|
||||
WriteResponse(w, nil)
|
||||
}
|
||||
|
@ -1,74 +0,0 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"gorm.io/gorm"
|
||||
"github.com/gorilla/mux"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func RemoveLabel(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
account, code, err := BearerAppToken(r, false)
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
params := mux.Vars(r)
|
||||
labelId := params["labelId"]
|
||||
|
||||
var slot store.LabelSlot
|
||||
if err := store.DB.Preload("Label.LabelData").Preload("Label.Groups.Cards").Where("account_id = ? AND label_slot_id = ?", account.ID, labelId).First(&slot).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
ErrResponse(w, http.StatusNotFound, err)
|
||||
} else {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
groups := slot.Label.Groups
|
||||
notify := map[string]*store.Card{}
|
||||
|
||||
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if res := tx.Model(slot.Label).Association("Groups").Clear(); res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Delete(&slot.Label.LabelData).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Delete(&slot.Label).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
for _, group := range groups {
|
||||
for _, card := range group.Cards {
|
||||
if res := tx.Model(&card).Update("ViewRevision", card.ViewRevision + 1).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
notify[card.Guid] = &card
|
||||
}
|
||||
}
|
||||
|
||||
slot.LabelID = 0
|
||||
slot.Label = nil
|
||||
slot.Revision = account.LabelRevision + 1
|
||||
if res := tx.Save(&slot).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Model(&account).Updates(store.Account{LabelRevision: account.LabelRevision + 1}).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, card := range notify {
|
||||
SetContactViewNotification(account, card)
|
||||
}
|
||||
SetStatus(account)
|
||||
WriteResponse(w, nil)
|
||||
}
|
||||
|
@ -1,76 +0,0 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"gorm.io/gorm"
|
||||
"github.com/gorilla/mux"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func SetArticleLabel(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
account, code, err := BearerAppToken(r, false);
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
|
||||
// scan parameters
|
||||
params := mux.Vars(r)
|
||||
articleId := params["articleId"]
|
||||
labelId := params["labelId"]
|
||||
|
||||
labelSlot := &store.LabelSlot{}
|
||||
if err := store.DB.Preload("Label.LabelSlot").Where("account_id = ? AND label_slot_id = ?", account.ID, labelId).First(&labelSlot).Error; err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
} else {
|
||||
ErrResponse(w, http.StatusNotFound, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if labelSlot.Label == nil {
|
||||
ErrResponse(w, http.StatusNotFound, errors.New("referenced empty label slot"))
|
||||
return
|
||||
}
|
||||
|
||||
articleSlot := &store.ArticleSlot{}
|
||||
if err := store.DB.Preload("Article.Labels.LabelSlot").Preload("Article.Groups.GroupSlot").Where("account_id = ? AND article_slot_id = ?", account.ID, articleId).First(&articleSlot).Error; err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
} else {
|
||||
ErrResponse(w, http.StatusNotFound, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if articleSlot.Article == nil {
|
||||
ErrResponse(w, http.StatusNotFound, errors.New("referenced empty article slot"))
|
||||
return
|
||||
}
|
||||
|
||||
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
||||
|
||||
if res := tx.Model(articleSlot.Article).Association("Labels").Append(labelSlot.Label); res != nil {
|
||||
return res
|
||||
}
|
||||
|
||||
if res := tx.Model(articleSlot).Update("revision", account.ContentRevision + 1).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
|
||||
if res := tx.Model(account).Update("content_revision", account.ContentRevision + 1).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
SetContentNotification(account)
|
||||
SetStatus(account)
|
||||
WriteResponse(w, getArticleModel(articleSlot, false, true))
|
||||
}
|
@ -6,7 +6,7 @@ import (
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func SetContentRevision(w http.ResponseWriter, r *http.Request) {
|
||||
func SetArticleRevision(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
card, code, err := BearerContactToken(r, false)
|
||||
if err != nil {
|
||||
@ -20,7 +20,7 @@ func SetContentRevision(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := NotifyProfileRevision(card, revision); err != nil {
|
||||
if err := NotifyArticleRevision(card, revision); err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
@ -28,11 +28,11 @@ func SetContentRevision(w http.ResponseWriter, r *http.Request) {
|
||||
WriteResponse(w, nil)
|
||||
}
|
||||
|
||||
func NotifyContentRevision(card *store.Card, revision int64) error {
|
||||
func NotifyArticleRevision(card *store.Card, revision int64) error {
|
||||
|
||||
act := &card.Account
|
||||
err := store.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if res := tx.Model(card).Where("id = ?", card.ID).Update("notified_content", revision).Error; res != nil {
|
||||
if res := tx.Model(card).Where("id = ?", card.ID).Update("notified_profile", revision).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Model(&card.CardSlot).Where("id = ?", card.CardSlot.ID).Update("revision", act.CardRevision+1).Error; res != nil {
|
@ -1,70 +0,0 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"gorm.io/gorm"
|
||||
"github.com/gorilla/mux"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func SetCardNotes(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
account, code, err := BearerAppToken(r, false);
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
|
||||
// scan parameters
|
||||
params := mux.Vars(r)
|
||||
cardId := params["cardId"]
|
||||
|
||||
var notes string
|
||||
if err := ParseRequest(r, w, ¬es); err != nil {
|
||||
ErrResponse(w, http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
// load referenced card
|
||||
var slot store.CardSlot
|
||||
if err := store.DB.Preload("Card").Where("account_id = ? AND card_slot_id = ?", account.ID, cardId).First(&slot).Error; err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
} else {
|
||||
ErrResponse(w, http.StatusNotFound, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if slot.Card == nil {
|
||||
ErrResponse(w, http.StatusNotFound, errors.New("card has been deleted"))
|
||||
return
|
||||
}
|
||||
|
||||
// update card
|
||||
slot.Revision = account.CardRevision + 1
|
||||
slot.Card.DetailRevision += 1
|
||||
slot.Card.Notes = notes
|
||||
|
||||
// save and update contact revision
|
||||
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if res := tx.Save(&slot.Card).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Preload("Card").Save(&slot).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Model(&account).Update("card_revision", account.CardRevision + 1).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
SetStatus(account)
|
||||
WriteResponse(w, getCardDetailModel(&slot));
|
||||
}
|
||||
|
@ -1,92 +0,0 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"gorm.io/gorm"
|
||||
"github.com/gorilla/mux"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func SetCardProfile(w http.ResponseWriter, r *http.Request) {
|
||||
var msg DataMessage
|
||||
|
||||
account, code, err := BearerAppToken(r, false);
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
|
||||
// scan parameters
|
||||
params := mux.Vars(r)
|
||||
cardId := params["cardId"]
|
||||
|
||||
if err := ParseRequest(r, w, &msg); err != nil {
|
||||
ErrResponse(w, http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
// load referenced card
|
||||
var slot store.CardSlot
|
||||
if err := store.DB.Preload("Card.Groups").Where("account_id = ? AND card_slot_id = ?", account.ID, cardId).First(&slot).Error; err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
} else {
|
||||
ErrResponse(w, http.StatusNotFound, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if slot.Card == nil {
|
||||
ErrResponse(w, http.StatusNotFound, errors.New("referenced slot is empty"))
|
||||
return
|
||||
}
|
||||
|
||||
var identity Identity
|
||||
guid, messageType, _, err := ReadDataMessage(&msg, &identity)
|
||||
if messageType != APP_MSGIDENTITY || err != nil {
|
||||
ErrResponse(w, http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
if slot.Card.Guid != guid {
|
||||
ErrResponse(w, http.StatusBadRequest, errors.New("slot does not contain specified contact"))
|
||||
return
|
||||
}
|
||||
|
||||
if slot.Card.ProfileRevision >= identity.Revision {
|
||||
WriteResponse(w, getCardModel(&slot))
|
||||
return
|
||||
}
|
||||
|
||||
// update card
|
||||
slot.Card.ProfileRevision = identity.Revision
|
||||
slot.Card.Username = identity.Handle
|
||||
slot.Card.Name = identity.Name
|
||||
slot.Card.Description = identity.Description
|
||||
slot.Card.Location = identity.Location
|
||||
slot.Card.Image = identity.Image
|
||||
slot.Card.Version = identity.Version
|
||||
slot.Card.Node = identity.Node
|
||||
slot.Revision = account.CardRevision + 1
|
||||
|
||||
// save and update contact revision
|
||||
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if res := tx.Save(&slot.Card).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Preload("Card").Save(&slot).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Model(&account).Update("card_revision", account.CardRevision + 1).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
SetStatus(account)
|
||||
WriteResponse(w, getCardProfileModel(&slot));
|
||||
}
|
||||
|
@ -34,18 +34,18 @@ func SetCardStatus(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
}
|
||||
var contentRevision int64
|
||||
content := r.FormValue("contentRevision")
|
||||
if content != "" {
|
||||
if contentRevision, res = strconv.ParseInt(content, 10, 64); res != nil {
|
||||
var articleRevision int64
|
||||
article := r.FormValue("articleRevision")
|
||||
if article != "" {
|
||||
if articleRevision, res = strconv.ParseInt(article, 10, 64); res != nil {
|
||||
ErrResponse(w, http.StatusBadRequest, res)
|
||||
return
|
||||
}
|
||||
}
|
||||
var labelRevision int64
|
||||
label := r.FormValue("labelRevision")
|
||||
if label != "" {
|
||||
if labelRevision, res = strconv.ParseInt(label, 10, 64); res != nil {
|
||||
var channelRevision int64
|
||||
channel := r.FormValue("channelRevision")
|
||||
if channel != "" {
|
||||
if channelRevision, res = strconv.ParseInt(channel, 10, 64); res != nil {
|
||||
ErrResponse(w, http.StatusBadRequest, res)
|
||||
return
|
||||
}
|
||||
@ -105,8 +105,8 @@ func SetCardStatus(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
slot.Card.Status = status
|
||||
slot.Card.NotifiedView = viewRevision
|
||||
slot.Card.NotifiedContent = contentRevision
|
||||
slot.Card.NotifiedLabel = labelRevision
|
||||
slot.Card.NotifiedArticle = articleRevision
|
||||
slot.Card.NotifiedChannel = channelRevision
|
||||
slot.Card.NotifiedProfile = profileRevision
|
||||
|
||||
// save and update contact revision
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func SetLabelRevision(w http.ResponseWriter, r *http.Request) {
|
||||
func SetChannelRevision(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
card, code, err := BearerContactToken(r, false)
|
||||
if err != nil {
|
||||
@ -20,7 +20,7 @@ func SetLabelRevision(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := NotifyProfileRevision(card, revision); err != nil {
|
||||
if err := NotifyChannelRevision(card, revision); err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
@ -28,11 +28,11 @@ func SetLabelRevision(w http.ResponseWriter, r *http.Request) {
|
||||
WriteResponse(w, nil)
|
||||
}
|
||||
|
||||
func NotifyLabelRevision(card *store.Card, revision int64) error {
|
||||
func NotifyChannelRevision(card *store.Card, revision int64) error {
|
||||
|
||||
act := &card.Account
|
||||
err := store.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if res := tx.Model(card).Where("id = ?", card.ID).Update("notified_label", revision).Error; res != nil {
|
||||
if res := tx.Model(card).Where("id = ?", card.ID).Update("notified_profile", revision).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Model(&card.CardSlot).Where("id = ?", card.CardSlot.ID).Update("revision", act.CardRevision+1).Error; res != nil {
|
@ -1,89 +0,0 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"gorm.io/gorm"
|
||||
"github.com/gorilla/mux"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func SetLabelGroup(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
account, code, err := BearerAppToken(r, false);
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
|
||||
// scan parameters
|
||||
params := mux.Vars(r)
|
||||
groupId := params["groupId"]
|
||||
labelId := params["labelId"]
|
||||
|
||||
labelSlot := &store.LabelSlot{}
|
||||
if err := store.DB.Preload("Label").Where("account_id = ? AND label_slot_id = ?", account.ID, labelId).First(&labelSlot).Error; err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
} else {
|
||||
ErrResponse(w, http.StatusNotFound, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if labelSlot.Label == nil {
|
||||
ErrResponse(w, http.StatusNotFound, errors.New("referenced empty label slot"))
|
||||
return
|
||||
}
|
||||
|
||||
groupSlot := &store.GroupSlot{}
|
||||
if err := store.DB.Preload("Group.GroupSlot").Preload("Group.Cards").Where("account_id = ? AND group_slot_id = ?", account.ID, groupId).First(&groupSlot).Error; err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
} else {
|
||||
ErrResponse(w, http.StatusNotFound, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if groupSlot.Group == nil {
|
||||
ErrResponse(w, http.StatusNotFound, errors.New("referenced empty group slot"))
|
||||
return
|
||||
}
|
||||
cards := &groupSlot.Group.Cards
|
||||
notify := []*store.Card{}
|
||||
|
||||
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
||||
|
||||
for _, card := range *cards {
|
||||
if res := tx.Model(&card).Update("ViewRevision", card.ViewRevision + 1).Error; res != nil {
|
||||
return res;
|
||||
}
|
||||
notify = append(notify, &card)
|
||||
}
|
||||
|
||||
if res := tx.Model(labelSlot.Label).Association("Groups").Append(groupSlot.Group); res != nil {
|
||||
return res
|
||||
}
|
||||
|
||||
if res := tx.Model(labelSlot).Update("revision", account.LabelRevision + 1).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
|
||||
if res := tx.Model(account).Update("label_revision", account.LabelRevision + 1).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, card := range notify {
|
||||
SetContactViewNotification(account, card)
|
||||
SetContactLabelNotification(account, card)
|
||||
}
|
||||
SetStatus(account)
|
||||
WriteResponse(w, getLabelModel(labelSlot, true, true))
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func SetNodeClaim(w http.ResponseWriter, r *http.Request) {
|
||||
func SetNodeStatus(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var config store.Config
|
||||
err := store.DB.Where("config_id = ?", CONFIG_CONFIGURED).First(&config).Error
|
@ -67,9 +67,9 @@ func SetOpenMessage(w http.ResponseWriter, r *http.Request) {
|
||||
card.ProfileRevision = connect.ProfileRevision
|
||||
card.Status = APP_CARDPENDING
|
||||
card.NotifiedProfile = connect.ProfileRevision
|
||||
card.NotifiedContent = connect.ContentRevision
|
||||
card.NotifiedArticle = connect.ArticleRevision
|
||||
card.NotifiedView = connect.ViewRevision
|
||||
card.NotifiedLabel = connect.LabelRevision
|
||||
card.NotifiedChannel = connect.ChannelRevision
|
||||
card.OutToken = connect.Token
|
||||
card.InToken = hex.EncodeToString(data)
|
||||
card.AccountID = account.Guid
|
||||
@ -135,14 +135,14 @@ func SetOpenMessage(w http.ResponseWriter, r *http.Request) {
|
||||
card.Node = connect.Node
|
||||
card.ProfileRevision = connect.ProfileRevision
|
||||
}
|
||||
if connect.ContentRevision > card.NotifiedContent {
|
||||
card.NotifiedContent = connect.ContentRevision
|
||||
if connect.ArticleRevision > card.NotifiedArticle {
|
||||
card.NotifiedArticle = connect.ArticleRevision
|
||||
}
|
||||
if connect.ViewRevision > card.NotifiedView {
|
||||
card.NotifiedView = connect.ViewRevision
|
||||
}
|
||||
if connect.LabelRevision > card.NotifiedLabel {
|
||||
card.NotifiedLabel = connect.LabelRevision
|
||||
if connect.ChannelRevision > card.NotifiedChannel {
|
||||
card.NotifiedChannel = connect.ChannelRevision
|
||||
}
|
||||
if connect.ProfileRevision > card.NotifiedProfile {
|
||||
card.NotifiedProfile = connect.ProfileRevision
|
||||
@ -192,14 +192,10 @@ func SetOpenMessage(w http.ResponseWriter, r *http.Request) {
|
||||
Token: slot.Card.InToken,
|
||||
Status: slot.Card.Status,
|
||||
ViewRevision: slot.Card.ViewRevision,
|
||||
LabelRevision: account.LabelRevision,
|
||||
ChannelRevision: account.ChannelRevision,
|
||||
ProfileRevision: account.ProfileRevision,
|
||||
ContentRevision: account.ContentRevision,
|
||||
ArticleRevision: account.ArticleRevision,
|
||||
}
|
||||
//SetContactProfileNotification(&account, slot.Card)
|
||||
//SetContactContentNotification(&account, slot.Card)
|
||||
//SetContactViewNotification(&account, slot.Card)
|
||||
//SetContactLabelNotification(&account, slot.Card)
|
||||
SetStatus(&account)
|
||||
WriteResponse(w, &status)
|
||||
}
|
||||
|
@ -1,49 +0,0 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"gorm.io/gorm"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func SetProfile(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
account, code, err := BearerAppToken(r, true);
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
detail := account.AccountDetail
|
||||
|
||||
// extract profile data from body
|
||||
var profileData ProfileData;
|
||||
err = ParseRequest(r, w, &profileData)
|
||||
if err != nil {
|
||||
ErrResponse(w, http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
// update record
|
||||
detail.Name = profileData.Name
|
||||
detail.Location = profileData.Location
|
||||
detail.Description = profileData.Description
|
||||
|
||||
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if res := store.DB.Save(&detail).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := store.DB.Model(&account).Update("profile_revision", account.ProfileRevision + 1).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
SetProfileNotification(account)
|
||||
SetStatus(account)
|
||||
WriteResponse(w, nil)
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ func SetViewRevision(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := NotifyProfileRevision(card, revision); err != nil {
|
||||
if err := NotifyViewRevision(card, revision); err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
@ -32,7 +32,7 @@ func NotifyViewRevision(card *store.Card, revision int64) error {
|
||||
|
||||
act := &card.Account
|
||||
err := store.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if res := tx.Model(card).Where("id = ?", card.ID).Update("notified_view", revision).Error; res != nil {
|
||||
if res := tx.Model(card).Where("id = ?", card.ID).Update("notified_profile", revision).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Model(&card.CardSlot).Where("id = ?", card.CardSlot.ID).Update("revision", act.CardRevision+1).Error; res != nil {
|
||||
|
@ -95,12 +95,10 @@ func Status(w http.ResponseWriter, r *http.Request) {
|
||||
func getRevision(account *store.Account) Revision {
|
||||
var r Revision
|
||||
r.Profile = account.ProfileRevision
|
||||
r.Content = account.ContentRevision
|
||||
r.Label = account.LabelRevision
|
||||
r.Article = account.ArticleRevision
|
||||
r.Channel = account.ChannelRevision
|
||||
r.Group = account.GroupRevision
|
||||
r.Card = account.CardRevision
|
||||
r.Dialogue = account.DialogueRevision
|
||||
r.Insight = account.InsightRevision
|
||||
return r
|
||||
}
|
||||
|
||||
|
@ -1,70 +0,0 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"gorm.io/gorm"
|
||||
"github.com/gorilla/mux"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func UpdateGroup(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
account, code, err := BearerAppToken(r, false)
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
params := mux.Vars(r)
|
||||
groupId := params["groupId"]
|
||||
|
||||
var subject Subject
|
||||
if err := ParseRequest(r, w, &subject); err != nil {
|
||||
ErrResponse(w, http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
// load specified group
|
||||
var slot store.GroupSlot
|
||||
if err := store.DB.Preload("Group.GroupData").Where("account_id = ? AND group_slot_id = ?", account.ID, groupId).First(&slot).Error; err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
} else {
|
||||
ErrResponse(w, http.StatusNotFound, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if slot.Group == nil {
|
||||
ErrResponse(w, http.StatusNotFound, errors.New("referenced deleted group"))
|
||||
return
|
||||
}
|
||||
|
||||
// update specified group
|
||||
slot.Revision = account.GroupRevision + 1
|
||||
slot.Group.DataType = subject.DataType
|
||||
slot.Group.GroupData.Data = subject.Data
|
||||
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if res := tx.Save(&slot.Group.GroupData).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Save(&slot.Group).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Save(&slot).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Model(&account).Update("group_revision", account.GroupRevision + 1).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
SetStatus(account)
|
||||
WriteResponse(w, getGroupModel(&slot))
|
||||
}
|
||||
|
||||
|
@ -21,8 +21,8 @@ const APP_CARDREQUESTED = "requested"
|
||||
const APP_CARDCONNECTING = "connecting"
|
||||
const APP_CARDCONNECTED = "connected"
|
||||
const APP_NOTIFYPROFILE = "profile"
|
||||
const APP_NOTIFYCONTENT = "content"
|
||||
const APP_NOTIFYLABEL = "label"
|
||||
const APP_NOTIFYARTICLE = "article"
|
||||
const APP_NOTIFYCHANNEL = "channel"
|
||||
const APP_NOTIFYVIEW = "view"
|
||||
const APP_TOKENAPP = "app"
|
||||
const APP_TOKENCONTACT = "contact"
|
||||
|
@ -13,17 +13,17 @@ func TestMain(m *testing.M) {
|
||||
os.Remove("databag.db")
|
||||
store.SetPath("databag.db")
|
||||
|
||||
r, w, _ := NewRequest("GET", "/admin/claimable", nil)
|
||||
GetNodeClaimable(w, r)
|
||||
r, w, _ := NewRequest("GET", "/admin/status", nil)
|
||||
GetNodeStatus(w, r)
|
||||
var available bool
|
||||
if ReadResponse(w, &available) != nil {
|
||||
panic("server not claimable")
|
||||
}
|
||||
|
||||
// claim server
|
||||
r, w, _ = NewRequest("PUT", "/admin/claim", nil)
|
||||
r, w, _ = NewRequest("PUT", "/admin/status", nil)
|
||||
SetCredentials(r, "admin:pass");
|
||||
SetNodeClaim(w, r)
|
||||
SetNodeStatus(w, r)
|
||||
if ReadResponse(w, nil) != nil {
|
||||
panic("failed to claim server")
|
||||
}
|
||||
|
@ -8,24 +8,46 @@ func getCardModel(slot *store.CardSlot) *Card {
|
||||
|
||||
if slot.Card == nil {
|
||||
return &Card{
|
||||
CardId: slot.CardSlotId,
|
||||
Id: slot.CardSlotId,
|
||||
Revision: slot.Revision,
|
||||
}
|
||||
}
|
||||
|
||||
return &Card{
|
||||
CardId: slot.CardSlotId,
|
||||
Id: slot.CardSlotId,
|
||||
Revision: slot.Revision,
|
||||
CardData: &CardData {
|
||||
Data: &CardData {
|
||||
NotifiedProfile: slot.Card.NotifiedProfile,
|
||||
NotifiedContent: slot.Card.NotifiedContent,
|
||||
NotifiedLabel: slot.Card.NotifiedLabel,
|
||||
NotifiedArticle: slot.Card.NotifiedArticle,
|
||||
NotifiedChannel: slot.Card.NotifiedChannel,
|
||||
NotifiedView: slot.Card.NotifiedView,
|
||||
ProfileRevision: slot.Card.ProfileRevision,
|
||||
DetailRevision: slot.Card.DetailRevision,
|
||||
CardDetail: getCardDetailModel(slot),
|
||||
CardProfile: getCardProfileModel(slot),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func getCardRevisionModel(slot *store.CardSlot) *Card {
|
||||
|
||||
if slot.Card == nil {
|
||||
return &Card{
|
||||
Id: slot.CardSlotId,
|
||||
Revision: slot.Revision,
|
||||
}
|
||||
}
|
||||
|
||||
return &Card{
|
||||
Id: slot.CardSlotId,
|
||||
Revision: slot.Revision,
|
||||
Data: &CardData {
|
||||
NotifiedProfile: slot.Card.NotifiedProfile,
|
||||
NotifiedArticle: slot.Card.NotifiedArticle,
|
||||
NotifiedChannel: slot.Card.NotifiedChannel,
|
||||
NotifiedView: slot.Card.NotifiedView,
|
||||
ProfileRevision: slot.Card.ProfileRevision,
|
||||
DetailRevision: slot.Card.DetailRevision,
|
||||
Guid: slot.Card.Guid,
|
||||
Status: slot.Card.Status,
|
||||
Token: slot.Card.OutToken,
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -38,7 +60,8 @@ func getCardDetailModel(slot *store.CardSlot) *CardDetail {
|
||||
}
|
||||
|
||||
return &CardDetail{
|
||||
Revision: slot.Card.DetailRevision,
|
||||
Status: slot.Card.Status,
|
||||
Token: slot.Card.OutToken,
|
||||
Notes: slot.Card.Notes,
|
||||
Groups: groups,
|
||||
}
|
||||
@ -47,7 +70,7 @@ func getCardDetailModel(slot *store.CardSlot) *CardDetail {
|
||||
func getCardProfileModel(slot *store.CardSlot) *CardProfile {
|
||||
|
||||
return &CardProfile{
|
||||
Revision: slot.Card.ProfileRevision,
|
||||
Guid: slot.Card.Guid,
|
||||
Handle: slot.Card.Username,
|
||||
Name: slot.Card.Name,
|
||||
Description: slot.Card.Description,
|
||||
@ -61,15 +84,15 @@ func getCardProfileModel(slot *store.CardSlot) *CardProfile {
|
||||
func getGroupModel(slot *store.GroupSlot) *Group {
|
||||
if slot.Group == nil {
|
||||
return &Group{
|
||||
GroupId: slot.GroupSlotId,
|
||||
Id: slot.GroupSlotId,
|
||||
Revision: slot.Revision,
|
||||
}
|
||||
}
|
||||
|
||||
return &Group{
|
||||
GroupId: slot.GroupSlotId,
|
||||
Id: slot.GroupSlotId,
|
||||
Revision: slot.Revision,
|
||||
GroupData: &GroupData {
|
||||
Data: &GroupData {
|
||||
DataType: slot.Group.DataType,
|
||||
Data: slot.Group.GroupData.Data,
|
||||
Created: slot.Group.Created,
|
||||
@ -78,72 +101,4 @@ func getGroupModel(slot *store.GroupSlot) *Group {
|
||||
}
|
||||
}
|
||||
|
||||
func getLabelModel(slot *store.LabelSlot, includeData bool, includeGroups bool) *Label {
|
||||
|
||||
if !includeData || slot.Label == nil {
|
||||
return &Label{
|
||||
LabelId: slot.LabelSlotId,
|
||||
Revision: slot.Revision,
|
||||
}
|
||||
}
|
||||
|
||||
var groups *[]string
|
||||
if includeGroups {
|
||||
groups = &[]string{}
|
||||
for _, group := range slot.Label.Groups {
|
||||
*groups = append(*groups, group.GroupSlot.GroupSlotId)
|
||||
}
|
||||
}
|
||||
|
||||
return &Label{
|
||||
LabelId: slot.LabelSlotId,
|
||||
Revision: slot.Revision,
|
||||
LabelData: &LabelData{
|
||||
DataType: slot.Label.DataType,
|
||||
Data: slot.Label.LabelData.Data,
|
||||
Created: slot.Label.Created,
|
||||
Updated: slot.Label.Updated,
|
||||
Groups: groups,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func getArticleModel(slot *store.ArticleSlot, contact bool, shared bool) *Article {
|
||||
|
||||
if !shared || slot.Article == nil {
|
||||
return &Article{
|
||||
ArticleId: slot.ArticleSlotId,
|
||||
Revision: slot.Revision,
|
||||
}
|
||||
}
|
||||
|
||||
var groups []string
|
||||
if !contact {
|
||||
for _, group := range slot.Article.Groups {
|
||||
groups = append(groups, group.GroupSlot.GroupSlotId)
|
||||
}
|
||||
}
|
||||
|
||||
var labels []string
|
||||
for _, label := range slot.Article.Labels {
|
||||
labels = append(labels, label.LabelSlot.LabelSlotId)
|
||||
}
|
||||
|
||||
return &Article{
|
||||
ArticleId: slot.ArticleSlotId,
|
||||
Revision: slot.Revision,
|
||||
ArticleData: &ArticleData{
|
||||
DataType: slot.Article.DataType,
|
||||
Data: slot.Article.Data,
|
||||
Status: slot.Article.Status,
|
||||
Labels: labels,
|
||||
Groups: groups,
|
||||
TagCount: slot.Article.TagCount,
|
||||
Created: slot.Article.Created,
|
||||
Updated: slot.Article.Updated,
|
||||
TagUpdated: slot.Article.TagUpdated,
|
||||
TagRevision: slot.Article.TagRevision,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,319 +1,440 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"os"
|
||||
//"os"
|
||||
)
|
||||
|
||||
type Account struct {
|
||||
|
||||
AccountId string `json:"accountId"`
|
||||
|
||||
Profile *Profile `json:"profile"`
|
||||
|
||||
Disabled bool `json:"disabled"`
|
||||
}
|
||||
|
||||
type AccountStatus struct {
|
||||
|
||||
Disabled bool `json:"disabled"`
|
||||
|
||||
StorageUsed float64 `json:"storageUsed"`
|
||||
|
||||
StorageAvailable float64 `json:"storageAvailable"`
|
||||
|
||||
ForwardingAddress string `json:"forwardingAddress"`
|
||||
}
|
||||
|
||||
type AccountsImportBody struct {
|
||||
FileName **os.File `json:"fileName,omitempty"`
|
||||
}
|
||||
|
||||
type Announce struct {
|
||||
|
||||
AppToken string `json:"appToken"`
|
||||
}
|
||||
|
||||
type App struct {
|
||||
AppId string `json:"appId"`
|
||||
AppData *AppData `json:"appData"`
|
||||
Attached int64 `json:"attached"`
|
||||
|
||||
Id string `json:"id"`
|
||||
|
||||
Revision int64 `json:"revision"`
|
||||
|
||||
Data *AppData `json:"data"`
|
||||
}
|
||||
|
||||
type AppData struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Url string `json:"url,omitempty"`
|
||||
Image string `json:"image,omitempty"`
|
||||
}
|
||||
|
||||
type Subject struct {
|
||||
DataType string `json:"dataType"`
|
||||
Data string `json:"data"`
|
||||
Name string `json:"name,omitempty"`
|
||||
|
||||
Description string `json:"description,omitempty"`
|
||||
|
||||
Url string `json:"url,omitempty"`
|
||||
|
||||
Image string `json:"image,omitempty"`
|
||||
|
||||
Attached int64 `json:"attached"`
|
||||
}
|
||||
|
||||
type Article struct {
|
||||
ArticleId string `json:"article_id"`
|
||||
|
||||
Id string `json:"id"`
|
||||
|
||||
Revision int64 `json:"revision"`
|
||||
ArticleData *ArticleData `json:"articleData"`
|
||||
|
||||
Data *ArticleData `json:"data"`
|
||||
}
|
||||
|
||||
type ArticleData struct {
|
||||
DataType string `json:"type"`
|
||||
|
||||
DataType string `json:"dataType"`
|
||||
|
||||
Data string `json:"data"`
|
||||
|
||||
Created int64 `json:"created"`
|
||||
|
||||
Updated int64 `json:"updated"`
|
||||
|
||||
Status string `json:"status"`
|
||||
Labels []string `json:"labels"`
|
||||
Groups []string `json:"groups,omitempty"`
|
||||
TagCount int32 `json:"tagCount"`
|
||||
TagUpdated int64 `json:"tagUpdated,omitempty"`
|
||||
TagRevision int64 `json:"tagRevision"`
|
||||
|
||||
Groups *ArticleGroups `json:"groups,omitempty"`
|
||||
}
|
||||
|
||||
type ArticleAccess struct {
|
||||
Labels []string `json:"labels"`
|
||||
type ArticleGroups struct {
|
||||
|
||||
Groups []string `json:"groups"`
|
||||
}
|
||||
|
||||
type ArticleIdAssetsBody struct {
|
||||
FileName **os.File `json:"fileName,omitempty"`
|
||||
}
|
||||
|
||||
type ArticleIdSubjectBody struct {
|
||||
Type_ string `json:"type"`
|
||||
Data string `json:"data"`
|
||||
}
|
||||
|
||||
type Asset struct {
|
||||
|
||||
AssetId string `json:"assetId"`
|
||||
|
||||
Transform string `json:"transform,omitempty"`
|
||||
|
||||
Status string `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
type Card struct {
|
||||
CardId string `json:"cardId"`
|
||||
Revision int64 `json:"revision,omitempty"`
|
||||
CardData *CardData `json:"articleData"`
|
||||
|
||||
Id string `json:"id"`
|
||||
|
||||
Revision int64 `json:"revision"`
|
||||
|
||||
Data *CardData `json:"data"`
|
||||
}
|
||||
|
||||
type CardData struct {
|
||||
Guid string `json:"guid"`
|
||||
Status string `json:"status"`
|
||||
Token string `json:"token,omitempty"`
|
||||
|
||||
DetailRevision int64 `json:"detailRevision"`
|
||||
|
||||
ProfileRevision int64 `json:"profileRevision"`
|
||||
|
||||
NotifiedProfile int64 `json:"notifiedProfile"`
|
||||
NotifiedContent int64 `json:"notifiedContent"`
|
||||
NotifiedLabel int64 `json:"notifiedLabel"`
|
||||
|
||||
NotifiedArticle int64 `json:"notifiedArticle"`
|
||||
|
||||
NotifiedChannel int64 `json:"notifiedChannel"`
|
||||
|
||||
NotifiedView int64 `json:"notifiedView"`
|
||||
|
||||
CardDetail *CardDetail `json:"cardDetail,omitempty"`
|
||||
|
||||
CardProfile *CardProfile `json:"cardProfile,omitempty"`
|
||||
}
|
||||
|
||||
type CardDetail struct {
|
||||
Revision int64 `json:"revision,omitempty"`
|
||||
|
||||
Status string `json:"status"`
|
||||
|
||||
Token string `json:"token,omitempty"`
|
||||
|
||||
Notes string `json:"notes,omitempty"`
|
||||
|
||||
Groups []string `json:"groups,omitempty"`
|
||||
}
|
||||
|
||||
type CardProfile struct {
|
||||
Revision int64 `json:"revision,omitempty"`
|
||||
|
||||
Guid string `json:"guid"`
|
||||
|
||||
Handle string `json:"handle,omitempty"`
|
||||
|
||||
Name string `json:"name,omitempty"`
|
||||
|
||||
Description string `json:"description,omitempty"`
|
||||
|
||||
Location string `json:"location,omitempty"`
|
||||
|
||||
ImageSet bool `json:"imageSet,omitempty"`
|
||||
Version string `json:"version"`
|
||||
|
||||
Version string `json:"version,omitempty"`
|
||||
|
||||
Node string `json:"node"`
|
||||
}
|
||||
|
||||
type Dialogue struct {
|
||||
DialogueId string `json:"dialogueId"`
|
||||
DialogueRevison int64 `json:"dialogueRevison,omitempty"`
|
||||
Type_ string `json:"type"`
|
||||
Data string `json:"data"`
|
||||
Created int64 `json:"created"`
|
||||
Active bool `json:"active"`
|
||||
InsightRevision int64 `json:"insightRevision,omitempty"`
|
||||
Insights []DialogueInsights `json:"insights"`
|
||||
type Channel struct {
|
||||
|
||||
Id string `json:"id"`
|
||||
|
||||
Revision string `json:"revision"`
|
||||
|
||||
Data *ChannelData `json:"data"`
|
||||
}
|
||||
|
||||
type DialogueIdSubjectBody struct {
|
||||
Type_ string `json:"type"`
|
||||
Data string `json:"data"`
|
||||
type ChannelData struct {
|
||||
|
||||
DetailRevision int64 `json:"detailRevision"`
|
||||
|
||||
TopicRevision int64 `json:"topicRevision"`
|
||||
|
||||
ChannelDetail *ChannelDetail `json:"channelDetail,omitempty"`
|
||||
|
||||
ChannelTopics *ChannelSize `json:"channelTopics,omitempty"`
|
||||
}
|
||||
|
||||
type DialogueInsights struct {
|
||||
CardId string `json:"cardId,omitempty"`
|
||||
Status string `json:"status,omitempty"`
|
||||
}
|
||||
type ChannelDetail struct {
|
||||
|
||||
type Group struct {
|
||||
GroupId string `json:"groupId"`
|
||||
Revision int64 `json:"revision"`
|
||||
GroupData *GroupData `json:"groupData"`
|
||||
}
|
||||
|
||||
type GroupData struct {
|
||||
DataType string `json:"dataType"`
|
||||
|
||||
Data string `json:"data"`
|
||||
|
||||
Created int64 `json:"created"`
|
||||
|
||||
Updated int64 `json:"updated"`
|
||||
|
||||
Viewers []string `json:"viewers,omitempty"`
|
||||
|
||||
ViewerGroups *ChannelGroups `json:"viewerGroups,omitempty"`
|
||||
|
||||
Members []string `json:"members,omitempty"`
|
||||
|
||||
MemberGroups *ChannelGroups `json:"memberGroups,omitempty"`
|
||||
}
|
||||
|
||||
type GroupsGroupIdBody struct {
|
||||
Type_ string `json:"type"`
|
||||
Data string `json:"data"`
|
||||
type ChannelGroups struct {
|
||||
|
||||
Groups []string `json:"groups"`
|
||||
}
|
||||
|
||||
type Insight struct {
|
||||
InsightId string `json:"insightId"`
|
||||
InsightRevision int64 `json:"insightRevision"`
|
||||
CardId string `json:"cardId"`
|
||||
type ChannelSize struct {
|
||||
|
||||
TopicCount int32 `json:"topicCount"`
|
||||
|
||||
TopicUpdated int64 `json:"topicUpdated"`
|
||||
}
|
||||
|
||||
type Claim struct {
|
||||
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
type Connect struct {
|
||||
|
||||
Contact string `json:"contact"`
|
||||
|
||||
Token string `json:"token"`
|
||||
|
||||
ViewRevision int64 `json:"viewRevision,omitempty"`
|
||||
|
||||
ArticleRevision int64 `json:"articleRevision,omitempty"`
|
||||
|
||||
ProfileRevision int64 `json:"profileRevision,omitempty"`
|
||||
|
||||
ChannelRevision int64 `json:"channelRevision,omitempty"`
|
||||
|
||||
Handle string `json:"handle,omitempty"`
|
||||
|
||||
Name string `json:"name,omitempty"`
|
||||
|
||||
Description string `json:"description,omitempty"`
|
||||
|
||||
Location string `json:"location,omitempty"`
|
||||
|
||||
Image string `json:"image,omitempty"`
|
||||
|
||||
Version string `json:"version,omitempty"`
|
||||
|
||||
Node string `json:"node,omitempty"`
|
||||
}
|
||||
|
||||
type ContactStatus struct {
|
||||
|
||||
Token string `json:"token,omitempty"`
|
||||
|
||||
ProfileRevision int64 `json:"profileRevision,omitempty"`
|
||||
|
||||
ArticleRevision int64 `json:"articleRevision,omitempty"`
|
||||
|
||||
ChannelRevision int64 `json:"channelRevision,omitempty"`
|
||||
|
||||
ViewRevision int64 `json:"viewRevision,omitempty"`
|
||||
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
type Label struct {
|
||||
LabelId string `json:"labelId"`
|
||||
Revision int64 `json:"revision"`
|
||||
LabelData *LabelData `json:"labelData"`
|
||||
type DataMessage struct {
|
||||
|
||||
Message string `json:"message"`
|
||||
|
||||
KeyType string `json:"keyType"`
|
||||
|
||||
PublicKey string `json:"publicKey"`
|
||||
|
||||
Signature string `json:"signature"`
|
||||
|
||||
SignatureType string `json:"signatureType"`
|
||||
}
|
||||
|
||||
type LabelData struct {
|
||||
DataType string `json:"type"`
|
||||
type Disconnect struct {
|
||||
|
||||
Contact string `json:"contact"`
|
||||
}
|
||||
|
||||
type Group struct {
|
||||
|
||||
Id string `json:"id"`
|
||||
|
||||
Revision int64 `json:"revision"`
|
||||
|
||||
Data *GroupData `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
type GroupData struct {
|
||||
|
||||
DataType string `json:"dataType"`
|
||||
|
||||
Data string `json:"data"`
|
||||
|
||||
Created int64 `json:"created"`
|
||||
|
||||
Updated int64 `json:"updated"`
|
||||
Groups *[]string `json:"groups,omitempty"`
|
||||
}
|
||||
|
||||
type Identity struct {
|
||||
|
||||
Revision int64 `json:"revision"`
|
||||
|
||||
Handle string `json:"handle,omitempty"`
|
||||
|
||||
Name string `json:"name,omitempty"`
|
||||
|
||||
Description string `json:"description,omitempty"`
|
||||
|
||||
Location string `json:"location,omitempty"`
|
||||
|
||||
Image string `json:"image,omitempty"`
|
||||
|
||||
Version string `json:"version"`
|
||||
|
||||
Node string `json:"node"`
|
||||
}
|
||||
|
||||
type NodeConfig struct {
|
||||
|
||||
Domain string `json:"domain"`
|
||||
|
||||
PublicLimit int64 `json:"publicLimit"`
|
||||
|
||||
AccountStorage int64 `json:"accountStorage"`
|
||||
}
|
||||
|
||||
type Profile struct {
|
||||
Guid string `json:"profileId"`
|
||||
|
||||
Guid string `json:"guid"`
|
||||
|
||||
Handle string `json:"handle,omitempty"`
|
||||
|
||||
Name string `json:"name,omitempty"`
|
||||
|
||||
Description string `json:"description,omitempty"`
|
||||
|
||||
Location string `json:"location,omitempty"`
|
||||
|
||||
Image string `json:"image,omitempty"`
|
||||
|
||||
Revision int64 `json:"revision"`
|
||||
|
||||
Version string `json:"version,omitempty"`
|
||||
|
||||
Node string `json:"node"`
|
||||
}
|
||||
|
||||
type ProfileData struct {
|
||||
|
||||
Name string `json:"name,omitempty"`
|
||||
|
||||
Description string `json:"description,omitempty"`
|
||||
|
||||
Location string `json:"location,omitempty"`
|
||||
}
|
||||
|
||||
type Revision struct {
|
||||
|
||||
Profile int64 `json:"profile"`
|
||||
Content int64 `json:"content"`
|
||||
Label int64 `json:"label"`
|
||||
Group int64 `json:"share"`
|
||||
|
||||
Article int64 `json:"article"`
|
||||
|
||||
Group int64 `json:"group"`
|
||||
|
||||
Channel int64 `json:"channel"`
|
||||
|
||||
Card int64 `json:"card"`
|
||||
Dialogue int64 `json:"dialogue"`
|
||||
Insight int64 `json:"insight"`
|
||||
}
|
||||
|
||||
type ShareGroupsBody struct {
|
||||
Type_ string `json:"type"`
|
||||
type SignedData struct {
|
||||
|
||||
Guid string `json:"guid"`
|
||||
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
|
||||
MessageType string `json:"messageType"`
|
||||
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
type Subject struct {
|
||||
|
||||
DataType string `json:"dataType"`
|
||||
|
||||
Data string `json:"data"`
|
||||
}
|
||||
|
||||
type Tag struct {
|
||||
TagId string `json:"tagId"`
|
||||
CardId string `json:"cardId,omitempty"`
|
||||
Revision int64 `json:"revision"`
|
||||
Type_ string `json:"type"`
|
||||
|
||||
Id string `json:"id"`
|
||||
|
||||
Revision string `json:"revision"`
|
||||
|
||||
Data *TagData `json:"data"`
|
||||
}
|
||||
|
||||
type TagData struct {
|
||||
|
||||
Guid string `json:"guid"`
|
||||
|
||||
DataType string `json:"dataType"`
|
||||
|
||||
Data string `json:"data"`
|
||||
|
||||
Created int64 `json:"created"`
|
||||
|
||||
Updated int64 `json:"updated"`
|
||||
}
|
||||
|
||||
type Topic struct {
|
||||
TopicId string `json:"topicId"`
|
||||
TopicRevision int64 `json:"topicRevision"`
|
||||
Type_ string `json:"type"`
|
||||
Data string `json:"data"`
|
||||
Created int64 `json:"created"`
|
||||
Modified int64 `json:"modified"`
|
||||
Status string `json:"status"`
|
||||
TagCount int32 `json:"tagCount"`
|
||||
TagUpdate int64 `json:"tagUpdate,omitempty"`
|
||||
|
||||
Id string `json:"id"`
|
||||
|
||||
Revision string `json:"revision"`
|
||||
|
||||
Data *TopicData `json:"data"`
|
||||
}
|
||||
|
||||
type TopicData struct {
|
||||
|
||||
DetailRevision int64 `json:"detailRevision"`
|
||||
|
||||
TagRevision int64 `json:"tagRevision"`
|
||||
|
||||
TopicDetail *TopicDetail `json:"topicDetail,omitempty"`
|
||||
|
||||
TopicTags *TopicSize `json:"topicTags:,omitempty"`
|
||||
}
|
||||
|
||||
type TopicIdAssetsBody struct {
|
||||
FileName **os.File `json:"fileName,omitempty"`
|
||||
}
|
||||
type TopicDetail struct {
|
||||
|
||||
type TopicIdSubjectBody struct {
|
||||
Type_ string `json:"type"`
|
||||
Data string `json:"data"`
|
||||
}
|
||||
|
||||
type TopicIdTagsBody struct {
|
||||
Type_ string `json:"type"`
|
||||
Data string `json:"data"`
|
||||
}
|
||||
|
||||
type Tunnel struct {
|
||||
CardId string `json:"cardId"`
|
||||
Type_ string `json:"type"`
|
||||
Data string `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
type ContactStatus struct {
|
||||
Token string `json:"token,omitempty"`
|
||||
Status string `json:"status"`
|
||||
ViewRevision int64 `json:"viewRevision"`
|
||||
LabelRevision int64 `json:"labelRevision"`
|
||||
ContentRevision int64 `json:"contentRevision"`
|
||||
ProfileRevision int64 `json:"profileRevision,omitempty"`
|
||||
}
|
||||
|
||||
type DataMessage struct {
|
||||
Message string `json:"message"`
|
||||
KeyType string `json:"keyType"`
|
||||
PublicKey string `json:"publicKey"`
|
||||
Signature string `json:"signature"`
|
||||
SignatureType string `json:"signatureType"`
|
||||
}
|
||||
|
||||
type SignedData struct {
|
||||
Guid string `json:"guid"`
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
MessageType string `json:"messageType"`
|
||||
Value string `json:"value"`
|
||||
|
||||
DataType string `json:"dataType"`
|
||||
|
||||
Data string `json:"data"`
|
||||
|
||||
Created int64 `json:"created"`
|
||||
|
||||
Modified int64 `json:"modified"`
|
||||
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
type Identity struct {
|
||||
Revision int64 `json:"revision"`
|
||||
Handle string `json:"handle,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Location string `json:"location,omitempty"`
|
||||
Image string `json:"image,omitempty"`
|
||||
Version string `json:"version"`
|
||||
Node string `json:"node"`
|
||||
}
|
||||
|
||||
type Connect struct {
|
||||
Contact string `json:"contact"`
|
||||
Token string `json:"token"`
|
||||
ViewRevision int64 `json:"viewRevision"`
|
||||
LabelRevision int64 `json:"labelRevision"`
|
||||
ContentRevision int64 `json:"contentRevision"`
|
||||
ProfileRevision int64 `json:"profileRevision,omitempty"`
|
||||
Handle string `json:"handle,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Location string `json:"location,omitempty"`
|
||||
Image string `json:"image,omitempty"`
|
||||
Version string `json:"version,omitempty"`
|
||||
Node string `json:"node,omitempty"`
|
||||
}
|
||||
|
||||
type Disconnect struct {
|
||||
Contact string `json:"contact"`
|
||||
}
|
||||
|
||||
type Authenticate struct {
|
||||
Token string `json:"token"`
|
||||
type TopicSize struct {
|
||||
|
||||
TagCount int32 `json:"tagCount"`
|
||||
|
||||
TagUpdated int64 `json:"tagUpdated"`
|
||||
}
|
||||
|
||||
|
@ -60,12 +60,12 @@ func SendLocalNotification(notification *store.Notification) {
|
||||
if err := NotifyProfileRevision(&card, notification.Revision); err != nil {
|
||||
ErrMsg(err)
|
||||
}
|
||||
} else if notification.Module == APP_NOTIFYCONTENT {
|
||||
if err := NotifyContentRevision(&card, notification.Revision); err != nil {
|
||||
} else if notification.Module == APP_NOTIFYARTICLE {
|
||||
if err := NotifyArticleRevision(&card, notification.Revision); err != nil {
|
||||
ErrMsg(err)
|
||||
}
|
||||
} else if notification.Module == APP_NOTIFYLABEL {
|
||||
if err := NotifyLabelRevision(&card, notification.Revision); err != nil {
|
||||
} else if notification.Module == APP_NOTIFYCHANNEL {
|
||||
if err := NotifyChannelRevision(&card, notification.Revision); err != nil {
|
||||
ErrMsg(err)
|
||||
}
|
||||
} else if notification.Module == APP_NOTIFYVIEW {
|
||||
@ -151,9 +151,9 @@ func SetContentNotification(account *store.Account) {
|
||||
for _, card := range cards {
|
||||
notification := &store.Notification{
|
||||
Node: card.Node,
|
||||
Module: APP_NOTIFYCONTENT,
|
||||
Module: APP_NOTIFYARTICLE,
|
||||
Token: card.OutToken,
|
||||
Revision: account.ContentRevision,
|
||||
Revision: account.ArticleRevision,
|
||||
}
|
||||
if err := tx.Save(notification).Error; err != nil {
|
||||
return err
|
||||
@ -178,9 +178,9 @@ func SetContactContentNotification(account *store.Account, card *store.Card) {
|
||||
// add new notification for card
|
||||
notification := &store.Notification{
|
||||
Node: card.Node,
|
||||
Module: APP_NOTIFYCONTENT,
|
||||
Module: APP_NOTIFYARTICLE,
|
||||
Token: card.OutToken,
|
||||
Revision: account.ContentRevision,
|
||||
Revision: account.ArticleRevision,
|
||||
}
|
||||
|
||||
if res := store.DB.Save(notification).Error; res != nil {
|
||||
@ -263,9 +263,9 @@ func SetLabelNotification(account *store.Account) {
|
||||
for _, card := range cards {
|
||||
notification := &store.Notification{
|
||||
Node: card.Node,
|
||||
Module: APP_NOTIFYLABEL,
|
||||
Module: APP_NOTIFYCHANNEL,
|
||||
Token: card.OutToken,
|
||||
Revision: account.LabelRevision,
|
||||
Revision: account.ChannelRevision,
|
||||
}
|
||||
if err := tx.Save(notification).Error; err != nil {
|
||||
return err
|
||||
@ -290,9 +290,9 @@ func SetContactLabelNotification(account *store.Account, card *store.Card) {
|
||||
// add new notification for card
|
||||
notification := &store.Notification{
|
||||
Node: card.Node,
|
||||
Module: APP_NOTIFYLABEL,
|
||||
Module: APP_NOTIFYCHANNEL,
|
||||
Token: card.OutToken,
|
||||
Revision: account.LabelRevision,
|
||||
Revision: account.ChannelRevision,
|
||||
}
|
||||
|
||||
if res := store.DB.Save(notification).Error; res != nil {
|
||||
|
@ -141,15 +141,15 @@ var routes = Routes{
|
||||
Route{
|
||||
"GetAccountUsername",
|
||||
strings.ToUpper("Get"),
|
||||
"/account/claimable",
|
||||
"/account/available",
|
||||
GetAccountUsername,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetPublicClaimable",
|
||||
"GetPublicStatus",
|
||||
strings.ToUpper("Get"),
|
||||
"/account/public/claimable",
|
||||
GetPublicClaimable,
|
||||
"/account/public/status",
|
||||
GetPublicStatus,
|
||||
},
|
||||
|
||||
Route{
|
||||
@ -215,13 +215,6 @@ var routes = Routes{
|
||||
GetNodeAccounts,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetNodeClaimable",
|
||||
strings.ToUpper("Get"),
|
||||
"/admin/claimable",
|
||||
GetNodeClaimable,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetNodeConfig",
|
||||
strings.ToUpper("Get"),
|
||||
@ -229,6 +222,13 @@ var routes = Routes{
|
||||
GetNodeConfig,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetNodeStatus",
|
||||
strings.ToUpper("Get"),
|
||||
"/admin/status",
|
||||
GetNodeStatus,
|
||||
},
|
||||
|
||||
Route{
|
||||
"ImportAccount",
|
||||
strings.ToUpper("Post"),
|
||||
@ -250,13 +250,6 @@ var routes = Routes{
|
||||
SetNodeAccount,
|
||||
},
|
||||
|
||||
Route{
|
||||
"SetNodeClaim",
|
||||
strings.ToUpper("Post"),
|
||||
"/admin/claim",
|
||||
SetNodeClaim,
|
||||
},
|
||||
|
||||
Route{
|
||||
"SetNodeConfig",
|
||||
strings.ToUpper("Put"),
|
||||
@ -264,6 +257,90 @@ var routes = Routes{
|
||||
SetNodeConfig,
|
||||
},
|
||||
|
||||
Route{
|
||||
"SetNodeStatus",
|
||||
strings.ToUpper("Put"),
|
||||
"/admin/status",
|
||||
SetNodeStatus,
|
||||
},
|
||||
|
||||
Route{
|
||||
"AddGroup",
|
||||
strings.ToUpper("Post"),
|
||||
"/alias/groups",
|
||||
AddGroup,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetGroups",
|
||||
strings.ToUpper("Get"),
|
||||
"/alias/groups",
|
||||
GetGroups,
|
||||
},
|
||||
|
||||
Route{
|
||||
"RemoveGroup",
|
||||
strings.ToUpper("Delete"),
|
||||
"/alias/groups/{groupId}",
|
||||
RemoveGroup,
|
||||
},
|
||||
|
||||
Route{
|
||||
"UpdateGroup",
|
||||
strings.ToUpper("Put"),
|
||||
"/alias/groups/{groupId}",
|
||||
UpdateGroup,
|
||||
},
|
||||
|
||||
Route{
|
||||
"AddArticle",
|
||||
strings.ToUpper("Post"),
|
||||
"/attribute/articles",
|
||||
AddArticle,
|
||||
},
|
||||
|
||||
Route{
|
||||
"ClearArticleGroup",
|
||||
strings.ToUpper("Delete"),
|
||||
"/attribute/articles/{articleId}/groups/{groupId}",
|
||||
ClearArticleGroup,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetArticleSubjectField",
|
||||
strings.ToUpper("Get"),
|
||||
"/attribute/articles/{articleId}/subject/{field}",
|
||||
GetArticleSubjectField,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetArticles",
|
||||
strings.ToUpper("Get"),
|
||||
"/attribute/articles",
|
||||
GetArticles,
|
||||
},
|
||||
|
||||
Route{
|
||||
"RemoveArticle",
|
||||
strings.ToUpper("Delete"),
|
||||
"/attribute/articles/{articleId}",
|
||||
RemoveArticle,
|
||||
},
|
||||
|
||||
Route{
|
||||
"SetArticleGroup",
|
||||
strings.ToUpper("Put"),
|
||||
"/attribute/articles/{articleId}/groups/{groupId}",
|
||||
SetArticleGroup,
|
||||
},
|
||||
|
||||
Route{
|
||||
"SetArticleSubject",
|
||||
strings.ToUpper("Put"),
|
||||
"/attribute/articles/{articleId}/subject",
|
||||
SetArticleSubject,
|
||||
},
|
||||
|
||||
Route{
|
||||
"Authorize",
|
||||
strings.ToUpper("Put"),
|
||||
@ -292,13 +369,6 @@ var routes = Routes{
|
||||
ClearCardNotes,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetCard",
|
||||
strings.ToUpper("Get"),
|
||||
"/contact/cards/{cardId}",
|
||||
GetCard,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetCardDetail",
|
||||
strings.ToUpper("Get"),
|
||||
@ -348,6 +418,13 @@ var routes = Routes{
|
||||
RemoveCard,
|
||||
},
|
||||
|
||||
Route{
|
||||
"SetArticleRevision",
|
||||
strings.ToUpper("Put"),
|
||||
"/contact/article/revision",
|
||||
SetArticleRevision,
|
||||
},
|
||||
|
||||
Route{
|
||||
"SetCardGroup",
|
||||
strings.ToUpper("Put"),
|
||||
@ -376,6 +453,13 @@ var routes = Routes{
|
||||
SetCardStatus,
|
||||
},
|
||||
|
||||
Route{
|
||||
"SetChannelRevision",
|
||||
strings.ToUpper("Put"),
|
||||
"/contact/channel/revision",
|
||||
SetChannelRevision,
|
||||
},
|
||||
|
||||
Route{
|
||||
"SetCloseMessage",
|
||||
strings.ToUpper("Put"),
|
||||
@ -383,20 +467,6 @@ var routes = Routes{
|
||||
SetCloseMessage,
|
||||
},
|
||||
|
||||
Route{
|
||||
"SetContentRevision",
|
||||
strings.ToUpper("Put"),
|
||||
"/contact/content/revision",
|
||||
SetContentRevision,
|
||||
},
|
||||
|
||||
Route{
|
||||
"SetLabelRevision",
|
||||
strings.ToUpper("Put"),
|
||||
"/contact/label/revision",
|
||||
SetLabelRevision,
|
||||
},
|
||||
|
||||
Route{
|
||||
"SetOpenMessage",
|
||||
strings.ToUpper("Put"),
|
||||
@ -419,430 +489,185 @@ var routes = Routes{
|
||||
},
|
||||
|
||||
Route{
|
||||
"AddArticle",
|
||||
"AddChannel",
|
||||
strings.ToUpper("Post"),
|
||||
"/content/articles",
|
||||
AddArticle,
|
||||
"/content/channels",
|
||||
AddChannel,
|
||||
},
|
||||
|
||||
Route{
|
||||
"AddArticleAsset",
|
||||
"AddChannelAsset",
|
||||
strings.ToUpper("Post"),
|
||||
"/content/articles/{articleId}/assets",
|
||||
AddArticleAsset,
|
||||
"/content/channels/{channelId}/topics/{topicId}/assets",
|
||||
AddChannelAsset,
|
||||
},
|
||||
|
||||
Route{
|
||||
"AddArticleTag",
|
||||
"AddChannelTopic",
|
||||
strings.ToUpper("Post"),
|
||||
"/content/articles/{articleId}/tags",
|
||||
AddArticleTag,
|
||||
"/content/channels/{channelId}/topics",
|
||||
AddChannelTopic,
|
||||
},
|
||||
|
||||
Route{
|
||||
"AddLabel",
|
||||
"AddChannelTopicTag",
|
||||
strings.ToUpper("Post"),
|
||||
"/content/labels",
|
||||
AddLabel,
|
||||
"/content/channels/{channelId}/topics/{topicId}/tags",
|
||||
AddChannelTopicTag,
|
||||
},
|
||||
|
||||
Route{
|
||||
"ClearArticleGroup",
|
||||
"ClearChannelGroup",
|
||||
strings.ToUpper("Delete"),
|
||||
"/content/articles/{articleId}/groups/{groupId}",
|
||||
ClearArticleGroup,
|
||||
"/content/channels/{channelId}/groups/{groupId}",
|
||||
ClearChannelGroup,
|
||||
},
|
||||
|
||||
Route{
|
||||
"ClearArticleLabel",
|
||||
"GetChannelAsset",
|
||||
strings.ToUpper("Get"),
|
||||
"/content/channels/{channelId}/topics/{topicId}/assets/{assetId}",
|
||||
GetChannelAsset,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetChannelAssets",
|
||||
strings.ToUpper("Get"),
|
||||
"/content/channels/{channelId}/topics/{topicId}/assets",
|
||||
GetChannelAssets,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetChannelDetail",
|
||||
strings.ToUpper("Get"),
|
||||
"/content/channels/{channelId}/detail",
|
||||
GetChannelDetail,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetChannelSize",
|
||||
strings.ToUpper("Get"),
|
||||
"/content/channels/{channelId}/size",
|
||||
GetChannelSize,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetChannelSubjectField",
|
||||
strings.ToUpper("Get"),
|
||||
"/content/channels/{channelId}/subject/{field}",
|
||||
GetChannelSubjectField,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetChannelTopicDetail",
|
||||
strings.ToUpper("Get"),
|
||||
"/content/channels/{channelId}/topics/{topicId}/detail",
|
||||
GetChannelTopicDetail,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetChannelTopicSize",
|
||||
strings.ToUpper("Get"),
|
||||
"/content/channels/{channelId}/topics/{topicId}/size",
|
||||
GetChannelTopicSize,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetChannelTopicSubjectField",
|
||||
strings.ToUpper("Get"),
|
||||
"/content/channels/{channelId}/topics/{topicId}/subject/{field}",
|
||||
GetChannelTopicSubjectField,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetChannelTopicTagSubjectField",
|
||||
strings.ToUpper("Get"),
|
||||
"/content/channels/{channelId}/topics/{topicId}/tags/{tagId}/subject/{field}",
|
||||
GetChannelTopicTagSubjectField,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetChannelTopicTags",
|
||||
strings.ToUpper("Get"),
|
||||
"/content/channels/{channelId}/topics/{topicId}/tags",
|
||||
GetChannelTopicTags,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetChannelTopics",
|
||||
strings.ToUpper("Get"),
|
||||
"/content/channels/{channelId}/topics",
|
||||
GetChannelTopics,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetChannels",
|
||||
strings.ToUpper("Get"),
|
||||
"/content/channels",
|
||||
GetChannels,
|
||||
},
|
||||
|
||||
Route{
|
||||
"RemoveChannel",
|
||||
strings.ToUpper("Delete"),
|
||||
"/content/articles/{articleId}/labels/{labelId}",
|
||||
ClearArticleLabel,
|
||||
"/content/channels/{channelId}",
|
||||
RemoveChannel,
|
||||
},
|
||||
|
||||
Route{
|
||||
"ClearLabelGroup",
|
||||
"RemoveChannelAsset",
|
||||
strings.ToUpper("Delete"),
|
||||
"/content/labels/{labelId}/groups/{groupId}",
|
||||
ClearLabelGroup,
|
||||
"/content/channels/{channelId}/topics/{topicId}/assets/{assetId}",
|
||||
RemoveChannelAsset,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetArticle",
|
||||
strings.ToUpper("Get"),
|
||||
"/content/articles/{articleId}",
|
||||
GetArticle,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetArticleAsset",
|
||||
strings.ToUpper("Get"),
|
||||
"/content/articles/{articleId}/assets/{assetId}",
|
||||
GetArticleAsset,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetArticleAssets",
|
||||
strings.ToUpper("Get"),
|
||||
"/content/articles/{articleId}/assets",
|
||||
GetArticleAssets,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetArticleSubjectField",
|
||||
strings.ToUpper("Get"),
|
||||
"/content/articles/{articleId}/subject/{field}",
|
||||
GetArticleSubjectField,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetArticleTag",
|
||||
strings.ToUpper("Get"),
|
||||
"/content/articles/{articleId}/tags/{tagId}",
|
||||
GetArticleTag,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetArticleTagBlockView",
|
||||
strings.ToUpper("Get"),
|
||||
"/content/articles/{articleId}/tagBlocks/view",
|
||||
GetArticleTagBlockView,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetArticleTagSubjectField",
|
||||
strings.ToUpper("Get"),
|
||||
"/content/articles/{articleId}/tags/{tagId}/subject/{field}",
|
||||
GetArticleTagSubjectField,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetArticleTagView",
|
||||
strings.ToUpper("Get"),
|
||||
"/content/articles/{articleId}/tagBlocks/{blockId}/view",
|
||||
GetArticleTagView,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetArticleTags",
|
||||
strings.ToUpper("Get"),
|
||||
"/content/articles/{articleId}/tagBlocks/{blockId}",
|
||||
GetArticleTags,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetArticles",
|
||||
strings.ToUpper("Get"),
|
||||
"/content/articles",
|
||||
GetArticles,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetLabels",
|
||||
strings.ToUpper("Get"),
|
||||
"/content/labels",
|
||||
GetLabels,
|
||||
},
|
||||
|
||||
Route{
|
||||
"RemoveArticle",
|
||||
"RemoveChannelTopic",
|
||||
strings.ToUpper("Delete"),
|
||||
"/content/articles/{articleId}",
|
||||
RemoveArticle,
|
||||
"/content/channels/{channelId}/topics/{topicId}",
|
||||
RemoveChannelTopic,
|
||||
},
|
||||
|
||||
Route{
|
||||
"RemoveArticleAsset",
|
||||
"RemoveChannelTopicTag",
|
||||
strings.ToUpper("Delete"),
|
||||
"/content/articles/{articleId}/assets/{assetId}",
|
||||
RemoveArticleAsset,
|
||||
"/content/channels/{channelId}/topics/{topicId}/tags/{tagId}",
|
||||
RemoveChannelTopicTag,
|
||||
},
|
||||
|
||||
Route{
|
||||
"RemoveArticleTag",
|
||||
strings.ToUpper("Delete"),
|
||||
"/content/articles/{articleId}/tags/{tagId}",
|
||||
RemoveArticleTag,
|
||||
},
|
||||
|
||||
Route{
|
||||
"RemoveLabel",
|
||||
strings.ToUpper("Delete"),
|
||||
"/content/labels/{labelId}",
|
||||
RemoveLabel,
|
||||
},
|
||||
|
||||
Route{
|
||||
"SetArticleConfirmed",
|
||||
"SetChannelConfirmed",
|
||||
strings.ToUpper("Put"),
|
||||
"/content/articles/{articleId}/confirmed",
|
||||
SetArticleConfirmed,
|
||||
"/content/channels/{channelId}/topics/{topicId}/confirmed",
|
||||
SetChannelConfirmed,
|
||||
},
|
||||
|
||||
Route{
|
||||
"SetArticleExpiration",
|
||||
"SetChannelGroup",
|
||||
strings.ToUpper("Put"),
|
||||
"/content/articles/{articleId}/expiration",
|
||||
SetArticleExpiration,
|
||||
"/content/channels/{channelId}/groups/{groupId}",
|
||||
SetChannelGroup,
|
||||
},
|
||||
|
||||
Route{
|
||||
"SetArticleGroup",
|
||||
strings.ToUpper("Post"),
|
||||
"/content/articles/{articleId}/groups/{groupId}",
|
||||
SetArticleGroup,
|
||||
},
|
||||
|
||||
Route{
|
||||
"SetArticleLabel",
|
||||
strings.ToUpper("Post"),
|
||||
"/content/articles/{articleId}/labels/{labelId}",
|
||||
SetArticleLabel,
|
||||
},
|
||||
|
||||
Route{
|
||||
"SetArticleSubject",
|
||||
"SetChannelSubject",
|
||||
strings.ToUpper("Put"),
|
||||
"/content/articles/{articleId}/subject",
|
||||
SetArticleSubject,
|
||||
"/content/channels/{channelId}/subject",
|
||||
SetChannelSubject,
|
||||
},
|
||||
|
||||
Route{
|
||||
"SetLabelGroup",
|
||||
strings.ToUpper("Post"),
|
||||
"/content/labels/{labelId}/groups/{groupId}",
|
||||
SetLabelGroup,
|
||||
},
|
||||
|
||||
Route{
|
||||
"UpdateLabel",
|
||||
"SetChannelTopicSubject",
|
||||
strings.ToUpper("Put"),
|
||||
"/content/labels/{labelId}",
|
||||
UpdateLabel,
|
||||
"/content/channels/{channelId}/topics/{topicId}/subject",
|
||||
SetChannelTopicSubject,
|
||||
},
|
||||
|
||||
Route{
|
||||
"AddDialogue",
|
||||
strings.ToUpper("Post"),
|
||||
"/conversation/dialogues",
|
||||
AddDialogue,
|
||||
},
|
||||
|
||||
Route{
|
||||
"AddDialogueInsight",
|
||||
"SetChannelTopicTagSubject",
|
||||
strings.ToUpper("Put"),
|
||||
"/conversation/dialogues/{dialogueId}/cards/{cardId}",
|
||||
AddDialogueInsight,
|
||||
},
|
||||
|
||||
Route{
|
||||
"AddDialogueTopic",
|
||||
strings.ToUpper("Post"),
|
||||
"/conversation/dialogues/{dialogueId}/topics",
|
||||
AddDialogueTopic,
|
||||
},
|
||||
|
||||
Route{
|
||||
"AddInsightDialogue",
|
||||
strings.ToUpper("Post"),
|
||||
"/conversation/insights/{dialogueId}",
|
||||
AddInsightDialogue,
|
||||
},
|
||||
|
||||
Route{
|
||||
"AddTopicAsset",
|
||||
strings.ToUpper("Post"),
|
||||
"/conversation/dialogues/{dialogueId}/topics/{topicId}/assets",
|
||||
AddTopicAsset,
|
||||
},
|
||||
|
||||
Route{
|
||||
"AddTopicTag",
|
||||
strings.ToUpper("Post"),
|
||||
"/conversation/dialogues/{dialogueId}/topics/{topicId}/tags",
|
||||
AddTopicTag,
|
||||
},
|
||||
|
||||
Route{
|
||||
"ConversationDialoguesDialogueIdTopicsTopicIdConfirmedPut",
|
||||
strings.ToUpper("Put"),
|
||||
"/conversation/dialogues/{dialogueId}/topics/{topicId}/confirmed",
|
||||
ConversationDialoguesDialogueIdTopicsTopicIdConfirmedPut,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetDialogueTopic",
|
||||
strings.ToUpper("Get"),
|
||||
"/conversation/dialogues/{dialogueId}/topics/{topicId}",
|
||||
GetDialogueTopic,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetDialogueTopicSubjectField",
|
||||
strings.ToUpper("Get"),
|
||||
"/conversation/dialogues/{dialogueId}/topics/{topicId}/subject/{field}",
|
||||
GetDialogueTopicSubjectField,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetDialogues",
|
||||
strings.ToUpper("Get"),
|
||||
"/conversation/dialogues",
|
||||
GetDialogues,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetInsights",
|
||||
strings.ToUpper("Get"),
|
||||
"/conversation/insights",
|
||||
GetInsights,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetTopicAsset",
|
||||
strings.ToUpper("Get"),
|
||||
"/conversation/dialogues/{dialogueId}/topics/{topicId}/assets/{assetId}",
|
||||
GetTopicAsset,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetTopicAssets",
|
||||
strings.ToUpper("Get"),
|
||||
"/conversation/dialogues/{dialogueId}/topics/{topicId}/assets",
|
||||
GetTopicAssets,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetTopicBlock",
|
||||
strings.ToUpper("Get"),
|
||||
"/conversation/dialogues/{dialogueId}/topicBlocks/{blockId}",
|
||||
GetTopicBlock,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetTopicBlockView",
|
||||
strings.ToUpper("Get"),
|
||||
"/conversation/dialogues/{dialogueId}/topicBlocks/view",
|
||||
GetTopicBlockView,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetTopicTag",
|
||||
strings.ToUpper("Get"),
|
||||
"/conversation/dialogues/{dialogueId}/topics/{topicId}/tags/{tagId}",
|
||||
GetTopicTag,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetTopicTagBlockView",
|
||||
strings.ToUpper("Get"),
|
||||
"/conversation/dialogues/{dialogueId}/topics/{topicId}/tagBlocks/view",
|
||||
GetTopicTagBlockView,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetTopicTagSubjectField",
|
||||
strings.ToUpper("Get"),
|
||||
"/conversation/dialogues/{dialogueId}/topics/{topicId}/tags/{tagId}/subject/{field}",
|
||||
GetTopicTagSubjectField,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetTopicTagView",
|
||||
strings.ToUpper("Get"),
|
||||
"/conversation/dialogues/{dialogueId}/topics/{topicId}/tagBlocks/{blockId}/view",
|
||||
GetTopicTagView,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetTopicTags",
|
||||
strings.ToUpper("Get"),
|
||||
"/conversation/dialogues/{dialogueId}/topics/{topicId}/tagBlocks/{blockId}",
|
||||
GetTopicTags,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetTopicViews",
|
||||
strings.ToUpper("Get"),
|
||||
"/conversation/dialogues/{dialogueId}/topicBlocks/{blockId}/view",
|
||||
GetTopicViews,
|
||||
},
|
||||
|
||||
Route{
|
||||
"RemoveDialogue",
|
||||
strings.ToUpper("Delete"),
|
||||
"/conversation/dialogues/{dialogueId}",
|
||||
RemoveDialogue,
|
||||
},
|
||||
|
||||
Route{
|
||||
"RemoveDialogueInsight",
|
||||
strings.ToUpper("Delete"),
|
||||
"/conversation/dialogues/{dialogueId}/cards/{cardId}",
|
||||
RemoveDialogueInsight,
|
||||
},
|
||||
|
||||
Route{
|
||||
"RemoveDialogueTopic",
|
||||
strings.ToUpper("Delete"),
|
||||
"/conversation/dialogues/{dialogueId}/topics/{topicId}",
|
||||
RemoveDialogueTopic,
|
||||
},
|
||||
|
||||
Route{
|
||||
"RemoveTopicAsset",
|
||||
strings.ToUpper("Delete"),
|
||||
"/conversation/dialogues/{dialogueId}/topics/{topicId}/assets/{assetId}",
|
||||
RemoveTopicAsset,
|
||||
},
|
||||
|
||||
Route{
|
||||
"RemoveTopicTag",
|
||||
strings.ToUpper("Delete"),
|
||||
"/conversation/dialogues/{dialogueId}/topics/{topicId}/tags/{tagId}",
|
||||
RemoveTopicTag,
|
||||
},
|
||||
|
||||
Route{
|
||||
"SetDialogueActive",
|
||||
strings.ToUpper("Put"),
|
||||
"/conversation/dialogues/{dialogueId}/active",
|
||||
SetDialogueActive,
|
||||
},
|
||||
|
||||
Route{
|
||||
"SetDialogueInsightStatus",
|
||||
strings.ToUpper("Put"),
|
||||
"/conversation/dialogues/{dialogueId}/status",
|
||||
SetDialogueInsightStatus,
|
||||
},
|
||||
|
||||
Route{
|
||||
"SetDialogueSubject",
|
||||
strings.ToUpper("Put"),
|
||||
"/conversation/dialogues/{dialogueId}/subject",
|
||||
SetDialogueSubject,
|
||||
},
|
||||
|
||||
Route{
|
||||
"SetInsightDialogue",
|
||||
strings.ToUpper("Delete"),
|
||||
"/conversation/insights/{dialogueId}",
|
||||
SetInsightDialogue,
|
||||
},
|
||||
|
||||
Route{
|
||||
"SetInsightStatus",
|
||||
strings.ToUpper("Put"),
|
||||
"/conversation/insights/{insightId}/status",
|
||||
SetInsightStatus,
|
||||
},
|
||||
|
||||
Route{
|
||||
"SetTopicSubject",
|
||||
strings.ToUpper("Put"),
|
||||
"/conversation/dialogues/{dialogueId}/topics/{topicId}/subject",
|
||||
SetTopicSubject,
|
||||
"/content/channels/{channelId}/topics/{topicId}/tags/{tagId}/subject",
|
||||
SetChannelTopicTagSubject,
|
||||
},
|
||||
|
||||
Route{
|
||||
@ -880,34 +705,6 @@ var routes = Routes{
|
||||
SetProfileImage,
|
||||
},
|
||||
|
||||
Route{
|
||||
"AddGroup",
|
||||
strings.ToUpper("Post"),
|
||||
"/share/groups",
|
||||
AddGroup,
|
||||
},
|
||||
|
||||
Route{
|
||||
"GetGroups",
|
||||
strings.ToUpper("Get"),
|
||||
"/share/groups",
|
||||
GetGroups,
|
||||
},
|
||||
|
||||
Route{
|
||||
"RemoveGroup",
|
||||
strings.ToUpper("Delete"),
|
||||
"/share/groups/{groupId}",
|
||||
RemoveGroup,
|
||||
},
|
||||
|
||||
Route{
|
||||
"UpdateGroup",
|
||||
strings.ToUpper("Put"),
|
||||
"/share/groups/{groupId}",
|
||||
UpdateGroup,
|
||||
},
|
||||
|
||||
Route{
|
||||
"Status",
|
||||
strings.ToUpper("Get"),
|
||||
|
@ -65,12 +65,10 @@ type Account struct {
|
||||
Username string `gorm:"not null;uniqueIndex"`
|
||||
Password []byte `gorm:"not null"`
|
||||
ProfileRevision int64 `gorm:"not null;default:1"`
|
||||
ContentRevision int64 `gorm:"not null;default:1"`
|
||||
ArticleRevision int64 `gorm:"not null;default:1"`
|
||||
GroupRevision int64 `gorm:"not null;default:1"`
|
||||
LabelRevision int64 `gorm:"not null;default:1"`
|
||||
ChannelRevision int64 `gorm:"not null;default:1"`
|
||||
CardRevision int64 `gorm:"not null;default:1"`
|
||||
DialogueRevision int64 `gorm:"not null;default:1"`
|
||||
InsightRevision int64 `gorm:"not null;default:1"`
|
||||
Created int64 `gorm:"autoCreateTime"`
|
||||
Disabled bool `gorm:"not null;default:false"`
|
||||
AccountDetail AccountDetail
|
||||
@ -183,8 +181,8 @@ type Card struct {
|
||||
Updated int64 `gorm:"autoUpdateTime"`
|
||||
ViewRevision int64 `gorm:"not null;default:1"`
|
||||
NotifiedView int64
|
||||
NotifiedContent int64
|
||||
NotifiedLabel int64
|
||||
NotifiedArticle int64
|
||||
NotifiedChannel int64
|
||||
NotifiedProfile int64
|
||||
Account Account `gorm:"references:Guid"`
|
||||
Groups []Group `gorm:"many2many:card_groups"`
|
||||
|
@ -112,8 +112,6 @@ func SendEndpointTest(
|
||||
//
|
||||
func AddTestGroup(prefix string) (*TestGroup, error) {
|
||||
var err error
|
||||
var rev *Revision
|
||||
var ws *websocket.Conn
|
||||
|
||||
// allocate contacts
|
||||
g := &TestGroup{}
|
||||
@ -130,134 +128,12 @@ func AddTestGroup(prefix string) (*TestGroup, error) {
|
||||
return g, err
|
||||
}
|
||||
|
||||
// setup A
|
||||
if g.A.B.CardId, err = AddTestCard(g.A.Token, g.B.Token); err != nil {
|
||||
return g, err
|
||||
}
|
||||
if err = OpenTestCard(g.A.Token, g.A.B.CardId); err != nil {
|
||||
return g, err
|
||||
}
|
||||
if g.A.B.GroupId, err = GroupTestCard(g.A.Token, g.A.B.CardId); err != nil {
|
||||
return g, err
|
||||
}
|
||||
if g.A.C.CardId, err = AddTestCard(g.A.Token, g.C.Token); err != nil {
|
||||
return g, err
|
||||
}
|
||||
if err = OpenTestCard(g.A.Token, g.A.C.CardId); err != nil {
|
||||
return g, err
|
||||
}
|
||||
if g.A.C.GroupId, err = GroupTestCard(g.A.Token, g.A.C.CardId); err != nil {
|
||||
return g, err
|
||||
}
|
||||
if g.A.D.CardId, err = AddTestCard(g.A.Token, g.D.Token); err != nil {
|
||||
return g, err
|
||||
}
|
||||
if err = OpenTestCard(g.A.Token, g.A.D.CardId); err != nil {
|
||||
return g, err
|
||||
}
|
||||
|
||||
// setup B
|
||||
if g.B.A.CardId, err = AddTestCard(g.B.Token, g.A.Token); err != nil {
|
||||
return g, err
|
||||
}
|
||||
if err = OpenTestCard(g.B.Token, g.B.A.CardId); err != nil {
|
||||
return g, err
|
||||
}
|
||||
if g.B.A.GroupId, err = GroupTestCard(g.B.Token, g.B.A.CardId); err != nil {
|
||||
return g, err
|
||||
}
|
||||
if g.B.C.CardId, err = AddTestCard(g.B.Token, g.C.Token); err != nil {
|
||||
return g, err
|
||||
}
|
||||
if g.B.C.GroupId, err = GroupTestCard(g.B.Token, g.B.C.CardId); err != nil {
|
||||
return g, err
|
||||
}
|
||||
|
||||
// setup C
|
||||
if g.C.D.CardId, err = AddTestCard(g.C.Token, g.D.Token); err != nil {
|
||||
return g, err
|
||||
}
|
||||
if err = OpenTestCard(g.C.Token, g.C.D.CardId); err != nil {
|
||||
return g, err
|
||||
}
|
||||
if g.C.D.GroupId, err = GroupTestCard(g.C.Token, g.C.D.CardId); err != nil {
|
||||
return g, err
|
||||
}
|
||||
if g.C.A.CardId, err = AddTestCard(g.C.Token, g.A.Token); err != nil {
|
||||
return g, err
|
||||
}
|
||||
if err = OpenTestCard(g.C.Token, g.C.A.CardId); err != nil {
|
||||
return g, err
|
||||
}
|
||||
if g.C.A.GroupId, err = GroupTestCard(g.C.Token, g.C.A.CardId); err != nil {
|
||||
return g, err
|
||||
}
|
||||
if g.C.B.CardId, err = AddTestCard(g.C.Token, g.B.Token); err != nil {
|
||||
return g, err
|
||||
}
|
||||
|
||||
// setup D
|
||||
if g.D.C.CardId, err = AddTestCard(g.D.Token, g.C.Token); err != nil {
|
||||
return g, err
|
||||
}
|
||||
if err = OpenTestCard(g.D.Token, g.D.C.CardId); err != nil {
|
||||
return g, err
|
||||
}
|
||||
if g.D.C.GroupId, err = GroupTestCard(g.D.Token, g.D.C.CardId); err != nil {
|
||||
return g, err
|
||||
}
|
||||
|
||||
// get contact tokens
|
||||
if g.A.B.Token, err = GetCardToken(g.A.Token, g.A.B.CardId); err != nil {
|
||||
return g, err
|
||||
}
|
||||
|
||||
if g.B.A.Token, err = GetCardToken(g.B.Token, g.B.A.CardId); err != nil {
|
||||
return g, err
|
||||
}
|
||||
if g.C.A.Token, err = GetCardToken(g.C.Token, g.C.A.CardId); err != nil {
|
||||
return g, err
|
||||
}
|
||||
if g.C.D.Token, err = GetCardToken(g.C.Token, g.C.D.CardId); err != nil {
|
||||
return g, err
|
||||
}
|
||||
if g.D.C.Token, err = GetCardToken(g.D.Token, g.D.C.CardId); err != nil {
|
||||
return g, err
|
||||
}
|
||||
|
||||
// connect websockets
|
||||
rev = &Revision{}
|
||||
if ws, err = StatusConnection(g.A.Token, rev); err != nil {
|
||||
return g, err
|
||||
}
|
||||
g.A.Revisions = make(chan *Revision, 64)
|
||||
g.A.Revisions <- rev
|
||||
go MonitorStatus(ws, &g.A);
|
||||
rev = &Revision{}
|
||||
if ws, err = StatusConnection(g.B.Token, rev); err != nil {
|
||||
return g, err
|
||||
}
|
||||
g.B.Revisions = make(chan *Revision, 64)
|
||||
g.B.Revisions <- rev
|
||||
go MonitorStatus(ws, &g.B);
|
||||
rev = &Revision{}
|
||||
if ws, err = StatusConnection(g.C.Token, rev); err != nil {
|
||||
return g, err
|
||||
}
|
||||
g.C.Revisions = make(chan *Revision, 64)
|
||||
g.C.Revisions <- rev
|
||||
go MonitorStatus(ws, &g.C);
|
||||
rev = &Revision{}
|
||||
if ws, err = StatusConnection(g.D.Token, rev); err != nil {
|
||||
return g, err
|
||||
}
|
||||
g.D.Revisions = make(chan *Revision, 64)
|
||||
g.D.Revisions <- rev
|
||||
go MonitorStatus(ws, &g.D);
|
||||
|
||||
return g, nil
|
||||
}
|
||||
|
||||
|
||||
func MonitorStatus(ws *websocket.Conn, contact *TestContact) {
|
||||
var data []byte
|
||||
var dataType int
|
||||
@ -288,24 +164,36 @@ func MonitorStatus(ws *websocket.Conn, contact *TestContact) {
|
||||
func GetCardToken(account string, cardId string) (token string, err error) {
|
||||
var r *http.Request
|
||||
var w *httptest.ResponseRecorder
|
||||
var card Card
|
||||
var cardDetail CardDetail
|
||||
var cardProfile CardProfile
|
||||
vars := make(map[string]string)
|
||||
vars["cardId"] = cardId
|
||||
|
||||
if r, w, err = NewRequest("GET", "/contact/cards/{cardId}", nil); err != nil {
|
||||
if r, w, err = NewRequest("GET", "/contact/cards/{cardId}/detail", nil); err != nil {
|
||||
return
|
||||
}
|
||||
vars["cardId"] = cardId
|
||||
r = mux.SetURLVars(r, vars)
|
||||
SetBearerAuth(r, account)
|
||||
GetCard(w, r)
|
||||
if err = ReadResponse(w, &card); err != nil {
|
||||
GetCardDetail(w, r)
|
||||
if err = ReadResponse(w, &cardDetail); err != nil {
|
||||
return
|
||||
}
|
||||
if card.CardData.Status != APP_CARDCONNECTED {
|
||||
if cardDetail.Status != APP_CARDCONNECTED {
|
||||
err = errors.New("card not connected")
|
||||
return
|
||||
}
|
||||
token = card.CardData.Guid + "." + card.CardData.Token
|
||||
|
||||
if r, w, err = NewRequest("GET", "/contact/cards/{cardId}/profile", nil); err != nil {
|
||||
return
|
||||
}
|
||||
r = mux.SetURLVars(r, vars)
|
||||
SetBearerAuth(r, account)
|
||||
GetCardProfile(w, r)
|
||||
if err = ReadResponse(w, &cardProfile); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
token = cardProfile.Guid + "." + cardDetail.Token
|
||||
return
|
||||
}
|
||||
|
||||
@ -330,13 +218,13 @@ func GroupTestCard(account string, cardId string) (groupId string, err error) {
|
||||
if err = ReadResponse(w, &group); err != nil {
|
||||
return
|
||||
}
|
||||
groupId = group.GroupId
|
||||
groupId = group.Id
|
||||
|
||||
// set contact group
|
||||
if r, w, err = NewRequest("PUT", "/contact/cards/{cardId}/groups/{groupId}", nil); err != nil {
|
||||
return
|
||||
}
|
||||
vars["groupId"] = group.GroupId
|
||||
vars["groupId"] = group.Id
|
||||
vars["cardId"] = cardId
|
||||
r = mux.SetURLVars(r, vars)
|
||||
SetBearerAuth(r, account)
|
||||
@ -389,10 +277,10 @@ func OpenTestCard(account string, cardId string) (err error) {
|
||||
// update status if connected
|
||||
if contactStatus.Status == APP_CARDCONNECTED {
|
||||
view := "viewRevision=" + strconv.FormatInt(contactStatus.ViewRevision, 10)
|
||||
content := "contentRevision=" + strconv.FormatInt(contactStatus.ContentRevision, 10)
|
||||
label := "labelRevision=" + strconv.FormatInt(contactStatus.LabelRevision, 10)
|
||||
article := "articleRevision=" + strconv.FormatInt(contactStatus.ArticleRevision, 10)
|
||||
channel := "channelRevision=" + strconv.FormatInt(contactStatus.ChannelRevision, 10)
|
||||
profile := "profileRevision=" + strconv.FormatInt(contactStatus.ProfileRevision, 10)
|
||||
if r, w, err = NewRequest("PUT", "/contact/cards/{cardId}/status?token=" + contactStatus.Token + "&" + view + "&" + content + "&" + label + "&" + profile, APP_CARDCONNECTED); err != nil {
|
||||
if r, w, err = NewRequest("PUT", "/contact/cards/{cardId}/status?token=" + contactStatus.Token + "&" + view + "&" + article + "&" + channel + "&" + profile, APP_CARDCONNECTED); err != nil {
|
||||
return
|
||||
}
|
||||
r = mux.SetURLVars(r, vars)
|
||||
@ -431,7 +319,7 @@ func AddTestCard(account string, contact string) (cardId string, err error) {
|
||||
if err = ReadResponse(w, &card); err != nil {
|
||||
return
|
||||
}
|
||||
cardId = card.CardId
|
||||
cardId = card.Id
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1,165 +0,0 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"strconv"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestAddArticle(t *testing.T) {
|
||||
var set *TestGroup
|
||||
var err error
|
||||
var rev *Revision
|
||||
var ver *Revision
|
||||
var article *Article
|
||||
var articles *[]Article
|
||||
var articleAccess *ArticleAccess
|
||||
var cards []Card
|
||||
var label *Label
|
||||
var subject *Subject
|
||||
var vars *map[string]string
|
||||
var contentRevision int64
|
||||
var viewRevision int64
|
||||
var labelRevision int64
|
||||
var labels *[]Label
|
||||
var view int64
|
||||
var header map[string][]string
|
||||
|
||||
// setup testing group
|
||||
set, err = AddTestGroup("addarticle")
|
||||
assert.NoError(t, err)
|
||||
|
||||
// initial revision
|
||||
rev = GetTestRevision(set.B.Revisions)
|
||||
|
||||
// create article
|
||||
articleAccess = &ArticleAccess{ Groups: []string{set.A.B.GroupId} }
|
||||
article = &Article{}
|
||||
assert.NoError(t, SendEndpointTest(AddArticle, "POST", "/content/articles", nil, articleAccess, APP_TOKENAPP, set.A.Token, article, nil))
|
||||
|
||||
article = &Article{}
|
||||
assert.NoError(t, SendEndpointTest(AddArticle, "POST", "/content/articles", nil, articleAccess, APP_TOKENAPP, set.A.Token, article, nil))
|
||||
|
||||
assert.NoError(t, SendEndpointTest(RemoveArticle, "DELETE", "/content/articls/" + article.ArticleId, &map[string]string{"articleId": article.ArticleId }, nil, APP_TOKENAPP, set.A.Token, nil, nil))
|
||||
|
||||
ver = GetTestRevision(set.B.Revisions)
|
||||
assert.NoError(t, SendEndpointTest(GetCards, "GET", "/contact/cards?cardRevision=" + strconv.FormatInt(rev.Card, 10), nil, nil, APP_TOKENAPP, set.B.Token, &cards, nil))
|
||||
assert.NotEqual(t, ver.Card, rev.Card)
|
||||
assert.Equal(t, 1, len(cards))
|
||||
rev = ver
|
||||
|
||||
articles = &[]Article{}
|
||||
assert.NoError(t, SendEndpointTest(GetArticles, "GET", "/content/articles", nil, nil, APP_TOKENAPP, set.A.Token, articles, nil))
|
||||
assert.Equal(t, 2, len(*articles))
|
||||
assert.True(t, (*articles)[0].ArticleData != nil || (*articles)[1].ArticleData != nil)
|
||||
assert.True(t, (*articles)[0].ArticleData == nil || (*articles)[1].ArticleData == nil)
|
||||
|
||||
articles = &[]Article{}
|
||||
assert.NoError(t, SendEndpointTest(GetArticles, "GET", "/content/articles", nil, nil, APP_TOKENCONTACT, set.B.A.Token, articles, &header))
|
||||
assert.Equal(t, 1, len(*articles))
|
||||
assert.True(t, (*articles)[0].ArticleData != nil)
|
||||
view, err = strconv.ParseInt(header["View-Revision"][0], 10, 64)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, view, cards[0].CardData.NotifiedView)
|
||||
|
||||
articles = &[]Article{}
|
||||
assert.NoError(t, SendEndpointTest(GetArticles, "GET", "/content/articles", nil, nil, APP_TOKENCONTACT, set.C.A.Token, articles, nil))
|
||||
assert.Equal(t, 0, len(*articles))
|
||||
|
||||
articles = &[]Article{}
|
||||
assert.NoError(t, SendEndpointTest(GetArticles, "GET", "/content/articles?contentRevision=0&viewRevision=" + strconv.FormatInt(cards[0].CardData.NotifiedView, 10), nil, nil, APP_TOKENCONTACT, set.B.A.Token, articles, nil))
|
||||
assert.Equal(t, 2, len(*articles))
|
||||
|
||||
ver = GetTestRevision(set.C.Revisions)
|
||||
|
||||
// add another article
|
||||
article = &Article{}
|
||||
articleAccess = &ArticleAccess{}
|
||||
assert.NoError(t, SendEndpointTest(AddArticle, "POST", "/content/articles", nil, articleAccess, APP_TOKENAPP, set.A.Token, article, nil))
|
||||
|
||||
// capture updated card on new article
|
||||
rev = GetTestRevision(set.C.Revisions)
|
||||
assert.NoError(t, SendEndpointTest(GetCards, "GET", "/contact/cards?cardRevision=" + strconv.FormatInt(ver.Card, 10), nil, nil, APP_TOKENAPP, set.C.Token, &cards, nil))
|
||||
assert.Equal(t, 1, len(cards))
|
||||
viewRevision = cards[0].CardData.NotifiedView
|
||||
contentRevision = cards[0].CardData.NotifiedContent
|
||||
labelRevision = cards[0].CardData.NotifiedLabel
|
||||
ver = rev
|
||||
|
||||
// create new label
|
||||
label = &Label{}
|
||||
subject = &Subject{ DataType: "labeltype", Data: "labeldata" }
|
||||
assert.NoError(t, SendEndpointTest(AddLabel, "POST", "/content/labels", nil, subject, APP_TOKENAPP, set.A.Token, label, nil))
|
||||
vars = &map[string]string{
|
||||
"labelId": label.LabelId,
|
||||
"groupId": set.A.C.GroupId,
|
||||
}
|
||||
label = &Label{}
|
||||
assert.NoError(t, SendEndpointTest(SetLabelGroup, "POST", "/content/labels/{labelId}/groups/{groupId}", vars, nil, APP_TOKENAPP, set.A.Token, label, nil))
|
||||
|
||||
// capture updated card on new assigned label
|
||||
rev = GetTestRevision(set.C.Revisions)
|
||||
assert.NoError(t, SendEndpointTest(GetCards, "GET", "/contact/cards?cardRevision=" + strconv.FormatInt(ver.Card, 10), nil, nil, APP_TOKENAPP, set.C.Token, &cards, nil))
|
||||
assert.Equal(t, 1, len(cards))
|
||||
assert.NotEqual(t, viewRevision, cards[0].CardData.NotifiedView)
|
||||
assert.NotEqual(t, labelRevision, cards[0].CardData.NotifiedLabel)
|
||||
viewRevision = cards[0].CardData.NotifiedView
|
||||
contentRevision = cards[0].CardData.NotifiedContent
|
||||
labelRevision = cards[0].CardData.NotifiedLabel
|
||||
ver = rev
|
||||
|
||||
// assign label to article
|
||||
vars = &map[string]string{
|
||||
"labelId": label.LabelId,
|
||||
"articleId": article.ArticleId,
|
||||
}
|
||||
article = &Article{}
|
||||
assert.NoError(t, SendEndpointTest(SetArticleLabel, "POST", "/content/articles/{articleId}/labels/{labelId}", vars, nil, APP_TOKENAPP, set.A.Token, article, nil))
|
||||
|
||||
// capture updated card on assigned article
|
||||
rev = GetTestRevision(set.C.Revisions)
|
||||
assert.NoError(t, SendEndpointTest(GetCards, "GET", "/contact/cards?cardRevision=" + strconv.FormatInt(ver.Card, 10), nil, nil, APP_TOKENAPP, set.C.Token, &cards, nil))
|
||||
assert.Equal(t, 1, len(cards))
|
||||
assert.NotEqual(t, contentRevision, cards[0].CardData.NotifiedContent)
|
||||
ver = rev
|
||||
|
||||
// confirm c can see new article
|
||||
articles = &[]Article{}
|
||||
assert.NoError(t, SendEndpointTest(GetArticles, "GET", "/content/articles", nil, nil, APP_TOKENCONTACT, set.C.A.Token, articles, nil))
|
||||
assert.Equal(t, 1, len(*articles))
|
||||
assert.Equal(t, (*articles)[0].ArticleId, article.ArticleId)
|
||||
assert.Equal(t, 1, len((*articles)[0].ArticleData.Labels))
|
||||
assert.Equal(t, (*articles)[0].ArticleData.Labels[0], label.LabelId)
|
||||
|
||||
// confirm b cannot see new article
|
||||
articles = &[]Article{}
|
||||
assert.NoError(t, SendEndpointTest(GetArticles, "GET", "/content/articles", nil, nil, APP_TOKENCONTACT, set.B.A.Token, articles, nil))
|
||||
assert.Equal(t, 1, len(*articles))
|
||||
assert.NotEqual(t, article.ArticleId, (*articles)[0].ArticleId)
|
||||
|
||||
labels = &[]Label{}
|
||||
assert.NoError(t, SendEndpointTest(GetLabels, "GET", "/content/labels", nil, nil, APP_TOKENAPP, set.A.Token, labels, nil))
|
||||
assert.Equal(t, 1, len(*labels))
|
||||
|
||||
labels = &[]Label{}
|
||||
assert.NoError(t, SendEndpointTest(GetLabels, "GET", "/content/labels", nil, nil, APP_TOKENCONTACT, set.B.A.Token, labels, nil))
|
||||
assert.Equal(t, 0, len(*labels))
|
||||
|
||||
labels = &[]Label{}
|
||||
assert.NoError(t, SendEndpointTest(GetLabels, "GET", "/content/labels", nil, nil, APP_TOKENCONTACT, set.C.A.Token, labels, &header))
|
||||
assert.Equal(t, 1, len(*labels))
|
||||
view, err = strconv.ParseInt(header["View-Revision"][0], 10, 64)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, cards[0].CardData.NotifiedView, view)
|
||||
|
||||
vars = &map[string]string{ "labelId": label.LabelId, }
|
||||
assert.NoError(t, SendEndpointTest(RemoveLabel, "DELETE", "/content/labels/{labelId}", vars, nil, APP_TOKENAPP, set.A.Token, nil, nil))
|
||||
|
||||
labels = &[]Label{}
|
||||
assert.NoError(t, SendEndpointTest(GetLabels, "GET", "/content/labels", nil, nil, APP_TOKENCONTACT, set.C.A.Token, labels, nil))
|
||||
assert.Equal(t, 0, len(*labels))
|
||||
|
||||
articles = &[]Article{}
|
||||
assert.NoError(t, SendEndpointTest(GetArticles, "GET", "/content/articles", nil, nil, APP_TOKENCONTACT, set.C.A.Token, articles, nil))
|
||||
assert.Equal(t, 0, len(*articles))
|
||||
}
|
@ -2,81 +2,11 @@ package databag
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"strconv"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestUpdateContact(t *testing.T) {
|
||||
var err error
|
||||
var set *TestGroup
|
||||
var rev *Revision
|
||||
var r *Revision
|
||||
var msg DataMessage
|
||||
var cards []Card
|
||||
var detail int64
|
||||
var profile int64
|
||||
var cardDetail *CardDetail
|
||||
var cardProfile *CardProfile
|
||||
|
||||
// setup testing group
|
||||
set, err = AddTestGroup("updatecontact")
|
||||
_, err := AddTestGroup("updatecontact")
|
||||
assert.NoError(t, err)
|
||||
|
||||
// setup testing group
|
||||
_, err = AddTestGroup("updatecontact")
|
||||
assert.Error(t, err)
|
||||
|
||||
rev = GetTestRevision(set.B.Revisions)
|
||||
|
||||
assert.NoError(t, SendEndpointTest(GetCards, "PUT", "/contact/cards", nil, nil, APP_TOKENAPP, set.B.Token, &cards, nil))
|
||||
|
||||
// update B profile
|
||||
profileData := ProfileData{
|
||||
Name: "Namer",
|
||||
Location: "San Francisco",
|
||||
Description: "databaggerr",
|
||||
};
|
||||
assert.NoError(t, SendEndpointTest(SetProfile, "PUT", "/profile/data", nil, &profileData, APP_TOKENAPP, set.A.Token, nil, nil))
|
||||
|
||||
r = GetTestRevision(set.B.Revisions)
|
||||
assert.NotEqual(t, rev.Card, r.Card)
|
||||
|
||||
assert.NoError(t, SendEndpointTest(GetCards, "GET", "/contact/cards?cardRevision=" + strconv.FormatInt(rev.Card, 10), nil, nil, APP_TOKENAPP, set.B.Token, &cards, nil))
|
||||
assert.Equal(t, 1, len(cards))
|
||||
assert.Equal(t, set.A.Guid, cards[0].CardData.Guid)
|
||||
profile = cards[0].CardData.ProfileRevision
|
||||
rev = r
|
||||
|
||||
cardProfile = &CardProfile{}
|
||||
assert.NoError(t, SendEndpointTest(GetProfileMessage, "GET", "/profile/message", nil, nil, APP_TOKENCONTACT, set.B.A.Token, &msg, nil))
|
||||
assert.NoError(t, SendEndpointTest(SetCardProfile, "PUT", "/contact/cards/{cardId}/profile", &map[string]string{"cardId":cards[0].CardId}, msg, APP_TOKENAPP, set.B.Token, cardProfile, nil))
|
||||
assert.Equal(t, "Namer", cardProfile.Name)
|
||||
|
||||
r = GetTestRevision(set.B.Revisions)
|
||||
assert.NotEqual(t, rev.Card, r.Card)
|
||||
|
||||
assert.NoError(t, SendEndpointTest(GetCards, "GET", "/contact/cards?cardRevision=" + strconv.FormatInt(rev.Card, 10), nil, nil, APP_TOKENAPP, set.B.Token, &cards, nil))
|
||||
assert.Equal(t, 1, len(cards))
|
||||
assert.Equal(t, set.A.Guid, cards[0].CardData.Guid)
|
||||
assert.NotEqual(t, profile, cards[0].CardData.ProfileRevision)
|
||||
detail = cards[0].CardData.DetailRevision
|
||||
rev = r
|
||||
|
||||
cardDetail = &CardDetail{}
|
||||
assert.NoError(t, SendEndpointTest(SetCardNotes, "PUT", "/contact/cards/{cardId}/notes", &map[string]string{"cardId":cards[0].CardId}, "some interesting notes", APP_TOKENAPP, set.B.Token, cardDetail, nil))
|
||||
assert.Equal(t, "some interesting notes", cardDetail.Notes)
|
||||
r = GetTestRevision(set.B.Revisions)
|
||||
assert.NotEqual(t, rev.Card, r.Card)
|
||||
rev = r
|
||||
|
||||
cardDetail = &CardDetail{}
|
||||
assert.NoError(t, SendEndpointTest(ClearCardNotes, "DELETE", "/contact/cards/{cardId}/notes", &map[string]string{"cardId":cards[0].CardId}, nil, APP_TOKENAPP, set.B.Token, cardDetail, nil))
|
||||
assert.Equal(t, "", cardDetail.Notes)
|
||||
r = GetTestRevision(set.B.Revisions)
|
||||
assert.NotEqual(t, rev.Card, r.Card)
|
||||
|
||||
assert.NoError(t, SendEndpointTest(GetCards, "GET", "/contact/cards?cardRevision=" + strconv.FormatInt(rev.Card, 10), nil, nil, APP_TOKENAPP, set.B.Token, &cards, nil))
|
||||
assert.Equal(t, 1, len(cards))
|
||||
assert.Equal(t, set.A.Guid, cards[0].CardData.Guid)
|
||||
assert.NotEqual(t, detail, cards[0].CardData.DetailRevision)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user