service.go 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. package ldap
  2. import (
  3. "crypto/md5"
  4. "encoding/hex"
  5. "errors"
  6. "fmt"
  7. "github.com/astaxie/beego/logs"
  8. "github.com/astaxie/beego/orm"
  9. "nginx-ui/server/config"
  10. "nginx-ui/server/models"
  11. "nginx-ui/server/vo"
  12. )
  13. type Service struct {
  14. }
  15. var ServiceInstance = new(Service)
  16. var UserIns = new(UserService)
  17. // GetServer 获取一个可用的LDAP 连接, 用于登录时获取服务信息
  18. func (c *Service) GetServer() (*models.LdapServer, error) {
  19. o := orm.NewOrm()
  20. server := models.LdapServer{
  21. Active: true,
  22. }
  23. err := o.Read(&server, "Active")
  24. if err != nil {
  25. return nil, err
  26. }
  27. return &server, nil
  28. }
  29. func (c *Service) Login(req *LDAPLoginReq) (*models.User, error) {
  30. server := models.LdapServer{Key: req.ServerKey}
  31. o := orm.NewOrm()
  32. err := o.Read(&server, "Key")
  33. if err != nil {
  34. return nil, errors.New("未找到对应的LDAP服务!")
  35. }
  36. client, err := GetActiveClient(&server)
  37. if err != nil {
  38. return nil, err
  39. }
  40. ldapUser, err := client.Authentication(req.Account, req.Password)
  41. if err != nil {
  42. return nil, err
  43. }
  44. ldapUser.Uid = server.Uid
  45. ldapUser.ServerKey = server.Key
  46. _, err = o.InsertOrUpdate(ldapUser, "DN")
  47. if err != nil {
  48. return nil, err
  49. }
  50. var user = models.User{
  51. Account: ldapUser.Account,
  52. }
  53. err = o.Read(&user, "Account")
  54. if err != nil {
  55. if !errors.Is(err, orm.ErrNoRows) {
  56. return nil, err
  57. }
  58. user.Password = ldapUser.Password
  59. user.Account = ldapUser.Account
  60. user.Nickname = ldapUser.UserName
  61. user.Source = "LDAP"
  62. _, err := o.Insert(&user)
  63. if err != nil {
  64. return nil, err
  65. }
  66. } else if user.Source == "LDAP" {
  67. // 更新用户
  68. user.Password = ldapUser.Password
  69. user.Nickname = ldapUser.UserName
  70. _, err = o.Update(&user, "Password", "Nickname")
  71. if err != nil {
  72. return nil, err
  73. }
  74. }
  75. user.Password = ""
  76. return &user, nil
  77. }
  78. // GetServers 获取用户所有的LDAP连接
  79. // get /ldap/server
  80. func (c *Service) GetServers(current *models.User, req *vo.PageReq) (*vo.PageResp, error) {
  81. o := orm.NewOrm()
  82. req.Ensure()
  83. qs := o.QueryTable(&models.LdapServer{})
  84. if !current.IsAdmin() {
  85. qs = qs.Filter("Uid", current.Account)
  86. }
  87. total, err := qs.Count()
  88. if err != nil {
  89. return nil, err
  90. }
  91. qs.OrderBy("Id")
  92. qs.Offset(req.Offset)
  93. qs.Limit(req.PageSize)
  94. var list []*models.LdapServer
  95. _, err = qs.All(&list)
  96. for _, v := range list {
  97. v.Password = config.ReplacePassword
  98. }
  99. if err != nil {
  100. return nil, err
  101. }
  102. resp := vo.PageResp{
  103. Current: req.Current,
  104. PageSize: req.PageSize,
  105. Total: total,
  106. List: list,
  107. }
  108. return &resp, err
  109. }
  110. // SyncUsers 同步用户信息
  111. // post /ldap/user/sync
  112. func (c *Service) SyncUsers(current *models.User, req *LDAPUserSyncReq) (int, error) {
  113. server := models.LdapServer{Key: req.ServerKey}
  114. o := orm.NewOrm()
  115. err := o.Read(&server, "Key")
  116. if err != nil {
  117. return 0, err
  118. }
  119. client, err := GetActiveClient(&server)
  120. if err != nil {
  121. return 0, err
  122. }
  123. users, err := client.Search(req.Filter)
  124. if err != nil {
  125. return 0, err
  126. }
  127. for _, user := range users {
  128. user.ServerKey = server.Key
  129. user.Uid = string(rune(current.Id))
  130. _, err := o.InsertOrUpdate(&user, "DN")
  131. if err != nil {
  132. logs.Error("save user fail: %v", err)
  133. }
  134. }
  135. return len(users), nil
  136. }
  137. // SyncUser SyncUsers 同步用户信息
  138. // post /ldap/user/sync
  139. func (c *Service) SyncUser(server *models.LdapServer, current *models.LdapUser) error {
  140. o := orm.NewOrm()
  141. if server == nil {
  142. server := &models.LdapServer{Key: current.ServerKey}
  143. err := o.Read(server, "Key")
  144. if err != nil {
  145. return err
  146. }
  147. }
  148. client, err := GetActiveClient(server)
  149. if err != nil {
  150. return err
  151. }
  152. users, err := client.Search(fmt.Sprintf("(&(objectClass=*)(uid=%s))", current.Account))
  153. if err != nil {
  154. return err
  155. }
  156. if len(users) != 1 {
  157. return errors.New("账号不存在或者账号重复!")
  158. }
  159. user := users[0]
  160. user.Id = current.Id
  161. user.ServerKey = current.ServerKey
  162. user.Uid = current.Uid
  163. user.Remark = current.Remark
  164. _, err = o.Update(&user)
  165. if err != nil {
  166. return err
  167. }
  168. return nil
  169. }
  170. // Update 保存或者修改
  171. // post /ldap/server
  172. func (c *Service) Update(current *models.User, body *models.LdapServer) (*models.LdapServer, error) {
  173. if body.Url == "" {
  174. return nil, errors.New("请完成服务配置,缺少Url!")
  175. }
  176. if body.Key == "" {
  177. key := md5.Sum([]byte(body.Url))
  178. body.Key = hex.EncodeToString(key[:])
  179. }
  180. o := orm.NewOrm()
  181. if body.Id == 0 {
  182. exist := models.LdapServer{Key: body.Key}
  183. err := o.Read(&exist, "Key")
  184. if err != nil && !errors.Is(err, orm.ErrNoRows) {
  185. return nil, err
  186. }
  187. if exist.Id > 0 {
  188. return nil, errors.New("该服务Url已存在!")
  189. }
  190. }
  191. if body.Id > 0 {
  192. exist := models.LdapServer{Id: body.Id}
  193. err := o.Read(&exist, "Id")
  194. if err != nil {
  195. return nil, err
  196. }
  197. if config.ReplacePassword == body.Password {
  198. body.Password = exist.Password
  199. }
  200. _, err = o.Update(body)
  201. if err != nil {
  202. return nil, err
  203. }
  204. } else {
  205. id, err := o.Insert(body)
  206. if err != nil {
  207. return nil, err
  208. }
  209. body.Id = int(id)
  210. }
  211. return body, nil
  212. }
  213. // Add Update 保存或者修改
  214. func (c *Service) Add(current *models.User, body *models.LdapServer) (*models.LdapServer, error) {
  215. if body.Url == "" {
  216. return nil, errors.New("请完成服务配置,缺少Url!")
  217. }
  218. if body.Key == "" {
  219. key := md5.Sum([]byte(body.Url))
  220. body.Key = hex.EncodeToString(key[:])
  221. }
  222. o := orm.NewOrm()
  223. if body.Id == 0 {
  224. exist := models.LdapServer{Key: body.Key}
  225. err := o.Read(&exist, "Key")
  226. if err != nil && !errors.Is(err, orm.ErrNoRows) {
  227. return nil, err
  228. }
  229. if exist.Id > 0 {
  230. return nil, errors.New("该服务Url已存在!")
  231. }
  232. }
  233. if body.Id > 0 {
  234. exist := models.LdapServer{Id: body.Id}
  235. err := o.Read(&exist, "Id")
  236. if err != nil {
  237. return nil, err
  238. }
  239. if config.ReplacePassword == body.Password {
  240. body.Password = exist.Password
  241. }
  242. _, err = o.Update(body)
  243. if err != nil {
  244. return nil, err
  245. }
  246. } else {
  247. id, err := o.Insert(body)
  248. if err != nil {
  249. return nil, err
  250. }
  251. body.Id = int(id)
  252. }
  253. return body, nil
  254. }
  255. // VerifyServer 验证服务
  256. func (c *Service) VerifyServer(req *VerifyReq) ([]models.LdapUser, error) {
  257. var server = &models.LdapServer{
  258. Id: req.Id,
  259. }
  260. o := orm.NewOrm()
  261. err := o.Read(server, "Id")
  262. if err != nil {
  263. return nil, err
  264. }
  265. client, err := GetActiveClient(server)
  266. if err != nil {
  267. return nil, err
  268. }
  269. if req.Filter == "" && req.Username != "" {
  270. req.Filter = fmt.Sprintf("(&(objectClass=*)(uid=%s))", req.Username)
  271. }
  272. if req.Filter != "" {
  273. users, err := client.Search(req.Filter)
  274. if err != nil {
  275. return nil, err
  276. }
  277. return users, nil
  278. }
  279. return make([]models.LdapUser, 0), nil
  280. }
  281. // UpdateUserPassword 更新用户密码
  282. // post /ldap/user/modifyPassword
  283. func (c *Service) UpdateUserPassword(req *UpdatePasswordReq, byAdmin bool) error {
  284. o := orm.NewOrm()
  285. user := models.LdapUser{
  286. Account: req.Account,
  287. }
  288. err := o.Read(&user, "Account")
  289. if err != nil {
  290. if errors.Is(err, orm.ErrNoRows) {
  291. return nil
  292. }
  293. logs.Error("read user fail: %v", err)
  294. return err
  295. }
  296. server := models.LdapServer{
  297. Key: user.ServerKey,
  298. }
  299. err = o.Read(&server, "Key")
  300. if err != nil {
  301. return err
  302. }
  303. client, err := GetActiveClient(&server)
  304. if err != nil {
  305. return err
  306. }
  307. if byAdmin {
  308. err = client.ModifyPasswordByAdmin(user.DN, req.Password)
  309. } else {
  310. err = client.ModifyPassword(user.DN, req.OldPassword, req.Password)
  311. }
  312. if err != nil {
  313. return err
  314. }
  315. err = c.SyncUser(&server, &user)
  316. if err != nil {
  317. return errors.New("密码更新成功,但更新用户信息失败:" + err.Error())
  318. }
  319. return nil
  320. }
  321. // GetUsers 获取全部用户
  322. // get /ldap/users
  323. func (c *Service) GetUsers(current *models.User, req *UserListReq) (*vo.PageResp, error) {
  324. req.Ensure()
  325. o := orm.NewOrm()
  326. qs := o.QueryTable(&models.LdapUser{})
  327. if !current.IsAdmin() {
  328. qs = qs.Filter("Uid", current.Account)
  329. }
  330. qs.Filter("ServerKey", req.ServerKey)
  331. total, err := qs.Count()
  332. if err != nil {
  333. return nil, err
  334. }
  335. qs.OrderBy("Id")
  336. qs.Offset(req.Offset)
  337. qs.Limit(req.PageSize)
  338. var list []*models.LdapUser
  339. _, err = qs.All(&list)
  340. if err != nil {
  341. return nil, err
  342. }
  343. resp := vo.PageResp{
  344. Current: req.Current,
  345. PageSize: req.PageSize,
  346. Total: total,
  347. List: list,
  348. }
  349. return &resp, nil
  350. }