mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-27 12:46:03 +01:00
Merge pull request #8176 from stonezdj/http_group
Refactor LDAP usergroup
This commit is contained in:
commit
c296f0ddfb
@ -15,10 +15,8 @@
|
||||
package group
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/goharbor/harbor/src/common"
|
||||
"github.com/goharbor/harbor/src/common/utils"
|
||||
|
||||
"github.com/goharbor/harbor/src/common/dao"
|
||||
@ -139,20 +137,3 @@ func OnBoardUserGroup(g *models.UserGroup, keyAttribute string, combinedKeyAttri
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetGroupDNQueryCondition get the part of IN ('XXX', 'XXX') condition
|
||||
func GetGroupDNQueryCondition(userGroupList []*models.UserGroup) string {
|
||||
result := make([]string, 0)
|
||||
count := 0
|
||||
for _, userGroup := range userGroupList {
|
||||
if userGroup.GroupType == common.LdapGroupType {
|
||||
result = append(result, "'"+userGroup.LdapGroupDN+"'")
|
||||
count++
|
||||
}
|
||||
}
|
||||
// No LDAP Group found
|
||||
if count == 0 {
|
||||
return ""
|
||||
}
|
||||
return strings.Join(result, ",")
|
||||
}
|
||||
|
@ -47,6 +47,8 @@ func TestMain(m *testing.M) {
|
||||
initSqls := []string{
|
||||
"insert into harbor_user (username, email, password, realname) values ('member_test_01', 'member_test_01@example.com', '123456', 'member_test_01')",
|
||||
"insert into project (name, owner_id) values ('member_test_01', 1)",
|
||||
`insert into project (name, owner_id) values ('group_project2', 1)`,
|
||||
`insert into project (name, owner_id) values ('group_project_private', 1)`,
|
||||
"insert into user_group (group_name, group_type, ldap_group_dn) values ('test_group_01', 1, 'cn=harbor_users,ou=sample,ou=vmware,dc=harbor,dc=com')",
|
||||
"update project set owner_id = (select user_id from harbor_user where username = 'member_test_01') where name = 'member_test_01'",
|
||||
"insert into project_member (project_id, entity_id, entity_type, role) values ( (select project_id from project where name = 'member_test_01') , (select user_id from harbor_user where username = 'member_test_01'), 'u', 1)",
|
||||
@ -55,6 +57,8 @@ func TestMain(m *testing.M) {
|
||||
|
||||
clearSqls := []string{
|
||||
"delete from project where name='member_test_01'",
|
||||
"delete from project where name='group_project2'",
|
||||
"delete from project where name='group_project_private'",
|
||||
"delete from harbor_user where username='member_test_01' or username='pm_sample'",
|
||||
"delete from user_group",
|
||||
"delete from project_member",
|
||||
@ -175,7 +179,7 @@ func TestUpdateUserGroup(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
fmt.Printf("id=%v", createdUserGroupID)
|
||||
fmt.Printf("id=%v\n", createdUserGroupID)
|
||||
if err := UpdateUserGroupName(tt.args.id, tt.args.groupName); (err != nil) != tt.wantErr {
|
||||
t.Errorf("UpdateUserGroup() error = %v, wantErr %v", err, tt.wantErr)
|
||||
userGroup, err := GetUserGroup(tt.args.id)
|
||||
@ -249,40 +253,6 @@ func TestOnBoardUserGroup(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetGroupDNQueryCondition(t *testing.T) {
|
||||
userGroupList := []*models.UserGroup{
|
||||
{
|
||||
GroupName: "sample1",
|
||||
GroupType: 1,
|
||||
LdapGroupDN: "cn=sample1_users,ou=groups,dc=example,dc=com",
|
||||
},
|
||||
{
|
||||
GroupName: "sample2",
|
||||
GroupType: 1,
|
||||
LdapGroupDN: "cn=sample2_users,ou=groups,dc=example,dc=com",
|
||||
},
|
||||
{
|
||||
GroupName: "sample3",
|
||||
GroupType: 0,
|
||||
LdapGroupDN: "cn=sample3_users,ou=groups,dc=example,dc=com",
|
||||
},
|
||||
}
|
||||
|
||||
groupQueryConditions := GetGroupDNQueryCondition(userGroupList)
|
||||
expectedConditions := `'cn=sample1_users,ou=groups,dc=example,dc=com','cn=sample2_users,ou=groups,dc=example,dc=com'`
|
||||
if groupQueryConditions != expectedConditions {
|
||||
t.Errorf("Failed to GetGroupDNQueryCondition, expected %v, actual %v", expectedConditions, groupQueryConditions)
|
||||
}
|
||||
var userGroupList2 []*models.UserGroup
|
||||
groupQueryCondition2 := GetGroupDNQueryCondition(userGroupList2)
|
||||
if len(groupQueryCondition2) > 0 {
|
||||
t.Errorf("Failed to GetGroupDNQueryCondition, expected %v, actual %v", "", groupQueryCondition2)
|
||||
}
|
||||
groupQueryCondition3 := GetGroupDNQueryCondition(nil)
|
||||
if len(groupQueryCondition3) > 0 {
|
||||
t.Errorf("Failed to GetGroupDNQueryCondition, expected %v, actual %v", "", groupQueryCondition3)
|
||||
}
|
||||
}
|
||||
func TestGetGroupProjects(t *testing.T) {
|
||||
userID, err := dao.Register(models.User{
|
||||
Username: "grouptestu09",
|
||||
@ -322,7 +292,6 @@ func TestGetGroupProjects(t *testing.T) {
|
||||
})
|
||||
defer project.DeleteProjectMemberByID(pmid)
|
||||
type args struct {
|
||||
groupDNCondition string
|
||||
query *models.ProjectQueryParam
|
||||
}
|
||||
member := &models.MemberQuery{
|
||||
@ -335,19 +304,17 @@ func TestGetGroupProjects(t *testing.T) {
|
||||
wantErr bool
|
||||
}{
|
||||
{"Query with group DN",
|
||||
args{"'cn=harbor_users,ou=groups,dc=example,dc=com'",
|
||||
&models.ProjectQueryParam{
|
||||
args{&models.ProjectQueryParam{
|
||||
Member: member,
|
||||
}},
|
||||
1, false},
|
||||
{"Query without group DN",
|
||||
args{"",
|
||||
&models.ProjectQueryParam{}},
|
||||
args{&models.ProjectQueryParam{}},
|
||||
1, false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := dao.GetGroupProjects(tt.args.groupDNCondition, tt.args.query)
|
||||
got, err := dao.GetGroupProjects([]int{groupID}, tt.args.query)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("GetGroupProjects() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
@ -392,7 +359,6 @@ func TestGetTotalGroupProjects(t *testing.T) {
|
||||
})
|
||||
defer project.DeleteProjectMemberByID(pmid)
|
||||
type args struct {
|
||||
groupDNCondition string
|
||||
query *models.ProjectQueryParam
|
||||
}
|
||||
tests := []struct {
|
||||
@ -401,18 +367,16 @@ func TestGetTotalGroupProjects(t *testing.T) {
|
||||
wantSize int
|
||||
wantErr bool
|
||||
}{
|
||||
{"Query with group DN",
|
||||
args{"'cn=harbor_users,ou=groups,dc=example,dc=com'",
|
||||
&models.ProjectQueryParam{}},
|
||||
{"Query with group ID",
|
||||
args{&models.ProjectQueryParam{}},
|
||||
1, false},
|
||||
{"Query without group DN",
|
||||
args{"",
|
||||
&models.ProjectQueryParam{}},
|
||||
{"Query without group ID",
|
||||
args{&models.ProjectQueryParam{}},
|
||||
1, false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := dao.GetTotalGroupProjects(tt.args.groupDNCondition, tt.args.query)
|
||||
got, err := dao.GetTotalGroupProjects([]int{groupID}, tt.args.query)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("GetGroupProjects() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
@ -423,3 +387,44 @@ func TestGetTotalGroupProjects(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
func TestGetRolesByLDAPGroup(t *testing.T) {
|
||||
|
||||
userGroupList, err := QueryUserGroup(models.UserGroup{LdapGroupDN: "cn=harbor_users,ou=sample,ou=vmware,dc=harbor,dc=com", GroupType: 1})
|
||||
if err != nil || len(userGroupList) < 1 {
|
||||
t.Errorf("failed to query user group, err %v", err)
|
||||
}
|
||||
project, err := dao.GetProjectByName("member_test_01")
|
||||
if err != nil {
|
||||
t.Errorf("Error occurred when Get project by name: %v", err)
|
||||
}
|
||||
privateProject, err := dao.GetProjectByName("group_project_private")
|
||||
if err != nil {
|
||||
t.Errorf("Error occurred when Get project by name: %v", err)
|
||||
}
|
||||
|
||||
type args struct {
|
||||
projectID int64
|
||||
groupIDs []int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantSize int
|
||||
wantErr bool
|
||||
}{
|
||||
{"Check normal", args{projectID: project.ProjectID, groupIDs: []int{userGroupList[0].ID}}, 1, false},
|
||||
{"Check non exist", args{projectID: privateProject.ProjectID, groupIDs: []int{9999}}, 0, false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := dao.GetRolesByGroupID(tt.args.projectID, tt.args.groupIDs)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("TestGetRolesByLDAPGroup() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if len(got) != tt.wantSize {
|
||||
t.Errorf("TestGetRolesByLDAPGroup() = %v, want %v", len(got), tt.wantSize)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -156,18 +156,19 @@ func GetProjects(query *models.ProjectQueryParam) ([]*models.Project, error) {
|
||||
|
||||
// GetGroupProjects - Get user's all projects, including user is the user member of this project
|
||||
// and the user is in the group which is a group member of this project.
|
||||
func GetGroupProjects(groupDNCondition string, query *models.ProjectQueryParam) ([]*models.Project, error) {
|
||||
func GetGroupProjects(groupIDs []int, query *models.ProjectQueryParam) ([]*models.Project, error) {
|
||||
sql, params := projectQueryConditions(query)
|
||||
sql = `select distinct p.project_id, p.name, p.owner_id,
|
||||
p.creation_time, p.update_time ` + sql
|
||||
if len(groupDNCondition) > 0 {
|
||||
groupIDCondition := JoinNumberConditions(groupIDs)
|
||||
if len(groupIDs) > 0 {
|
||||
sql = fmt.Sprintf(
|
||||
`%s union select distinct p.project_id, p.name, p.owner_id, p.creation_time, p.update_time
|
||||
from project p
|
||||
left join project_member pm on p.project_id = pm.project_id
|
||||
left join user_group ug on ug.id = pm.entity_id and pm.entity_type = 'g' and ug.group_type = 1
|
||||
where ug.ldap_group_dn in ( %s ) order by name`,
|
||||
sql, groupDNCondition)
|
||||
left join user_group ug on ug.id = pm.entity_id and pm.entity_type = 'g'
|
||||
where ug.id in ( %s ) order by name`,
|
||||
sql, groupIDCondition)
|
||||
}
|
||||
sqlStr, queryParams := CreatePagination(query, sql, params)
|
||||
log.Debugf("query sql:%v", sql)
|
||||
@ -178,10 +179,11 @@ func GetGroupProjects(groupDNCondition string, query *models.ProjectQueryParam)
|
||||
|
||||
// GetTotalGroupProjects - Get the total count of projects, including user is the member of this project and the
|
||||
// user is in the group, which is the group member of this project.
|
||||
func GetTotalGroupProjects(groupDNCondition string, query *models.ProjectQueryParam) (int, error) {
|
||||
func GetTotalGroupProjects(groupIDs []int, query *models.ProjectQueryParam) (int, error) {
|
||||
var sql string
|
||||
sqlCondition, params := projectQueryConditions(query)
|
||||
if len(groupDNCondition) == 0 {
|
||||
groupIDCondition := JoinNumberConditions(groupIDs)
|
||||
if len(groupIDs) == 0 {
|
||||
sql = `select count(1) ` + sqlCondition
|
||||
} else {
|
||||
sql = fmt.Sprintf(
|
||||
@ -189,9 +191,9 @@ func GetTotalGroupProjects(groupDNCondition string, query *models.ProjectQueryPa
|
||||
from ( select p.project_id %s union select p.project_id
|
||||
from project p
|
||||
left join project_member pm on p.project_id = pm.project_id
|
||||
left join user_group ug on ug.id = pm.entity_id and pm.entity_type = 'g' and ug.group_type = 1
|
||||
where ug.ldap_group_dn in ( %s )) t`,
|
||||
sqlCondition, groupDNCondition)
|
||||
left join user_group ug on ug.id = pm.entity_id and pm.entity_type = 'g'
|
||||
where ug.id in ( %s )) t`,
|
||||
sqlCondition, groupIDCondition)
|
||||
}
|
||||
log.Debugf("query sql:%v", sql)
|
||||
var count int
|
||||
@ -291,24 +293,24 @@ func DeleteProject(id int64) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// GetRolesByLDAPGroup - Get Project roles of the
|
||||
// specified group DN is a member of current project
|
||||
func GetRolesByLDAPGroup(projectID int64, groupDNCondition string) ([]int, error) {
|
||||
// GetRolesByGroupID - Get Project roles of the
|
||||
// specified group is a member of current project
|
||||
func GetRolesByGroupID(projectID int64, groupIDs []int) ([]int, error) {
|
||||
var roles []int
|
||||
if len(groupDNCondition) == 0 {
|
||||
if len(groupIDs) == 0 {
|
||||
return roles, nil
|
||||
}
|
||||
groupIDCondition := JoinNumberConditions(groupIDs)
|
||||
o := GetOrmer()
|
||||
// Because an LDAP user can be memberof multiple groups,
|
||||
// the role is in descent order (1-admin, 2-developer, 3-guest, 4-master), use min to select the max privilege role.
|
||||
sql := fmt.Sprintf(
|
||||
`select min(pm.role) from project_member pm
|
||||
left join user_group ug on pm.entity_type = 'g' and pm.entity_id = ug.id
|
||||
where ug.ldap_group_dn in ( %s ) and pm.project_id = ? `,
|
||||
groupDNCondition)
|
||||
where ug.id in ( %s ) and pm.project_id = ?`,
|
||||
groupIDCondition)
|
||||
log.Debugf("sql:%v", sql)
|
||||
if _, err := o.Raw(sql, projectID).QueryRows(&roles); err != nil {
|
||||
log.Warningf("Error in GetRolesByLDAPGroup, error: %v", err)
|
||||
log.Warningf("Error in GetRolesByGroupID, error: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
// If there is no row selected, the min returns an empty row, to avoid return 0 as role
|
||||
|
@ -148,16 +148,3 @@ func SearchMemberByName(projectID int64, entityName string) ([]*models.Member, e
|
||||
_, err := o.Raw(sql, queryParam).QueryRows(&members)
|
||||
return members, err
|
||||
}
|
||||
|
||||
// GetRolesByGroup -- Query group roles
|
||||
func GetRolesByGroup(projectID int64, groupDNCondition string) []int {
|
||||
var roles []int
|
||||
o := dao.GetOrmer()
|
||||
sql := `select role from project_member pm
|
||||
left join user_group ug on pm.project_id = ?
|
||||
where ug.group_type = 1 and ug.ldap_group_dn in (` + groupDNCondition + `)`
|
||||
if _, err := o.Raw(sql, projectID).QueryRows(&roles); err != nil {
|
||||
return roles
|
||||
}
|
||||
return roles
|
||||
}
|
||||
|
@ -305,30 +305,3 @@ func PrepareGroupTest() {
|
||||
}
|
||||
dao.PrepareTestData(clearSqls, initSqls)
|
||||
}
|
||||
func TestGetRolesByGroup(t *testing.T) {
|
||||
PrepareGroupTest()
|
||||
|
||||
project, err := dao.GetProjectByName("group_project")
|
||||
if err != nil {
|
||||
t.Errorf("Error occurred when GetProjectByName : %v", err)
|
||||
}
|
||||
type args struct {
|
||||
projectID int64
|
||||
groupDNCondition string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want []int
|
||||
}{
|
||||
{"Query group with role", args{project.ProjectID, "'cn=harbor_user,dc=example,dc=com'"}, []int{2}},
|
||||
{"Query group no role", args{project.ProjectID, "'cn=another_user,dc=example,dc=com'"}, []int{}},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := GetRolesByGroup(tt.args.projectID, tt.args.groupDNCondition); !dao.ArrayEqual(got, tt.want) {
|
||||
t.Errorf("GetRolesByGroup() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -118,36 +118,6 @@ func Test_projectQueryConditions(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetGroupProjects(t *testing.T) {
|
||||
prepareGroupTest()
|
||||
query := &models.ProjectQueryParam{Member: &models.MemberQuery{Name: "sample_group"}}
|
||||
type args struct {
|
||||
groupDNCondition string
|
||||
query *models.ProjectQueryParam
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantSize int
|
||||
wantErr bool
|
||||
}{
|
||||
{"Verify correct sql", args{groupDNCondition: "'cn=harbor_user,dc=example,dc=com'", query: query}, 1, false},
|
||||
{"Verify missed sql", args{groupDNCondition: "'cn=another_user,dc=example,dc=com'", query: query}, 0, false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := GetGroupProjects(tt.args.groupDNCondition, tt.args.query)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("GetGroupProjects() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if len(got) != tt.wantSize {
|
||||
t.Errorf("GetGroupProjects() = %v, want %v", got, tt.wantSize)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func prepareGroupTest() {
|
||||
initSqls := []string{
|
||||
`insert into user_group (group_name, group_type, ldap_group_dn) values ('harbor_group_01', 1, 'cn=harbor_user,dc=example,dc=com')`,
|
||||
@ -169,73 +139,6 @@ func prepareGroupTest() {
|
||||
PrepareTestData(clearSqls, initSqls)
|
||||
}
|
||||
|
||||
func TestGetTotalGroupProjects(t *testing.T) {
|
||||
prepareGroupTest()
|
||||
query := &models.ProjectQueryParam{Member: &models.MemberQuery{Name: "sample_group"}}
|
||||
type args struct {
|
||||
groupDNCondition string
|
||||
query *models.ProjectQueryParam
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want int
|
||||
wantErr bool
|
||||
}{
|
||||
{"Verify correct sql", args{groupDNCondition: "'cn=harbor_user,dc=example,dc=com'", query: query}, 1, false},
|
||||
{"Verify missed sql", args{groupDNCondition: "'cn=another_user,dc=example,dc=com'", query: query}, 0, false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := GetTotalGroupProjects(tt.args.groupDNCondition, tt.args.query)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("GetTotalGroupProjects() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if got != tt.want {
|
||||
t.Errorf("GetTotalGroupProjects() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetRolesByLDAPGroup(t *testing.T) {
|
||||
prepareGroupTest()
|
||||
project, err := GetProjectByName("group_project")
|
||||
if err != nil {
|
||||
t.Errorf("Error occurred when Get project by name: %v", err)
|
||||
}
|
||||
privateProject, err := GetProjectByName("group_project_private")
|
||||
if err != nil {
|
||||
t.Errorf("Error occurred when Get project by name: %v", err)
|
||||
}
|
||||
type args struct {
|
||||
projectID int64
|
||||
groupDNCondition string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantSize int
|
||||
wantErr bool
|
||||
}{
|
||||
{"Check normal", args{project.ProjectID, "'cn=harbor_user,dc=example,dc=com'"}, 1, false},
|
||||
{"Check non exist", args{privateProject.ProjectID, "'cn=not_harbor_user,dc=example,dc=com'"}, 0, false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := GetRolesByLDAPGroup(tt.args.projectID, tt.args.groupDNCondition)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("TestGetRolesByLDAPGroup() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if len(got) != tt.wantSize {
|
||||
t.Errorf("TestGetRolesByLDAPGroup() = %v, want %v", len(got), tt.wantSize)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestProjetExistsByName(t *testing.T) {
|
||||
name := "project_exist_by_name_test"
|
||||
exist := ProjectExistsByName(name)
|
||||
|
11
src/common/dao/utils.go
Normal file
11
src/common/dao/utils.go
Normal file
@ -0,0 +1,11 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// JoinNumberConditions - To join number condition into string,used in sql query
|
||||
func JoinNumberConditions(ids []int) string {
|
||||
return strings.Trim(strings.Replace(fmt.Sprint(ids), " ", ",", -1), "[]")
|
||||
}
|
24
src/common/dao/utils_test.go
Normal file
24
src/common/dao/utils_test.go
Normal file
@ -0,0 +1,24 @@
|
||||
package dao
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestJoinNumberConditions(t *testing.T) {
|
||||
type args struct {
|
||||
ids []int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{name: "normal test", args: args{[]int{1, 2, 3}}, want: "1,2,3"},
|
||||
{name: "dummy test", args: args{[]int{}}, want: ""},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := JoinNumberConditions(tt.args.ids); got != tt.want {
|
||||
t.Errorf("JoinNumberConditions() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -130,7 +130,7 @@ type ProjectQueryParam struct {
|
||||
type MemberQuery struct {
|
||||
Name string // the username of member
|
||||
Role int // the role of the member has to the project
|
||||
GroupList []*UserGroup // the group list of current user
|
||||
GroupIDs []int // the group ID of current user belongs to
|
||||
}
|
||||
|
||||
// Pagination ...
|
||||
|
@ -40,7 +40,7 @@ type User struct {
|
||||
Salt string `orm:"column(salt)" json:"-"`
|
||||
CreationTime time.Time `orm:"column(creation_time);auto_now_add" json:"creation_time"`
|
||||
UpdateTime time.Time `orm:"column(update_time);auto_now" json:"update_time"`
|
||||
GroupList []*UserGroup `orm:"-" json:"-"`
|
||||
GroupIDs []int `orm:"-" json:"-"`
|
||||
OIDCUserMeta *OIDCUser `orm:"-" json:"oidc_user_meta,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,6 @@ package local
|
||||
import (
|
||||
"github.com/goharbor/harbor/src/common"
|
||||
"github.com/goharbor/harbor/src/common/dao"
|
||||
"github.com/goharbor/harbor/src/common/dao/group"
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
"github.com/goharbor/harbor/src/common/rbac"
|
||||
"github.com/goharbor/harbor/src/common/rbac/project"
|
||||
@ -140,12 +139,11 @@ func (s *SecurityContext) GetRolesByGroup(projectIDOrName interface{}) []int {
|
||||
user := s.user
|
||||
project, err := s.pm.Get(projectIDOrName)
|
||||
// No user, group or project info
|
||||
if err != nil || project == nil || user == nil || len(user.GroupList) == 0 {
|
||||
if err != nil || project == nil || user == nil || len(user.GroupIDs) == 0 {
|
||||
return roles
|
||||
}
|
||||
// Get role by LDAP group
|
||||
groupDNConditions := group.GetGroupDNQueryCondition(user.GroupList)
|
||||
roles, err = dao.GetRolesByLDAPGroup(project.ProjectID, groupDNConditions)
|
||||
// Get role by Group ID
|
||||
roles, err = dao.GetRolesByGroupID(project.ProjectID, user.GroupIDs)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
@ -158,7 +156,7 @@ func (s *SecurityContext) GetMyProjects() ([]*models.Project, error) {
|
||||
&models.ProjectQueryParam{
|
||||
Member: &models.MemberQuery{
|
||||
Name: s.GetUsername(),
|
||||
GroupList: s.user.GroupList,
|
||||
GroupIDs: s.user.GroupIDs,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -20,6 +20,7 @@ import (
|
||||
|
||||
"github.com/goharbor/harbor/src/common"
|
||||
"github.com/goharbor/harbor/src/common/dao"
|
||||
"github.com/goharbor/harbor/src/common/dao/group"
|
||||
"github.com/goharbor/harbor/src/common/dao/project"
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
"github.com/goharbor/harbor/src/common/rbac"
|
||||
@ -253,9 +254,16 @@ func TestHasPushPullPermWithGroup(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Errorf("Error occurred when GetUser: %v", err)
|
||||
}
|
||||
developer.GroupList = []*models.UserGroup{
|
||||
{GroupName: "test_group", GroupType: 1, LdapGroupDN: "cn=harbor_user,dc=example,dc=com"},
|
||||
|
||||
userGroups, err := group.QueryUserGroup(models.UserGroup{GroupType: common.LdapGroupType, LdapGroupDN: "cn=harbor_user,dc=example,dc=com"})
|
||||
if err != nil {
|
||||
t.Errorf("Failed to query user group %v", err)
|
||||
}
|
||||
if len(userGroups) < 1 {
|
||||
t.Errorf("Failed to retrieve user group")
|
||||
}
|
||||
|
||||
developer.GroupIDs = []int{userGroups[0].ID}
|
||||
|
||||
resource := rbac.NewProjectNamespace(project.Name).Resource(rbac.ResourceRepository)
|
||||
|
||||
@ -332,9 +340,15 @@ func TestSecurityContext_GetRolesByGroup(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Errorf("Error occurred when GetUser: %v", err)
|
||||
}
|
||||
developer.GroupList = []*models.UserGroup{
|
||||
{GroupName: "test_group", GroupType: 1, LdapGroupDN: "cn=harbor_user,dc=example,dc=com"},
|
||||
userGroups, err := group.QueryUserGroup(models.UserGroup{GroupType: common.LdapGroupType, LdapGroupDN: "cn=harbor_user,dc=example,dc=com"})
|
||||
if err != nil {
|
||||
t.Errorf("Failed to query user group %v", err)
|
||||
}
|
||||
if len(userGroups) < 1 {
|
||||
t.Errorf("Failed to retrieve user group")
|
||||
}
|
||||
|
||||
developer.GroupIDs = []int{userGroups[0].ID}
|
||||
type fields struct {
|
||||
user *models.User
|
||||
pm promgr.ProjectManager
|
||||
|
@ -20,11 +20,11 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/goharbor/harbor/src/common"
|
||||
"github.com/goharbor/harbor/src/common/dao"
|
||||
"github.com/goharbor/harbor/src/common/dao/group"
|
||||
"github.com/goharbor/harbor/src/common/utils"
|
||||
goldap "gopkg.in/ldap.v2"
|
||||
|
||||
"github.com/goharbor/harbor/src/common/dao"
|
||||
"github.com/goharbor/harbor/src/common/dao/group"
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
ldapUtils "github.com/goharbor/harbor/src/common/utils/ldap"
|
||||
"github.com/goharbor/harbor/src/common/utils/log"
|
||||
@ -79,7 +79,7 @@ func (l *Auth) Authenticate(m models.AuthModel) (*models.User, error) {
|
||||
u.Username = ldapUsers[0].Username
|
||||
u.Email = strings.TrimSpace(ldapUsers[0].Email)
|
||||
u.Realname = ldapUsers[0].Realname
|
||||
userGroups := make([]*models.UserGroup, 0)
|
||||
ugIDs := []int{}
|
||||
|
||||
dn := ldapUsers[0].DN
|
||||
if err = ldapSession.Bind(dn, m.Password); err != nil {
|
||||
@ -95,6 +95,7 @@ func (l *Auth) Authenticate(m models.AuthModel) (*models.User, error) {
|
||||
for _, groupDN := range ldapUsers[0].GroupDNList {
|
||||
|
||||
groupDN = utils.TrimLower(groupDN)
|
||||
// Attach LDAP group admin
|
||||
if len(groupAdminDN) > 0 && groupAdminDN == groupDN {
|
||||
u.HasAdminRole = true
|
||||
}
|
||||
@ -103,16 +104,16 @@ func (l *Auth) Authenticate(m models.AuthModel) (*models.User, error) {
|
||||
GroupType: 1,
|
||||
LdapGroupDN: groupDN,
|
||||
}
|
||||
userGroupList, err := group.QueryUserGroup(userGroupQuery)
|
||||
userGroups, err := group.QueryUserGroup(userGroupQuery)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if len(userGroupList) == 0 {
|
||||
if len(userGroups) == 0 {
|
||||
continue
|
||||
}
|
||||
userGroups = append(userGroups, userGroupList[0])
|
||||
ugIDs = append(ugIDs, userGroups[0].ID)
|
||||
}
|
||||
u.GroupList = userGroups
|
||||
u.GroupIDs = ugIDs
|
||||
|
||||
return &u, nil
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/goharbor/harbor/src/common/dao"
|
||||
"github.com/goharbor/harbor/src/common/dao/group"
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
"github.com/goharbor/harbor/src/common/utils"
|
||||
errutil "github.com/goharbor/harbor/src/common/utils/error"
|
||||
@ -132,19 +131,16 @@ func (d *driver) Update(projectIDOrName interface{},
|
||||
func (d *driver) List(query *models.ProjectQueryParam) (*models.ProjectQueryResult, error) {
|
||||
var total int64
|
||||
var projects []*models.Project
|
||||
var groupDNCondition string
|
||||
|
||||
// List with LDAP group projects
|
||||
var groupIDs []int
|
||||
if query != nil && query.Member != nil {
|
||||
groupDNCondition = group.GetGroupDNQueryCondition(query.Member.GroupList)
|
||||
groupIDs = query.Member.GroupIDs
|
||||
}
|
||||
|
||||
count, err := dao.GetTotalGroupProjects(groupDNCondition, query)
|
||||
count, err := dao.GetTotalGroupProjects(groupIDs, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
total = int64(count)
|
||||
projects, err = dao.GetGroupProjects(groupDNCondition, query)
|
||||
projects, err = dao.GetGroupProjects(groupIDs, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user