Skip to content

Commit 4916f46

Browse files
authored
Merge pull request #662 from actiontech/dev-sqle-ee-gbase-8a-datasource
fix: require non-empty DB service password on add/update
2 parents 4772ac2 + a13bcb1 commit 4916f46

3 files changed

Lines changed: 327 additions & 0 deletions

File tree

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package v1
2+
3+
import (
4+
"strings"
5+
"testing"
6+
7+
utilConf "github.com/actiontech/dms/pkg/dms-common/pkg/config"
8+
)
9+
10+
func TestAddDBServiceReq_EmptyPasswordRejected(t *testing.T) {
11+
t.Parallel()
12+
13+
base := func(password string) *AddDBServiceReq {
14+
return &AddDBServiceReq{
15+
ProjectUid: "700300",
16+
DBService: &DBService{
17+
Name: "gbase8a_empty_pwd",
18+
DBType: "GBase-8a",
19+
Host: "10.186.16.126",
20+
Port: "5258",
21+
User: "root",
22+
Password: password,
23+
Business: "default",
24+
MaintenanceTimes: nil,
25+
},
26+
}
27+
}
28+
29+
t.Run("password_empty_string", func(t *testing.T) {
30+
t.Parallel()
31+
err := utilConf.Validate(base(""))
32+
if err == nil {
33+
t.Fatal("expected empty password to fail Add validation")
34+
}
35+
msg := strings.ToLower(err.Error())
36+
if !strings.Contains(msg, "password") || !strings.Contains(msg, "required") {
37+
t.Fatalf("expected Password required validation error, got: %v", err)
38+
}
39+
})
40+
41+
t.Run("password_non_empty_passes_password_rule", func(t *testing.T) {
42+
t.Parallel()
43+
if err := utilConf.Validate(base("not-empty")); err != nil {
44+
t.Fatalf("expected non-empty password to pass Add validation, got: %v", err)
45+
}
46+
})
47+
}
48+
49+
func TestAddDBServiceReq_MissingHostStillRequired(t *testing.T) {
50+
t.Parallel()
51+
52+
req := &AddDBServiceReq{
53+
ProjectUid: "700300",
54+
DBService: &DBService{
55+
Name: "gbase8a_missing_host",
56+
DBType: "GBase-8a",
57+
Host: "",
58+
Port: "5258",
59+
User: "root",
60+
Password: "not-empty",
61+
Business: "default",
62+
},
63+
}
64+
65+
err := utilConf.Validate(req)
66+
if err == nil {
67+
t.Fatal("expected missing Host to fail validation")
68+
}
69+
msg := err.Error()
70+
if !strings.Contains(msg, "Host") || !strings.Contains(msg, "required") {
71+
t.Fatalf("expected Host required validation error, got: %v", err)
72+
}
73+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package v2
2+
3+
import (
4+
"strings"
5+
"testing"
6+
7+
utilConf "github.com/actiontech/dms/pkg/dms-common/pkg/config"
8+
)
9+
10+
func TestAddDBServiceReq_EmptyPasswordRejected(t *testing.T) {
11+
t.Parallel()
12+
13+
base := func(password string) *AddDBServiceReq {
14+
return &AddDBServiceReq{
15+
ProjectUid: "700300",
16+
DBService: &DBService{
17+
Name: "gbase8a_empty_pwd",
18+
DBType: "GBase-8a",
19+
Host: "10.186.16.126",
20+
Port: "5258",
21+
User: "root",
22+
Password: password,
23+
EnvironmentTagUID: "2086752861772845056",
24+
MaintenanceTimes: nil,
25+
},
26+
}
27+
}
28+
29+
t.Run("password_empty_string", func(t *testing.T) {
30+
t.Parallel()
31+
err := utilConf.Validate(base(""))
32+
if err == nil {
33+
t.Fatal("expected empty password to fail Add validation")
34+
}
35+
msg := strings.ToLower(err.Error())
36+
if !strings.Contains(msg, "password") || !strings.Contains(msg, "required") {
37+
t.Fatalf("expected Password required validation error, got: %v", err)
38+
}
39+
})
40+
41+
t.Run("password_non_empty_passes_password_rule", func(t *testing.T) {
42+
t.Parallel()
43+
if err := utilConf.Validate(base("not-empty")); err != nil {
44+
t.Fatalf("expected non-empty password to pass Add validation, got: %v", err)
45+
}
46+
})
47+
}
48+
49+
func TestAddDBServiceReq_MissingHostStillRequired(t *testing.T) {
50+
t.Parallel()
51+
52+
req := &AddDBServiceReq{
53+
ProjectUid: "700300",
54+
DBService: &DBService{
55+
Name: "gbase8a_missing_host",
56+
DBType: "GBase-8a",
57+
Host: "",
58+
Port: "5258",
59+
User: "root",
60+
Password: "not-empty",
61+
EnvironmentTagUID: "2086752861772845056",
62+
},
63+
}
64+
65+
err := utilConf.Validate(req)
66+
if err == nil {
67+
t.Fatal("expected missing Host to fail validation")
68+
}
69+
msg := err.Error()
70+
if !strings.Contains(msg, "Host") || !strings.Contains(msg, "required") {
71+
t.Fatalf("expected Host required validation error, got: %v", err)
72+
}
73+
}
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
package biz
2+
3+
import (
4+
"context"
5+
"io"
6+
"strings"
7+
"testing"
8+
9+
pkgConst "github.com/actiontech/dms/internal/dms/pkg/constant"
10+
utilLog "github.com/actiontech/dms/pkg/dms-common/pkg/log"
11+
)
12+
13+
type fakeDBServiceRepoForPassword struct {
14+
svc *DBService
15+
updated *DBService
16+
}
17+
18+
func (f *fakeDBServiceRepoForPassword) SaveDBServices(context.Context, []*DBService) error {
19+
return nil
20+
}
21+
func (f *fakeDBServiceRepoForPassword) GetDBServicesByIds(context.Context, []string) ([]*DBService, error) {
22+
return nil, nil
23+
}
24+
func (f *fakeDBServiceRepoForPassword) ListDBServices(context.Context, *ListDBServicesOption) ([]*DBService, int64, error) {
25+
return nil, 0, nil
26+
}
27+
func (f *fakeDBServiceRepoForPassword) DelDBService(context.Context, string) error { return nil }
28+
func (f *fakeDBServiceRepoForPassword) GetDBService(_ context.Context, _ string) (*DBService, error) {
29+
return f.svc, nil
30+
}
31+
func (f *fakeDBServiceRepoForPassword) GetDBServices(context.Context, []pkgConst.FilterCondition) ([]*DBService, error) {
32+
return nil, nil
33+
}
34+
func (f *fakeDBServiceRepoForPassword) CheckDBServiceExist(context.Context, []string) (bool, error) {
35+
return true, nil
36+
}
37+
func (f *fakeDBServiceRepoForPassword) UpdateDBService(_ context.Context, dbService *DBService) error {
38+
f.updated = dbService
39+
return nil
40+
}
41+
func (f *fakeDBServiceRepoForPassword) CountDBService(context.Context) ([]DBTypeCount, error) {
42+
return nil, nil
43+
}
44+
func (f *fakeDBServiceRepoForPassword) GetBusinessByProjectUID(context.Context, string) ([]string, error) {
45+
return nil, nil
46+
}
47+
func (f *fakeDBServiceRepoForPassword) GetFieldDistinctValue(context.Context, DBServiceField, interface{}) error {
48+
return nil
49+
}
50+
51+
type fakeProjectRepoForPassword struct {
52+
project *Project
53+
}
54+
55+
func (f *fakeProjectRepoForPassword) SaveProject(context.Context, *Project) error { return nil }
56+
func (f *fakeProjectRepoForPassword) BatchSaveProjects(context.Context, []*Project) error {
57+
return nil
58+
}
59+
func (f *fakeProjectRepoForPassword) ListProjects(context.Context, *ListProjectsOption, string) ([]*Project, int64, error) {
60+
return nil, 0, nil
61+
}
62+
func (f *fakeProjectRepoForPassword) GetProject(context.Context, string) (*Project, error) {
63+
return f.project, nil
64+
}
65+
func (f *fakeProjectRepoForPassword) GetProjectByName(context.Context, string) (*Project, error) {
66+
return f.project, nil
67+
}
68+
func (f *fakeProjectRepoForPassword) GetProjectByNames(context.Context, []string) ([]*Project, error) {
69+
return []*Project{f.project}, nil
70+
}
71+
func (f *fakeProjectRepoForPassword) UpdateProject(context.Context, *Project) error { return nil }
72+
func (f *fakeProjectRepoForPassword) DelProject(context.Context, string) error { return nil }
73+
func (f *fakeProjectRepoForPassword) UpdateDBServiceBusiness(context.Context, string, string, string) error {
74+
return nil
75+
}
76+
77+
type fakeEnvTagRepoForPassword struct {
78+
tag *EnvironmentTag
79+
}
80+
81+
func (f *fakeEnvTagRepoForPassword) CreateEnvironmentTag(context.Context, *EnvironmentTag) error {
82+
return nil
83+
}
84+
func (f *fakeEnvTagRepoForPassword) UpdateEnvironmentTag(context.Context, string, string, string) error {
85+
return nil
86+
}
87+
func (f *fakeEnvTagRepoForPassword) DeleteEnvironmentTag(context.Context, string) error { return nil }
88+
func (f *fakeEnvTagRepoForPassword) GetEnvironmentTagByName(context.Context, string, string) (bool, *EnvironmentTag, error) {
89+
return true, f.tag, nil
90+
}
91+
func (f *fakeEnvTagRepoForPassword) GetEnvironmentTagByUID(context.Context, string) (*EnvironmentTag, error) {
92+
return f.tag, nil
93+
}
94+
func (f *fakeEnvTagRepoForPassword) ListEnvironmentTags(context.Context, *ListEnvironmentTagsOption) ([]*EnvironmentTag, int64, error) {
95+
return nil, 0, nil
96+
}
97+
98+
func newDBServiceUsecaseForEmptyPasswordTest(repo *fakeDBServiceRepoForPassword) *DBServiceUsecase {
99+
logger := utilLog.NewMyLogger(io.Discard)
100+
projectRepo := &fakeProjectRepoForPassword{
101+
project: &Project{UID: "700300", Status: ProjectStatusActive},
102+
}
103+
projectUC := &ProjectUsecase{
104+
repo: projectRepo,
105+
log: utilLog.NewHelper(logger, utilLog.WithMessageKey("biz.project.test")),
106+
}
107+
opUC := NewOpPermissionVerifyUsecase(logger, nil, &mockOpPermissionVerifyRepo{}, &mockUserRepo{users: map[string]*User{}})
108+
envUC := &EnvironmentTagUsecase{
109+
environmentTagRepo: &fakeEnvTagRepoForPassword{
110+
tag: &EnvironmentTag{UID: "env-1", Name: "prod"},
111+
},
112+
log: utilLog.NewHelper(logger, utilLog.WithMessageKey("biz.env.test")),
113+
}
114+
pluginUC := &PluginUsecase{registeredPlugins: nil}
115+
return NewDBServiceUsecase(logger, repo, nil, pluginUC, opUC, projectUC, nil, envUC)
116+
}
117+
118+
func TestUpdateDBServiceByArgs_EmptyPasswordRejected(t *testing.T) {
119+
repo := &fakeDBServiceRepoForPassword{
120+
svc: &DBService{
121+
UID: "ds-1",
122+
Name: "gbase8a",
123+
DBType: "GBase-8a",
124+
Host: "10.186.16.126",
125+
Port: "5258",
126+
User: "root",
127+
Password: "old-secret",
128+
ProjectUID: "700300",
129+
},
130+
}
131+
uc := newDBServiceUsecaseForEmptyPasswordTest(repo)
132+
empty := ""
133+
err := uc.UpdateDBServiceByArgs(context.Background(), "ds-1", &BizDBServiceArgs{
134+
DBType: "GBase-8a",
135+
Host: "10.186.16.126",
136+
Port: "5258",
137+
User: "root",
138+
Password: &empty,
139+
EnvironmentTagUID: "env-1",
140+
}, pkgConst.UIDOfUserAdmin)
141+
if err == nil {
142+
t.Fatal("expected Update with password=\"\" to fail")
143+
}
144+
if !strings.Contains(err.Error(), "password can't be empty") {
145+
t.Fatalf("expected \"password can't be empty\", got: %v", err)
146+
}
147+
if repo.updated != nil {
148+
t.Fatal("expected UpdateDBService not to be called when password is empty")
149+
}
150+
}
151+
152+
func TestUpdateDBServiceByArgs_MissingHostStillRejected(t *testing.T) {
153+
repo := &fakeDBServiceRepoForPassword{
154+
svc: &DBService{
155+
UID: "ds-1",
156+
Name: "gbase8a",
157+
DBType: "GBase-8a",
158+
Host: "10.186.16.126",
159+
Port: "5258",
160+
User: "root",
161+
Password: "old-secret",
162+
ProjectUID: "700300",
163+
},
164+
}
165+
uc := newDBServiceUsecaseForEmptyPasswordTest(repo)
166+
pwd := "not-empty"
167+
err := uc.UpdateDBServiceByArgs(context.Background(), "ds-1", &BizDBServiceArgs{
168+
DBType: "GBase-8a",
169+
Host: "",
170+
Port: "5258",
171+
User: "root",
172+
Password: &pwd,
173+
EnvironmentTagUID: "env-1",
174+
}, pkgConst.UIDOfUserAdmin)
175+
if err == nil {
176+
t.Fatal("expected missing Host to fail Update")
177+
}
178+
if !strings.Contains(err.Error(), "host") {
179+
t.Fatalf("expected host-related error, got: %v", err)
180+
}
181+
}

0 commit comments

Comments
 (0)