diff --git a/make/common/templates/adminserver/env b/make/common/templates/adminserver/env index 0b7c555bc..cfcd1b591 100644 --- a/make/common/templates/adminserver/env +++ b/make/common/templates/adminserver/env @@ -11,6 +11,7 @@ LDAP_FILTER=$ldap_filter LDAP_UID=$ldap_uid LDAP_SCOPE=$ldap_scope LDAP_TIMEOUT=$ldap_timeout +LDAP_VERIFY_CERT=true DATABASE_TYPE=mysql MYSQL_HOST=$db_host MYSQL_PORT=$db_port diff --git a/src/adminserver/systemcfg/systemcfg.go b/src/adminserver/systemcfg/systemcfg.go index 9cbb5d4c8..b60aedd43 100644 --- a/src/adminserver/systemcfg/systemcfg.go +++ b/src/adminserver/systemcfg/systemcfg.go @@ -81,6 +81,10 @@ var ( env: "LDAP_TIMEOUT", parse: parseStringToInt, }, + common.LDAPVerifyCert: &parser{ + env: "LDAP_VERIFY_CERT", + parse: parseStringToBool, + }, common.EmailHost: "EMAIL_HOST", common.EmailPort: &parser{ env: "EMAIL_PORT", diff --git a/src/adminserver/systemcfg/systemcfg_test.go b/src/adminserver/systemcfg/systemcfg_test.go index 6a55ceece..cbc71a29a 100644 --- a/src/adminserver/systemcfg/systemcfg_test.go +++ b/src/adminserver/systemcfg/systemcfg_test.go @@ -90,11 +90,16 @@ func TestLoadFromEnv(t *testing.T) { t.Fatalf("failed to set env: %v", err) } + if err := os.Setenv("LDAP_VERIFY_CERT", "false"); err != nil { + t.Fatalf("failed to set env: %v", err) + } + cfgs = map[string]interface{}{} err = LoadFromEnv(cfgs, false) assert.Nil(t, err) assert.Equal(t, extEndpoint, cfgs[common.ExtEndpoint]) assert.Equal(t, ldapURL, cfgs[common.LDAPURL]) + assert.Equal(t, false, cfgs[common.LDAPVerifyCert]) os.Clearenv() if err := os.Setenv("LDAP_URL", ldapURL); err != nil { @@ -104,6 +109,10 @@ func TestLoadFromEnv(t *testing.T) { t.Fatalf("failed to set env: %v", err) } + if err := os.Setenv("LDAP_VERIFY_CERT", "true"); err != nil { + t.Fatalf("failed to set env: %v", err) + } + cfgs = map[string]interface{}{ common.LDAPURL: "ldap_url", } @@ -111,4 +120,5 @@ func TestLoadFromEnv(t *testing.T) { assert.Nil(t, err) assert.Equal(t, extEndpoint, cfgs[common.ExtEndpoint]) assert.Equal(t, "ldap_url", cfgs[common.LDAPURL]) + assert.Equal(t, true, cfgs[common.LDAPVerifyCert]) } diff --git a/src/common/const.go b/src/common/const.go index ae39ee3ea..c3f01cc81 100644 --- a/src/common/const.go +++ b/src/common/const.go @@ -48,6 +48,7 @@ const ( LDAPFilter = "ldap_filter" LDAPScope = "ldap_scope" LDAPTimeout = "ldap_timeout" + LDAPVerifyCert = "ldap_verify_cert" TokenServiceURL = "token_service_url" RegistryURL = "registry_url" EmailHost = "email_host" diff --git a/src/common/models/config.go b/src/common/models/config.go index ba5c91863..d5c7c4e21 100644 --- a/src/common/models/config.go +++ b/src/common/models/config.go @@ -33,6 +33,7 @@ type LDAP struct { UID string `json:"uid"` Scope int `json:"scope"` Timeout int `json:"timeout"` // in second + VerifyCert bool `json:"verify_cert"` } // Database ... diff --git a/src/common/models/ldap.go b/src/common/models/ldap.go index e26cdfe3f..48e03cc77 100644 --- a/src/common/models/ldap.go +++ b/src/common/models/ldap.go @@ -24,6 +24,7 @@ type LdapConf struct { LdapUID string `json:"ldap_uid"` LdapScope int `json:"ldap_scope"` LdapConnectionTimeout int `json:"ldap_connection_timeout"` + LdapVerifyCert bool `json:"ldap_verify_cert"` } // LdapUser ... diff --git a/src/common/utils/ldap/ldap.go b/src/common/utils/ldap/ldap.go index dc1a7cd97..524008793 100644 --- a/src/common/utils/ldap/ldap.go +++ b/src/common/utils/ldap/ldap.go @@ -60,6 +60,7 @@ func GetSystemLdapConf() (models.LdapConf, error) { ldapConfs.LdapUID = ldap.UID ldapConfs.LdapScope = ldap.Scope ldapConfs.LdapConnectionTimeout = ldap.Timeout + ldapConfs.LdapVerifyCert = ldap.VerifyCert // ldapConfs = config.LDAP().URL // ldapConfs.LdapSearchDn = config.LDAP().SearchDn @@ -205,7 +206,8 @@ func SearchUser(ldapConfs models.LdapConf) ([]models.LdapUser, error) { for _, ldapEntry := range result.Entries { var u models.LdapUser for _, attr := range ldapEntry.Attributes { - val := attr.Values[0] + //OpenLDAP sometimes contains leading space in username + 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(ldapConfs.LdapUID): @@ -337,6 +339,7 @@ func dialLDAP(ldapConfs models.LdapConf) (*goldap.Conn, error) { var ldap *goldap.Conn splitLdapURL := strings.Split(ldapConfs.LdapURL, "://") protocol, hostport := splitLdapURL[0], splitLdapURL[1] + host := strings.Split(hostport, ":")[0] // Sets a Dial Timeout for LDAP connectionTimeout := ldapConfs.LdapConnectionTimeout @@ -346,7 +349,8 @@ func dialLDAP(ldapConfs models.LdapConf) (*goldap.Conn, error) { case "ldap": ldap, err = goldap.Dial("tcp", hostport) case "ldaps": - ldap, err = goldap.DialTLS("tcp", hostport, &tls.Config{InsecureSkipVerify: true}) + log.Debug("Start to dial ldaps") + ldap, err = goldap.DialTLS("tcp", hostport, &tls.Config{ServerName: host, InsecureSkipVerify: !ldapConfs.LdapVerifyCert}) } return ldap, err @@ -401,3 +405,38 @@ func searchLDAP(ldapConfs models.LdapConf, ldap *goldap.Conn) (*goldap.SearchRes return result, nil } + +// SearchAndImportUser - Search user in LDAP, if this user exist, import it to database +func SearchAndImportUser(username string) (int64, error) { + var err error + var userID int64 + + ldapConfs, err := GetSystemLdapConf() + if err != nil { + log.Errorf("Can not get ldap configuration, error %v", err) + return 0, err + } + ldapConfs, err = ValidateLdapConf(ldapConfs) + if err != nil { + log.Errorf("Invalid ldap request, error: %v", err) + return 0, err + } + + ldapConfs.LdapFilter = MakeFilter(username, ldapConfs.LdapFilter, ldapConfs.LdapUID) + log.Debugf("Search with LDAP with filter %s", ldapConfs.LdapFilter) + + ldapUsers, err := SearchUser(ldapConfs) + if err != nil { + log.Errorf("Can not search ldap, error %v, filter: %s", err, ldapConfs.LdapFilter) + return 0, err + } + + if len(ldapUsers) > 0 { + log.Debugf("Importing user %s to local database", ldapUsers[0].Username) + if userID, err = ImportUser(ldapUsers[0]); err != nil { + log.Errorf("Can not import ldap user to local db, error %v", err) + return 0, err + } + } + return userID, err +} diff --git a/src/common/utils/ldap/ldap_test.go b/src/common/utils/ldap/ldap_test.go index 9dae96da7..bfff44330 100644 --- a/src/common/utils/ldap/ldap_test.go +++ b/src/common/utils/ldap/ldap_test.go @@ -17,6 +17,7 @@ package ldap import ( //"fmt" //"strings" + "os" "testing" @@ -65,6 +66,45 @@ var adminServerLdapTestConfig = map[string]interface{}{ common.AdminInitialPassword: "password", } +var adminServerDefaultConfigWithVerifyCert = map[string]interface{}{ + common.ExtEndpoint: "https://host01.com", + common.AUTHMode: common.LDAPAuth, + common.DatabaseType: "mysql", + common.MySQLHost: "127.0.0.1", + common.MySQLPort: 3306, + common.MySQLUsername: "root", + common.MySQLPassword: "root123", + common.MySQLDatabase: "registry", + common.SQLiteFile: "/tmp/registry.db", + common.SelfRegistration: true, + common.LDAPURL: "ldap://127.0.0.1:389", + common.LDAPSearchDN: "cn=admin,dc=example,dc=com", + common.LDAPSearchPwd: "admin", + common.LDAPBaseDN: "dc=example,dc=com", + common.LDAPUID: "uid", + common.LDAPFilter: "", + common.LDAPScope: 3, + common.LDAPTimeout: 30, + common.LDAPVerifyCert: true, + common.TokenServiceURL: "http://token_service", + common.RegistryURL: "http://registry", + common.EmailHost: "127.0.0.1", + common.EmailPort: 25, + common.EmailUsername: "user01", + common.EmailPassword: "password", + common.EmailFrom: "from", + common.EmailSSL: true, + common.EmailIdentity: "", + common.ProjectCreationRestriction: common.ProCrtRestrAdmOnly, + common.MaxJobWorkers: 3, + common.TokenExpiration: 30, + common.CfgExpiration: 5, + common.AdminInitialPassword: "password", + common.AdmiralEndpoint: "http://www.vmware.com", + common.WithNotary: false, + common.WithClair: false, +} + func TestMain(t *testing.T) { server, err := test.NewAdminserver(adminServerLdapTestConfig) if err != nil { @@ -125,6 +165,7 @@ func TestGetSystemLdapConf(t *testing.T) { } func TestValidateLdapConf(t *testing.T) { + testLdapConfig, err := GetSystemLdapConf() if err != nil { t.Fatalf("failed to get system ldap config %v", err) @@ -138,6 +179,7 @@ func TestValidateLdapConf(t *testing.T) { } func TestMakeFilter(t *testing.T) { + testLdapConfig, err := GetSystemLdapConf() if err != nil { @@ -254,3 +296,26 @@ func TestSearchUser(t *testing.T) { t.Errorf("unexpected ldap user search result: %s = %s", "ldapUsers[0].Username", ldapUsers[0].Username) } } + +func TestSearchAndImportUser(t *testing.T) { + + userID, err := SearchAndImportUser("test") + + if err != nil { + t.Fatalf("Failed on error : %v ", err) + } + + if userID <= 0 { + t.Fatalf("userID= %v", userID) + } +} + +func TestSearchAndImportUserNotExist(t *testing.T) { + + userID, _ := SearchAndImportUser("notexist") + + if userID > 0 { + t.Fatal("Can not import a non exist ldap user!") + t.Fail() + } +} diff --git a/src/ui/api/config.go b/src/ui/api/config.go index 768394ba4..79beb1d52 100644 --- a/src/ui/api/config.go +++ b/src/ui/api/config.go @@ -40,6 +40,7 @@ var ( common.LDAPFilter, common.LDAPScope, common.LDAPTimeout, + common.LDAPVerifyCert, common.EmailHost, common.EmailPort, common.EmailUsername, @@ -80,6 +81,7 @@ var ( common.EmailSSL, common.EmailInsecure, common.SelfRegistration, + common.LDAPVerifyCert, } passwordKeys = []string{ diff --git a/src/ui/api/member.go b/src/ui/api/member.go index e1bc02041..0ac5e35af 100644 --- a/src/ui/api/member.go +++ b/src/ui/api/member.go @@ -17,10 +17,13 @@ package api import ( "fmt" "net/http" + "strings" "github.com/vmware/harbor/src/common/dao" "github.com/vmware/harbor/src/common/models" + ldapUtils "github.com/vmware/harbor/src/common/utils/ldap" "github.com/vmware/harbor/src/common/utils/log" + "github.com/vmware/harbor/src/ui/config" ) // ProjectMemberAPI handles request to /api/projects/{}/members/{} @@ -158,12 +161,38 @@ func (pma *ProjectMemberAPI) Post() { var req memberReq pma.DecodeJSONReq(&req) - username := req.Username + username := strings.TrimSpace(req.Username) userID := checkUserExists(username) if userID <= 0 { - log.Warningf("User does not exist, user name: %s", username) - pma.RenderError(http.StatusNotFound, "User does not exist") - return + //check current authorization mode + authMode, err := config.AuthMode() + if err != nil { + log.Errorf("Failed the retrieve auth_mode, error: %s", err) + pma.RenderError(http.StatusInternalServerError, "Failed to retrieve auth_mode") + return + } + + if authMode != "ldap_auth" { + log.Errorf("User does not exist, user name: %s", username) + pma.RenderError(http.StatusNotFound, "User does not exist") + return + } + + //search and import user + newUserID, err := ldapUtils.SearchAndImportUser(username) + if err != nil { + log.Errorf("Search and import user failed, error: %v ", err) + pma.RenderError(http.StatusInternalServerError, "Failed to search and import user") + return + } + + if newUserID <= 0 { + log.Error("Failed to create user") + pma.RenderError(http.StatusNotFound, "Failed to create user") + return + } + + userID = int(newUserID) } rolelist, err := dao.GetUserProjectRoles(userID, projectID) if err != nil { diff --git a/src/ui/config/config.go b/src/ui/config/config.go index 8d3d9c8bf..1609e82d3 100644 --- a/src/ui/config/config.go +++ b/src/ui/config/config.go @@ -173,7 +173,6 @@ func LDAP() (*models.LDAP, error) { if err != nil { return nil, err } - ldap := &models.LDAP{} ldap.URL = cfg[common.LDAPURL].(string) ldap.SearchDN = cfg[common.LDAPSearchDN].(string) @@ -183,6 +182,11 @@ func LDAP() (*models.LDAP, error) { ldap.Filter = cfg[common.LDAPFilter].(string) ldap.Scope = int(cfg[common.LDAPScope].(float64)) ldap.Timeout = int(cfg[common.LDAPTimeout].(float64)) + if cfg[common.LDAPVerifyCert] != nil { + ldap.VerifyCert = cfg[common.LDAPVerifyCert].(bool) + } else { + ldap.VerifyCert = true + } return ldap, nil } diff --git a/src/ui_ng/lib/src/config/config.ts b/src/ui_ng/lib/src/config/config.ts index fe024927c..decc1fd95 100644 --- a/src/ui_ng/lib/src/config/config.ts +++ b/src/ui_ng/lib/src/config/config.ts @@ -64,6 +64,7 @@ export class Configuration { ldap_timeout: NumberValueItem; ldap_uid: StringValueItem; ldap_url: StringValueItem; + ldap_verify_cert: BoolValueItem; email_host: StringValueItem; email_identity: StringValueItem; email_from: StringValueItem; @@ -89,6 +90,7 @@ export class Configuration { this.ldap_timeout = new NumberValueItem(5, true); this.ldap_uid = new StringValueItem("", true); this.ldap_url = new StringValueItem("", true); + this.ldap_verify_cert = new BoolValueItem(true, true); this.email_host = new StringValueItem("", true); this.email_identity = new StringValueItem("", true); this.email_from = new StringValueItem("", true); diff --git a/src/ui_ng/src/app/config/auth/config-auth.component.html b/src/ui_ng/src/app/config/auth/config-auth.component.html index d982f0894..23bbf383b 100644 --- a/src/ui_ng/src/app/config/auth/config-auth.component.html +++ b/src/ui_ng/src/app/config/auth/config-auth.component.html @@ -111,6 +111,15 @@ {{'CONFIG.TOOLTIP.LDAP_SCOPE' | translate}} +
+ + + + + {{'CONFIG.TOOLTIP.VERIFY_CERT' | translate}} + + +
diff --git a/src/ui_ng/src/app/config/auth/config-auth.component.ts b/src/ui_ng/src/app/config/auth/config-auth.component.ts index 37a9afb6e..80e86bbaa 100644 --- a/src/ui_ng/src/app/config/auth/config-auth.component.ts +++ b/src/ui_ng/src/app/config/auth/config-auth.component.ts @@ -50,6 +50,10 @@ export class ConfigurationAuthComponent { } } + setVerifyCertValue($event: any) { + this.currentConfig.ldap_verify_cert.value = $event; + } + disabled(prop: any): boolean { return !(prop && prop.editable); } diff --git a/src/ui_ng/src/i18n/lang/en-us-lang.json b/src/ui_ng/src/i18n/lang/en-us-lang.json index 2031a765e..d0a7a1c75 100644 --- a/src/ui_ng/src/i18n/lang/en-us-lang.json +++ b/src/ui_ng/src/i18n/lang/en-us-lang.json @@ -425,7 +425,8 @@ "TOKEN_EXPIRATION": "The expiration time (in minutes) of a token created by the token service. Default is 30 minutes.", "PRO_CREATION_RESTRICTION": "The flag to define what users have permission to create projects. By default, everyone can create a project. Set to 'Admin Only' so that only an administrator can create a project.", "ROOT_CERT_DOWNLOAD": "Download the root certificate of registry.", - "SCANNING_POLICY": "Set image scanning policy based on different requirements. 'None': No active policy; 'Daily At': Triggering scanning at the specified time everyday." + "SCANNING_POLICY": "Set image scanning policy based on different requirements. 'None': No active policy; 'Daily At': Triggering scanning at the specified time everyday.", + "VERIFY_CERT": "Verify Cert from LDAP Server" }, "LDAP": { "URL": "LDAP URL", @@ -434,7 +435,8 @@ "BASE_DN": "LDAP Base DN", "FILTER": "LDAP Filter", "UID": "LDAP UID", - "SCOPE": "LDAP Scope" + "SCOPE": "LDAP Scope", + "VERIFY_CERT": "LDAP Verify Cert" }, "SCANNING": { "TRIGGER_SCAN_ALL_SUCCESS": "Trigger scan all successfully!", diff --git a/src/ui_ng/src/i18n/lang/es-es-lang.json b/src/ui_ng/src/i18n/lang/es-es-lang.json index ac73c9578..a3ee89d89 100644 --- a/src/ui_ng/src/i18n/lang/es-es-lang.json +++ b/src/ui_ng/src/i18n/lang/es-es-lang.json @@ -426,7 +426,8 @@ "TOKEN_EXPIRATION": "El tiempo de expiración (en minutos) del token creado por el servicio de tokens. Por defecto son 30 minutos.", "PRO_CREATION_RESTRICTION": "Marca para definir qué usuarios tienen permisos para crear proyectos. Por defecto, todos pueden crear proyectos. Seleccione 'Solo Administradores' para que solamente los administradores puedan crear proyectos.", "ROOT_CERT_DOWNLOAD": "Download the root certificate of registry.", - "SCANNING_POLICY": "Set image scanning policy based on different requirements. 'None': No active policy; 'Daily At': Triggering scanning at the specified time everyday." + "SCANNING_POLICY": "Set image scanning policy based on different requirements. 'None': No active policy; 'Daily At': Triggering scanning at the specified time everyday.", + "VERIFY_CERT": "Verify Cert from LDAP Server" }, "LDAP": { "URL": "LDAP URL", @@ -435,7 +436,8 @@ "BASE_DN": "LDAP Base DN", "FILTER": "LDAP Filtro", "UID": "LDAP UID", - "SCOPE": "LDAP Ámbito" + "SCOPE": "LDAP Ámbito", + "VERIFY_CERT": "LDAP Verify Cert" }, "SCANNING": { "TRIGGER_SCAN_ALL_SUCCESS": "Trigger scan all successfully!", diff --git a/src/ui_ng/src/i18n/lang/zh-cn-lang.json b/src/ui_ng/src/i18n/lang/zh-cn-lang.json index a16a6f328..ad3c0037c 100644 --- a/src/ui_ng/src/i18n/lang/zh-cn-lang.json +++ b/src/ui_ng/src/i18n/lang/zh-cn-lang.json @@ -425,7 +425,8 @@ "TOKEN_EXPIRATION": "由令牌服务创建的令牌的过期时间(分钟),默认为30分钟。", "PRO_CREATION_RESTRICTION": "用来确定哪些用户有权限创建项目,默认为’所有人‘,设置为’仅管理员‘则只有管理员可以创建项目。", "ROOT_CERT_DOWNLOAD": "下载镜像库根证书.", - "SCANNING_POLICY": "基于不同需求设置镜像扫描策略。‘无’:不设置任何策略;‘每日定时’:每天在设置的时间定时执行扫描。" + "SCANNING_POLICY": "基于不同需求设置镜像扫描策略。‘无’:不设置任何策略;‘每日定时’:每天在设置的时间定时执行扫描。". + "VERIFY_CERT": "检查来自LDAP服务端的证书" }, "LDAP": { "URL": "LDAP URL", @@ -434,7 +435,8 @@ "BASE_DN": "LDAP基础DN", "FILTER": "LDAP过滤器", "UID": "LDAP用户UID的属性", - "SCOPE": "LDAP搜索范围" + "SCOPE": "LDAP搜索范围", + "VERIFY_CERT": "LDAP 检查证书" }, "SCANNING": { "TRIGGER_SCAN_ALL_SUCCESS": "启动扫描所有镜像任务成功!", diff --git a/tests/ldapprepare.sh b/tests/ldapprepare.sh index dded75a38..2734ca825 100755 --- a/tests/ldapprepare.sh +++ b/tests/ldapprepare.sh @@ -5,11 +5,12 @@ docker rm -f $NAME 2>/dev/null docker run --env LDAP_ORGANISATION="Harbor." \ --env LDAP_DOMAIN="example.com" \ --env LDAP_ADMIN_PASSWORD="admin" \ +--env LDAP_TLS_VERIFY_CLIENT="never" \ -p 389:389 \ -p 636:636 \ --detach --name $NAME osixia/openldap:1.1.7 -sleep 3 +sleep 5 docker cp ldap_test.ldif ldap_server:/ docker exec ldap_server ldapadd -x -D "cn=admin,dc=example,dc=com" -w admin -f /ldap_test.ldif -ZZ diff --git a/tests/resources/Harbor-Pages/Configuration.robot b/tests/resources/Harbor-Pages/Configuration.robot index 584d0ac37..ccb780b3b 100644 --- a/tests/resources/Harbor-Pages/Configuration.robot +++ b/tests/resources/Harbor-Pages/Configuration.robot @@ -24,17 +24,18 @@ Init LDAP ${rc} ${output}= Run And Return Rc And Output ip addr s eth0 |grep "inet "|awk '{print $2}' |awk -F "/" '{print $1}' Log ${output} Sleep 2 - Input Text xpath=//*[@id="ldapUrl"] ldap://${output} + Input Text xpath=//*[@id="ldapUrl"] ldaps://${output} Sleep 1 - Input Text xpath=//*[@id="ldapSearchDN"] cn=admin,dc=example,dc=org + Input Text xpath=//*[@id="ldapSearchDN"] cn=admin,dc=example,dc=com Sleep 1 Input Text xpath=//*[@id="ldapSearchPwd"] admin Sleep 1 - Input Text xpath=//*[@id="ldapBaseDN"] dc=example,dc=org + Input Text xpath=//*[@id="ldapBaseDN"] dc=example,dc=com Sleep 1 Input Text xpath=//*[@id="ldapUid"] cn Sleep 1 Capture Page Screenshot + Disable Ldap Verify Cert Checkbox Click Element xpath=/html/body/harbor-app/harbor-shell/clr-main-container/div/div/config/div/div/div/button[1] Sleep 2 Click Element xpath=/html/body/harbor-app/harbor-shell/clr-main-container/div/div/config/div/div/div/button[3] @@ -45,6 +46,44 @@ Switch To Configure Click Element xpath=/html/body/harbor-app/harbor-shell/clr-main-container/div/nav/section/section/ul/li[3]/a Sleep 2 +Test Ldap Connection + ${rc} ${output}= Run And Return Rc And Output ip addr s eth0 |grep "inet "|awk '{print $2}' |awk -F "/" '{print $1}' + Log ${output} + Sleep 2 + Input Text xpath=//*[@id="ldapUrl"] ldaps://${output} + Sleep 1 + Input Text xpath=//*[@id="ldapSearchDN"] cn=admin,dc=example,dc=com + Sleep 1 + Input Text xpath=//*[@id="ldapSearchPwd"] admin + Sleep 1 + Input Text xpath=//*[@id="ldapBaseDN"] dc=example,dc=com + Sleep 1 + Input Text xpath=//*[@id="ldapUid"] cn + Sleep 1 + + # default is checked, click test connection to verify fail as no cert. + Click Element xpath=${test_ldap_xpath} + Sleep 1 + Wait Until Page Contains Failed to verify LDAP server with error + Sleep 5 + + Disable Ldap Verify Cert Checkbox + # ldap checkbox unchecked, click test connection to verify success. + Sleep 1 + Click Element xpath=${test_ldap_xpath} + Capture Page Screenshot + Wait Until Page Contains Connection to LDAP server is verified timeout=15 + +Disable Ldap Verify Cert Checkbox + Mouse Down xpath=//*[@id="clr-checkbox-ldapVerifyCert"] + Mouse Up xpath=//*[@id="clr-checkbox-ldapVerifyCert"] + Sleep 2 + Capture Page Screenshot + Ldap Verify Cert Checkbox Should Be Disabled + +Ldap Verify Cert Checkbox Should Be Disabled + Checkbox Should Not Be Selected xpath=//*[@id="clr-checkbox-ldapVerifyCert"] + Set Pro Create Admin Only #set limit to admin only Sleep 2 diff --git a/tests/resources/Harbor-Pages/Configuration_Elements.robot b/tests/resources/Harbor-Pages/Configuration_Elements.robot index 5aa0e5e0d..47c600058 100644 --- a/tests/resources/Harbor-Pages/Configuration_Elements.robot +++ b/tests/resources/Harbor-Pages/Configuration_Elements.robot @@ -17,4 +17,5 @@ Documentation This resource provides any keywords related to the Harbor private *** Variables *** ${project_create_xpath} //project//div[@class="option-left"]/button -${self_reg_xpath} //input[@id="clr-checkbox-selfReg"] \ No newline at end of file +${self_reg_xpath} //input[@id="clr-checkbox-selfReg"] +${test_ldap_xpath} /html/body/harbor-app/harbor-shell/clr-main-container/div/div/config/div/div/div/button[3] \ No newline at end of file diff --git a/tests/resources/Harbor-Util.robot b/tests/resources/Harbor-Util.robot index 028ce0375..668603736 100644 --- a/tests/resources/Harbor-Util.robot +++ b/tests/resources/Harbor-Util.robot @@ -71,11 +71,12 @@ Switch To LDAP Config Harbor cfg auth=ldap_auth http_proxy=https Prepare Up Harbor - ${rc}= Run And Return Rc docker pull vmware/harbor-ldap-test:1.1.1 + ${rc}= Run And Return Rc docker pull osixia/openldap:1.1.7 Log ${rc} Should Be Equal As Integers ${rc} 0 - ${rc}= Run And Return Rc docker run --name ldap-container -p 389:389 --detach vmware/harbor-ldap-test:1.1.1 + ${rc} ${output}= Run And Return Rc And Output cd tests && ./ldapprepare.sh Log ${rc} + Log ${output} Should Be Equal As Integers ${rc} 0 ${rc} ${output}= Run And Return Rc And Output docker ps Log ${output} diff --git a/tests/robot-cases/Group0-BAT/BAT.robot b/tests/robot-cases/Group0-BAT/BAT.robot index 044d94e54..1fd7ea6db 100644 --- a/tests/robot-cases/Group0-BAT/BAT.robot +++ b/tests/robot-cases/Group0-BAT/BAT.robot @@ -328,30 +328,38 @@ Test Case - Admin Push Signed Image Test Case - Admin Push Un-Signed Image ${rc} ${output}= Run And Return Rc And Output docker push ${ip}/library/hello-world:latest Log To Console ${output} - -Test Case - Ldap Sign in and out + +Test Case - Ldap Verify Cert Switch To LDAP + Init Chrome Driver + Sign In Harbor ${HARBOR_URL} %{HARBOR_ADMIN} %{HARBOR_PASSWORD} + Switch To Configure + Test Ldap Connection + Close Browser + +Test Case - Ldap Sign in and out Init Chrome Driver Sign In Harbor ${HARBOR_URL} %{HARBOR_ADMIN} %{HARBOR_PASSWORD} Switch To Configure Init LDAP Logout Harbor - Sign In Harbor ${HARBOR_URL} user001 user001 + Sign In Harbor ${HARBOR_URL} test 123456 Close Browser Test Case - Ldap User Create Project Init Chrome Driver ${d}= Get Current Date result_format=%m%s - Sign In Harbor ${HARBOR_URL} user001 user001 + Sign In Harbor ${HARBOR_URL} test 123456 Create An New Project project${d} Close Browser Test Case - Ldap User Push An Image Init Chrome Driver ${d}= Get Current Date result_format=%m%s - Sign In Harbor ${HARBOR_URL} user001 user001 + Sign In Harbor ${HARBOR_URL} test 123456 Create An New Project project${d} - Push Image ${ip} user001 user001 project${d} hello-world:latest + + Push Image ${ip} test 123456 project${d} hello-world:latest Go Into Project project${d} Wait Until Page Contains project${d}/hello-world Close Browser