2025-08-26 00:43:50 +08:00
|
|
|
|
/*
|
|
|
|
|
Package main 是 Go LDAP Admin 项目的主入口文件
|
|
|
|
|
|
|
|
|
|
Go LDAP Admin 是一个基于 Go + Vue 实现的 OpenLDAP 后台管理系统,
|
|
|
|
|
旨在为 OpenLDAP 服务端提供一个简单易用、清晰美观的现代化管理后台。
|
|
|
|
|
|
|
|
|
|
主要功能:
|
|
|
|
|
- 用户管理:支持用户的增删改查,密码管理等
|
|
|
|
|
- 组织架构管理:支持部门/组的层级管理
|
|
|
|
|
- 权限控制:基于 RBAC 的角色权限管理
|
|
|
|
|
- LDAP 集成:与 OpenLDAP 服务器双向同步
|
|
|
|
|
- 企业 IM 集成:支持钉钉、企业微信、飞书等平台同步
|
|
|
|
|
- 操作审计:完整的操作日志记录
|
|
|
|
|
|
|
|
|
|
技术栈:
|
|
|
|
|
- Web 框架:Gin
|
|
|
|
|
- ORM:GORM
|
|
|
|
|
- 数据库:MySQL/SQLite
|
|
|
|
|
- 权限控制:Casbin
|
|
|
|
|
- LDAP 客户端:go-ldap
|
|
|
|
|
- 认证:JWT
|
|
|
|
|
*/
|
2022-05-18 17:57:03 +08:00
|
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"fmt"
|
|
|
|
|
"net/http"
|
|
|
|
|
"os"
|
|
|
|
|
"os/signal"
|
|
|
|
|
"time"
|
|
|
|
|
|
2022-06-14 11:17:38 +08:00
|
|
|
|
"github.com/eryajf/go-ldap-admin/logic"
|
|
|
|
|
|
2022-05-29 10:06:21 +08:00
|
|
|
|
"github.com/eryajf/go-ldap-admin/config"
|
|
|
|
|
"github.com/eryajf/go-ldap-admin/middleware"
|
|
|
|
|
"github.com/eryajf/go-ldap-admin/public/common"
|
|
|
|
|
"github.com/eryajf/go-ldap-admin/routes"
|
|
|
|
|
"github.com/eryajf/go-ldap-admin/service/isql"
|
2022-05-18 17:57:03 +08:00
|
|
|
|
)
|
|
|
|
|
|
2025-08-26 00:43:50 +08:00
|
|
|
|
// Swagger API 文档配置
|
2024-05-20 21:55:42 +08:00
|
|
|
|
// @title Go Ldap Admin
|
|
|
|
|
// @version 1.0
|
|
|
|
|
// @description 基于Go+Vue实现的openLDAP后台管理项目
|
|
|
|
|
// @termsOfService https://github.com/eryajf/go-ldap-admin
|
|
|
|
|
|
|
|
|
|
// @contact.name 项目作者:二丫讲梵 、 swagger作者:南宫乘风
|
|
|
|
|
// @contact.url https://github.com/eryajf/go-ldap-admin
|
|
|
|
|
// @contact.email https://github.com/eryajf/go-ldap-admin
|
|
|
|
|
|
|
|
|
|
// @host 127.0.0.1:8888
|
|
|
|
|
// @BasePath /api
|
|
|
|
|
// @securityDefinitions.apikey ApiKeyAuth
|
|
|
|
|
// @in header
|
|
|
|
|
// @name Authorization
|
2025-08-26 00:43:50 +08:00
|
|
|
|
|
|
|
|
|
// main 函数是程序的入口点,负责初始化各个组件并启动 HTTP 服务器
|
2022-05-18 17:57:03 +08:00
|
|
|
|
func main() {
|
2025-08-26 00:43:50 +08:00
|
|
|
|
// ==================== 系统初始化阶段 ====================
|
2022-05-18 17:57:03 +08:00
|
|
|
|
|
2025-08-26 00:43:50 +08:00
|
|
|
|
// 1. 加载配置文件到全局配置结构体
|
|
|
|
|
// 从 config.yml 文件中读取系统配置,包括数据库、LDAP、JWT 等配置信息
|
2022-05-18 17:57:03 +08:00
|
|
|
|
config.InitConfig()
|
|
|
|
|
|
2025-08-26 00:43:50 +08:00
|
|
|
|
// 2. 初始化日志系统
|
|
|
|
|
// 配置 zap 日志库,设置日志级别、输出格式、文件轮转等
|
2022-05-18 17:57:03 +08:00
|
|
|
|
common.InitLogger()
|
|
|
|
|
|
2025-08-26 00:43:50 +08:00
|
|
|
|
// 3. 初始化数据库连接
|
|
|
|
|
// 根据配置连接 MySQL 或 SQLite 数据库,建立连接池
|
2022-12-30 14:50:59 +08:00
|
|
|
|
common.InitDB()
|
2022-05-18 17:57:03 +08:00
|
|
|
|
|
2025-08-26 00:43:50 +08:00
|
|
|
|
// 4. 初始化 LDAP 连接
|
|
|
|
|
// 建立与 OpenLDAP 服务器的连接池,用于用户认证和数据同步
|
2022-05-18 17:57:03 +08:00
|
|
|
|
common.InitLDAP()
|
|
|
|
|
|
2025-08-26 00:43:50 +08:00
|
|
|
|
// 5. 初始化 Casbin 策略管理器
|
|
|
|
|
// 加载 RBAC 权限模型,用于接口级别的权限控制
|
2022-05-18 17:57:03 +08:00
|
|
|
|
common.InitCasbinEnforcer()
|
|
|
|
|
|
2025-08-26 00:43:50 +08:00
|
|
|
|
// 6. 初始化数据校验器
|
|
|
|
|
// 配置 gin 的数据校验器,用于请求参数验证
|
2022-05-18 17:57:03 +08:00
|
|
|
|
common.InitValidate()
|
|
|
|
|
|
2025-08-26 00:43:50 +08:00
|
|
|
|
// 7. 初始化基础数据
|
|
|
|
|
// 如果是首次启动,会创建默认的管理员账户、角色、菜单等基础数据
|
2022-05-18 17:57:03 +08:00
|
|
|
|
common.InitData()
|
|
|
|
|
|
2025-08-26 00:43:50 +08:00
|
|
|
|
// ==================== 后台服务启动 ====================
|
|
|
|
|
|
|
|
|
|
// 启动操作日志处理协程
|
|
|
|
|
// 操作日志中间件将日志发送到 channel 中,这里启动 3 个 goroutine
|
|
|
|
|
// 异步处理 channel 中的日志并写入数据库,提高系统性能
|
2022-05-18 17:57:03 +08:00
|
|
|
|
for i := 0; i < 3; i++ {
|
|
|
|
|
go isql.OperationLog.SaveOperationLogChannel(middleware.OperationLogChan)
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-26 00:43:50 +08:00
|
|
|
|
// ==================== HTTP 服务器配置 ====================
|
|
|
|
|
|
2022-05-18 17:57:03 +08:00
|
|
|
|
// 注册所有路由
|
2025-08-26 00:43:50 +08:00
|
|
|
|
// 包括用户管理、组织架构、权限管理、系统管理等所有 API 路由
|
2022-05-18 17:57:03 +08:00
|
|
|
|
r := routes.InitRoutes()
|
|
|
|
|
|
2025-08-26 00:43:50 +08:00
|
|
|
|
// 配置服务器监听地址和端口
|
|
|
|
|
host := "0.0.0.0" // 监听所有网络接口
|
|
|
|
|
port := config.Conf.System.Port // 从配置文件读取端口号
|
2022-05-18 17:57:03 +08:00
|
|
|
|
|
2025-08-26 00:43:50 +08:00
|
|
|
|
// 创建 HTTP 服务器实例
|
2022-05-18 17:57:03 +08:00
|
|
|
|
srv := &http.Server{
|
|
|
|
|
Addr: fmt.Sprintf("%s:%d", host, port),
|
|
|
|
|
Handler: r,
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-26 00:43:50 +08:00
|
|
|
|
// ==================== 服务器启动 ====================
|
|
|
|
|
|
|
|
|
|
// 在单独的 goroutine 中启动 HTTP 服务器
|
|
|
|
|
// 这样不会阻塞后续的优雅关闭处理逻辑
|
2022-05-18 17:57:03 +08:00
|
|
|
|
go func() {
|
|
|
|
|
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
2025-08-26 00:43:50 +08:00
|
|
|
|
common.Log.Fatalf("HTTP 服务器启动失败: %s\n", err)
|
2022-05-18 17:57:03 +08:00
|
|
|
|
}
|
|
|
|
|
}()
|
2022-07-10 17:40:04 +08:00
|
|
|
|
|
2025-08-26 00:43:50 +08:00
|
|
|
|
// 启动定时任务调度器
|
|
|
|
|
// 用于执行企业 IM 同步、数据清理等定时任务
|
2022-07-10 17:40:04 +08:00
|
|
|
|
logic.InitCron()
|
2022-05-18 17:57:03 +08:00
|
|
|
|
|
2025-08-26 00:43:50 +08:00
|
|
|
|
// 输出服务器启动成功信息
|
|
|
|
|
common.Log.Info(fmt.Sprintf("🚀 Go LDAP Admin 服务器启动成功! 访问地址: http://%s:%d", host, port))
|
|
|
|
|
|
|
|
|
|
// ==================== 优雅关闭处理 ====================
|
2022-05-18 17:57:03 +08:00
|
|
|
|
|
2025-08-26 00:43:50 +08:00
|
|
|
|
// 创建信号接收通道,用于接收系统关闭信号
|
2022-06-14 11:17:38 +08:00
|
|
|
|
quit := make(chan os.Signal, 1)
|
2025-08-26 00:43:50 +08:00
|
|
|
|
|
|
|
|
|
// 注册信号处理
|
|
|
|
|
// kill (无参数) 默认发送 syscall.SIGTERM 信号
|
|
|
|
|
// kill -2 发送 syscall.SIGINT 信号 (Ctrl+C)
|
|
|
|
|
// kill -9 发送 syscall.SIGKILL 信号,但无法被捕获,所以不需要处理
|
2022-06-14 11:17:38 +08:00
|
|
|
|
signal.Notify(quit, os.Interrupt)
|
2025-08-26 00:43:50 +08:00
|
|
|
|
|
|
|
|
|
// 阻塞等待关闭信号
|
2022-05-18 17:57:03 +08:00
|
|
|
|
<-quit
|
2025-08-26 00:43:50 +08:00
|
|
|
|
common.Log.Info("🛑 接收到关闭信号,开始优雅关闭服务器...")
|
2022-05-18 17:57:03 +08:00
|
|
|
|
|
2025-08-26 00:43:50 +08:00
|
|
|
|
// 创建带超时的上下文,给服务器 5 秒时间完成当前正在处理的请求
|
2022-05-18 17:57:03 +08:00
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
|
|
|
defer cancel()
|
2025-08-26 00:43:50 +08:00
|
|
|
|
|
|
|
|
|
// 优雅关闭服务器
|
2022-05-18 17:57:03 +08:00
|
|
|
|
if err := srv.Shutdown(ctx); err != nil {
|
2025-08-26 00:43:50 +08:00
|
|
|
|
common.Log.Fatal("❌ 服务器强制关闭:", err)
|
2022-05-18 17:57:03 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-08-26 00:43:50 +08:00
|
|
|
|
common.Log.Info("✅ 服务器已安全退出!")
|
2022-05-18 17:57:03 +08:00
|
|
|
|
}
|