user_service.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. package ldap
  2. import (
  3. "errors"
  4. "fmt"
  5. "github.com/astaxie/beego/logs"
  6. "github.com/astaxie/beego/orm"
  7. "github.com/go-ldap/ldap/v3"
  8. "nginx-ui/server/config"
  9. "nginx-ui/server/models"
  10. )
  11. type UserService struct {
  12. }
  13. // Add Update 保存或者修改
  14. func (c *UserService) Add(body *models.LdapUser) (*models.LdapUser, error) {
  15. server := models.LdapServer{
  16. Key: body.ServerKey,
  17. }
  18. o := orm.NewOrm()
  19. err := o.Read(&server, "Key")
  20. if err != nil {
  21. return nil, err
  22. }
  23. body.Uid = server.Uid
  24. _, err = o.InsertOrUpdate(body)
  25. if err != nil {
  26. return nil, err
  27. }
  28. client, err := GetActiveClient(&server)
  29. if err != nil {
  30. return nil, err
  31. }
  32. err = client.Add(body)
  33. if err != nil {
  34. return nil, err
  35. }
  36. if body.Password != config.ReplacePassword {
  37. err := client.ModifyPasswordByAdmin(body.DN, body.Password)
  38. if err != nil {
  39. return nil, errors.New("新增成功,但密码修改失败!")
  40. }
  41. }
  42. entry, err := client.SearchByAccount(body.Account)
  43. if err != nil {
  44. return nil, err
  45. }
  46. modifyLDAPUser(body, entry)
  47. _, _ = o.Update(body)
  48. return body, nil
  49. }
  50. // get /ldap/users
  51. func (c *UserService) GetDetail(id int) (*models.LdapUser, error) {
  52. o := orm.NewOrm()
  53. user := models.LdapUser{Id: id}
  54. err := o.Read(&user, "Id")
  55. if err != nil {
  56. return nil, err
  57. }
  58. user.Password = config.ReplacePassword
  59. return &user, nil
  60. }
  61. func (c *UserService) Search(server *models.LdapServer, filter string) ([]*models.LdapUser, []*models.LdapOrganize, error) {
  62. client, err := GetActiveClient(server)
  63. if err != nil {
  64. return nil, nil, err
  65. }
  66. entries, err := client.Search(filter)
  67. if err != nil {
  68. return nil, nil, err
  69. }
  70. var users []*models.LdapUser
  71. var organizeList []*models.LdapOrganize
  72. for _, entry := range entries {
  73. var isOrganize = false
  74. objectClass := entry.GetAttributeValues("objectClass")
  75. for _, oc := range objectClass {
  76. if oc == server.OrganizeClass || oc == "organization" {
  77. isOrganize = true
  78. break
  79. }
  80. }
  81. if isOrganize {
  82. organize := models.LdapOrganize{
  83. Name: entry.GetAttributeValue("ou"),
  84. DN: entry.DN,
  85. ServerKey: server.Key,
  86. ObjectClass: entry.GetAttributeValue("objectClass"),
  87. }
  88. organizeList = append(organizeList, &organize)
  89. } else {
  90. user := createUser(entry)
  91. user.ServerKey = server.Key
  92. users = append(users, &user)
  93. }
  94. }
  95. return users, organizeList, nil
  96. }
  97. // SyncUser SyncUsers 同步用户信息
  98. // post /ldap/user/sync
  99. func (c *UserService) SyncUser(server *models.LdapServer, current *models.LdapUser) error {
  100. o := orm.NewOrm()
  101. if server == nil {
  102. server := &models.LdapServer{Key: current.ServerKey}
  103. err := o.Read(server, "Key")
  104. if err != nil {
  105. return err
  106. }
  107. }
  108. filter := fmt.Sprintf("(&(objectClass=*)(uid=%s))", current.Account)
  109. users, _, err := c.Search(server, filter)
  110. if len(users) != 1 {
  111. return errors.New("账号不存在或者账号重复!")
  112. }
  113. user := users[0]
  114. user.Id = current.Id
  115. user.ServerKey = current.ServerKey
  116. user.Uid = current.Uid
  117. user.Remark = current.Remark
  118. _, err = o.Update(user)
  119. if err != nil {
  120. return err
  121. }
  122. return nil
  123. }
  124. // SyncUsers 同步用户信息
  125. // post /ldap/user/sync
  126. func (c *UserService) SyncUsers(current *models.User, req *LDAPUserSyncReq) (int, error) {
  127. server := &models.LdapServer{Key: req.ServerKey}
  128. o := orm.NewOrm()
  129. err := o.Read(server, "Key")
  130. if err != nil {
  131. return 0, err
  132. }
  133. users, organizeList, err := c.Search(server, req.Filter)
  134. if err != nil {
  135. return 0, err
  136. }
  137. for _, user := range users {
  138. user.Uid = string(rune(current.Id))
  139. _, err := o.InsertOrUpdate(user, "DN")
  140. if err != nil {
  141. logs.Error("save user fail: %v", err)
  142. }
  143. }
  144. for _, organize := range organizeList {
  145. _, err = o.InsertOrUpdate(organize, "DN")
  146. if err != nil {
  147. logs.Error("save organize fail: %v", err)
  148. }
  149. }
  150. return len(users), nil
  151. }
  152. func (c *UserService) Authentication(server *models.LdapServer, account string, password string) (*models.User, error) {
  153. o := orm.NewOrm()
  154. ldapUser := &models.LdapUser{
  155. Account: account,
  156. }
  157. err := o.Read(ldapUser, "Account")
  158. if err != nil && !errors.Is(err, orm.ErrNoRows) {
  159. return nil, err
  160. } else if err != nil {
  161. // The username and password we want to check
  162. filter := fmt.Sprintf("(&(objectClass=*)(uid=%s))", ldap.EscapeFilter(account))
  163. users, _, err := c.Search(server, filter)
  164. if err != nil || len(users) != 1 {
  165. logs.Error("search fail: %v", err)
  166. return nil, errors.New("您输入的账号或者密码错误!")
  167. }
  168. ldapUser = users[0]
  169. _, err = o.InsertOrUpdate(ldapUser, "DN")
  170. if err != nil {
  171. return nil, err
  172. }
  173. }
  174. userDN := ldapUser.DN
  175. client, err := GetActiveClient(server)
  176. if err != nil {
  177. return nil, err
  178. }
  179. err = client.Authentication(userDN, password)
  180. if err != nil {
  181. return nil, err
  182. }
  183. user := &models.User{
  184. Account: account,
  185. }
  186. err = o.Read(user, "Account")
  187. if err != nil && !errors.Is(err, orm.ErrNoRows) {
  188. return nil, err
  189. } else if err != nil {
  190. createLocalUser(user, ldapUser)
  191. _, err = o.Insert(user)
  192. if err != nil {
  193. return nil, err
  194. }
  195. } else if user.Source == "LDAP" {
  196. user.Nickname = ldapUser.UserName
  197. _, _ = o.Update(user, "Nickname")
  198. }
  199. return user, nil
  200. }
  201. // UpdateUserPassword 更新用户密码
  202. // post /ldap/user/modifyPassword
  203. func (c *UserService) UpdateUserPassword(req *UpdatePasswordReq, byAdmin bool) error {
  204. o := orm.NewOrm()
  205. user := models.LdapUser{
  206. Account: req.Account,
  207. }
  208. err := o.Read(&user, "Account")
  209. if err != nil {
  210. if errors.Is(err, orm.ErrNoRows) {
  211. return nil
  212. }
  213. logs.Error("read user fail: %v", err)
  214. return err
  215. }
  216. server := models.LdapServer{
  217. Key: user.ServerKey,
  218. }
  219. err = o.Read(&server, "Key")
  220. if err != nil {
  221. return err
  222. }
  223. client, err := GetActiveClient(&server)
  224. if err != nil {
  225. return err
  226. }
  227. if byAdmin {
  228. err = client.ModifyPasswordByAdmin(user.DN, req.Password)
  229. } else {
  230. err = client.ModifyPassword(user.DN, req.OldPassword, req.Password)
  231. }
  232. if err != nil {
  233. return err
  234. }
  235. err = c.SyncUser(&server, &user)
  236. if err != nil {
  237. return errors.New("密码更新成功,但更新用户信息失败:" + err.Error())
  238. }
  239. return nil
  240. }