3
0

fix(messaging): fix stutters, Init(), errors

This commit is contained in:
Tit Petric
2019-04-03 15:05:23 +02:00
parent 8315c76b75
commit ec736aecd9
7 changed files with 216 additions and 194 deletions
+9 -11
View File
@@ -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{}
+77 -80
View File
@@ -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
}
+7 -3
View File
@@ -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"
)
+3 -3
View File
@@ -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(),
}
}
+66 -56
View File
@@ -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
+30 -26
View File
@@ -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 {
+24 -15
View File
@@ -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 {