service.go 7.0 KB

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