mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-08 19:50:05 +01:00
Merge pull request #4412 from stonezdj/add_ldap_group_param
Add LDAP Group Search Configure Param
This commit is contained in:
commit
139a0c59ba
@ -12,6 +12,10 @@ LDAP_UID=$ldap_uid
|
|||||||
LDAP_SCOPE=$ldap_scope
|
LDAP_SCOPE=$ldap_scope
|
||||||
LDAP_TIMEOUT=$ldap_timeout
|
LDAP_TIMEOUT=$ldap_timeout
|
||||||
LDAP_VERIFY_CERT=$ldap_verify_cert
|
LDAP_VERIFY_CERT=$ldap_verify_cert
|
||||||
|
LDAP_GROUP_BASEDN=$ldap_group_basedn
|
||||||
|
LDAP_GROUP_FILTER=$ldap_group_filter
|
||||||
|
LDAP_GROUP_GID=$ldap_group_gid
|
||||||
|
LDAP_GROUP_SCOPE=$ldap_group_scope
|
||||||
DATABASE_TYPE=mysql
|
DATABASE_TYPE=mysql
|
||||||
MYSQL_HOST=$db_host
|
MYSQL_HOST=$db_host
|
||||||
MYSQL_PORT=$db_port
|
MYSQL_PORT=$db_port
|
||||||
|
@ -91,6 +91,18 @@ ldap_timeout = 5
|
|||||||
#Verify certificate from LDAP server
|
#Verify certificate from LDAP server
|
||||||
ldap_verify_cert = true
|
ldap_verify_cert = true
|
||||||
|
|
||||||
|
#The base dn from which to lookup a group in LDAP/AD
|
||||||
|
ldap_group_basedn = ou=group,dc=mydomain,dc=com
|
||||||
|
|
||||||
|
#filter to search LDAP/AD group
|
||||||
|
ldap_group_filter = objectclass=group
|
||||||
|
|
||||||
|
#The attribute used to name a LDAP/AD group, it could be cn, name
|
||||||
|
ldap_group_gid = cn
|
||||||
|
|
||||||
|
#The scope to search for ldap groups. 0-LDAP_SCOPE_BASE, 1-LDAP_SCOPE_ONELEVEL, 2-LDAP_SCOPE_SUBTREE
|
||||||
|
ldap_group_scope = 2
|
||||||
|
|
||||||
#Turn on or off the self-registration feature
|
#Turn on or off the self-registration feature
|
||||||
self_registration = on
|
self_registration = on
|
||||||
|
|
||||||
|
@ -224,6 +224,10 @@ ldap_uid = rcp.get("configuration", "ldap_uid")
|
|||||||
ldap_scope = rcp.get("configuration", "ldap_scope")
|
ldap_scope = rcp.get("configuration", "ldap_scope")
|
||||||
ldap_timeout = rcp.get("configuration", "ldap_timeout")
|
ldap_timeout = rcp.get("configuration", "ldap_timeout")
|
||||||
ldap_verify_cert = rcp.get("configuration", "ldap_verify_cert")
|
ldap_verify_cert = rcp.get("configuration", "ldap_verify_cert")
|
||||||
|
ldap_group_basedn = rcp.get("configuration", "ldap_group_basedn")
|
||||||
|
ldap_group_filter = rcp.get("configuration", "ldap_group_filter")
|
||||||
|
ldap_group_gid = rcp.get("configuration", "ldap_group_gid")
|
||||||
|
ldap_group_scope = rcp.get("configuration", "ldap_group_scope")
|
||||||
db_password = rcp.get("configuration", "db_password")
|
db_password = rcp.get("configuration", "db_password")
|
||||||
db_host = rcp.get("configuration", "db_host")
|
db_host = rcp.get("configuration", "db_host")
|
||||||
db_user = rcp.get("configuration", "db_user")
|
db_user = rcp.get("configuration", "db_user")
|
||||||
@ -325,6 +329,10 @@ render(os.path.join(templates_dir, "adminserver", "env"),
|
|||||||
ldap_scope=ldap_scope,
|
ldap_scope=ldap_scope,
|
||||||
ldap_verify_cert=ldap_verify_cert,
|
ldap_verify_cert=ldap_verify_cert,
|
||||||
ldap_timeout=ldap_timeout,
|
ldap_timeout=ldap_timeout,
|
||||||
|
ldap_group_basedn=ldap_group_basedn,
|
||||||
|
ldap_group_filter=ldap_group_filter,
|
||||||
|
ldap_group_gid=ldap_group_gid,
|
||||||
|
ldap_group_scope=ldap_group_scope,
|
||||||
db_password=db_password,
|
db_password=db_password,
|
||||||
db_host=db_host,
|
db_host=db_host,
|
||||||
db_user=db_user,
|
db_user=db_user,
|
||||||
|
@ -89,6 +89,13 @@ var (
|
|||||||
env: "LDAP_VERIFY_CERT",
|
env: "LDAP_VERIFY_CERT",
|
||||||
parse: parseStringToBool,
|
parse: parseStringToBool,
|
||||||
},
|
},
|
||||||
|
common.LDAPGroupBaseDN: "LDAP_GROUP_BASEDN",
|
||||||
|
common.LDAPGroupSearchFilter: "LDAP_GROUP_FILTER",
|
||||||
|
common.LDAPGroupAttributeName: "LDAP_GROUP_GID",
|
||||||
|
common.LDAPGroupSearchScope: &parser{
|
||||||
|
env: "LDAP_GROUP_SCOPE",
|
||||||
|
parse: parseStringToInt,
|
||||||
|
},
|
||||||
common.EmailHost: "EMAIL_HOST",
|
common.EmailHost: "EMAIL_HOST",
|
||||||
common.EmailPort: &parser{
|
common.EmailPort: &parser{
|
||||||
env: "EMAIL_PORT",
|
env: "EMAIL_PORT",
|
||||||
@ -152,7 +159,7 @@ var (
|
|||||||
repeatLoadEnvs = map[string]interface{}{
|
repeatLoadEnvs = map[string]interface{}{
|
||||||
common.ExtEndpoint: "EXT_ENDPOINT",
|
common.ExtEndpoint: "EXT_ENDPOINT",
|
||||||
common.MySQLPassword: "MYSQL_PWD",
|
common.MySQLPassword: "MYSQL_PWD",
|
||||||
common.MySQLHost: "MYSQL_HOST",
|
common.MySQLHost: "MYSQL_HOST",
|
||||||
common.MySQLUsername: "MYSQL_USR",
|
common.MySQLUsername: "MYSQL_USR",
|
||||||
common.MySQLDatabase: "MYSQL_DATABASE",
|
common.MySQLDatabase: "MYSQL_DATABASE",
|
||||||
common.MySQLPort: &parser{
|
common.MySQLPort: &parser{
|
||||||
@ -179,8 +186,8 @@ var (
|
|||||||
common.ClairDBPassword: "CLAIR_DB_PASSWORD",
|
common.ClairDBPassword: "CLAIR_DB_PASSWORD",
|
||||||
common.ClairDBHost: "CLAIR_DB_HOST",
|
common.ClairDBHost: "CLAIR_DB_HOST",
|
||||||
common.ClairDBUsername: "CLAIR_DB_USERNAME",
|
common.ClairDBUsername: "CLAIR_DB_USERNAME",
|
||||||
common.ClairDBPort: &parser{
|
common.ClairDBPort: &parser{
|
||||||
env: "CLAIR_DB_PORT",
|
env: "CLAIR_DB_PORT",
|
||||||
parse: parseStringToInt,
|
parse: parseStringToInt,
|
||||||
},
|
},
|
||||||
common.UAAEndpoint: "UAA_ENDPOINT",
|
common.UAAEndpoint: "UAA_ENDPOINT",
|
||||||
@ -395,4 +402,5 @@ func validLdapScope(cfg map[string]interface{}, isMigrate bool) {
|
|||||||
ldapScope = 0
|
ldapScope = 0
|
||||||
}
|
}
|
||||||
cfg[ldapScopeKey] = ldapScope
|
cfg[ldapScopeKey] = ldapScope
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,10 @@ const (
|
|||||||
LDAPScope = "ldap_scope"
|
LDAPScope = "ldap_scope"
|
||||||
LDAPTimeout = "ldap_timeout"
|
LDAPTimeout = "ldap_timeout"
|
||||||
LDAPVerifyCert = "ldap_verify_cert"
|
LDAPVerifyCert = "ldap_verify_cert"
|
||||||
|
LDAPGroupBaseDN = "ldap_group_base_dn"
|
||||||
|
LDAPGroupSearchFilter = "ldap_group_search_filter"
|
||||||
|
LDAPGroupAttributeName = "ldap_group_attribute_name"
|
||||||
|
LDAPGroupSearchScope = "ldap_group_search_scope"
|
||||||
TokenServiceURL = "token_service_url"
|
TokenServiceURL = "token_service_url"
|
||||||
RegistryURL = "registry_url"
|
RegistryURL = "registry_url"
|
||||||
EmailHost = "email_host"
|
EmailHost = "email_host"
|
||||||
|
@ -27,12 +27,21 @@ type LdapConf struct {
|
|||||||
LdapVerifyCert bool `json:"ldap_verify_cert"`
|
LdapVerifyCert bool `json:"ldap_verify_cert"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LdapGroupConf holds information about ldap group
|
||||||
|
type LdapGroupConf struct {
|
||||||
|
LdapGroupBaseDN string `json:"ldap_group_base_dn,omitempty"`
|
||||||
|
LdapGroupFilter string `json:"ldap_group_filter,omitempty"`
|
||||||
|
LdapGroupNameAttribute string `json:"ldap_group_name_attribute,omitempty"`
|
||||||
|
LdapGroupSearchScope int `json:"ldap_group_search_scope"`
|
||||||
|
}
|
||||||
|
|
||||||
// LdapUser ...
|
// LdapUser ...
|
||||||
type LdapUser struct {
|
type LdapUser struct {
|
||||||
Username string `json:"ldap_username"`
|
Username string `json:"ldap_username"`
|
||||||
Email string `json:"ldap_email"`
|
Email string `json:"ldap_email"`
|
||||||
Realname string `json:"ldap_realname"`
|
Realname string `json:"ldap_realname"`
|
||||||
DN string `json:"-"`
|
DN string `json:"-"`
|
||||||
|
GroupDNList []string `json:"ldap_groupdn"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//LdapImportUser ...
|
//LdapImportUser ...
|
||||||
@ -45,3 +54,9 @@ type LdapFailedImportUser struct {
|
|||||||
UID string `json:"uid"`
|
UID string `json:"uid"`
|
||||||
Error string `json:"err_msg"`
|
Error string `json:"err_msg"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LdapGroup ...
|
||||||
|
type LdapGroup struct {
|
||||||
|
GroupName string `json:"group_name,omitempty"`
|
||||||
|
GroupDN string `json:"group_dn,omitempty"`
|
||||||
|
}
|
||||||
|
@ -185,6 +185,7 @@ func (session *Session) SearchUser(username string) ([]models.LdapUser, error) {
|
|||||||
|
|
||||||
for _, ldapEntry := range result.Entries {
|
for _, ldapEntry := range result.Entries {
|
||||||
var u models.LdapUser
|
var u models.LdapUser
|
||||||
|
groupDNList := []string{}
|
||||||
for _, attr := range ldapEntry.Attributes {
|
for _, attr := range ldapEntry.Attributes {
|
||||||
//OpenLdap sometimes contain leading space in useranme
|
//OpenLdap sometimes contain leading space in useranme
|
||||||
val := strings.TrimSpace(attr.Values[0])
|
val := strings.TrimSpace(attr.Values[0])
|
||||||
@ -200,7 +201,10 @@ func (session *Session) SearchUser(username string) ([]models.LdapUser, error) {
|
|||||||
u.Email = val
|
u.Email = val
|
||||||
case "email":
|
case "email":
|
||||||
u.Email = val
|
u.Email = val
|
||||||
|
case "memberof":
|
||||||
|
groupDNList = append(groupDNList, val)
|
||||||
}
|
}
|
||||||
|
u.GroupDNList = groupDNList
|
||||||
}
|
}
|
||||||
u.DN = ldapEntry.DN
|
u.DN = ldapEntry.DN
|
||||||
ldapUsers = append(ldapUsers, u)
|
ldapUsers = append(ldapUsers, u)
|
||||||
@ -248,20 +252,28 @@ func (session *Session) Open() error {
|
|||||||
|
|
||||||
// SearchLdap to search ldap with the provide filter
|
// SearchLdap to search ldap with the provide filter
|
||||||
func (session *Session) SearchLdap(filter string) (*goldap.SearchResult, error) {
|
func (session *Session) SearchLdap(filter string) (*goldap.SearchResult, error) {
|
||||||
|
attributes := []string{"uid", "cn", "mail", "email", "memberof"}
|
||||||
if err := session.Bind(session.ldapConfig.LdapSearchDn, session.ldapConfig.LdapSearchPassword); err != nil {
|
|
||||||
return nil, fmt.Errorf("Can not bind search dn, error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
attributes := []string{"uid", "cn", "mail", "email"}
|
|
||||||
lowerUID := strings.ToLower(session.ldapConfig.LdapUID)
|
lowerUID := strings.ToLower(session.ldapConfig.LdapUID)
|
||||||
|
|
||||||
if lowerUID != "uid" && lowerUID != "cn" && lowerUID != "mail" && lowerUID != "email" {
|
if lowerUID != "uid" && lowerUID != "cn" && lowerUID != "mail" && lowerUID != "email" {
|
||||||
attributes = append(attributes, session.ldapConfig.LdapUID)
|
attributes = append(attributes, session.ldapConfig.LdapUID)
|
||||||
}
|
}
|
||||||
|
return session.SearchLdapAttribute(session.ldapConfig.LdapBaseDn, filter, attributes)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SearchLdapAttribute - to search ldap with the provide filter, with specified attributes
|
||||||
|
func (session *Session) SearchLdapAttribute(baseDN, filter string, attributes []string) (*goldap.SearchResult, error) {
|
||||||
|
|
||||||
|
if err := session.Bind(session.ldapConfig.LdapSearchDn, session.ldapConfig.LdapSearchPassword); err != nil {
|
||||||
|
return nil, fmt.Errorf("Can not bind search dn, error: %v", err)
|
||||||
|
}
|
||||||
|
filter = strings.TrimSpace(filter)
|
||||||
|
if !(strings.HasPrefix(filter, "(") || strings.HasSuffix(filter, ")")) {
|
||||||
|
filter = "(" + filter + ")"
|
||||||
|
}
|
||||||
log.Debugf("Search ldap with filter:%v", filter)
|
log.Debugf("Search ldap with filter:%v", filter)
|
||||||
searchRequest := goldap.NewSearchRequest(
|
searchRequest := goldap.NewSearchRequest(
|
||||||
session.ldapConfig.LdapBaseDn,
|
baseDN,
|
||||||
session.ldapConfig.LdapScope,
|
session.ldapConfig.LdapScope,
|
||||||
goldap.NeverDerefAliases,
|
goldap.NeverDerefAliases,
|
||||||
0, //Unlimited results
|
0, //Unlimited results
|
||||||
@ -318,3 +330,69 @@ func (session *Session) Close() {
|
|||||||
session.ldapConn.Close()
|
session.ldapConn.Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//SearchGroupByName ...
|
||||||
|
func (session *Session) SearchGroupByName(groupName string) ([]models.LdapGroup, error) {
|
||||||
|
ldapGroupConfig, err := config.LDAPGroupConf()
|
||||||
|
log.Debugf("Ldap group config: %+v", ldapGroupConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return session.searchGroup(ldapGroupConfig.LdapGroupBaseDN, ldapGroupConfig.LdapGroupFilter, groupName, ldapGroupConfig.LdapGroupNameAttribute)
|
||||||
|
}
|
||||||
|
|
||||||
|
//SearchGroupByDN ...
|
||||||
|
func (session *Session) SearchGroupByDN(groupDN string) ([]models.LdapGroup, error) {
|
||||||
|
ldapGroupConfig, err := config.LDAPGroupConf()
|
||||||
|
log.Debugf("Ldap group config: %+v", ldapGroupConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return session.searchGroup(groupDN, ldapGroupConfig.LdapGroupFilter, "", ldapGroupConfig.LdapGroupNameAttribute)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (session *Session) searchGroup(baseDN, filter, groupName, groupNameAttribute string) ([]models.LdapGroup, error) {
|
||||||
|
ldapGroups := make([]models.LdapGroup, 0)
|
||||||
|
log.Debugf("Groupname: %v, basedn: %v", groupName, baseDN)
|
||||||
|
ldapFilter := createGroupSearchFilter(filter, groupName, groupNameAttribute)
|
||||||
|
attributes := []string{groupNameAttribute}
|
||||||
|
result, err := session.SearchLdapAttribute(baseDN, ldapFilter, attributes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, ldapEntry := range result.Entries {
|
||||||
|
var group models.LdapGroup
|
||||||
|
group.GroupDN = ldapEntry.DN
|
||||||
|
for _, attr := range ldapEntry.Attributes {
|
||||||
|
//OpenLdap sometimes contain leading space in useranme
|
||||||
|
val := strings.TrimSpace(attr.Values[0])
|
||||||
|
log.Debugf("Current ldap entry attr name: %s\n", attr.Name)
|
||||||
|
switch strings.ToLower(attr.Name) {
|
||||||
|
case strings.ToLower(groupNameAttribute):
|
||||||
|
group.GroupName = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ldapGroups = append(ldapGroups, group)
|
||||||
|
}
|
||||||
|
return ldapGroups, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func createGroupSearchFilter(oldFilter, groupName, groupNameAttribute string) string {
|
||||||
|
filter := ""
|
||||||
|
groupName = goldap.EscapeFilter(groupName)
|
||||||
|
groupNameAttribute = goldap.EscapeFilter(groupNameAttribute)
|
||||||
|
if len(oldFilter) == 0 {
|
||||||
|
if len(groupName) == 0 {
|
||||||
|
filter = groupNameAttribute + "=*"
|
||||||
|
} else {
|
||||||
|
filter = groupNameAttribute + "=*" + groupName + "*"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if len(groupName) == 0 {
|
||||||
|
filter = oldFilter
|
||||||
|
} else {
|
||||||
|
filter = "(&(" + oldFilter + ")(" + groupNameAttribute + "=*" + groupName + "*))"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filter
|
||||||
|
}
|
||||||
|
@ -15,15 +15,16 @@ package ldap
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/vmware/harbor/src/common/models"
|
|
||||||
|
|
||||||
"github.com/vmware/harbor/src/common"
|
"github.com/vmware/harbor/src/common"
|
||||||
"github.com/vmware/harbor/src/common/dao"
|
"github.com/vmware/harbor/src/common/dao"
|
||||||
|
"github.com/vmware/harbor/src/common/models"
|
||||||
"github.com/vmware/harbor/src/common/utils/log"
|
"github.com/vmware/harbor/src/common/utils/log"
|
||||||
"github.com/vmware/harbor/src/common/utils/test"
|
"github.com/vmware/harbor/src/common/utils/test"
|
||||||
uiConfig "github.com/vmware/harbor/src/ui/config"
|
uiConfig "github.com/vmware/harbor/src/ui/config"
|
||||||
|
goldap "gopkg.in/ldap.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var adminServerLdapTestConfig = map[string]interface{}{
|
var adminServerLdapTestConfig = map[string]interface{}{
|
||||||
@ -217,6 +218,14 @@ func TestSearchUser(t *testing.T) {
|
|||||||
t.Fatalf("failed to search user test!")
|
t.Fatalf("failed to search user test!")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result2, err := session.SearchUser("mike")
|
||||||
|
if err != nil || len(result2) == 0 {
|
||||||
|
t.Fatalf("failed to search user mike!")
|
||||||
|
}
|
||||||
|
if len(result2[0].GroupDNList) < 1 && result2[0].GroupDNList[0] != "cn=harbor_users,ou=groups,dc=example,dc=com" {
|
||||||
|
t.Fatalf("failed to search user mike's memberof")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFormatURL(t *testing.T) {
|
func TestFormatURL(t *testing.T) {
|
||||||
@ -254,3 +263,80 @@ func TestFormatURL(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_createGroupSearchFilter(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
oldFilter string
|
||||||
|
groupName string
|
||||||
|
groupNameAttribute string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{"Normal Filter", args{oldFilter: "objectclass=groupOfNames", groupName: "harbor_users", groupNameAttribute: "cn"}, "(&(objectclass=groupOfNames)(cn=*harbor_users*))"},
|
||||||
|
{"Empty Old", args{groupName: "harbor_users", groupNameAttribute: "cn"}, "cn=*harbor_users*"},
|
||||||
|
{"Empty Both", args{groupNameAttribute: "cn"}, "cn=*"},
|
||||||
|
{"Empty name", args{oldFilter: "objectclass=groupOfNames", groupNameAttribute: "cn"}, "objectclass=groupOfNames"},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := createGroupSearchFilter(tt.args.oldFilter, tt.args.groupName, tt.args.groupNameAttribute); got != tt.want {
|
||||||
|
t.Errorf("createGroupSearchFilter() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSession_SearchGroup(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
ldapConfig models.LdapConf
|
||||||
|
ldapConn *goldap.Conn
|
||||||
|
}
|
||||||
|
type args struct {
|
||||||
|
baseDN string
|
||||||
|
filter string
|
||||||
|
groupName string
|
||||||
|
groupNameAttribute string
|
||||||
|
}
|
||||||
|
|
||||||
|
ldapConfig := models.LdapConf{
|
||||||
|
LdapURL: adminServerLdapTestConfig[common.LDAPURL].(string) + ":389",
|
||||||
|
LdapSearchDn: adminServerLdapTestConfig[common.LDAPSearchDN].(string),
|
||||||
|
LdapScope: 2,
|
||||||
|
LdapSearchPassword: adminServerLdapTestConfig[common.LDAPSearchPwd].(string),
|
||||||
|
LdapBaseDn: adminServerLdapTestConfig[common.LDAPBaseDN].(string),
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
args args
|
||||||
|
want []models.LdapGroup
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{"normal search",
|
||||||
|
fields{ldapConfig: ldapConfig},
|
||||||
|
args{baseDN: "dc=example,dc=com", filter: "objectClass=groupOfNames", groupName: "harbor_users", groupNameAttribute: "cn"},
|
||||||
|
[]models.LdapGroup{models.LdapGroup{GroupName: "harbor_users", GroupDN: "cn=harbor_users,ou=groups,dc=example,dc=com"}}, false},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
session := &Session{
|
||||||
|
ldapConfig: tt.fields.ldapConfig,
|
||||||
|
ldapConn: tt.fields.ldapConn,
|
||||||
|
}
|
||||||
|
session.Open()
|
||||||
|
defer session.Close()
|
||||||
|
got, err := session.searchGroup(tt.args.baseDN, tt.args.filter, tt.args.groupName, tt.args.groupNameAttribute)
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("Session.SearchGroup() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(got, tt.want) {
|
||||||
|
t.Errorf("Session.SearchGroup() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -42,6 +42,10 @@ var adminServerDefaultConfig = map[string]interface{}{
|
|||||||
common.LDAPFilter: "",
|
common.LDAPFilter: "",
|
||||||
common.LDAPScope: 3,
|
common.LDAPScope: 3,
|
||||||
common.LDAPTimeout: 30,
|
common.LDAPTimeout: 30,
|
||||||
|
common.LDAPGroupBaseDN: "dc=example,dc=com",
|
||||||
|
common.LDAPGroupSearchFilter: "objectClass=groupOfNames",
|
||||||
|
common.LDAPGroupSearchScope: 2,
|
||||||
|
common.LDAPGroupAttributeName: "cn",
|
||||||
common.TokenServiceURL: "http://token_service",
|
common.TokenServiceURL: "http://token_service",
|
||||||
common.RegistryURL: "http://registry",
|
common.RegistryURL: "http://registry",
|
||||||
common.EmailHost: "127.0.0.1",
|
common.EmailHost: "127.0.0.1",
|
||||||
|
@ -41,6 +41,10 @@ var (
|
|||||||
common.LDAPScope,
|
common.LDAPScope,
|
||||||
common.LDAPTimeout,
|
common.LDAPTimeout,
|
||||||
common.LDAPVerifyCert,
|
common.LDAPVerifyCert,
|
||||||
|
common.LDAPGroupAttributeName,
|
||||||
|
common.LDAPGroupBaseDN,
|
||||||
|
common.LDAPGroupSearchFilter,
|
||||||
|
common.LDAPGroupSearchScope,
|
||||||
common.EmailHost,
|
common.EmailHost,
|
||||||
common.EmailPort,
|
common.EmailPort,
|
||||||
common.EmailUsername,
|
common.EmailUsername,
|
||||||
@ -66,6 +70,9 @@ var (
|
|||||||
common.LDAPBaseDN,
|
common.LDAPBaseDN,
|
||||||
common.LDAPUID,
|
common.LDAPUID,
|
||||||
common.LDAPFilter,
|
common.LDAPFilter,
|
||||||
|
common.LDAPGroupAttributeName,
|
||||||
|
common.LDAPGroupBaseDN,
|
||||||
|
common.LDAPGroupSearchFilter,
|
||||||
common.EmailHost,
|
common.EmailHost,
|
||||||
common.EmailUsername,
|
common.EmailUsername,
|
||||||
common.EmailPassword,
|
common.EmailPassword,
|
||||||
@ -80,6 +87,7 @@ var (
|
|||||||
common.EmailPort,
|
common.EmailPort,
|
||||||
common.LDAPScope,
|
common.LDAPScope,
|
||||||
common.LDAPTimeout,
|
common.LDAPTimeout,
|
||||||
|
common.LDAPGroupSearchScope,
|
||||||
common.TokenExpiration,
|
common.TokenExpiration,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/vmware/harbor/src/adminserver/client"
|
"github.com/vmware/harbor/src/adminserver/client"
|
||||||
@ -205,6 +206,35 @@ func LDAPConf() (*models.LdapConf, error) {
|
|||||||
return ldapConf, nil
|
return ldapConf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LDAPGroupConf returns the setting of ldap group search
|
||||||
|
func LDAPGroupConf() (*models.LdapGroupConf, error) {
|
||||||
|
|
||||||
|
cfg, err := mg.Get()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ldapGroupConf := &models.LdapGroupConf{LdapGroupSearchScope: 2}
|
||||||
|
if _, ok := cfg[common.LDAPGroupBaseDN]; ok {
|
||||||
|
ldapGroupConf.LdapGroupBaseDN = cfg[common.LDAPGroupBaseDN].(string)
|
||||||
|
}
|
||||||
|
if _, ok := cfg[common.LDAPGroupSearchFilter]; ok {
|
||||||
|
ldapGroupConf.LdapGroupFilter = cfg[common.LDAPGroupSearchFilter].(string)
|
||||||
|
}
|
||||||
|
if _, ok := cfg[common.LDAPGroupAttributeName]; ok {
|
||||||
|
ldapGroupConf.LdapGroupNameAttribute = cfg[common.LDAPGroupAttributeName].(string)
|
||||||
|
}
|
||||||
|
if _, ok := cfg[common.LDAPGroupSearchScope]; ok {
|
||||||
|
if scopeStr, ok := cfg[common.LDAPGroupSearchScope].(string); ok {
|
||||||
|
ldapGroupConf.LdapGroupSearchScope, err = strconv.Atoi(scopeStr)
|
||||||
|
}
|
||||||
|
if scopeFloat, ok := cfg[common.LDAPGroupSearchScope].(float64); ok {
|
||||||
|
ldapGroupConf.LdapGroupSearchScope = int(scopeFloat)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ldapGroupConf, nil
|
||||||
|
}
|
||||||
|
|
||||||
// TokenExpiration returns the token expiration time (in minute)
|
// TokenExpiration returns the token expiration time (in minute)
|
||||||
func TokenExpiration() (int, error) {
|
func TokenExpiration() (int, error) {
|
||||||
cfg, err := mg.Get()
|
cfg, err := mg.Get()
|
||||||
|
@ -75,6 +75,10 @@ func TestConfig(t *testing.T) {
|
|||||||
t.Fatalf("failed to get ldap settings: %v", err)
|
t.Fatalf("failed to get ldap settings: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if _, err := LDAPGroupConf(); err != nil {
|
||||||
|
t.Fatalf("failed to get ldap group settings: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
if _, err := TokenExpiration(); err != nil {
|
if _, err := TokenExpiration(); err != nil {
|
||||||
t.Fatalf("failed to get token expiration: %v", err)
|
t.Fatalf("failed to get token expiration: %v", err)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user