Skip to content

Commit

Permalink
Fix path namespace for Job event handling (#344)
Browse files Browse the repository at this point in the history
* Fix path namespace for Job event handling

The repository data are not included in the `JobEvent` and we can get the namespace only
by the `event.ProjectName` field. This field doesn't match always the real url of the
combinations `[group]/[repo]`

* [fix] use the homepage url to extract the full namespace

* [fix] apply review recommendations

* [fix] normalise namespace unit tests
  • Loading branch information
spirosoik authored Jan 12, 2023
1 parent 0e0a0c4 commit 4f646cf
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 5 deletions.
2 changes: 1 addition & 1 deletion server/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ func (p *Plugin) handleWebhook(w http.ResponseWriter, r *http.Request) {
handlers, errHandler = p.WebhookHandler.HandlePipeline(ctx, event)
case *gitlabLib.JobEvent:
repoPrivate = event.Repository.Visibility == gitlabLib.PrivateVisibility
pathWithNamespace = event.Repository.PathWithNamespace
pathWithNamespace = event.ProjectName
fromUser = event.User.Name
handlers, errHandler = p.WebhookHandler.HandleJobs(ctx, event)
case *gitlabLib.TagEvent:
Expand Down
12 changes: 8 additions & 4 deletions server/webhook/jobs.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,17 @@ func (w *webhook) handleChannelJob(ctx context.Context, event *gitlab.JobEvent)
default:
return res, nil
}
message += fmt.Sprintf("**Repository**: [%s](%s)\n", event.ProjectName, event.Repository.GitHTTPURL)
namespaceMetadata, err := normalizeNamespacedProjectByHomepage(event.Repository.Homepage)
if err != nil {
return nil, err
}
fullNamespacePath := fmt.Sprintf("%s/%s", namespaceMetadata.Namespace, namespaceMetadata.Project)
message += fmt.Sprintf("**Repository**: [%s](%s)\n", fullNamespacePath, event.Repository.GitHTTPURL)
message += fmt.Sprintf("**Triggered By**: %s\n", senderGitlabUsername)
message += fmt.Sprintf("**Visit job [here](%s)** \n", w.gitlabRetreiver.GetJobURL(event.ProjectName, event.BuildID))
message += fmt.Sprintf("**Visit job [here](%s)** \n", w.gitlabRetreiver.GetJobURL(fullNamespacePath, event.BuildID))
toChannels := make([]string, 0)
namespace, project := normalizeNamespacedProject(event.ProjectName)
subs := w.gitlabRetreiver.GetSubscribedChannelsForProject(
ctx, namespace, project,
ctx, namespaceMetadata.Namespace, namespaceMetadata.Project,
repo.Visibility == gitlab.PublicVisibility,
)
for _, sub := range subs {
Expand Down
25 changes: 25 additions & 0 deletions server/webhook/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ package webhook
import (
"context"
"fmt"
"net/url"
"strings"

"github.com/pkg/errors"

"github.com/mattermost/mattermost-plugin-gitlab/server/subscription"

"github.com/microcosm-cc/bluemonday"
Expand Down Expand Up @@ -165,6 +168,28 @@ func normalizeNamespacedProject(pathWithNamespace string) (namespace string, pro
return strings.Join(splits[:len(splits)-1], "/"), splits[len(splits)-1]
}

type namespaceProjectMetadata struct {
Namespace string
Project string
}

// normalizeNamespacedProjectByHomepage converts data from web hooks to format expected by our plugin.
func normalizeNamespacedProjectByHomepage(homepage string) (*namespaceProjectMetadata, error) {
u, err := url.Parse(homepage)
if err != nil {
return nil, errors.Wrap(err, "failed to parse homepage URL")
}
splits := strings.Split(u.Path, "/")
if len(splits) < 2 {
return nil, errors.New("")
}

return &namespaceProjectMetadata{
Namespace: strings.Join(splits[1:len(splits)-1], "/"),
Project: splits[len(splits)-1],
}, nil
}

func sanitizeDescription(description string) string {
var policy = bluemonday.StrictPolicy()
policy.SkipElementsContent("details")
Expand Down
33 changes: 33 additions & 0 deletions server/webhook/webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,36 @@ func TestNormalizeNamespacedProject(t *testing.T) {
})
}
}

var testDataNormalizeNamespacedProjectByHomepage = []testDataNormalizeNamespacedProjectStr{
{
Title: "homepage with group",
InputPathWithNamespace: "http://test.url/group/project",
ExpectedNamespace: "group",
ExpectedProject: "project",
},
{
Title: "homepage with subgroup",
InputPathWithNamespace: "http://test.url/group/subgroup/project",
ExpectedNamespace: "group/subgroup",
ExpectedProject: "project",
},
{
Title: "homepage with subgroup of a subgroup",
InputPathWithNamespace: "http://test.url/group/subgroup/subgroup/project",
ExpectedNamespace: "group/subgroup/subgroup",
ExpectedProject: "project",
},
}

func TestNormalizeNamespacedProjectByHomePate(t *testing.T) {
t.Parallel()
for _, test := range testDataNormalizeNamespacedProjectByHomepage {
t.Run(test.Title, func(t *testing.T) {
namespaceMetadata, err := normalizeNamespacedProjectByHomepage(test.InputPathWithNamespace)
assert.NoError(t, err)
assert.Equal(t, test.ExpectedNamespace, namespaceMetadata.Namespace)
assert.Equal(t, test.ExpectedProject, namespaceMetadata.Project)
})
}
}

0 comments on commit 4f646cf

Please sign in to comment.