mirror of
https://github.com/balzack/databag.git
synced 2025-02-14 20:49:16 +00:00
117 lines
3.1 KiB
Go
117 lines
3.1 KiB
Go
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
|
|
}
|
|
|
|
|
|
|
|
|