mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-24 17:47:46 +01:00
commit
a6a4a1fc18
@ -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
28
src/common/models/ldap.go
Normal 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
159
src/ui/api/ldap.go
Normal 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
|
||||
|
||||
}
|
@ -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{})
|
||||
|
Loading…
Reference in New Issue
Block a user