Skip to content

Commit

Permalink
chore(): NextWithHook with dynamic hook and logic for NotifyLinesExceed
Browse files Browse the repository at this point in the history
  • Loading branch information
alyfinder committed Dec 4, 2024
1 parent 2dfc6fd commit 6711101
Show file tree
Hide file tree
Showing 10 changed files with 189 additions and 43 deletions.
6 changes: 0 additions & 6 deletions internal/core/repos/activities/branch.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"go.breu.io/quantm/internal/core/kernel"
"go.breu.io/quantm/internal/core/repos/defs"
"go.breu.io/quantm/internal/core/repos/fns"
"go.breu.io/quantm/internal/events"
eventsv1 "go.breu.io/quantm/internal/proto/ctrlplane/events/v1"
)

Expand Down Expand Up @@ -379,8 +378,3 @@ func (a *Branch) diff_to_result(ctx context.Context, diff *git.Diff) (*eventsv1.

return result, nil
}

func (a *Branch) LinesExceed(ctx context.Context, diff *events.Event[eventsv1.ChatHook, eventsv1.Diff]) error {
// call the chat provider slack.
return nil
}
4 changes: 2 additions & 2 deletions internal/core/repos/cast/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import (
)

// PushEventToDiffEvent converts a Push event to a diff event.
// TODO - the hook should be a parameter to this function.
func PushEventToDiffEvent(
push *events.Event[eventsv1.RepoHook, eventsv1.Push],
hook int32,
payload *eventsv1.Diff,
) *events.Event[eventsv1.ChatHook, eventsv1.Diff] {
return events.NextWithHook[eventsv1.RepoHook, eventsv1.ChatHook, eventsv1.Push, eventsv1.Diff](
push,
eventsv1.ChatHook_CHAT_HOOK_SLACK,
eventsv1.ChatHook(hook),
events.ScopeDiff,
events.ActionDiff,
).SetPayload(payload)
Expand Down
8 changes: 6 additions & 2 deletions internal/core/repos/states/branch.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/google/uuid"
"go.temporal.io/sdk/workflow"

"go.breu.io/quantm/internal/core/kernel"
"go.breu.io/quantm/internal/core/repos/activities"
"go.breu.io/quantm/internal/core/repos/cast"
"go.breu.io/quantm/internal/core/repos/defs"
Expand Down Expand Up @@ -168,8 +169,11 @@ func (state *Branch) compare_diff(
dlt := diff.GetLines().GetAdded() + diff.GetLines().GetRemoved()

if dlt > state.Repo.Threshold {
event := cast.PushEventToDiffEvent(push, diff)
if err := state.run(ctx, "line_exceed", state.acts.LinesExceed, event, nil); err != nil {
// check the repo's connected chat or user's connected chat.
event := cast.PushEventToDiffEvent(push, state.Messaging.Hook, diff)

io := kernel.Get().ChatHook(eventsv1.ChatHook(state.Messaging.Hook))
if err := state.run(ctx, "line_exceed", io.NotifyLinesExceed, event, nil); err != nil {
state.logger.Error("lines_exceed: unable to to send", "error", err.Error())
}
}
Expand Down
28 changes: 0 additions & 28 deletions internal/db/uuid.go

This file was deleted.

88 changes: 86 additions & 2 deletions internal/hooks/slack/activities/activities.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,18 @@ package activities

import (
"context"
"encoding/json"
"strconv"
"time"

"github.com/google/uuid"
"github.com/slack-go/slack"

"go.breu.io/quantm/internal/db"
"go.breu.io/quantm/internal/events"
"go.breu.io/quantm/internal/hooks/slack/cast"
"go.breu.io/quantm/internal/hooks/slack/config"
"go.breu.io/quantm/internal/hooks/slack/fns"
eventsv1 "go.breu.io/quantm/internal/proto/ctrlplane/events/v1"
)

Expand All @@ -12,8 +22,82 @@ type (
Activities struct{}
)

const (
footer = "Powered by quantm.io"
)

func (a *Activities) NotifyLinesExceed(
ctx context.Context, event *events.Event[eventsv1.RepoHook, eventsv1.Diff],
ctx context.Context, event *events.Event[eventsv1.ChatHook, eventsv1.Diff],
) error {
return nil
var err error

token := ""
target := ""

if event.Subject.UserID != uuid.Nil {
token, target, err = a.to_user(ctx, event.Subject.UserID)
if err != nil {
return err
}
} else {
token, target, err = a.to_repo(ctx, event.Subject.ID)
if err != nil {
return err
}
}

attachment := slack.Attachment{
Color: "warning",
Pretext: "The number of lines in this pull request exceeds the allowed threshold. Please review and adjust accordingly.",
Fallback: "Line Exceed Detected",
MarkdownIn: []string{"fields"},
Footer: footer,
Fields: fns.LineExceedFields(event),
Ts: json.Number(strconv.FormatInt(time.Now().Unix(), 10)),
}

client, err := config.GetSlackClient(token)
if err != nil {
return err
}

return fns.SendMessage(client, target, attachment)
}

func (a *Activities) to_user(ctx context.Context, link_to uuid.UUID) (string, string, error) {
msg, err := db.Queries().GetMessagesByLinkTo(ctx, link_to)
if err != nil {
return "", "", err
}

d, err := cast.ByteToMessageProviderSlackUserInfo(msg.Data)
if err != nil {
return "", "", err
}

token, err := fns.Reveal(d.BotToken, d.ProviderTeamID)
if err != nil {
return "", "", err
}

return token, d.ProviderUserID, nil
}

func (a *Activities) to_repo(ctx context.Context, link_to uuid.UUID) (string, string, error) {
msg, err := db.Queries().GetMessagesByLinkTo(ctx, link_to)
if err != nil {
return "", "", err
}

d, err := cast.ByteToMessageProviderSlackData(msg.Data)
if err != nil {
return "", "", err
}

token, err := fns.Reveal(d.BotToken, d.WorkspaceID)
if err != nil {
return "", "", err
}

return token, d.ChannelID, nil
}
29 changes: 29 additions & 0 deletions internal/hooks/slack/cast/data.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package cast

import (
"encoding/json"

"go.breu.io/quantm/internal/hooks/slack/defs"
)

func ByteToMessageProviderSlackUserInfo(data []byte) (*defs.MessageProviderSlackUserInfo, error) {
d := &defs.MessageProviderSlackUserInfo{}

err := json.Unmarshal(data, d)
if err != nil {
return nil, err
}

return d, nil
}

func ByteToMessageProviderSlackData(data []byte) (*defs.MessageProviderSlackData, error) {
d := &defs.MessageProviderSlackData{}

err := json.Unmarshal(data, d)
if err != nil {
return nil, err
}

return d, nil
}
2 changes: 1 addition & 1 deletion internal/hooks/slack/fns/attachments.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
eventsv1 "go.breu.io/quantm/internal/proto/ctrlplane/events/v1"
)

func LineExceedFields(event *events.Event[eventsv1.RepoHook, eventsv1.Diff]) []slack.AttachmentField {
func LineExceedFields(event *events.Event[eventsv1.ChatHook, eventsv1.Diff]) []slack.AttachmentField {
fields := []slack.AttachmentField{
{
Title: "*Repository*",
Expand Down
24 changes: 24 additions & 0 deletions internal/hooks/slack/fns/crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import (
"crypto/cipher"
"crypto/rand"
"crypto/sha512"
"encoding/base64"
"io"
"log/slog"

"go.breu.io/quantm/internal/auth"
"go.breu.io/quantm/internal/hooks/slack/errors"
Expand Down Expand Up @@ -62,3 +64,25 @@ func Generate(workspaceID string) []byte {

return h.Sum(nil)[:32]
}

// Reveal decodes a base64-encoded encrypted token and decrypts it using a generated key.
func Reveal(botToken, workspaceID string) (string, error) {
// Decode the base64-encoded encrypted token.
decoded, err := base64.StdEncoding.DecodeString(botToken)
if err != nil {
slog.Error("Failed to decode the token", slog.Any("e", err))
return "", err
}

// Generate the same key used for encryption.
key := Generate(workspaceID)

// Decrypt the token.
decrypted, err := Decrypt(decoded, key)
if err != nil {
slog.Error("Failed to decrypt the token", slog.Any("e", err))
return "", err
}

return string(decrypted), nil
}
5 changes: 3 additions & 2 deletions internal/hooks/slack/nomad/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"go.breu.io/quantm/internal/hooks/slack/fns"
eventsv1 "go.breu.io/quantm/internal/proto/ctrlplane/events/v1"
slackv1 "go.breu.io/quantm/internal/proto/hooks/slack/v1"
"go.breu.io/quantm/internal/utils"
)

func _user(
Expand Down Expand Up @@ -54,7 +55,7 @@ func _user(
}

// Convert the string to uuid.UUID
link_to, err := db.ParseUUID(reqst.Msg.GetLinkTo())
link_to, err := utils.ParseUUID(reqst.Msg.GetLinkTo())
if err != nil {
return err
}
Expand Down Expand Up @@ -101,7 +102,7 @@ func _bot(
}

// Convert the string to uuid.UUID
link_to, err := db.ParseUUID(reqst.Msg.GetLinkTo())
link_to, err := utils.ParseUUID(reqst.Msg.GetLinkTo())
if err != nil {
return err
}
Expand Down
38 changes: 38 additions & 0 deletions internal/utils/id.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package utils

import (
"github.com/google/uuid"
)

// NewUUID generates a new version 7 UUID. It returns an error if UUID generation fails.
func NewUUID() (uuid.UUID, error) {
return uuid.NewV7()
}

// MustUUID generates a new version 7 UUID. It panics if UUID generation fails.
//
// The only condition under which it could theoretically return an error is if the underlying system's source of
// randomness is completely broken or unavailable. This is an exceptionally rare and serious system-level problem. It
// would indicate a much deeper issue than just UUID generation. In practice, it almost certainly never going to fail.
// That's why the MustUUID function, which panics on error, is generally considered acceptable in this specific context.
// The panic implies a catastrophic failure of the system's random number generator, which is far more severe than a
// simple UUID generation failure. A crash due to this problem is arguably preferable to silently generating a
// non-unique or predictable UUID, leading to subtle and hard-to-debug issues.
func MustUUID() uuid.UUID {
id, err := NewUUID()
if err != nil {
panic(err)
}

return id
}

// ParseUUID converts a string into a uuid.UUID and returns an error if invalid.
func ParseUUID(input string) (uuid.UUID, error) {
parsed, err := uuid.Parse(input)
if err != nil {
return uuid.Nil, err
}

return parsed, nil
}

0 comments on commit 6711101

Please sign in to comment.