fix(messaging): fix stutters, Init(), errors
This commit is contained in:
@@ -33,8 +33,8 @@ type (
|
||||
ctx context.Context
|
||||
|
||||
store store.Store
|
||||
usr systemService.UserService
|
||||
evl EventService
|
||||
user systemService.UserService
|
||||
event EventService
|
||||
|
||||
attachment repository.AttachmentRepository
|
||||
message repository.MessageRepository
|
||||
@@ -50,12 +50,10 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
func Attachment(store store.Store) AttachmentService {
|
||||
func Attachment(ctx context.Context, store store.Store) AttachmentService {
|
||||
return (&attachment{
|
||||
store: store,
|
||||
usr: systemService.DefaultUser,
|
||||
evl: DefaultEvent,
|
||||
}).With(context.Background())
|
||||
}).With(ctx)
|
||||
}
|
||||
|
||||
func (svc *attachment) With(ctx context.Context) AttachmentService {
|
||||
@@ -65,8 +63,8 @@ func (svc *attachment) With(ctx context.Context) AttachmentService {
|
||||
ctx: ctx,
|
||||
|
||||
store: svc.store,
|
||||
usr: systemService.User(ctx),
|
||||
evl: svc.evl.With(ctx),
|
||||
user: systemService.User(ctx),
|
||||
event: Event(ctx),
|
||||
|
||||
attachment: repository.Attachment(ctx, db),
|
||||
message: repository.Message(ctx, db),
|
||||
@@ -154,7 +152,7 @@ func (svc *attachment) Create(name string, size int64, fh io.ReadSeeker, channel
|
||||
|
||||
// Create the first message, doing this directly with repository to circumvent
|
||||
// message service constraints
|
||||
if msg, err = svc.message.CreateMessage(msg); err != nil {
|
||||
if msg, err = svc.message.Create(msg); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -291,12 +289,12 @@ func (svc *attachment) processImage(original io.ReadSeeker, att *types.Attachmen
|
||||
func (svc *attachment) sendEvent(msg *types.Message) (err error) {
|
||||
if msg.User == nil {
|
||||
// @todo pull user from cache
|
||||
if msg.User, err = svc.usr.FindByID(msg.UserID); err != nil {
|
||||
if msg.User, err = svc.user.FindByID(msg.UserID); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return svc.evl.Message(msg)
|
||||
return svc.event.Message(msg)
|
||||
}
|
||||
|
||||
var _ AttachmentService = &attachment{}
|
||||
|
||||
@@ -19,10 +19,10 @@ type (
|
||||
db db
|
||||
ctx context.Context
|
||||
|
||||
usr systemService.UserService
|
||||
user systemService.UserService
|
||||
|
||||
evl EventService
|
||||
prm PermissionsService
|
||||
event EventService
|
||||
perms PermissionsService
|
||||
|
||||
channel repository.ChannelRepository
|
||||
cmember repository.ChannelMemberRepository
|
||||
@@ -67,12 +67,8 @@ const (
|
||||
settingsChannelTopicLength = 200
|
||||
)
|
||||
|
||||
func Channel() ChannelService {
|
||||
return (&channel{
|
||||
usr: systemService.DefaultUser,
|
||||
evl: DefaultEvent,
|
||||
prm: DefaultPermissions,
|
||||
}).With(context.Background())
|
||||
func Channel(ctx context.Context) ChannelService {
|
||||
return (&channel{}).With(ctx)
|
||||
}
|
||||
|
||||
func (svc *channel) With(ctx context.Context) ChannelService {
|
||||
@@ -81,9 +77,9 @@ func (svc *channel) With(ctx context.Context) ChannelService {
|
||||
db: db,
|
||||
ctx: ctx,
|
||||
|
||||
usr: systemService.User(ctx),
|
||||
evl: svc.evl.With(ctx),
|
||||
prm: svc.prm.With(ctx),
|
||||
user: systemService.User(ctx),
|
||||
event: Event(ctx),
|
||||
perms: Permissions(ctx),
|
||||
|
||||
channel: repository.Channel(ctx, db),
|
||||
cmember: repository.ChannelMember(ctx, db),
|
||||
@@ -96,15 +92,15 @@ func (svc *channel) With(ctx context.Context) ChannelService {
|
||||
}
|
||||
|
||||
func (svc *channel) FindByID(ID uint64) (ch *types.Channel, err error) {
|
||||
ch, err = svc.channel.FindChannelByID(ID)
|
||||
ch, err = svc.channel.FindByID(ID)
|
||||
if err != nil {
|
||||
return
|
||||
} else if err = svc.preloadExtras(types.ChannelSet{ch}); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if !svc.prm.CanReadChannel(ch) {
|
||||
return nil, errors.New("not allowed to access channel")
|
||||
if !svc.perms.CanReadChannel(ch) {
|
||||
return nil, errors.WithStack(ErrNoPermissions)
|
||||
}
|
||||
|
||||
return
|
||||
@@ -114,14 +110,14 @@ func (svc *channel) Find(filter *types.ChannelFilter) (cc types.ChannelSet, err
|
||||
filter.CurrentUserID = auth.GetIdentityFromContext(svc.ctx).Identity()
|
||||
|
||||
return cc, svc.db.Transaction(func() (err error) {
|
||||
if cc, err = svc.channel.FindChannels(filter); err != nil {
|
||||
if cc, err = svc.channel.Find(filter); err != nil {
|
||||
return
|
||||
} else if err = svc.preloadExtras(cc); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
cc, err = cc.Filter(func(c *types.Channel) (b bool, e error) {
|
||||
return svc.prm.CanReadChannel(c), nil
|
||||
return svc.perms.CanReadChannel(c), nil
|
||||
})
|
||||
|
||||
return
|
||||
@@ -191,7 +187,7 @@ func (svc *channel) FindMembers(channelID uint64) (out types.ChannelMemberSet, e
|
||||
return err
|
||||
}
|
||||
|
||||
if uu, err := svc.usr.Find(nil); err != nil {
|
||||
if uu, err := svc.user.Find(nil); err != nil {
|
||||
return err
|
||||
} else {
|
||||
return out.Walk(func(member *types.ChannelMember) error {
|
||||
@@ -219,20 +215,20 @@ func (svc *channel) Create(in *types.Channel) (out *types.Channel, err error) {
|
||||
// Group already exists so let's just return it
|
||||
return nil
|
||||
} else if out != nil && !out.CanObserve {
|
||||
return errors.New("not allowed to create this channel due to permission settings")
|
||||
return errors.WithStack(ErrNoPermissions)
|
||||
}
|
||||
}
|
||||
|
||||
if in.Type == types.ChannelTypePublic && !svc.prm.CanCreatePublicChannel() {
|
||||
return errors.New("not allowed to create public channels")
|
||||
if in.Type == types.ChannelTypePublic && !svc.perms.CanCreatePublicChannel() {
|
||||
return errors.WithStack(ErrNoPermissions)
|
||||
}
|
||||
|
||||
if in.Type == types.ChannelTypePrivate && !svc.prm.CanCreatePrivateChannel() {
|
||||
return errors.New("not allowed to create private channels")
|
||||
if in.Type == types.ChannelTypePrivate && !svc.perms.CanCreatePrivateChannel() {
|
||||
return errors.WithStack(ErrNoPermissions)
|
||||
}
|
||||
|
||||
if in.Type == types.ChannelTypeGroup && !svc.prm.CanCreateGroupChannel() {
|
||||
return errors.New("not allowed to create group channels")
|
||||
if in.Type == types.ChannelTypeGroup && !svc.perms.CanCreateGroupChannel() {
|
||||
return errors.WithStack(ErrNoPermissions)
|
||||
}
|
||||
|
||||
if len(in.Name) == 0 && in.Type != types.ChannelTypeGroup {
|
||||
@@ -257,7 +253,7 @@ func (svc *channel) Create(in *types.Channel) (out *types.Channel, err error) {
|
||||
}
|
||||
|
||||
// Save the channel
|
||||
if out, err = svc.channel.CreateChannel(out); err != nil {
|
||||
if out, err = svc.channel.Create(out); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -271,7 +267,7 @@ func (svc *channel) Create(in *types.Channel) (out *types.Channel, err error) {
|
||||
}
|
||||
|
||||
// Subscribe all members
|
||||
return svc.evl.Join(m.UserID, out.ID)
|
||||
return svc.event.Join(m.UserID, out.ID)
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
@@ -325,7 +321,7 @@ func (svc *channel) buildMemberSet(owner uint64, members ...uint64) (mm types.Ch
|
||||
}
|
||||
|
||||
func (svc *channel) checkGroupExistance(mm types.ChannelMemberSet) (out *types.Channel, err error) {
|
||||
if out, err = svc.channel.FindChannelByMemberSet(mm.AllMemberIDs()...); err == repository.ErrChannelNotFound {
|
||||
if out, err = svc.channel.FindByMemberSet(mm.AllMemberIDs()...); err == repository.ErrChannelNotFound {
|
||||
return nil, nil
|
||||
} else if out != nil && err == nil {
|
||||
err = svc.preloadExtras(types.ChannelSet{out})
|
||||
@@ -342,21 +338,21 @@ func (svc *channel) Update(in *types.Channel) (ch *types.Channel, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
if !svc.prm.CanUpdateChannel(ch) {
|
||||
return errors.New("not allowed to update this channel")
|
||||
if !svc.perms.CanUpdateChannel(ch) {
|
||||
return errors.WithStack(ErrNoPermissions)
|
||||
}
|
||||
|
||||
if in.Type.IsValid() && ch.Type != in.Type {
|
||||
if in.Type == types.ChannelTypePublic && !svc.prm.CanCreatePublicChannel() {
|
||||
return errors.New("not allowed to change type of this channel to **public**")
|
||||
if in.Type == types.ChannelTypePublic && !svc.perms.CanCreatePublicChannel() {
|
||||
return errors.WithStack(ErrNoPermissions)
|
||||
}
|
||||
|
||||
if in.Type == types.ChannelTypePrivate && !svc.prm.CanCreatePrivateChannel() {
|
||||
return errors.New("not allowed to change type of this channel to **private**")
|
||||
if in.Type == types.ChannelTypePrivate && !svc.perms.CanCreatePrivateChannel() {
|
||||
return errors.WithStack(ErrNoPermissions)
|
||||
}
|
||||
|
||||
if in.Type == types.ChannelTypeGroup && !svc.prm.CanCreateGroupChannel() {
|
||||
return errors.New("not allowed to change type of this channel to **group**")
|
||||
if in.Type == types.ChannelTypeGroup && !svc.perms.CanCreateGroupChannel() {
|
||||
return errors.WithStack(ErrNoPermissions)
|
||||
}
|
||||
|
||||
changed = true
|
||||
@@ -394,7 +390,7 @@ func (svc *channel) Update(in *types.Channel) (ch *types.Channel, err error) {
|
||||
return nil
|
||||
}
|
||||
// Save the updated channel
|
||||
if ch, err = svc.channel.UpdateChannel(in); err != nil {
|
||||
if ch, err = svc.channel.Update(in); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -412,8 +408,8 @@ func (svc *channel) Delete(ID uint64) (ch *types.Channel, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
if !svc.prm.CanDeleteChannel(ch) {
|
||||
return errors.New("not allowed to delete this channel")
|
||||
if !svc.perms.CanDeleteChannel(ch) {
|
||||
return errors.WithStack(ErrNoPermissions)
|
||||
}
|
||||
|
||||
if ch.DeletedAt != nil {
|
||||
@@ -425,7 +421,7 @@ func (svc *channel) Delete(ID uint64) (ch *types.Channel, err error) {
|
||||
|
||||
svc.scheduleSystemMessage(ch, "<@%d> deleted this channel", userID)
|
||||
|
||||
if err = svc.channel.DeleteChannelByID(ID); err != nil {
|
||||
if err = svc.channel.DeleteByID(ID); err != nil {
|
||||
return
|
||||
} else {
|
||||
// Set deletedAt timestamp so that our clients can react properly...
|
||||
@@ -446,8 +442,8 @@ func (svc *channel) Undelete(ID uint64) (ch *types.Channel, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
if !svc.prm.CanUndeleteChannel(ch) {
|
||||
return errors.New("not allowed to undelete this channel")
|
||||
if !svc.perms.CanUndeleteChannel(ch) {
|
||||
return errors.WithStack(ErrNoPermissions)
|
||||
}
|
||||
|
||||
if ch.DeletedAt == nil {
|
||||
@@ -456,7 +452,7 @@ func (svc *channel) Undelete(ID uint64) (ch *types.Channel, err error) {
|
||||
|
||||
svc.scheduleSystemMessage(ch, "<@%d> undeleted this channel", userID)
|
||||
|
||||
if err = svc.channel.UndeleteChannelByID(ID); err != nil {
|
||||
if err = svc.channel.UndeleteByID(ID); err != nil {
|
||||
return
|
||||
} else {
|
||||
// Remove deletedAt timestamp so that our clients can react properly...
|
||||
@@ -505,8 +501,8 @@ func (svc *channel) Archive(ID uint64) (ch *types.Channel, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
if !svc.prm.CanArchiveChannel(ch) {
|
||||
return errors.New("not allowed to archive this channel")
|
||||
if !svc.perms.CanArchiveChannel(ch) {
|
||||
return errors.WithStack(ErrNoPermissions)
|
||||
}
|
||||
|
||||
if ch.ArchivedAt != nil {
|
||||
@@ -515,7 +511,7 @@ func (svc *channel) Archive(ID uint64) (ch *types.Channel, err error) {
|
||||
|
||||
svc.scheduleSystemMessage(ch, "<@%d> archived this channel", userID)
|
||||
|
||||
if err = svc.channel.ArchiveChannelByID(ID); err != nil {
|
||||
if err = svc.channel.ArchiveByID(ID); err != nil {
|
||||
return
|
||||
} else {
|
||||
// Set archivedAt timestamp so that our clients can react properly...
|
||||
@@ -535,15 +531,15 @@ func (svc *channel) Unarchive(ID uint64) (ch *types.Channel, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
if !svc.prm.CanUnarchiveChannel(ch) {
|
||||
return errors.New("not allowed to unarchive this channel")
|
||||
if !svc.perms.CanUnarchiveChannel(ch) {
|
||||
return errors.WithStack(ErrNoPermissions)
|
||||
}
|
||||
|
||||
if ch.ArchivedAt == nil {
|
||||
return errors.New("channel not archived")
|
||||
}
|
||||
|
||||
if err = svc.channel.UnarchiveChannelByID(ID); err != nil {
|
||||
if err = svc.channel.UnarchiveByID(ID); err != nil {
|
||||
return
|
||||
} else {
|
||||
// Unset archivedAt timestamp so that our clients can react properly...
|
||||
@@ -574,8 +570,8 @@ func (svc *channel) InviteUser(channelID uint64, memberIDs ...uint64) (out types
|
||||
return nil, errors.New("adding members to a group is not currently supported")
|
||||
}
|
||||
|
||||
if !svc.prm.CanManageChannelMembers(ch) {
|
||||
return nil, errors.New("not allowed to invite members")
|
||||
if !svc.perms.CanManageChannelMembers(ch) {
|
||||
return nil, errors.WithStack(ErrNoPermissions)
|
||||
}
|
||||
|
||||
return out, svc.db.Transaction(func() (err error) {
|
||||
@@ -583,7 +579,7 @@ func (svc *channel) InviteUser(channelID uint64, memberIDs ...uint64) (out types
|
||||
return
|
||||
}
|
||||
|
||||
users, err := svc.usr.Find(nil)
|
||||
users, err := svc.user.Find(nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -642,7 +638,7 @@ func (svc *channel) AddMember(channelID uint64, memberIDs ...uint64) (out types.
|
||||
return
|
||||
}
|
||||
|
||||
users, err := svc.usr.Find(nil)
|
||||
users, err := svc.user.Find(nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -665,10 +661,10 @@ func (svc *channel) AddMember(channelID uint64, memberIDs ...uint64) (out types.
|
||||
}
|
||||
}
|
||||
|
||||
if memberID == userID && !svc.prm.CanJoinChannel(ch) {
|
||||
return errors.New("not allowed to join")
|
||||
} else if memberID != userID && !svc.prm.CanManageChannelMembers(ch) {
|
||||
return errors.New("not allowed to add channel members")
|
||||
if memberID == userID && !svc.perms.CanJoinChannel(ch) {
|
||||
return errors.WithStack(ErrNoPermissions)
|
||||
} else if memberID != userID && !svc.perms.CanManageChannelMembers(ch) {
|
||||
return errors.WithStack(ErrNoPermissions)
|
||||
}
|
||||
|
||||
if !exists {
|
||||
@@ -692,7 +688,7 @@ func (svc *channel) AddMember(channelID uint64, memberIDs ...uint64) (out types.
|
||||
member, err = svc.cmember.Create(member)
|
||||
}
|
||||
|
||||
svc.evl.Join(memberID, channelID)
|
||||
svc.event.Join(memberID, channelID)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -736,10 +732,11 @@ func (svc *channel) DeleteMember(channelID uint64, memberIDs ...uint64) (err err
|
||||
continue
|
||||
}
|
||||
|
||||
if memberID == userID && !svc.prm.CanJoinChannel(ch) {
|
||||
return errors.New("not allowed to leave")
|
||||
} else if !svc.prm.CanManageChannelMembers(ch) {
|
||||
return errors.New("not allowed to remove channel members")
|
||||
if memberID == userID && !svc.perms.CanJoinChannel(ch) {
|
||||
return errors.WithStack(ErrNoPermissions)
|
||||
}
|
||||
if !svc.perms.CanManageChannelMembers(ch) {
|
||||
return errors.WithStack(ErrNoPermissions)
|
||||
}
|
||||
|
||||
if userID == memberID {
|
||||
@@ -752,7 +749,7 @@ func (svc *channel) DeleteMember(channelID uint64, memberIDs ...uint64) (err err
|
||||
return err
|
||||
}
|
||||
|
||||
svc.evl.Part(memberID, channelID)
|
||||
svc.event.Part(memberID, channelID)
|
||||
}
|
||||
|
||||
return svc.flushSystemMessages()
|
||||
@@ -782,10 +779,10 @@ func (svc *channel) flushSystemMessages() (err error) {
|
||||
}()
|
||||
|
||||
return svc.sysmsgs.Walk(func(msg *types.Message) error {
|
||||
if msg, err = svc.message.CreateMessage(msg); err != nil {
|
||||
if msg, err = svc.message.Create(msg); err != nil {
|
||||
return err
|
||||
} else {
|
||||
return svc.evl.Message(msg)
|
||||
return svc.event.Message(msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -810,7 +807,7 @@ func (svc *channel) sendChannelEvent(ch *types.Channel) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = svc.evl.Channel(ch); err != nil {
|
||||
if err = svc.event.Channel(ch); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -818,22 +815,22 @@ func (svc *channel) sendChannelEvent(ch *types.Channel) (err error) {
|
||||
}
|
||||
|
||||
func (svc *channel) setPermissionFlags(ch *types.Channel) (err error) {
|
||||
ch.CanJoin = svc.prm.CanJoinChannel(ch)
|
||||
ch.CanPart = svc.prm.CanLeaveChannel(ch)
|
||||
ch.CanObserve = svc.prm.CanReadChannel(ch)
|
||||
ch.CanSendMessages = svc.prm.CanSendMessage(ch)
|
||||
ch.CanJoin = svc.perms.CanJoinChannel(ch)
|
||||
ch.CanPart = svc.perms.CanLeaveChannel(ch)
|
||||
ch.CanObserve = svc.perms.CanReadChannel(ch)
|
||||
ch.CanSendMessages = svc.perms.CanSendMessage(ch)
|
||||
|
||||
ch.CanDeleteMessages = svc.prm.CanDeleteMessages(ch)
|
||||
ch.CanDeleteOwnMessages = svc.prm.CanDeleteOwnMessages(ch)
|
||||
ch.CanUpdateMessages = svc.prm.CanUpdateMessages(ch)
|
||||
ch.CanUpdateOwnMessages = svc.prm.CanUpdateOwnMessages(ch)
|
||||
ch.CanChangeMembers = svc.prm.CanManageChannelMembers(ch)
|
||||
ch.CanDeleteMessages = svc.perms.CanDeleteMessages(ch)
|
||||
ch.CanDeleteOwnMessages = svc.perms.CanDeleteOwnMessages(ch)
|
||||
ch.CanUpdateMessages = svc.perms.CanUpdateMessages(ch)
|
||||
ch.CanUpdateOwnMessages = svc.perms.CanUpdateOwnMessages(ch)
|
||||
ch.CanChangeMembers = svc.perms.CanManageChannelMembers(ch)
|
||||
|
||||
ch.CanUpdate = svc.prm.CanUpdateChannel(ch)
|
||||
ch.CanArchive = svc.prm.CanArchiveChannel(ch)
|
||||
ch.CanUnarchive = svc.prm.CanUnarchiveChannel(ch)
|
||||
ch.CanDelete = svc.prm.CanDeleteChannel(ch)
|
||||
ch.CanUndelete = svc.prm.CanUndeleteChannel(ch)
|
||||
ch.CanUpdate = svc.perms.CanUpdateChannel(ch)
|
||||
ch.CanArchive = svc.perms.CanArchiveChannel(ch)
|
||||
ch.CanUnarchive = svc.perms.CanUnarchiveChannel(ch)
|
||||
ch.CanDelete = svc.perms.CanDeleteChannel(ch)
|
||||
ch.CanUndelete = svc.perms.CanUndeleteChannel(ch)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
package service
|
||||
|
||||
type (
|
||||
serviceError string
|
||||
readableError string
|
||||
)
|
||||
|
||||
func (e serviceError) Error() string {
|
||||
return "crust.messaging.service." + string(e)
|
||||
func (e readableError) Error() string {
|
||||
return string(e)
|
||||
}
|
||||
|
||||
const (
|
||||
ErrNoPermissions readableError = "You don't have permissions for this operation"
|
||||
)
|
||||
|
||||
@@ -27,14 +27,14 @@ type (
|
||||
)
|
||||
|
||||
// Event sends sends events back to all (or specific) subscribers
|
||||
func Event() EventService {
|
||||
return (&event{events: repository.Events()}).With(context.Background())
|
||||
func Event(ctx context.Context) EventService {
|
||||
return (&event{}).With(ctx)
|
||||
}
|
||||
|
||||
func (svc *event) With(ctx context.Context) EventService {
|
||||
return &event{
|
||||
ctx: ctx,
|
||||
events: svc.events,
|
||||
events: repository.Events(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,9 +28,9 @@ type (
|
||||
mflag repository.MessageFlagRepository
|
||||
mentions repository.MentionRepository
|
||||
|
||||
usr systemService.UserService
|
||||
evl EventService
|
||||
prm PermissionsService
|
||||
usr systemService.UserService
|
||||
event EventService
|
||||
prm PermissionsService
|
||||
}
|
||||
|
||||
MessageService interface {
|
||||
@@ -40,6 +40,7 @@ type (
|
||||
FindThreads(filter *types.MessageFilter) (types.MessageSet, error)
|
||||
|
||||
Create(messages *types.Message) (*types.Message, error)
|
||||
|
||||
Update(messages *types.Message) (*types.Message, error)
|
||||
|
||||
React(messageID uint64, reaction string) error
|
||||
@@ -53,7 +54,7 @@ type (
|
||||
Bookmark(messageID uint64) error
|
||||
RemoveBookmark(messageID uint64) error
|
||||
|
||||
Delete(ID uint64) error
|
||||
Delete(messageID uint64) error
|
||||
}
|
||||
)
|
||||
|
||||
@@ -66,12 +67,8 @@ var (
|
||||
mentionsFinder = regexp.MustCompile(mentionRE)
|
||||
)
|
||||
|
||||
func Message() MessageService {
|
||||
return &message{
|
||||
usr: systemService.DefaultUser,
|
||||
evl: DefaultEvent,
|
||||
prm: DefaultPermissions,
|
||||
}
|
||||
func Message(ctx context.Context) MessageService {
|
||||
return (&message{}).With(ctx)
|
||||
}
|
||||
|
||||
func (svc *message) With(ctx context.Context) MessageService {
|
||||
@@ -80,9 +77,9 @@ func (svc *message) With(ctx context.Context) MessageService {
|
||||
db: db,
|
||||
ctx: ctx,
|
||||
|
||||
usr: systemService.User(ctx),
|
||||
evl: svc.evl.With(ctx),
|
||||
prm: svc.prm.With(ctx),
|
||||
usr: systemService.User(ctx),
|
||||
event: Event(ctx),
|
||||
prm: Permissions(ctx),
|
||||
|
||||
attachment: repository.Attachment(ctx, db),
|
||||
channel: repository.Channel(ctx, db),
|
||||
@@ -101,11 +98,11 @@ func (svc *message) Find(filter *types.MessageFilter) (mm types.MessageSet, err
|
||||
if ch, err := svc.findChannelByID(filter.ChannelID); err != nil {
|
||||
return nil, err
|
||||
} else if !svc.prm.CanReadChannel(ch) {
|
||||
return nil, errors.New("not allowed to access channel")
|
||||
return nil, errors.WithStack(ErrNoPermissions)
|
||||
}
|
||||
}
|
||||
|
||||
mm, err = svc.message.FindMessages(filter)
|
||||
mm, err = svc.message.Find(filter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -120,7 +117,7 @@ func (svc *message) FindThreads(filter *types.MessageFilter) (mm types.MessageSe
|
||||
if ch, err := svc.findChannelByID(filter.ChannelID); err != nil {
|
||||
return nil, err
|
||||
} else if !svc.prm.CanReadChannel(ch) {
|
||||
return nil, errors.New("not allowed to access channel")
|
||||
return nil, errors.WithStack(ErrNoPermissions)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,9 +143,10 @@ func (svc *message) Create(in *types.Message) (message *types.Message, err error
|
||||
return nil, errors.Errorf("message length (%d characters) too long (max: %d)", mlen, settingsMessageBodyLength)
|
||||
}
|
||||
|
||||
var currentUserID = auth.GetIdentityFromContext(svc.ctx).Identity()
|
||||
|
||||
in.UserID = currentUserID
|
||||
// keep pre-existing user id set
|
||||
if in.UserID == 0 {
|
||||
in.UserID = auth.GetIdentityFromContext(svc.ctx).Identity()
|
||||
}
|
||||
|
||||
return message, svc.db.Transaction(func() (err error) {
|
||||
// Broadcast queue
|
||||
@@ -161,7 +159,7 @@ func (svc *message) Create(in *types.Message) (message *types.Message, err error
|
||||
|
||||
for replyTo > 0 {
|
||||
// Find original message
|
||||
original, err = svc.message.FindMessageByID(in.ReplyTo)
|
||||
original, err = svc.message.FindByID(in.ReplyTo)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -193,13 +191,16 @@ func (svc *message) Create(in *types.Message) (message *types.Message, err error
|
||||
return errors.New("channelID missing")
|
||||
} else if ch, err = svc.findChannelByID(in.ChannelID); err != nil {
|
||||
return
|
||||
} else if in.ReplyTo > 0 && !svc.prm.CanReplyMessage(ch) {
|
||||
return errors.New("not allowed to reply in this channel")
|
||||
} else if !svc.prm.CanSendMessage(ch) {
|
||||
return errors.New("not allowed to send messages in this channel")
|
||||
}
|
||||
|
||||
if message, err = svc.message.CreateMessage(in); err != nil {
|
||||
if in.ReplyTo > 0 && !svc.prm.CanReplyMessage(ch) {
|
||||
return errors.WithStack(ErrNoPermissions)
|
||||
}
|
||||
if !svc.prm.CanSendMessage(ch) {
|
||||
return errors.WithStack(ErrNoPermissions)
|
||||
}
|
||||
|
||||
if message, err = svc.message.Create(in); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -225,7 +226,8 @@ func (svc *message) Update(in *types.Message) (message *types.Message, err error
|
||||
|
||||
if mlen == 0 {
|
||||
return nil, errors.Errorf("refusing to update message without contents")
|
||||
} else if settingsMessageBodyLength > 0 && mlen > settingsMessageBodyLength {
|
||||
}
|
||||
if settingsMessageBodyLength > 0 && mlen > settingsMessageBodyLength {
|
||||
return nil, errors.Errorf("message length (%d characters) too long (max: %d)", mlen, settingsMessageBodyLength)
|
||||
}
|
||||
|
||||
@@ -237,10 +239,11 @@ func (svc *message) Update(in *types.Message) (message *types.Message, err error
|
||||
if ch, err = svc.findChannelByID(in.ChannelID); err != nil {
|
||||
return err
|
||||
} else if !svc.prm.CanReadChannel(ch) {
|
||||
return errors.New("not allowed to access channel")
|
||||
return errors.WithStack(ErrNoPermissions)
|
||||
}
|
||||
|
||||
message, err = svc.message.FindMessageByID(in.ID)
|
||||
message, err = svc.message.FindByID(in.ID)
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not load message for editing")
|
||||
}
|
||||
@@ -251,15 +254,15 @@ func (svc *message) Update(in *types.Message) (message *types.Message, err error
|
||||
}
|
||||
|
||||
if message.UserID == currentUserID && !svc.prm.CanUpdateOwnMessages(ch) {
|
||||
return errors.New("not allowed to edit your messages in this channel")
|
||||
return errors.WithStack(ErrNoPermissions)
|
||||
} else if message.UserID != currentUserID && !svc.prm.CanUpdateMessages(ch) {
|
||||
return errors.New("not allowed to edit messages in this channel")
|
||||
return errors.WithStack(ErrNoPermissions)
|
||||
}
|
||||
|
||||
// Allow message content to be changed
|
||||
message.Message = in.Message
|
||||
|
||||
if message, err = svc.message.UpdateMessage(message); err != nil {
|
||||
if message, err = svc.message.Update(message); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -271,7 +274,7 @@ func (svc *message) Update(in *types.Message) (message *types.Message, err error
|
||||
})
|
||||
}
|
||||
|
||||
func (svc *message) Delete(ID uint64) error {
|
||||
func (svc *message) Delete(messageID uint64) error {
|
||||
var currentUserID = auth.GetIdentityFromContext(svc.ctx).Identity()
|
||||
|
||||
_ = currentUserID
|
||||
@@ -282,7 +285,7 @@ func (svc *message) Delete(ID uint64) error {
|
||||
var deletedMsg, original *types.Message
|
||||
var ch *types.Channel
|
||||
|
||||
deletedMsg, err = svc.message.FindMessageByID(ID)
|
||||
deletedMsg, err = svc.message.FindByID(messageID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -290,21 +293,23 @@ func (svc *message) Delete(ID uint64) error {
|
||||
if ch, err = svc.findChannelByID(deletedMsg.ChannelID); err != nil {
|
||||
return err
|
||||
} else if !svc.prm.CanReadChannel(ch) {
|
||||
return errors.New("not allowed to access channel")
|
||||
return errors.WithStack(ErrNoPermissions)
|
||||
}
|
||||
|
||||
if deletedMsg.ReplyTo > 0 {
|
||||
original, err = svc.message.FindMessageByID(deletedMsg.ReplyTo)
|
||||
original, err = svc.message.FindByID(deletedMsg.ReplyTo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ch, err = svc.channel.FindChannelByID(original.ChannelID); err != nil {
|
||||
if ch, err = svc.channel.FindByID(original.ChannelID); err != nil {
|
||||
return
|
||||
} else if original.UserID == currentUserID && !svc.prm.CanUpdateOwnMessages(ch) {
|
||||
return errors.New("not allowed to delete your messages in this channel")
|
||||
} else if !svc.prm.CanUpdateMessages(ch) {
|
||||
return errors.New("not allowed to delete messages in this channel")
|
||||
}
|
||||
if original.UserID == currentUserID && !svc.prm.CanUpdateOwnMessages(ch) {
|
||||
return errors.WithStack(ErrNoPermissions)
|
||||
}
|
||||
if !svc.prm.CanUpdateMessages(ch) {
|
||||
return errors.WithStack(ErrNoPermissions)
|
||||
}
|
||||
|
||||
// This is a reply to another message, decrease reply counter on the original, on struct and in the
|
||||
@@ -321,7 +326,7 @@ func (svc *message) Delete(ID uint64) error {
|
||||
bq = append(bq, original)
|
||||
}
|
||||
|
||||
if err = svc.message.DeleteMessageByID(ID); err != nil {
|
||||
if err = svc.message.DeleteByID(messageID); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -332,7 +337,7 @@ func (svc *message) Delete(ID uint64) error {
|
||||
deletedMsg.DeletedAt = timeNowPtr()
|
||||
}
|
||||
|
||||
if err = svc.updateMentions(ID, nil); err != nil {
|
||||
if err = svc.updateMentions(messageID, nil); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -352,14 +357,14 @@ func (svc *message) MarkAsRead(channelID, threadID, lastReadMessageID uint64) (c
|
||||
if ch, err = svc.findChannelByID(channelID); err != nil {
|
||||
return err
|
||||
} else if !svc.prm.CanReadChannel(ch) {
|
||||
return errors.New("not allowed to access channel")
|
||||
return errors.WithStack(ErrNoPermissions)
|
||||
} else if !ch.IsValid() {
|
||||
return errors.New("invalid channel")
|
||||
}
|
||||
|
||||
if threadID > 0 {
|
||||
// Validate thread
|
||||
if thread, err = svc.message.FindMessageByID(threadID); err != nil {
|
||||
if thread, err = svc.message.FindByID(threadID); err != nil {
|
||||
return errors.Wrap(err, "unable to verify thread")
|
||||
} else if !thread.IsValid() {
|
||||
return errors.New("invalid thread")
|
||||
@@ -368,7 +373,7 @@ func (svc *message) MarkAsRead(channelID, threadID, lastReadMessageID uint64) (c
|
||||
|
||||
if lastReadMessageID > 0 {
|
||||
// Validate thread
|
||||
if lastMessage, err = svc.message.FindMessageByID(lastReadMessageID); err != nil {
|
||||
if lastMessage, err = svc.message.FindByID(lastReadMessageID); err != nil {
|
||||
return errors.Wrap(err, "unable to verify last message")
|
||||
} else if !lastMessage.IsValid() {
|
||||
return errors.New("invalid message")
|
||||
@@ -445,22 +450,26 @@ func (svc *message) flag(messageID uint64, flag string, remove bool) error {
|
||||
if f.ID == 0 && remove {
|
||||
// Skip removing, flag does not exists
|
||||
return nil
|
||||
} else if f.ID > 0 && !remove {
|
||||
}
|
||||
if f.ID > 0 && !remove {
|
||||
// Skip adding, flag already exists
|
||||
return nil
|
||||
} else if err != nil && err != repository.ErrMessageFlagNotFound {
|
||||
}
|
||||
if err != nil && err != repository.ErrMessageFlagNotFound {
|
||||
// Other errors, exit
|
||||
return
|
||||
}
|
||||
|
||||
if msg, err = svc.message.FindMessageByID(messageID); err != nil {
|
||||
if msg, err = svc.message.FindByID(messageID); err != nil {
|
||||
return
|
||||
} else if ch, err = svc.findChannelByID(msg.ChannelID); err != nil {
|
||||
return
|
||||
} else if !svc.prm.CanReadChannel(ch) {
|
||||
return errors.New("not allowed to access channel")
|
||||
} else if f.IsReaction() && !svc.prm.CanReactMessage(ch) {
|
||||
return errors.New("not allowed to react on channels")
|
||||
}
|
||||
if !svc.prm.CanReadChannel(ch) {
|
||||
return errors.WithStack(ErrNoPermissions)
|
||||
}
|
||||
if f.IsReaction() && !svc.prm.CanReactMessage(ch) {
|
||||
return errors.WithStack(ErrNoPermissions)
|
||||
}
|
||||
|
||||
if remove {
|
||||
@@ -476,9 +485,10 @@ func (svc *message) flag(messageID uint64, flag string, remove bool) error {
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
return
|
||||
}
|
||||
|
||||
// @todo: log possible error
|
||||
svc.sendFlagEvent(f)
|
||||
|
||||
return
|
||||
@@ -607,7 +617,7 @@ func (svc *message) sendEvent(mm ...*types.Message) (err error) {
|
||||
msg.User, _ = svc.usr.FindByID(msg.UserID)
|
||||
}
|
||||
|
||||
if err = svc.evl.Message(msg); err != nil {
|
||||
if err = svc.event.Message(msg); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -618,7 +628,7 @@ func (svc *message) sendEvent(mm ...*types.Message) (err error) {
|
||||
// Sends message to event loop
|
||||
func (svc *message) sendFlagEvent(ff ...*types.MessageFlag) (err error) {
|
||||
for _, f := range ff {
|
||||
if err = svc.evl.MessageFlag(f); err != nil {
|
||||
if err = svc.event.MessageFlag(f); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -688,7 +698,7 @@ func (svc message) findChannelByID(channelID uint64) (ch *types.Channel, err err
|
||||
mm types.ChannelMemberSet
|
||||
)
|
||||
|
||||
if ch, err = svc.channel.FindChannelByID(channelID); err != nil {
|
||||
if ch, err = svc.channel.FindByID(channelID); err != nil {
|
||||
return nil, err
|
||||
} else if mm, err = svc.cmember.Find(&types.ChannelMemberFilter{ChannelID: ch.ID}); err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -33,28 +33,30 @@ type (
|
||||
CanCreatePrivateChannel() bool
|
||||
CanCreateGroupChannel() bool
|
||||
|
||||
CanUpdateChannel(ch *types.Channel) bool
|
||||
CanReadChannel(ch *types.Channel) bool
|
||||
CanJoinChannel(ch *types.Channel) bool
|
||||
CanLeaveChannel(ch *types.Channel) bool
|
||||
CanDeleteChannel(ch *types.Channel) bool
|
||||
CanUndeleteChannel(ch *types.Channel) bool
|
||||
CanArchiveChannel(ch *types.Channel) bool
|
||||
CanUnarchiveChannel(ch *types.Channel) bool
|
||||
CanUpdateChannel(*types.Channel) bool
|
||||
CanReadChannel(*types.Channel) bool
|
||||
CanJoinChannel(*types.Channel) bool
|
||||
CanLeaveChannel(*types.Channel) bool
|
||||
CanDeleteChannel(*types.Channel) bool
|
||||
CanUndeleteChannel(*types.Channel) bool
|
||||
CanArchiveChannel(*types.Channel) bool
|
||||
CanUnarchiveChannel(*types.Channel) bool
|
||||
|
||||
CanManageChannelMembers(ch *types.Channel) bool
|
||||
CanManageChannelWebhooks(ch *types.Channel) bool
|
||||
CanManageChannelAttachments(ch *types.Channel) bool
|
||||
CanManageChannelMembers(*types.Channel) bool
|
||||
CanManageChannelAttachments(*types.Channel) bool
|
||||
|
||||
CanSendMessage(ch *types.Channel) bool
|
||||
CanReplyMessage(ch *types.Channel) bool
|
||||
CanEmbedMessage(ch *types.Channel) bool
|
||||
CanAttachMessage(ch *types.Channel) bool
|
||||
CanUpdateOwnMessages(ch *types.Channel) bool
|
||||
CanUpdateMessages(ch *types.Channel) bool
|
||||
CanDeleteOwnMessages(ch *types.Channel) bool
|
||||
CanDeleteMessages(ch *types.Channel) bool
|
||||
CanReactMessage(ch *types.Channel) bool
|
||||
CanManageWebhooks(*types.Webhook) bool
|
||||
CanManageOwnWebhooks(*types.Webhook) bool
|
||||
|
||||
CanSendMessage(*types.Channel) bool
|
||||
CanReplyMessage(*types.Channel) bool
|
||||
CanEmbedMessage(*types.Channel) bool
|
||||
CanAttachMessage(*types.Channel) bool
|
||||
CanUpdateOwnMessages(*types.Channel) bool
|
||||
CanUpdateMessages(*types.Channel) bool
|
||||
CanDeleteOwnMessages(*types.Channel) bool
|
||||
CanDeleteMessages(*types.Channel) bool
|
||||
CanReactMessage(*types.Channel) bool
|
||||
}
|
||||
|
||||
effectivePermission struct {
|
||||
@@ -64,10 +66,8 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
func Permissions() PermissionsService {
|
||||
return (&permissions{
|
||||
rules: systemService.DefaultRules,
|
||||
}).With(context.Background())
|
||||
func Permissions(ctx context.Context) PermissionsService {
|
||||
return (&permissions{}).With(ctx)
|
||||
}
|
||||
|
||||
func (p *permissions) With(ctx context.Context) PermissionsService {
|
||||
@@ -154,8 +154,12 @@ func (p *permissions) CanManageChannelMembers(ch *types.Channel) bool {
|
||||
return p.checkAccess(ch, "members.manage", p.isChannelOwnerFallback(ch))
|
||||
}
|
||||
|
||||
func (p *permissions) CanManageChannelWebhooks(ch *types.Channel) bool {
|
||||
return p.checkAccess(ch, "webhooks.manage")
|
||||
func (p *permissions) CanManageWebhooks(webhook *types.Webhook) bool {
|
||||
return p.checkAccess(webhook, "webhook.manage.all")
|
||||
}
|
||||
|
||||
func (p *permissions) CanManageOwnWebhooks(webhook *types.Webhook) bool {
|
||||
return p.checkAccess(webhook, "webhook.manage.own")
|
||||
}
|
||||
|
||||
func (p *permissions) CanManageChannelAttachments(ch *types.Channel) bool {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"log"
|
||||
"sync"
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/crusttech/crust/internal/config"
|
||||
"github.com/crusttech/crust/internal/http"
|
||||
"github.com/crusttech/crust/internal/store"
|
||||
)
|
||||
|
||||
@@ -15,7 +16,6 @@ type (
|
||||
)
|
||||
|
||||
var (
|
||||
o sync.Once
|
||||
DefaultAttachment AttachmentService
|
||||
DefaultChannel ChannelService
|
||||
DefaultMessage MessageService
|
||||
@@ -24,20 +24,29 @@ var (
|
||||
DefaultPermissions PermissionsService
|
||||
)
|
||||
|
||||
func Init() {
|
||||
o.Do(func() {
|
||||
fs, err := store.New("var/store")
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to initialize store: %v", err)
|
||||
}
|
||||
func Init() error {
|
||||
fs, err := store.New("var/store")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
DefaultPermissions = Permissions()
|
||||
DefaultEvent = Event()
|
||||
DefaultAttachment = Attachment(fs)
|
||||
DefaultMessage = Message()
|
||||
DefaultChannel = Channel()
|
||||
DefaultPubSub = PubSub()
|
||||
_, err := http.New(&config.HTTPClient{
|
||||
Timeout: 10,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
DefaultPermissions = Permissions(ctx)
|
||||
DefaultEvent = Event(ctx)
|
||||
DefaultAttachment = Attachment(ctx, fs)
|
||||
DefaultMessage = Message(ctx)
|
||||
DefaultChannel = Channel(ctx)
|
||||
DefaultPubSub = PubSub()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func timeNowPtr() *time.Time {
|
||||
|
||||
Reference in New Issue
Block a user