ldap.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. package ldap
  2. import (
  3. "log"
  4. "regexp"
  5. "github.com/go-ldap/ldap"
  6. auth "imuslab.com/arozos/mod/auth"
  7. "imuslab.com/arozos/mod/auth/ldap/ldapreader"
  8. "imuslab.com/arozos/mod/auth/oauth2/syncdb"
  9. reg "imuslab.com/arozos/mod/auth/register"
  10. db "imuslab.com/arozos/mod/database"
  11. permission "imuslab.com/arozos/mod/permission"
  12. "imuslab.com/arozos/mod/time/nightly"
  13. "imuslab.com/arozos/mod/user"
  14. )
  15. type ldapHandler struct {
  16. ag *auth.AuthAgent
  17. ldapreader *ldapreader.LdapReader
  18. reg *reg.RegisterHandler
  19. coredb *db.Database
  20. permissionHandler *permission.PermissionHandler
  21. userHandler *user.UserHandler
  22. iconSystem string
  23. syncdb *syncdb.SyncDB
  24. nightlyManager *nightly.TaskManager
  25. }
  26. type Config struct {
  27. Enabled bool `json:"enabled"`
  28. BindUsername string `json:"bind_username"`
  29. BindPassword string `json:"bind_password"`
  30. FQDN string `json:"fqdn"`
  31. BaseDN string `json:"base_dn"`
  32. }
  33. type UserAccount struct {
  34. Username string `json:"username"`
  35. Group []string `json:"group"`
  36. EquivGroup []string `json:"equiv_group"`
  37. }
  38. //syncorizeUserReturnInterface not designed to be used outside
  39. type syncorizeUserReturnInterface struct {
  40. Userinfo []UserAccount `json:"userinfo"`
  41. TotalLength int `json:"total_length"`
  42. Length int `json:"length"`
  43. Error string `json:"error"`
  44. }
  45. //NewLdapHandler xxx
  46. func NewLdapHandler(authAgent *auth.AuthAgent, register *reg.RegisterHandler, coreDb *db.Database, permissionHandler *permission.PermissionHandler, userHandler *user.UserHandler, nightlyManager *nightly.TaskManager, iconSystem string) *ldapHandler {
  47. //ldap handler init
  48. log.Println("Starting LDAP client...")
  49. err := coreDb.NewTable("ldap")
  50. if err != nil {
  51. log.Println("Failed to create LDAP database. Terminating.")
  52. panic(err)
  53. }
  54. //key value to be used for LDAP authentication
  55. BindUsername := readSingleConfig("BindUsername", coreDb)
  56. BindPassword := readSingleConfig("BindPassword", coreDb)
  57. FQDN := readSingleConfig("FQDN", coreDb)
  58. BaseDN := readSingleConfig("BaseDN", coreDb)
  59. LDAPHandler := ldapHandler{
  60. ag: authAgent,
  61. ldapreader: ldapreader.NewLDAPReader(BindUsername, BindPassword, FQDN, BaseDN),
  62. reg: register,
  63. coredb: coreDb,
  64. permissionHandler: permissionHandler,
  65. userHandler: userHandler,
  66. iconSystem: iconSystem,
  67. syncdb: syncdb.NewSyncDB(),
  68. nightlyManager: nightlyManager,
  69. }
  70. nightlyManager.RegisterNightlyTask(LDAPHandler.NightlySync)
  71. return &LDAPHandler
  72. }
  73. //@para limit: -1 means unlimited
  74. func (ldap *ldapHandler) getAllUser(limit int) ([]UserAccount, int, error) {
  75. //read the user account from ldap, if limit is -1 then it will read all USERS
  76. var accounts []UserAccount
  77. result, err := ldap.ldapreader.GetAllUser()
  78. if err != nil {
  79. return []UserAccount{}, 0, err
  80. }
  81. //loop through the result
  82. for i, v := range result {
  83. account := ldap.convertGroup(v)
  84. accounts = append(accounts, account)
  85. if i+1 > limit && limit != -1 {
  86. break
  87. }
  88. }
  89. //check if the return struct is empty, if yes then insert empty
  90. if len(accounts) > 0 {
  91. return accounts[1:], len(result), nil
  92. } else {
  93. return []UserAccount{}, 0, nil
  94. }
  95. }
  96. func (ldap *ldapHandler) convertGroup(ldapUser *ldap.Entry) UserAccount {
  97. //check the group belongs
  98. var Group []string
  99. var EquivGroup []string
  100. regexSyntax := regexp.MustCompile("cn=([^,]+),")
  101. for _, v := range ldapUser.GetAttributeValues("memberOf") {
  102. groups := regexSyntax.FindStringSubmatch(v)
  103. if len(groups) > 0 {
  104. //check if the LDAP group is already exists in ArOZOS system
  105. if ldap.permissionHandler.GroupExists(groups[1]) {
  106. EquivGroup = append(EquivGroup, groups[1])
  107. }
  108. //LDAP list
  109. Group = append(Group, groups[1])
  110. }
  111. }
  112. if len(EquivGroup) < 1 {
  113. if !ldap.permissionHandler.GroupExists(ldap.reg.GetDefaultUserGroup()) {
  114. //create new user group named default, prventing user don't have a group
  115. ldap.permissionHandler.NewPermissionGroup("default", false, 15<<30, []string{}, "Desktop")
  116. ldap.reg.SetDefaultUserGroup("default")
  117. }
  118. EquivGroup = append(EquivGroup, ldap.reg.GetDefaultUserGroup())
  119. }
  120. account := UserAccount{
  121. Username: ldapUser.GetAttributeValue("cn"),
  122. Group: Group,
  123. EquivGroup: EquivGroup,
  124. }
  125. return account
  126. }
  127. func (ldap *ldapHandler) NightlySync() {
  128. checkLDAPenabled := ldap.readSingleConfig("enabled")
  129. if checkLDAPenabled == "true" {
  130. err := ldap.SynchronizeUserFromLDAP()
  131. if err != nil {
  132. log.Println(err)
  133. }
  134. }
  135. }
  136. func (ldap *ldapHandler) SynchronizeUserFromLDAP() error {
  137. //check if suer is admin before executing the command
  138. //if user is admin then check if user will lost him/her's admin access
  139. ldapUsersList, _, err := ldap.getAllUser(-1)
  140. if err != nil {
  141. return err
  142. }
  143. for _, ldapUser := range ldapUsersList {
  144. //check if user exist in system
  145. if ldap.ag.UserExists(ldapUser.Username) {
  146. //if exists, then check if the user group is the same with ldap's setting
  147. //Get the permission groups by their ids
  148. userinfo, err := ldap.userHandler.GetUserInfoFromUsername(ldapUser.Username)
  149. if err != nil {
  150. return err
  151. }
  152. newPermissionGroups := ldap.permissionHandler.GetPermissionGroupByNameList(ldapUser.EquivGroup)
  153. //Set the user's permission to these groups
  154. userinfo.SetUserPermissionGroup(newPermissionGroups)
  155. }
  156. }
  157. return nil
  158. }