Expanding ws payload names, some code cleanup
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/crusttech/crust/sam/types"
|
||||
"github.com/titpetric/factory"
|
||||
"time"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -34,7 +35,7 @@ const (
|
||||
|
||||
sqlChannelDirect = `SELECT *
|
||||
FROM channels AS c
|
||||
WHERE c.type = 'group'
|
||||
WHERE c.type = ?
|
||||
AND c.id IN (SELECT rel_channel
|
||||
FROM channel_members
|
||||
GROUP BY rel_channel
|
||||
@@ -71,10 +72,12 @@ func (r *repository) FindDirectChannelByUserID(fromUserID, toUserID uint64) (*ty
|
||||
toUserID, fromUserID = fromUserID, toUserID
|
||||
}
|
||||
|
||||
return mod, isFound(r.db().Get(mod, sqlChannelDirect, fromUserID, toUserID), mod.ID > 0, ErrChannelNotFound)
|
||||
return mod, isFound(r.db().Get(mod, sqlChannelDirect, types.ChannelTypeDirect, fromUserID, toUserID), mod.ID > 0, ErrChannelNotFound)
|
||||
}
|
||||
|
||||
func (r *repository) FindChannels(filter *types.ChannelFilter) ([]*types.Channel, error) {
|
||||
// @todo: actual searching (filter.Query) not just a full select
|
||||
|
||||
params := make([]interface{}, 0)
|
||||
rval := make([]*types.Channel, 0)
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ func (ctrl *Channel) Create(ctx context.Context, r *request.ChannelCreate) (inte
|
||||
|
||||
func (ctrl *Channel) Edit(ctx context.Context, r *request.ChannelEdit) (interface{}, error) {
|
||||
channel := &types.Channel{
|
||||
ID: r.ChannelID,
|
||||
Name: r.Name,
|
||||
Topic: r.Topic,
|
||||
}
|
||||
|
||||
@@ -12,10 +12,7 @@ import (
|
||||
type (
|
||||
channel struct {
|
||||
rpo channelRepository
|
||||
//
|
||||
//sec struct {
|
||||
// ch channelSecurity
|
||||
//}
|
||||
usr UserService
|
||||
}
|
||||
|
||||
ChannelService interface {
|
||||
@@ -43,6 +40,7 @@ func Channel() *channel {
|
||||
var svc = &channel{}
|
||||
|
||||
svc.rpo = repository.New()
|
||||
svc.usr = User()
|
||||
//svc.sec.ch = ChannelSecurity(svc.rpo)
|
||||
|
||||
return svc
|
||||
@@ -63,8 +61,11 @@ func (svc channel) FindByID(ctx context.Context, id uint64) (ch *types.Channel,
|
||||
|
||||
func (svc channel) Find(ctx context.Context, filter *types.ChannelFilter) ([]*types.Channel, error) {
|
||||
// @todo: permission check to return only channels that channel has access to
|
||||
// @todo: actual searching not just a full select
|
||||
return svc.rpo.FindChannels(filter)
|
||||
if cc, err := svc.rpo.FindChannels(filter); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return cc, svc.usr.LoadFromChannels(ctx, cc)
|
||||
}
|
||||
}
|
||||
|
||||
// Returns all channels with membership info
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"github.com/crusttech/crust/internal/auth"
|
||||
"github.com/crusttech/crust/sam/repository"
|
||||
"github.com/crusttech/crust/sam/types"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
@@ -84,7 +85,7 @@ func (svc message) Direct(ctx context.Context, recipientID uint64, in *types.Mes
|
||||
dch, err := r.FindDirectChannelByUserID(currentUserID, recipientID)
|
||||
if err == repository.ErrChannelNotFound {
|
||||
dch, err = r.CreateChannel(&types.Channel{
|
||||
Type: types.ChannelTypeGroup,
|
||||
Type: types.ChannelTypeDirect,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
@@ -94,10 +95,12 @@ func (svc message) Direct(ctx context.Context, recipientID uint64, in *types.Mes
|
||||
membership := &types.ChannelMember{ChannelID: dch.ID, Type: types.ChannelMembershipTypeOwner}
|
||||
|
||||
membership.UserID = currentUserID
|
||||
spew.Dump(membership)
|
||||
if _, err = r.AddChannelMember(membership); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
spew.Dump(membership)
|
||||
membership.UserID = recipientID
|
||||
if _, err = r.AddChannelMember(membership); err != nil {
|
||||
return
|
||||
@@ -110,6 +113,9 @@ func (svc message) Direct(ctx context.Context, recipientID uint64, in *types.Mes
|
||||
// Make sure our message is sent to the right channel
|
||||
in.ChannelID = dch.ID
|
||||
in.UserID = currentUserID
|
||||
in.Type = types.MessageTypeSimpleMessage
|
||||
|
||||
spew.Dump(in)
|
||||
|
||||
// @todo send new msg to the event-loop
|
||||
out, err = r.CreateMessage(in)
|
||||
|
||||
@@ -18,6 +18,7 @@ type (
|
||||
|
||||
UserService interface {
|
||||
Find(ctx context.Context, filter *types.UserFilter) ([]*types.User, error)
|
||||
LoadFromChannels(ctx context.Context, cc types.ChannelSet) (err error)
|
||||
}
|
||||
|
||||
userRepository interface {
|
||||
@@ -52,6 +53,14 @@ func (svc user) FindByID(ctx context.Context, id uint64) (*types.User, error) {
|
||||
return svc.rpo.WithCtx(ctx).FindUserByID(id)
|
||||
}
|
||||
|
||||
func (svc user) LoadFromChannels(ctx context.Context, cc types.ChannelSet) (err error) {
|
||||
return cc.Walk(func(c *types.Channel) error {
|
||||
// @todo doing N selects (one per chan) for now, optimize!
|
||||
c.Members, err = svc.rpo.FindUsers(&types.UserFilter{MembersOfChannel: c.ID})
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func (svc user) Find(ctx context.Context, filter *types.UserFilter) ([]*types.User, error) {
|
||||
return svc.rpo.FindUsers(filter)
|
||||
}
|
||||
|
||||
+17
-2
@@ -23,7 +23,8 @@ type (
|
||||
|
||||
LastMessageID uint64 `json:",omitempty" db:"rel_last_message"`
|
||||
|
||||
Member *ChannelMember `json:"-" db:"-"`
|
||||
Member *ChannelMember `json:"-" db:"-"`
|
||||
Members []*User `json:"-" db:"-"`
|
||||
}
|
||||
|
||||
ChannelMember struct {
|
||||
@@ -37,13 +38,26 @@ type (
|
||||
}
|
||||
|
||||
ChannelFilter struct {
|
||||
Query string
|
||||
Query string
|
||||
IncludeMembers bool
|
||||
}
|
||||
|
||||
ChannelMembershipType string
|
||||
ChannelType string
|
||||
|
||||
ChannelSet []*Channel
|
||||
)
|
||||
|
||||
func (cc ChannelSet) Walk(w func(*Channel) error) (err error) {
|
||||
for i := range cc {
|
||||
if err = w(cc[i]); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
const (
|
||||
ChannelMembershipTypeOwner ChannelMembershipType = "owner"
|
||||
ChannelMembershipTypeMember = "member"
|
||||
@@ -51,4 +65,5 @@ const (
|
||||
ChannelTypePublic ChannelType = "public"
|
||||
ChannelTypePrivate = "private"
|
||||
ChannelTypeGroup = "group"
|
||||
ChannelTypeDirect = "direct"
|
||||
)
|
||||
|
||||
@@ -23,8 +23,20 @@ type (
|
||||
Query string
|
||||
MembersOfChannel uint64
|
||||
}
|
||||
|
||||
UserSet []*User
|
||||
)
|
||||
|
||||
func (uu UserSet) Walk(w func(*User) error) (err error) {
|
||||
for i := range uu {
|
||||
if err = w(uu[i]); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (u *User) Valid() bool {
|
||||
return u.ID > 0 && u.SuspendedAt == nil && u.DeletedAt == nil
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package incoming
|
||||
|
||||
type (
|
||||
ChannelList struct{}
|
||||
Channels struct{}
|
||||
|
||||
ChannelJoin struct {
|
||||
ChannelID string `json:"id"`
|
||||
@@ -12,18 +12,16 @@ type (
|
||||
}
|
||||
|
||||
ChannelCreate struct {
|
||||
Name string `json:"name"`
|
||||
Topic string `json:"topic"`
|
||||
Name *string `json:"name"`
|
||||
Topic *string `json:"topic"`
|
||||
Type *string `json:"type"`
|
||||
}
|
||||
|
||||
ChannelRename struct {
|
||||
ChannelID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
ChannelChangeTopic struct {
|
||||
ChannelID string `json:"id"`
|
||||
Topic string `json:"topic"`
|
||||
ChannelUpdate struct {
|
||||
ID string `json:"id"`
|
||||
Name *string `json:"name"`
|
||||
Topic *string `json:"topic"`
|
||||
Type *string `json:"type"`
|
||||
}
|
||||
|
||||
ChannelDelete struct {
|
||||
|
||||
@@ -2,23 +2,23 @@ package incoming
|
||||
|
||||
type (
|
||||
MessageCreate struct {
|
||||
ChannelID string `json:"cid"`
|
||||
Message string `json:"msg"`
|
||||
ChannelID string `json:"channelId"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
MessageUpdate struct {
|
||||
ID string `json:"id"`
|
||||
Message string `json:"msg"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
MessageDelete struct {
|
||||
ChannelID string `json:"cid"`
|
||||
ChannelID string `json:"channelId"`
|
||||
ID string `json:"id"`
|
||||
}
|
||||
|
||||
MessageHistory struct {
|
||||
ChannelID string `json:"cid"`
|
||||
FromID string `json:"fid,omitempty"`
|
||||
UntilID string `json:"uid,omitempty"`
|
||||
Messages struct {
|
||||
ChannelID string `json:"channelId"`
|
||||
FromID string `json:"fromId,omitempty"`
|
||||
UntilID string `json:"untilId,omitempty"`
|
||||
}
|
||||
)
|
||||
|
||||
@@ -2,22 +2,21 @@ package incoming
|
||||
|
||||
type Payload struct {
|
||||
// Channel actions
|
||||
*ChannelList `json:"chlist"`
|
||||
*ChannelJoin `json:"chjoin"`
|
||||
*ChannelPart `json:"chpart"`
|
||||
*Channels `json:"channels"`
|
||||
*ChannelJoin `json:"joinChannel"`
|
||||
*ChannelPart `json:"partChannel"`
|
||||
|
||||
*ChannelChangeTopic `json:"chct"`
|
||||
*ChannelRename `json:"chrn"`
|
||||
*ChannelCreate `json:"chcr"`
|
||||
*ChannelDelete `json:"chdel"`
|
||||
*ChannelCreate `json:"createChannel"`
|
||||
*ChannelUpdate `json:"updateChannel"`
|
||||
*ChannelDelete `json:"deleteChannel"`
|
||||
|
||||
// Get channel message history
|
||||
*MessageHistory `json:"chopen"`
|
||||
*Messages `json:"messages"`
|
||||
|
||||
// Message actions
|
||||
*MessageCreate `json:"msgcre"`
|
||||
*MessageUpdate `json:"msgupd"`
|
||||
*MessageDelete `json:"msgdel"`
|
||||
*MessageCreate `json:"createMessage"`
|
||||
*MessageUpdate `json:"updateMessage"`
|
||||
*MessageDelete `json:"deleteMessage"`
|
||||
|
||||
*UserList `json:"users"`
|
||||
*Users `json:"getUsers"`
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
package incoming
|
||||
|
||||
type (
|
||||
UserList struct{}
|
||||
Users struct{}
|
||||
)
|
||||
|
||||
@@ -34,7 +34,9 @@ type (
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Topic string `json:"topic"`
|
||||
Type string `json:"type"`
|
||||
LastMessageID string `json:"lastMessageId"`
|
||||
Members *Users `json:"members,omitempty"`
|
||||
}
|
||||
|
||||
Channels []*Channel
|
||||
|
||||
@@ -36,6 +36,8 @@ func payloadFromChannel(ch *types.Channel) *outgoing.Channel {
|
||||
Name: ch.Name,
|
||||
LastMessageID: uint64toa(ch.LastMessageID),
|
||||
Topic: ch.Topic,
|
||||
Type: string(ch.Type),
|
||||
Members: payloadFromUsers(ch.Members),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +72,7 @@ func payloadFromUsers(users []*types.User) *outgoing.Users {
|
||||
}
|
||||
|
||||
retval := outgoing.Users(uu)
|
||||
|
||||
return &retval
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package websocket
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/crusttech/crust/sam/websocket/incoming"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
@@ -12,6 +13,8 @@ func (s *Session) dispatch(raw []byte) (err error) {
|
||||
return errors.Wrap(err, "Session.incoming: payload malformed")
|
||||
}
|
||||
|
||||
spew.Dump(p, string(raw))
|
||||
|
||||
ctx := s.Context()
|
||||
switch {
|
||||
|
||||
@@ -22,27 +25,25 @@ func (s *Session) dispatch(raw []byte) (err error) {
|
||||
return s.messageUpdate(ctx, p.MessageUpdate)
|
||||
case p.MessageDelete != nil:
|
||||
return s.messageDelete(ctx, p.MessageDelete)
|
||||
case p.MessageHistory != nil:
|
||||
return s.messageHistory(ctx, p.MessageHistory)
|
||||
case p.Messages != nil:
|
||||
return s.messageHistory(ctx, p.Messages)
|
||||
|
||||
// channel actions
|
||||
case p.ChannelJoin != nil:
|
||||
return s.channelJoin(ctx, p.ChannelJoin)
|
||||
case p.ChannelPart != nil:
|
||||
return s.channelPart(ctx, p.ChannelPart)
|
||||
case p.ChannelList != nil:
|
||||
return s.channelList(ctx, p.ChannelList)
|
||||
case p.Channels != nil:
|
||||
return s.channelList(ctx, p.Channels)
|
||||
case p.ChannelCreate != nil:
|
||||
return s.channelCreate(ctx, p.ChannelCreate)
|
||||
case p.ChannelDelete != nil:
|
||||
return s.channelDelete(ctx, p.ChannelDelete)
|
||||
case p.ChannelRename != nil:
|
||||
return s.channelRename(ctx, p.ChannelRename)
|
||||
case p.ChannelChangeTopic != nil:
|
||||
return s.channelChangeTopic(ctx, p.ChannelChangeTopic)
|
||||
case p.ChannelUpdate != nil:
|
||||
return s.channelUpdate(ctx, p.ChannelUpdate)
|
||||
|
||||
case p.UserList != nil:
|
||||
return s.userList(ctx, p.UserList)
|
||||
case p.Users != nil:
|
||||
return s.userList(ctx, p.Users)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -43,8 +43,8 @@ func (s *Session) channelPart(ctx context.Context, p *incoming.ChannelPart) erro
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Session) channelList(ctx context.Context, p *incoming.ChannelList) error {
|
||||
channels, err := service.Channel().Find(ctx, nil)
|
||||
func (s *Session) channelList(ctx context.Context, p *incoming.Channels) error {
|
||||
channels, err := service.Channel().Find(ctx, &types.ChannelFilter{IncludeMembers: true})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -54,9 +54,19 @@ func (s *Session) channelList(ctx context.Context, p *incoming.ChannelList) erro
|
||||
|
||||
func (s *Session) channelCreate(ctx context.Context, p *incoming.ChannelCreate) (err error) {
|
||||
ch := &types.Channel{
|
||||
Type: types.ChannelTypePublic,
|
||||
Name: p.Name,
|
||||
Topic: p.Topic,
|
||||
Type: types.ChannelTypePublic,
|
||||
}
|
||||
|
||||
if p.Name != nil {
|
||||
ch.Name = *p.Name
|
||||
}
|
||||
|
||||
if p.Topic != nil {
|
||||
ch.Topic = *p.Topic
|
||||
}
|
||||
|
||||
if p.Type != nil {
|
||||
ch.Type = types.ChannelType(*p.Type)
|
||||
}
|
||||
|
||||
ch, err = service.Channel().Create(ctx, ch)
|
||||
@@ -91,44 +101,28 @@ func (s *Session) channelDelete(ctx context.Context, p *incoming.ChannelDelete)
|
||||
}, p.ChannelID)
|
||||
}
|
||||
|
||||
func (s *Session) channelRename(ctx context.Context, p *incoming.ChannelRename) error {
|
||||
ch, err := service.Channel().FindByID(ctx, parseUInt64(p.ChannelID))
|
||||
func (s *Session) channelUpdate(ctx context.Context, p *incoming.ChannelUpdate) error {
|
||||
ch, err := service.Channel().FindByID(ctx, parseUInt64(p.ID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ch.Name == p.Name {
|
||||
// No changes, ignore
|
||||
return nil
|
||||
if p.Name != nil {
|
||||
ch.Name = *p.Name
|
||||
}
|
||||
|
||||
ch.Name = p.Name
|
||||
if p.Topic != nil {
|
||||
ch.Topic = *p.Topic
|
||||
}
|
||||
|
||||
if p.Type != nil {
|
||||
ch.Type = types.ChannelType(*p.Type)
|
||||
}
|
||||
|
||||
ch, err = service.Channel().Update(ctx, ch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return s.sendToAllSubscribers(payloadFromChannel(ch), p.ChannelID)
|
||||
}
|
||||
|
||||
func (s *Session) channelChangeTopic(ctx context.Context, p *incoming.ChannelChangeTopic) error {
|
||||
ch, err := service.Channel().FindByID(ctx, parseUInt64(p.ChannelID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ch.Topic == p.Topic {
|
||||
// No changes, ignore
|
||||
return nil
|
||||
}
|
||||
|
||||
ch.Topic = p.Topic
|
||||
|
||||
ch, err = service.Channel().Update(ctx, ch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return s.sendToAllSubscribers(payloadFromChannel(ch), p.ChannelID)
|
||||
return s.sendToAllSubscribers(payloadFromChannel(ch), p.ID)
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ func (s *Session) messageDelete(ctx context.Context, p *incoming.MessageDelete)
|
||||
return s.sendToAllSubscribers(&outgoing.MessageDelete{ID: p.ID}, p.ChannelID)
|
||||
}
|
||||
|
||||
func (s *Session) messageHistory(ctx context.Context, p *incoming.MessageHistory) error {
|
||||
func (s *Session) messageHistory(ctx context.Context, p *incoming.Messages) error {
|
||||
var (
|
||||
filter = &types.MessageFilter{
|
||||
ChannelID: parseUInt64(p.ChannelID),
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"github.com/crusttech/crust/sam/websocket/incoming"
|
||||
)
|
||||
|
||||
func (s *Session) userList(ctx context.Context, p *incoming.UserList) error {
|
||||
func (s *Session) userList(ctx context.Context, p *incoming.Users) error {
|
||||
users, err := service.User().Find(ctx, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
Reference in New Issue
Block a user