关注公众号,将获取更多运维干货

简介

Web框架: FastAPI

Python库: ldap3

配置文件目录


│  main.py  #主配置文件
├─openldap
│ │ config.py #存放配置文件和数据模型文件
│ │ ldap.py #接口配置文件
│ │ __init__.py
│ │
│ ├─extensions
│ │ │ ldap_api.py #自定义类
│ │ │ __init__.py


实现步骤

main.py

from fastapi import FastAPI
import uvicorn
from openldap import router


app = FastAPI()


app.include_router(router, prefix='/ldap', tags=["LDAP用户管理"])




if __name__ == '__main__':
uvicorn.run('main:app',host='0.0.0.0',port=8888,reload=True,debug=True,workers=1)


__init__(openldap下面这个)



from .ldap import router


config.py



from enum import Enum
from pydantic import BaseModel
from .extensions import ldap_api


ldap_config = {
"host" : "192.168.253.235",
"post" : 636,
"base_dn" : 'dc=demo,dc=cn',
"user" : "cn=Manager,dc=demo,dc=cn",
"password" : "12345678",
"use_ssl" : True,
"basedn": "DC=demo,DC=cn"
}


class BaseOu(str,Enum):
'''继承string和enum的子类'''
Group = 'Group'
People = 'People'
Manager = 'Manager'


class DnInfo(BaseModel):
'''定义dn请求体'''
groupName: str
cnName: str
ouName: str


class Config:
schema_extra = {
"example": {
"groupName": "测试组",
"cnName": "linlin",
"ouName": "测试组"
}
}

ldap_api.py

from ldap3 import Server, Connection,ALL_ATTRIBUTES,SUBTREE,Attribute
from openldap.config import ldap_config
import json
from fastapi import HTTPException,status


class LDAP(object):
def __init__(self):
'''初始化LDAP连接'''
self.conn = Connection(
Server(
host=ldap_config["host"],
port=ldap_config["post"],
use_ssl=ldap_config["use_ssl"],
),
user=ldap_config["user"],
password=ldap_config["password"],
)
self.conn.bind()


def add_ou(self,ouName: str,baseou: str):
'''
作用:
创建ou
:param ouname:
:return:
'''
self.conn.add(
f'ou={ouName},ou={baseou},{ldap_config["basedn"]}',
['organizationalUnit'],
attributes={'objectClass':['organizationalUnit']}
)
return self.conn.result


def add_user(self):
pass


def add_group(self,groupName: str,cnName:str,ouName:str,baseou: str):
'''
作用:
创建Group
参数解释:
使用groupOfNames结构对象,需要member属性,以防止创建空组,member可以是新用户或已存在用户
:return:
'''
self.conn.add(
f'ou={groupName},ou={baseou},{ldap_config["basedn"]}',
['groupOfNames'],
{
'cn': f'{groupName}',
'member': f'cn={cnName},ou=f{ouName},ou={baseou},{ldap_config["basedn"]}'
}
)
return self.conn.result


def get_all_group(self):
'''
作用:
列出所有Group
参数解释:
attributes:ALL_ATTRIBUTES 获取所有字段
conn.bind(): 说明Connection连接成功,否则失败
返回值:
:return: 返回Dict
'''
try:
self.entryStatus = self.conn.search(
search_base=f'OU=Group,{ldap_config["basedn"]}',
search_filter="(objectClass=groupOfNames)",
attributes = ALL_ATTRIBUTES,
search_scope=SUBTREE,
)
entryGroupList = {}
for entry in self.conn.entries:
entryGroupList.update({json.loads(entry.entry_to_json())['attributes']['cn'][0]:json.loads(entry.entry_to_json())['attributes']})
except Exception as e:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=e
)
finally:
self.conn.unbind


return entryGroupList


def get_all_users(self):
'''
作用:
获取所有用户
参数解释:
entry['cn']: 可以直接获取用户名
search_base: basedn 根目录,对应ldapsearch命令-b,dc=demo,dc=cn
attributes:ALL_ATTRIBUTES 返回所有字段
返回值:
:return: 返回Dict
'''
try:
self.conn.search(
search_base=f'{ldap_config["basedn"]}',
search_filter="(objectClass=inetOrgPerson)",
attributes = ALL_ATTRIBUTES,
search_scope=SUBTREE,
)
entryUserList={}
for entry in self.conn.entries:
entryUserList.update({json.loads(entry.entry_to_json())['attributes']['cn'][0]:json.loads(entry.entry_to_json())['attributes']})
except Exception as e:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=e
)
finally:
self.conn.unbind


return entryUserList


def get_all_ou(self):
'''
作用:
获取所有ou
参数解释:
unbind:断开链接
:return:
'''
try:
self.conn.search(
search_base=f'{ldap_config["basedn"]}',
search_filter="(objectClass=organizationalUnit)",
attributes = ALL_ATTRIBUTES,
search_scope=SUBTREE,
)
entryOuList = {}
for entry in self.conn.entries:
entryOuList.update({json.loads(entry.entry_to_json())['attributes']['ou'][0]:json.loads(entry.entry_to_json())['attributes']})
except Exception as e:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=e
)
finally:
self.conn.unbind()


return entryOuList


ldap.py

from fastapi import APIRouter,Path
from .extensions import ldap_api
from openldap.config import DnInfo
from typing import List,Optional,Dict
from openldap.config import BaseOu


router = APIRouter()


@router.get("/group",response_model=Dict,description="列出所有Group")
async def get_all_group():
'''响应返回一个JSON,定义一个字典'''
ldap = ldap_api.LDAP()
entryGroupList = ldap.get_all_group()


return entryGroupList


@router.get("/users",response_model=Dict,description="列出所有User")
async def get_all_users():
'''响应返回一个JSON,定义一个字典'''
ldap = ldap_api.LDAP()
entryUserList = ldap.get_all_users()
return entryUserList


@router.get("/ou",response_model=Dict,description="获取所有ou")
async def get_all_ou():
'''响应返回一个JSON,定义一个字典'''
ldap = ldap_api.LDAP()
entryOuList = ldap.get_all_ou()
return entryOuList


@router.post("/ou",description="添加ou")
async def add_ou(ouName: str,baseou: BaseOu):
'''定义BaseOu枚举类,用于选择baseou组织'''
ldap = ldap_api.LDAP()
addOu = ldap.add_ou(ouName,baseou)
return addOu


@router.post('/group',description="添加Group")
async def add_group(ou: DnInfo,baseou: BaseOu):
ldap = ldap_api.LDAP()
addGroup = ldap.add_group(ou.groupName,ou.cnName,ou.ouName,baseou)
return addGroup


效果图

打开交互式文档

xxxxxxxxxx
 
1
http://127.0.0.1:8888/docs#/

写了5个接口

基于ldap3库开发OpenAPI增删改查接口(一)_json


查看所有Group

基于ldap3库开发OpenAPI增删改查接口(一)_json_02


查看所有ou

基于ldap3库开发OpenAPI增删改查接口(一)_配置文件_03


查看所有用户,返回一个dict,每个dict是一个用户的详细信息

基于ldap3库开发OpenAPI增删改查接口(一)_sed_04


创建一个Group

设置请求体

基于ldap3库开发OpenAPI增删改查接口(一)_json_05

result为0表示创建成功

基于ldap3库开发OpenAPI增删改查接口(一)_配置文件_06


创建一个ou

设置请求体

基于ldap3库开发OpenAPI增删改查接口(一)_配置文件_07

result为0表示创建成功

基于ldap3库开发OpenAPI增删改查接口(一)_json_08



更多文章请扫一扫

 扫描下面二维码关注公众号获取更多学习资源

基于ldap3库开发OpenAPI增删改查接口(一)_json_09