databag/net/server/internal/api_getChannels.go

168 lines
4.5 KiB
Go
Raw Normal View History

2022-02-15 23:17:06 +00:00
package databag
import (
"strings"
"errors"
"strconv"
"net/http"
"encoding/json"
"databag/internal/store"
)
func GetChannels(w http.ResponseWriter, r *http.Request) {
var channelRevisionSet bool
var channelRevision int64
var viewRevisionSet bool
var viewRevision int64
var typesSet bool
var types []string
channel := r.FormValue("channelRevision")
if channel != "" {
var err error
channelRevisionSet = true
if channelRevision, err = strconv.ParseInt(channel, 10, 64); err != nil {
ErrResponse(w, http.StatusBadRequest, err)
return
}
}
view := r.FormValue("viewRevision")
if view != "" {
var err error
viewRevisionSet = true
if viewRevision, err = strconv.ParseInt(view, 10, 64); err != nil {
ErrResponse(w, http.StatusBadRequest, err)
return
}
}
schemas := r.FormValue("types")
if schemas != "" {
var err error
typesSet = true
dec := json.NewDecoder(strings.NewReader(schemas))
if dec.Decode(&types) != nil {
ErrResponse(w, http.StatusBadRequest, err)
return
}
}
var response []*Channel
tokenType := r.Header.Get("TokenType")
if tokenType == APP_TOKENAGENT {
2022-02-15 23:17:06 +00:00
account, code, err := BearerAppToken(r, false);
if err != nil {
ErrResponse(w, code, err)
return
}
var slots []store.ChannelSlot
if channelRevisionSet {
2022-02-17 08:30:33 +00:00
if err := store.DB.Preload("Channel").Where("account_id = ? AND revision > ?", account.ID, channelRevision).Find(&slots).Error; err != nil {
2022-02-15 23:17:06 +00:00
ErrResponse(w, http.StatusInternalServerError, err)
return
}
} else {
2022-02-17 08:30:33 +00:00
if err := store.DB.Preload("Channel.Cards.CardSlot").Preload("Channel.Groups.GroupSlot").Where("account_id = ? AND channel_id != 0", account.ID).Find(&slots).Error; err != nil {
2022-02-15 23:17:06 +00:00
ErrResponse(w, http.StatusInternalServerError, err)
return
}
}
for _, slot := range slots {
if !typesSet || hasChannelType(types, slot.Channel) {
2022-02-16 08:00:07 +00:00
if channelRevisionSet {
response = append(response, getChannelRevisionModel(&slot, true))
} else if slot.Channel != nil {
response = append(response, getChannelModel(&slot, true, true))
}
2022-02-15 23:17:06 +00:00
}
}
w.Header().Set("Channel-Revision", strconv.FormatInt(account.ChannelRevision, 10))
} else if tokenType == APP_TOKENCONTACT {
card, code, err := BearerContactToken(r, true)
if err != nil {
ErrResponse(w, code, err)
return
}
if viewRevisionSet || channelRevisionSet {
if viewRevision != card.ViewRevision {
ErrResponse(w, http.StatusGone, errors.New("channel view has changed"))
return
}
}
account := &card.Account
var slots []store.ChannelSlot
if channelRevisionSet {
2022-02-16 08:00:07 +00:00
if err := store.DB.Preload("Channel.Cards").Preload("Channel.Groups.Cards").Where("account_id = ? AND revision > ?", account.ID, channelRevision).Find(&slots).Error; err != nil {
2022-02-15 23:17:06 +00:00
ErrResponse(w, http.StatusInternalServerError, err)
return
}
} else {
2022-02-16 08:00:07 +00:00
if err := store.DB.Preload("Channel.Cards").Preload("Channel.Groups.Cards").Where("account_id = ? AND channel_id != 0", account.ID).Find(&slots).Error; err != nil {
2022-02-15 23:17:06 +00:00
ErrResponse(w, http.StatusInternalServerError, err)
return
}
}
for _, slot := range slots {
if !typesSet || hasChannelType(types, slot.Channel) {
2022-02-23 06:11:56 +00:00
shared := isChannelShared(card.Guid, slot.Channel)
2022-02-16 08:00:07 +00:00
if channelRevisionSet {
response = append(response, getChannelRevisionModel(&slot, shared))
} else if shared {
response = append(response, getChannelModel(&slot, true, false))
}
2022-02-15 23:17:06 +00:00
}
}
w.Header().Set("Channel-Revision", strconv.FormatInt(account.ChannelRevision, 10))
w.Header().Set("View-Revision", strconv.FormatInt(card.ViewRevision, 10))
} else {
ErrResponse(w, http.StatusBadRequest, errors.New("invalid token type"))
return
}
WriteResponse(w, response)
}
func isChannelShared(guid string, channel *store.Channel) bool {
if channel == nil {
return false
}
for _, card := range channel.Cards {
if guid == card.Guid {
return true
}
}
for _, group := range channel.Groups {
for _, card := range group.Cards {
if guid == card.Guid {
return true
}
}
}
return false
}
func hasChannelType(types []string, channel *store.Channel) bool {
if channel == nil {
return false
}
for _, schema := range types {
if schema == channel.DataType {
return true
}
}
return false
}