Skip to content

Commit

Permalink
add method to send message to groups
Browse files Browse the repository at this point in the history
  • Loading branch information
David Christofas committed Feb 22, 2022
1 parent 2e8bc3e commit 15896b6
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 19 deletions.
5 changes: 5 additions & 0 deletions changelog/unreleased/notifications-service.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Enhancement: Implement notifications service

Implemented the minimal version of the notifications service to be able to notify a user when they received a share.

https://github.com/owncloud/ocis/pull/3217
78 changes: 63 additions & 15 deletions notifications/pkg/channels/channels.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,20 @@ import (
"net/smtp"

gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
groups "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1"
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
"github.com/cs3org/reva/pkg/rgrpc/todo/pool"
"github.com/owncloud/ocis/notifications/pkg/config"
"github.com/owncloud/ocis/ocis-pkg/log"
"github.com/pkg/errors"
)

// Channel defines the methods of a communication channel.
type Channel interface {
// Todo(c0rby): Do we need a PrepareMessage method?
// Maybe channels need to format the message or will the caller
// of SendMessage do that?
// SendMessage sends a message in a channel specific way.
SendMessage(receiver, msg string) error
// SendMessage sends a message to users.
SendMessage(userIDs []string, msg string) error
// SendMessageToGroup sends a message to a group.
SendMessageToGroup(groupdID *groups.GroupId, msg string) error
}

// NewMailChannel instantiates a new mail communication channel.
Expand All @@ -30,28 +32,74 @@ func NewMailChannel(cfg config.Config, logger log.Logger) (Channel, error) {
return Mail{
gatewayClient: gc,
conf: cfg,
logger: logger,
}, nil
}

// Mail is the communcation channel for email.
type Mail struct {
gatewayClient gateway.GatewayAPIClient
conf config.Config
logger log.Logger
}

func (m Mail) SendMessage(receiver, msg string) error {
smtpConf := m.conf.Notifications.SMTP
res, err := m.gatewayClient.Authenticate(context.Background(), &gateway.AuthenticateRequest{
Type: "machine",
ClientId: "userid:" + receiver,
ClientSecret: m.conf.Notifications.MachineAuthSecret,
})
// SendMessage sends a message to all given users.
func (m Mail) SendMessage(userIDs []string, msg string) error {
to, err := m.getReceiverAddresses(userIDs)
if err != nil {
return err
}

to := []string{res.User.Mail}
body := []byte(msg)

smtpConf := m.conf.Notifications.SMTP
auth := smtp.PlainAuth("", smtpConf.Sender, smtpConf.Password, smtpConf.Host)
return smtp.SendMail(smtpConf.Host+":"+smtpConf.Port, auth, smtpConf.Sender, to, body)
if err := smtp.SendMail(smtpConf.Host+":"+smtpConf.Port, auth, smtpConf.Sender, to, body); err != nil {
return errors.Wrap(err, "could not send mail")
}
return nil
}

// SendMessageToGroup sends a message to all members of the given group.
func (m Mail) SendMessageToGroup(groupID *groups.GroupId, msg string) error {
// TODO We need an authenticated context here...
res, err := m.gatewayClient.GetGroup(context.Background(), &groups.GetGroupRequest{GroupId: groupID})
if err != nil {
return err
}
if res.Status.Code != rpc.Code_CODE_OK {
return errors.New("could not get group")
}

members := make([]string, 0, len(res.Group.Members))
for _, id := range res.Group.Members {
members = append(members, id.OpaqueId)
}

return m.SendMessage(members, msg)
}

func (m Mail) getReceiverAddresses(receivers []string) ([]string, error) {
addresses := make([]string, 0, len(receivers))
for _, id := range receivers {
// Authenticate is too costly but at the moment our only option to get the user.
// We don't have an authenticated context so calling `GetUser` doesn't work.
res, err := m.gatewayClient.Authenticate(context.Background(), &gateway.AuthenticateRequest{
Type: "machine",
ClientId: "userid:" + id,
ClientSecret: m.conf.Notifications.MachineAuthSecret,
})
if err != nil {
return nil, err
}
if res.Status.Code != rpc.Code_CODE_OK {
m.logger.Error().
Interface("status", res.Status).
Str("receiver_id", id).
Msg("could not get user")
continue
}
addresses = append(addresses, res.User.Mail)
}

return addresses, nil
}
14 changes: 10 additions & 4 deletions notifications/pkg/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,17 @@ func (s eventsNotifier) Run() error {
go func() {
switch e := evt.(type) {
case events.ShareCreated:
if err := s.channel.SendMessage(e.GranteeUserID.OpaqueId, "You got a share"); err != nil {
s.logger.Error().
Err(err).
Msg("failed to send a message")
msg := "You got a share!"
var err error
if e.GranteeUserID != nil {
err = s.channel.SendMessage([]string{e.GranteeUserID.OpaqueId}, msg)
} else if e.GranteeGroupID != nil {
err = s.channel.SendMessageToGroup(e.GranteeGroupID, msg)
}
s.logger.Error().
Err(err).
Str("event", "ShareCreated").
Msg("failed to send a message")
}
}()
case <-s.signals:
Expand Down

0 comments on commit 15896b6

Please sign in to comment.