diff --git a/integrations/access/jira/client.go b/integrations/access/jira/client.go index 8777ed9e1a13c..3933f653d63d8 100644 --- a/integrations/access/jira/client.go +++ b/integrations/access/jira/client.go @@ -163,6 +163,17 @@ func statusFromStatusCode(httpCode int) types.PluginStatus { return &types.PluginStatusV1{Code: code} } +// buildSummary creates the Issue's summary by using the user name and roles. +// No official docs seem to exist, but it's _known_ that summary field must be less than 255 chars: +// Eg https://community.atlassian.com/t5/Jira-questions/Summary-must-be-less-than-255-characters/qaq-p/989632 +func buildSummary(reqData RequestData) string { + summary := fmt.Sprintf("%s requested %s", reqData.User, strings.Join(reqData.Roles, ", ")) + if len(summary) <= 254 { + return summary + } + return fmt.Sprintf("%s requested access to %d roles", reqData.User, len(reqData.Roles)) +} + // HealthCheck checks Jira endpoint for validity and also checks the project permissions. func (j *Jira) HealthCheck(ctx context.Context) error { log := logger.Get(ctx) @@ -244,7 +255,7 @@ func (j *Jira) CreateIssue(ctx context.Context, reqID string, reqData RequestDat Fields: IssueFieldsInput{ Type: &IssueType{Name: j.issueType}, Project: &Project{Key: j.project}, - Summary: fmt.Sprintf("%s requested %s", reqData.User, strings.Join(reqData.Roles, ", ")), + Summary: buildSummary(reqData), Description: description, }, } diff --git a/integrations/access/jira/client_test.go b/integrations/access/jira/client_test.go new file mode 100644 index 0000000000000..fcbe7005549c8 --- /dev/null +++ b/integrations/access/jira/client_test.go @@ -0,0 +1,56 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package jira + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestBuildSummary(t *testing.T) { + for _, tt := range []struct { + name string + reqData RequestData + expected string + }{ + { + name: "single role", + reqData: RequestData{ + Roles: []string{"editor"}, + User: "my-user", + }, + expected: "my-user requested editor", + }, + { + name: "lots of roles that exceed the field size are truncated", + reqData: RequestData{ + Roles: strings.Split(strings.TrimRight(strings.Repeat("editor,", 1000), ","), ","), + User: "my-user", + }, + expected: "my-user requested access to 1000 roles", + }, + } { + t.Run(tt.name, func(t *testing.T) { + got := buildSummary(tt.reqData) + require.Equal(t, tt.expected, got) + }) + } +}