mirror of
https://github.com/balzack/databag.git
synced 2025-03-13 00:50:03 +00:00
testing group removal
This commit is contained in:
parent
3b85a6e023
commit
ea17a74c99
@ -1,30 +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 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)
|
||||
}
|
||||
|
49
net/server/internal/api_getGroups.go
Normal file
49
net/server/internal/api_getGroups.go
Normal file
@ -0,0 +1,49 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"net/http"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func GetGroups(w http.ResponseWriter, r *http.Request) {
|
||||
var groupRevisionSet bool
|
||||
var groupRevision int64
|
||||
|
||||
account, code, err := BearerAppToken(r, false);
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
|
||||
group := r.FormValue("revision")
|
||||
if group != "" {
|
||||
groupRevisionSet = true
|
||||
if groupRevision, err = strconv.ParseInt(group, 10, 64); err != nil {
|
||||
ErrResponse(w, http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var slots []store.GroupSlot
|
||||
if groupRevisionSet {
|
||||
if err := store.DB.Preload("Group.GroupData").Where("account_id = ? AND revision > ?", account.ID, groupRevision).Find(&slots).Error; err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if err := store.DB.Preload("Group.GroupData").Where("account_id = ? AND group_id != 0", account.ID).Find(&slots).Error; err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var response []*Group
|
||||
for _, slot := range slots {
|
||||
response = append(response, getGroupModel(&slot))
|
||||
}
|
||||
|
||||
w.Header().Set("Group-Revision", strconv.FormatInt(account.GroupRevision, 10))
|
||||
WriteResponse(w, response)
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ func RemoveCard(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// 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 err := store.DB.Preload("Card.Groups").Preload("Card.Channels.ChannelSlot").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 {
|
||||
@ -37,7 +37,14 @@ func RemoveCard(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// save and update contact revision
|
||||
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
||||
// TODO clear from channels
|
||||
for _, channel := range slot.Card.Channels {
|
||||
if res := tx.Model(&channel).Association("Cards").Delete(&slot.Card); res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Model(&channel.ChannelSlot).Update("revision", account.ChannelRevision + 1).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
}
|
||||
if res := tx.Model(&slot.Card).Association("Groups").Clear(); res != nil {
|
||||
return res
|
||||
}
|
||||
@ -54,6 +61,9 @@ func RemoveCard(w http.ResponseWriter, r *http.Request) {
|
||||
if res := tx.Model(&account).Update("card_revision", account.CardRevision + 1).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Model(&account).Update("channel_revision", account.ChannelRevision + 1).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
@ -61,6 +71,7 @@ func RemoveCard(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
SetChannelNotification(account)
|
||||
SetStatus(account)
|
||||
WriteResponse(w, nil);
|
||||
}
|
||||
|
94
net/server/internal/api_removeGroup.go
Normal file
94
net/server/internal/api_removeGroup.go
Normal file
@ -0,0 +1,94 @@
|
||||
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
|
||||
}
|
||||
|
||||
// scan parameters
|
||||
params := mux.Vars(r)
|
||||
groupId := params["groupId"]
|
||||
|
||||
// load referenced group
|
||||
var slot store.GroupSlot
|
||||
if err := store.DB.Preload("Group.Cards.CardSlot").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("group has been deleted"))
|
||||
return
|
||||
}
|
||||
|
||||
var cards []*store.Card
|
||||
for _, card := range slot.Group.Cards {
|
||||
cards = append(cards, &card)
|
||||
}
|
||||
|
||||
// save and update contact revision
|
||||
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if res := tx.Model(&slot.Group).Association("Channels").Clear(); res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Model(&slot.Group).Association("Articles").Clear(); res != nil {
|
||||
return res
|
||||
}
|
||||
for _, card := range cards {
|
||||
if res := tx.Model(card).Update("view_revision", card.ViewRevision + 1).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Model(card).Update("detail_revision", card.DetailRevision + 1).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Model(card.CardSlot).Update("revision", account.CardRevision + 1).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
}
|
||||
if res := tx.Model(&slot.Group).Association("Cards").Clear(); res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Delete(&slot.Group).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
slot.Group = nil
|
||||
if res := tx.Model(&slot).Update("group_id", 0).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Model(&slot).Update("revision", account.GroupRevision + 1).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Model(&account).Update("group_revision", account.GroupRevision + 1).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
|
||||
}
|
||||
|
||||
for _, card := range cards {
|
||||
SetContactViewNotification(account, card)
|
||||
}
|
||||
SetStatus(account)
|
||||
WriteResponse(w, nil);
|
||||
}
|
||||
|
68
net/server/internal/api_updateGroup.go
Normal file
68
net/server/internal/api_updateGroup.go
Normal file
@ -0,0 +1,68 @@
|
||||
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
|
||||
}
|
||||
|
||||
// scan parameters
|
||||
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 referenced 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("group has been deleted"))
|
||||
return
|
||||
}
|
||||
|
||||
// save and update contact revision
|
||||
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if res := tx.Model(&slot.Group.GroupData).Update("data", subject.Data).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Model(&slot.Group).Update("data_type", subject.DataType).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Model(&slot).Update("revision", account.GroupRevision + 1).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));
|
||||
}
|
||||
|
@ -184,4 +184,36 @@ func SetContactChannelNotification(account *store.Account, card *store.Card) {
|
||||
}
|
||||
}
|
||||
|
||||
// notify all cards of channel change
|
||||
// when card is deleted
|
||||
func SetChannelNotification(account *store.Account) {
|
||||
|
||||
// select all connected cards
|
||||
var cards []store.Card
|
||||
if err := store.DB.Where("account_id = ? AND status = ?", account.Guid, APP_CARDCONNECTED).Find(&cards).Error; err != nil {
|
||||
ErrMsg(err)
|
||||
return
|
||||
}
|
||||
|
||||
// add new notification for each card
|
||||
err := store.DB.Transaction(func(tx *gorm.DB) error {
|
||||
for _, card := range cards {
|
||||
notification := &store.Notification{
|
||||
Node: card.Node,
|
||||
Module: APP_NOTIFYCHANNEL,
|
||||
Token: card.OutToken,
|
||||
Revision: account.ChannelRevision,
|
||||
}
|
||||
if err := tx.Save(notification).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
notify <- notification
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
ErrMsg(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -111,6 +111,8 @@ type Group struct {
|
||||
Created int64 `gorm:"autoCreateTime"`
|
||||
Updated int64 `gorm:"autoUpdateTime"`
|
||||
Cards []Card `gorm:"many2many:card_groups"`
|
||||
Channels []Channel `gorm:"many2many:channel_groups"`
|
||||
Articles []Article `gorm:"many2many:article_groups"`
|
||||
GroupData GroupData
|
||||
GroupSlot GroupSlot
|
||||
}
|
||||
@ -156,6 +158,7 @@ type Card struct {
|
||||
NotifiedProfile int64
|
||||
Account Account `gorm:"references:Guid"`
|
||||
Groups []Group `gorm:"many2many:card_groups"`
|
||||
Channels []Channel `gorm:"many2many:channel_cards"`
|
||||
CardSlot CardSlot
|
||||
}
|
||||
|
||||
@ -199,8 +202,8 @@ type Channel struct {
|
||||
SizeRevision int64 `gorm:"not null"`
|
||||
TopicUpdated int64
|
||||
TopicCount int64
|
||||
Viewers []Group `gorm:"many2many:viewer_groups;"`
|
||||
Members []Group `gorm:"many2many:member_groups;"`
|
||||
Groups []Group `gorm:"many2many:channel_groups;"`
|
||||
Cards []Card `gorm:"many2many:channel_cards;"`
|
||||
ChannelSlot ChannelSlot
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@ func TestContactSync(t *testing.T) {
|
||||
var detail CardDetail
|
||||
var rev *Revision
|
||||
var viewRevision int64
|
||||
var groups *[]Group
|
||||
|
||||
// setup testing group
|
||||
set, err := AddTestGroup("contactsync")
|
||||
@ -143,4 +144,34 @@ func TestContactSync(t *testing.T) {
|
||||
assert.NoError(t, ApiTestMsg(GetCard, "GET", "/contact/cards/{cardId}",
|
||||
¶m, nil, APP_TOKENAPP, set.A.Token, card, nil))
|
||||
assert.Nil(t, card.Data)
|
||||
|
||||
// update and delete group
|
||||
param["groupId"] = set.D.C.GroupId
|
||||
subject := &Subject{ DataType: "contactsynctype", Data: "contactsyncdata" }
|
||||
assert.NoError(t, ApiTestMsg(UpdateGroup, "PUT", "/alias/groups/{groupId}",
|
||||
¶m, subject, APP_TOKENAPP, set.D.Token, nil, nil))
|
||||
groups = &[]Group{}
|
||||
assert.NoError(t, ApiTestMsg(GetGroups, "GET", "/alias/groups",
|
||||
nil, nil, APP_TOKENAPP, set.D.Token, groups, nil))
|
||||
assert.Equal(t, 1, len(*groups))
|
||||
assert.Equal(t, "contactsynctype", (*groups)[0].Data.DataType)
|
||||
assert.Equal(t, "contactsyncdata", (*groups)[0].Data.Data)
|
||||
rev = GetTestRevision(set.C.Revisions)
|
||||
card = &Card{}
|
||||
param["cardId"] = set.C.D.CardId
|
||||
assert.NoError(t, ApiTestMsg(GetCard, "GET", "/contact/cards/{cardId}",
|
||||
¶m, nil, APP_TOKENAPP, set.C.Token, card, nil))
|
||||
viewRevision = card.Data.NotifiedView
|
||||
param["groupId"] = set.D.C.GroupId
|
||||
assert.NoError(t, ApiTestMsg(RemoveGroup, "GET", "/alias/groups/{groupId}",
|
||||
¶m, nil, APP_TOKENAPP, set.D.Token, nil, nil))
|
||||
groups = &[]Group{}
|
||||
assert.NoError(t, ApiTestMsg(GetGroups, "GET", "/alias/groups",
|
||||
nil, nil, APP_TOKENAPP, set.D.Token, groups, nil))
|
||||
assert.Equal(t, 0, len(*groups))
|
||||
assert.NotEqual(t, rev.Card, GetTestRevision(set.C.Revisions).Card)
|
||||
card = &Card{}
|
||||
assert.NoError(t, ApiTestMsg(GetCard, "GET", "/contact/cards/{cardId}",
|
||||
¶m, nil, APP_TOKENAPP, set.C.Token, card, nil))
|
||||
assert.NotEqual(t, viewRevision, card.Data.NotifiedView)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user