add ldap ping feature

This commit is contained in:
yhua 2017-01-09 18:24:31 +08:00
parent ce0a44010d
commit 7fbe811394
4 changed files with 243 additions and 2 deletions

View File

@ -6,7 +6,7 @@ info:
description: These APIs provide services for manipulating Harbor project.
version: "0.3.0"
# the domain of the service
host: localhost
host: localshot
# array of all schemes that your API supports
schemes:
- http
@ -1347,7 +1347,30 @@ paths:
404:
description: Not found the default root certificate.
500:
description: Unexpected internal errors.
description: Unexpected internal errors.
/ldap/ping:
post:
summary: Ping available ldap service.
description: |
This endpoint ping the available ldap service for test related configuration parameters.
parameters:
- name: ldapconf
in: body
description: ldap configuration.
required: true
schema:
$ref: '#/definitions/LdapConf'
tags:
- Products
responses:
200:
description: Ping ldap service successfully.
401:
description: Only admin has this authority.
403:
description: Inviald ldap configuration parameters.
500:
description: Unexpected internal errors.
definitions:
Search:
type: object
@ -1798,3 +1821,32 @@ definitions:
description: The storage of system.
items:
$ref: '#/definitions/Storage'
LdapConf:
type: object
properties:
ldap_url:
type: string
description: The url of ldap service.
ldap_searchdn:
type: string
description: The search dn of ldap service.
ldap_search_pwd:
type: string
description: The search password of ldap service.
ldap_basedn:
type: string
description: The base dn of ldap service.
ldap_filter:
type: string
description: The serach filter of ldap service.
ldap_uid:
type: string
description: The serach uid of ldap service.
ldap_scope:
type: integer
format: int64
description: The serach scope of ldap service.
ldap_connect_timeout:
type: integer
format: int64
description: The connect timeout of ldap service(second).

28
src/common/models/ldap.go Normal file
View File

@ -0,0 +1,28 @@
/*
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
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 models
// LdapConf holds information about repository that accessed most
type LdapConf struct {
LdapURL string `json:"ldap_url"`
LdapSearchDn string `json:"ldap_searchdn"`
LdapSearchPwd string `json:"ldap_search_pwd"`
LdapBaseDn string `json:"ldap_basedn"`
LdapFilter string `json:"ldap_filter"`
LdapUID string `json:"ldap_uid"`
LdapScope int `json:"ldap_scope"`
LdapConnectTimeout int `json:"ldap_connect_timeout"`
}

159
src/ui/api/ldap.go Normal file
View File

@ -0,0 +1,159 @@
/*
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
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 api
import (
"fmt"
"net/http"
"strconv"
"strings"
"time"
"crypto/tls"
"github.com/vmware/harbor/src/common/api"
"github.com/vmware/harbor/src/common/dao"
"github.com/vmware/harbor/src/common/models"
"github.com/vmware/harbor/src/common/utils/log"
goldap "gopkg.in/ldap.v2"
)
// LdapAPI handles requesst to /api/ldap/ping /api/ldap/search
type LdapAPI struct {
api.BaseAPI
}
var ldapConfs models.LdapConf
// Prepare ...
func (l *LdapAPI) Prepare() {
userID := l.ValidateUser()
isSysAdmin, err := dao.IsAdminRole(userID)
if err != nil {
log.Errorf("error occurred in IsAdminRole: %v", err)
l.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
}
if !isSysAdmin {
l.CustomAbort(http.StatusForbidden, http.StatusText(http.StatusForbidden))
}
}
// Ping ...
func (l *LdapAPI) Ping() {
l.DecodeJSONReqAndValidate(&ldapConfs)
err := validateLdapReq(ldapConfs)
if err != nil {
log.Errorf("Invalid ldap request, error: %v", err)
l.RenderError(http.StatusBadRequest, fmt.Sprintf("invalid ldap request: %v", err))
return
}
err = connectTest(ldapConfs)
if err != nil {
log.Errorf("Ldap connect fail, error: %v", err)
l.RenderError(http.StatusBadRequest, fmt.Sprintf("ldap connect fail: %v", err))
return
}
}
func validateLdapReq(ldapConfs models.LdapConf) error {
ldapURL := ldapConfs.LdapURL
if ldapURL == "" {
return fmt.Errorf("can not get any available LDAP_URL")
}
log.Debug("ldapURL:", ldapURL)
ldapConnectTimeout := ldapConfs.LdapConnectTimeout
log.Debug("ldapConnectTimeout:", ldapConnectTimeout)
return nil
}
func connectTest(ldapConfs models.LdapConf) error {
var ldap *goldap.Conn
var protocol, hostport string
var host, port string
var err error
ldapURL := ldapConfs.LdapURL
// This routine keeps compability with the old format used on harbor.cfg
if strings.Contains(ldapURL, "://") {
splitLdapURL := strings.Split(ldapURL, "://")
protocol, hostport = splitLdapURL[0], splitLdapURL[1]
if !((protocol == "ldap") || (protocol == "ldaps")) {
return fmt.Errorf("unknown ldap protocl")
}
} else {
hostport = ldapURL
protocol = "ldap"
}
// This tries to detect the used port, if not defined
if strings.Contains(hostport, ":") {
splitHostPort := strings.Split(hostport, ":")
host, port = splitHostPort[0], splitHostPort[1]
_, error := strconv.Atoi(splitHostPort[1])
if error != nil {
return fmt.Errorf("illegal url format")
}
} else {
host = hostport
switch protocol {
case "ldap":
port = "389"
case "ldaps":
port = "636"
}
}
// Sets a Dial Timeout for LDAP
connectTimeout := ldapConfs.LdapConnectTimeout
goldap.DefaultTimeout = time.Duration(connectTimeout) * time.Second
switch protocol {
case "ldap":
ldap, err = goldap.Dial("tcp", fmt.Sprintf("%s:%s", host, port))
case "ldaps":
ldap, err = goldap.DialTLS("tcp", fmt.Sprintf("%s:%s", host, port), &tls.Config{InsecureSkipVerify: true})
}
if err != nil {
return err
}
defer ldap.Close()
ldapSearchDn := ldapConfs.LdapSearchDn
if ldapSearchDn != "" {
log.Debug("Search DN: ", ldapSearchDn)
ldapSearchPwd := ldapConfs.LdapSearchPwd
err = ldap.Bind(ldapSearchDn, ldapSearchPwd)
if err != nil {
log.Debug("Bind search dn error", err)
return err
}
}
return nil
}

View File

@ -87,6 +87,8 @@ func initRouters() {
beego.Router("/api/systeminfo/volumes", &api.SystemInfoAPI{}, "get:GetVolumeInfo")
beego.Router("/api/systeminfo/getcert", &api.SystemInfoAPI{}, "get:GetCert")
beego.Router("/api/ldap/ping", &api.LdapAPI{}, "post:Ping")
//external service that hosted on harbor process:
beego.Router("/service/notifications", &service.NotificationHandler{})
beego.Router("/service/token", &token.Handler{})