diff --git a/api/v2.0/swagger.yaml b/api/v2.0/swagger.yaml index 85ab299a1..b4ef459f8 100644 --- a/api/v2.0/swagger.yaml +++ b/api/v2.0/swagger.yaml @@ -6135,6 +6135,7 @@ definitions: project_name: type: string description: The name of the project. + maxLength: 255 public: type: boolean description: deprecated, reserved for project creation in replication @@ -8023,6 +8024,7 @@ definitions: properties: email: type: string + maxLength: 255 realname: type: string comment: @@ -8031,6 +8033,7 @@ definitions: type: string username: type: string + maxLength: 255 OIDCUserInfo: type: object properties: diff --git a/src/lib/truncate.go b/src/lib/truncate.go new file mode 100644 index 000000000..2deb9f2e7 --- /dev/null +++ b/src/lib/truncate.go @@ -0,0 +1,25 @@ +// Copyright Project Harbor Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package lib + +// Truncate tries to append the "suffix" to the "str". If the length of the appended string exceeds "n", +// the function truncates the "str" to make sure the "suffix" is appended +func Truncate(str, suffix string, n int) string { + s := str + suffix + if len(s) <= n { + return s + } + return s[:len(str)-(len(s)-n)] + suffix +} diff --git a/src/lib/truncate_test.go b/src/lib/truncate_test.go new file mode 100644 index 000000000..92bf12599 --- /dev/null +++ b/src/lib/truncate_test.go @@ -0,0 +1,42 @@ +// Copyright Project Harbor Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package lib + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestTruncate(t *testing.T) { + assert := assert.New(t) + + // n > length + str := "abc" + suffix := "#123" + n := 10 + assert.Equal("abc#123", Truncate(str, suffix, n)) + + // n == length + str = "abc" + suffix = "#123" + n = 7 + assert.Equal("abc#123", Truncate(str, suffix, n)) + + // n < length + str = "abc" + suffix = "#123" + n = 5 + assert.Equal("a#123", Truncate(str, suffix, n)) +} diff --git a/src/pkg/project/dao/dao.go b/src/pkg/project/dao/dao.go index ddbebe28d..420f4e77f 100644 --- a/src/pkg/project/dao/dao.go +++ b/src/pkg/project/dao/dao.go @@ -20,6 +20,7 @@ import ( "time" "github.com/goharbor/harbor/src/common" + "github.com/goharbor/harbor/src/lib" "github.com/goharbor/harbor/src/lib/orm" "github.com/goharbor/harbor/src/lib/q" "github.com/goharbor/harbor/src/pkg/project/models" @@ -112,7 +113,7 @@ func (d *dao) Delete(ctx context.Context, id int64) error { } project.Deleted = true - project.Name = fmt.Sprintf("%s#%d", project.Name, project.ProjectID) + project.Name = lib.Truncate(project.Name, fmt.Sprintf("#%d", project.ProjectID), 255) o, err := orm.FromContext(ctx) if err != nil { diff --git a/src/pkg/user/manager.go b/src/pkg/user/manager.go index 57465a48a..9fcfef32e 100644 --- a/src/pkg/user/manager.go +++ b/src/pkg/user/manager.go @@ -20,6 +20,7 @@ import ( "strings" "github.com/goharbor/harbor/src/common/utils" + "github.com/goharbor/harbor/src/lib" "github.com/goharbor/harbor/src/lib/errors" "github.com/goharbor/harbor/src/lib/q" "github.com/goharbor/harbor/src/pkg/user/dao" @@ -70,8 +71,8 @@ func (m *manager) Delete(ctx context.Context, id int) error { if err != nil { return err } - u.Username = fmt.Sprintf("%s#%d", u.Username, u.UserID) - u.Email = fmt.Sprintf("%s#%d", u.Email, u.UserID) + u.Username = lib.Truncate(u.Username, fmt.Sprintf("#%d", u.UserID), 255) + u.Email = lib.Truncate(u.Email, fmt.Sprintf("#%d", u.UserID), 255) u.Deleted = true return m.dao.Update(ctx, u, "username", "email", "deleted") }