173 lines
4.6 KiB
Go
173 lines
4.6 KiB
Go
package ldap_lib
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/go-ldap/ldap/v3"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type Ldap struct {
|
|
baseDN string
|
|
rootDN string
|
|
conn *ldap.Conn
|
|
peopleGroupDN string
|
|
jwtSecret string
|
|
MysqlConn *gorm.DB
|
|
}
|
|
|
|
func NewLdap(conn *ldap.Conn, baseDN, rootDN, peopleGroupDN, jwtSecret string, mysqlConn *gorm.DB) *Ldap {
|
|
return &Ldap{
|
|
baseDN: baseDN,
|
|
rootDN: rootDN,
|
|
conn: conn,
|
|
peopleGroupDN: peopleGroupDN,
|
|
jwtSecret: jwtSecret,
|
|
MysqlConn: mysqlConn,
|
|
}
|
|
}
|
|
|
|
// 更新资源(分组/用户)
|
|
func (l *Ldap) Update(DN string, attr map[string][]string) error {
|
|
if DN == l.rootDN {
|
|
return errors.New("根用户不能更新")
|
|
}
|
|
modify := ldap.NewModifyRequest(DN, nil)
|
|
for key, v := range attr {
|
|
modify.Replace(key, v)
|
|
}
|
|
return l.conn.Modify(modify)
|
|
}
|
|
|
|
// 创建资源(分组/用户)
|
|
func (l *Ldap) Create(DN string, attr map[string][]string) error {
|
|
add := ldap.NewAddRequest(DN, nil)
|
|
for key, v := range attr {
|
|
add.Attribute(key, v)
|
|
}
|
|
return l.conn.Add(add)
|
|
}
|
|
|
|
// 删除资源(分组/用户)
|
|
func (l *Ldap) Delete(DN string) error {
|
|
if DN == l.rootDN {
|
|
return errors.New("根用户不能删除")
|
|
}
|
|
del := ldap.NewDelRequest(DN, nil)
|
|
return l.conn.Del(del)
|
|
}
|
|
|
|
// 查询资源(分组/用户)
|
|
func (l *Ldap) Search(DN string, scope int, filter string, attr []string, controls []ldap.Control) (resp *ldap.SearchResult, err error) {
|
|
if DN == l.rootDN {
|
|
return nil, errors.New("没有权限查询根用户")
|
|
}
|
|
if filter == "" {
|
|
rootCn := strings.Split(l.rootDN, ",")
|
|
if len(rootCn) == 0 {
|
|
return nil, errors.New("root用户DN未设置")
|
|
}
|
|
filter = "(&(objectClass=*)(!(" + rootCn[0] + ")))"
|
|
}
|
|
searchRequest := ldap.NewSearchRequest(
|
|
DN,
|
|
scope, ldap.NeverDerefAliases, 0, 0, false,
|
|
filter,
|
|
attr,
|
|
controls,
|
|
)
|
|
// 执行搜索请求
|
|
return l.conn.Search(searchRequest)
|
|
}
|
|
|
|
// 分页查询资源(分组/用户)
|
|
func (l *Ldap) SearchWithPaging(DN string, scope int, filter string, attr []string, pageSize uint32, pagingCookie string) (resp *ldap.SearchResult, err error) {
|
|
if DN == l.rootDN {
|
|
return nil, errors.New("没有权限查询根用户")
|
|
}
|
|
if filter == "" {
|
|
rootCn := strings.Split(l.rootDN, ",")
|
|
if len(rootCn) == 0 {
|
|
return nil, errors.New("root用户DN未设置")
|
|
}
|
|
filter = "(&(objectClass=*)(!(" + rootCn[0] + ")))"
|
|
}
|
|
searchRequest := ldap.NewSearchRequest(
|
|
DN,
|
|
scope, ldap.NeverDerefAliases, 0, 0, false,
|
|
filter,
|
|
attr,
|
|
nil,
|
|
)
|
|
pagingCtl := ldap.NewControlPaging(pageSize)
|
|
pagingCtl.SetCookie([]byte(pagingCookie))
|
|
searchRequest.Controls = []ldap.Control{
|
|
pagingCtl,
|
|
}
|
|
// 执行搜索请求
|
|
return l.conn.Search(searchRequest)
|
|
}
|
|
|
|
// *********************************************************************************************
|
|
// 查询组织列表
|
|
type OrganizationInfo struct {
|
|
Name string `json:"name"`
|
|
DN string `json:"dn"`
|
|
Owner string `json:"owner"`
|
|
Members []string `json:"members"`
|
|
}
|
|
|
|
func (l *Ldap) GetOrganizationList(scope int, organizationDNs []string, fields []string, control []ldap.Control) ([]OrganizationInfo, error) {
|
|
filterBuilder := strings.Builder{}
|
|
for _, dn := range organizationDNs {
|
|
//提取 ou
|
|
filterBuilder.WriteString(fmt.Sprintf("(%s)", strings.Split(dn, ",")[0]))
|
|
}
|
|
filter := "(&(objectClass=groupOfUniqueNames)(objectClass=top))"
|
|
if filterBuilder.Len() > 0 {
|
|
filter = "(&(objectClass=groupOfUniqueNames)(objectClass=top)(|" + filterBuilder.String() + "))"
|
|
}
|
|
organizationsResult, err := l.Search(l.baseDN, scope, filter, fields, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
list := make([]OrganizationInfo, 0, len(organizationsResult.Entries))
|
|
for _, entry := range organizationsResult.Entries {
|
|
data := OrganizationInfo{
|
|
DN: entry.DN,
|
|
}
|
|
for _, attr := range entry.Attributes {
|
|
switch attr.Name {
|
|
case "businessCategory": //名称
|
|
data.Name = strings.Join(attr.Values, ",")
|
|
case "owner": //负责人
|
|
data.Owner = strings.Join(attr.Values, ",")
|
|
case "uniqueMember": //成员
|
|
data.Members = attr.Values
|
|
}
|
|
}
|
|
list = append(list, data)
|
|
}
|
|
return list, nil
|
|
}
|
|
|
|
// AddUserToGroup 添加用户到组织
|
|
func (l *Ldap) AddUserToOrganization(organizationDN, userDN string) error {
|
|
modify := ldap.NewModifyRequest(organizationDN, nil)
|
|
modify.Add("uniqueMember", []string{userDN})
|
|
return l.conn.Modify(modify)
|
|
}
|
|
|
|
// DelUserFromGroup 将用户从分组删除
|
|
func (l *Ldap) RemoveUserFromOrganization(groupDN, userDN string) error {
|
|
if userDN == l.rootDN {
|
|
return errors.New("根用户不能从分组删除")
|
|
}
|
|
modify := ldap.NewModifyRequest(groupDN, nil)
|
|
modify.Delete("uniqueMember", []string{userDN})
|
|
return l.conn.Modify(modify)
|
|
}
|