mirror of
https://github.com/balzack/databag.git
synced 2025-02-12 03:29:16 +00:00
added profile notification
This commit is contained in:
parent
a2354704fc
commit
bc0921c721
@ -48,12 +48,12 @@ func SetCardStatus(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// update card
|
||||
card.Status = status
|
||||
card.DataRevision += 1
|
||||
if token != "" {
|
||||
card.OutToken = token
|
||||
}
|
||||
if status == APP_CARDCONNECTING {
|
||||
if card.Status != APP_CARDCONNECTING && card.Status != APP_CARDCONNECTED {
|
||||
data, err := securerandom.Bytes(32)
|
||||
if err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
@ -61,6 +61,8 @@ func SetCardStatus(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
card.InToken = hex.EncodeToString(data)
|
||||
}
|
||||
}
|
||||
card.Status = status
|
||||
|
||||
// save and update contact revision
|
||||
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
||||
|
@ -2,13 +2,48 @@ package databag
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"gorm.io/gorm"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func SetContentRevision(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
||||
card, code, err := BearerContactToken(r)
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
|
||||
var revision int64
|
||||
if err := ParseRequest(r, w, &revision); err != nil {
|
||||
ErrResponse(w, http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := NotifyProfileRevision(card, revision); err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
WriteResponse(w, nil)
|
||||
}
|
||||
|
||||
func NotifyContentRevision(token string, revision int64) error {
|
||||
func NotifyContentRevision(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("remote_content", revision).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Model(act).Where("id = ?", act.ID).Update("card_revision", act.CardRevision+1).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
SetStatus(act)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -2,14 +2,49 @@ package databag
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"gorm.io/gorm"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func SetProfileRevision(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
||||
card, code, err := BearerContactToken(r)
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
|
||||
var revision int64
|
||||
if err := ParseRequest(r, w, &revision); err != nil {
|
||||
ErrResponse(w, http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := NotifyProfileRevision(card, revision); err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
WriteResponse(w, nil)
|
||||
}
|
||||
|
||||
func NotifyProfileRevision(token string, revision int64) error {
|
||||
func NotifyProfileRevision(card *store.Card, revision int64) error {
|
||||
|
||||
card.RemoteProfile = revision
|
||||
act := &card.Account
|
||||
err := store.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if res := tx.Model(card).Where("id = ?", card.ID).Update("remote_profile", revision).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Model(act).Where("id = ?", act.ID).Update("card_revision", act.CardRevision+1).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
SetStatus(act)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -114,6 +114,28 @@ func BearerAppToken(r *http.Request, detail bool) (*store.Account, int, error) {
|
||||
return &app.Account, http.StatusOK, nil
|
||||
}
|
||||
|
||||
func BearerContactToken(r *http.Request) (*store.Card, int, error) {
|
||||
|
||||
// parse bearer authentication
|
||||
auth := r.Header.Get("Authorization")
|
||||
token := strings.TrimSpace(strings.TrimPrefix(auth, "Bearer"))
|
||||
|
||||
// find token record
|
||||
var card store.Card
|
||||
if err := store.DB.Preload("Account").Where("InToken = ?", token).First(&card).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, http.StatusNotFound, err
|
||||
} else {
|
||||
return nil, http.StatusInternalServerError, err
|
||||
}
|
||||
}
|
||||
if card.Account.Disabled {
|
||||
return nil, http.StatusGone, errors.New("account is inactive")
|
||||
}
|
||||
|
||||
return &card, http.StatusOK, nil
|
||||
}
|
||||
|
||||
func BasicCredentials(r *http.Request) (string, []byte, error) {
|
||||
|
||||
var username string
|
||||
|
@ -1,6 +1,7 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"gorm.io/gorm"
|
||||
"databag/internal/store"
|
||||
)
|
||||
@ -43,12 +44,24 @@ func SendNotifications() {
|
||||
}
|
||||
|
||||
func SendLocalNotification(notification *store.Notification) {
|
||||
|
||||
// pull reference account
|
||||
var card store.Card
|
||||
if err := store.DB.Preload("Account").Where("in_token = ?", notification.Token).First(&card).Error; err != nil {
|
||||
ErrMsg(err)
|
||||
return
|
||||
}
|
||||
if card.Account.Disabled {
|
||||
ErrMsg(errors.New("account is inactive"))
|
||||
return
|
||||
}
|
||||
|
||||
if notification.Module == APP_MODULEPROFILE {
|
||||
if err := NotifyProfileRevision(notification.Token, notification.Revision); err != nil {
|
||||
if err := NotifyProfileRevision(&card, notification.Revision); err != nil {
|
||||
ErrMsg(err)
|
||||
}
|
||||
} else if notification.Module == APP_MODULECONTENT {
|
||||
if err := NotifyContentRevision(notification.Token, notification.Revision); err != nil {
|
||||
if err := NotifyContentRevision(&card, notification.Revision); err != nil {
|
||||
ErrMsg(err)
|
||||
}
|
||||
} else {
|
||||
|
@ -2,30 +2,65 @@ package databag
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"encoding/json"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestProfileNotification(t *testing.T) {
|
||||
var views []CardView
|
||||
var revision Revision
|
||||
var data []byte
|
||||
|
||||
// start notifcation thread
|
||||
go SendNotifications()
|
||||
|
||||
// connect contacts
|
||||
access := AddTestContacts(t, "profilenotification", 2);
|
||||
contact := ConnectTestContacts(t, access[0], access[1])
|
||||
ConnectTestContacts(t, access[0], access[1])
|
||||
|
||||
PrintMsg(access)
|
||||
PrintMsg(contact)
|
||||
// get views list of cards
|
||||
r, w, _ := NewRequest("GET", "/contact/cards/view", nil)
|
||||
SetBearerAuth(r, access[0])
|
||||
GetCardView(w, r)
|
||||
assert.NoError(t, ReadResponse(w, &views))
|
||||
assert.Equal(t, len(views), 1)
|
||||
profileRevision := views[0].RemoteProfile
|
||||
|
||||
// connect revision websocket for A
|
||||
// app connects websocket
|
||||
ws := getTestWebsocket()
|
||||
announce := Announce{ AppToken: access[0] }
|
||||
data, _ = json.Marshal(&announce)
|
||||
ws.WriteMessage(websocket.TextMessage, data)
|
||||
|
||||
// get profile revision of B
|
||||
// receive revision
|
||||
_, data, _ = ws.ReadMessage()
|
||||
assert.NoError(t, json.Unmarshal(data, &revision))
|
||||
cardRevision := revision.Card
|
||||
|
||||
// update profile of B
|
||||
// update B profile
|
||||
profileData := ProfileData{
|
||||
Name: "Namer",
|
||||
Location: "San Francisco",
|
||||
Description: "databaggerr",
|
||||
};
|
||||
r, w, _ = NewRequest("PUT", "/profile/data", &profileData)
|
||||
SetBearerAuth(r, access[1])
|
||||
SetProfile(w, r)
|
||||
assert.NoError(t, ReadResponse(w, nil))
|
||||
|
||||
// read revision message
|
||||
// receive revision
|
||||
_, data, _ = ws.ReadMessage()
|
||||
assert.NoError(t, json.Unmarshal(data, &revision))
|
||||
assert.NotEqual(t, cardRevision, revision.Card)
|
||||
|
||||
// check card increment
|
||||
|
||||
// check B profile incremented
|
||||
// get views list of cards
|
||||
r, w, _ = NewRequest("GET", "/contact/cards/view", nil)
|
||||
SetBearerAuth(r, access[0])
|
||||
GetCardView(w, r)
|
||||
assert.NoError(t, ReadResponse(w, &views))
|
||||
assert.Equal(t, len(views), 1)
|
||||
assert.NotEqual(t, profileRevision, views[0].RemoteProfile)
|
||||
|
||||
// stop notification thread
|
||||
ExitNotifications()
|
||||
|
Loading…
Reference in New Issue
Block a user