user_service.go 6.2 KB

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