ldap.go 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. package ldap
  2. import (
  3. "encoding/json"
  4. "log"
  5. "net/http"
  6. "regexp"
  7. "strconv"
  8. auth "imuslab.com/arozos/mod/auth"
  9. "imuslab.com/arozos/mod/auth/ldap/ldapreader"
  10. reg "imuslab.com/arozos/mod/auth/register"
  11. "imuslab.com/arozos/mod/common"
  12. db "imuslab.com/arozos/mod/database"
  13. permission "imuslab.com/arozos/mod/permission"
  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. }
  22. type Config struct {
  23. Enabled bool `json:"enabled"`
  24. AutoRedirect bool `json:"auto_redirect"`
  25. BindUsername string `json:"bind_username"`
  26. BindPassword string `json:"bind_password"`
  27. FQDN string `json:"fqdn"`
  28. BaseDN string `json:"base_dn"`
  29. }
  30. type UserAccount struct {
  31. Username string `json:"username"`
  32. Group []string `json:"group"`
  33. EquivGroup []string `json:"equiv_group"`
  34. }
  35. /*
  36. TODO: not sure why auto redirect will keep enable
  37. */
  38. //NewLdapHandler xxx
  39. func NewLdapHandler(authAgent *auth.AuthAgent, register *reg.RegisterHandler, coreDb *db.Database, permissionHandler *permission.PermissionHandler) *ldapHandler {
  40. //ldap handler init
  41. log.Println("Starting LDAP client...")
  42. err := coreDb.NewTable("ldap")
  43. if err != nil {
  44. log.Println("Failed to create LDAP database. Terminating.")
  45. panic(err)
  46. }
  47. //key value to be used for LDAP authentication
  48. BindUsername := readSingleConfig("BindUsername", coreDb)
  49. BindPassword := readSingleConfig("BindPassword", coreDb)
  50. FQDN := readSingleConfig("FQDN", coreDb)
  51. BaseDN := readSingleConfig("BaseDN", coreDb)
  52. LDAPHandler := ldapHandler{
  53. ag: authAgent,
  54. ldapreader: ldapreader.NewLDAPReader(BindUsername, BindPassword, FQDN, BaseDN),
  55. reg: register,
  56. coredb: coreDb,
  57. permissionHandler: permissionHandler,
  58. }
  59. return &LDAPHandler
  60. }
  61. func (ldap *ldapHandler) ReadConfig(w http.ResponseWriter, r *http.Request) {
  62. //basic components
  63. enabled, err := strconv.ParseBool(ldap.readSingleConfig("enabled"))
  64. if err != nil {
  65. common.SendTextResponse(w, "Invalid config value [key=enabled].")
  66. return
  67. }
  68. autoredirect, err := strconv.ParseBool(ldap.readSingleConfig("autoredirect"))
  69. if err != nil {
  70. common.SendTextResponse(w, "Invalid config value [key=autoredirect].")
  71. return
  72. }
  73. //get the LDAP config from db
  74. BindUsername := ldap.readSingleConfig("BindUsername")
  75. BindPassword := ldap.readSingleConfig("BindPassword")
  76. FQDN := ldap.readSingleConfig("FQDN")
  77. BaseDN := ldap.readSingleConfig("BaseDN")
  78. //marshall it and return
  79. config, err := json.Marshal(Config{
  80. Enabled: enabled,
  81. AutoRedirect: autoredirect,
  82. BindUsername: BindUsername,
  83. BindPassword: BindPassword,
  84. FQDN: FQDN,
  85. BaseDN: BaseDN,
  86. })
  87. if err != nil {
  88. empty, err := json.Marshal(Config{})
  89. if err != nil {
  90. common.SendErrorResponse(w, "Error while marshalling config")
  91. }
  92. common.SendJSONResponse(w, string(empty))
  93. }
  94. common.SendJSONResponse(w, string(config))
  95. }
  96. func (ldap *ldapHandler) WriteConfig(w http.ResponseWriter, r *http.Request) {
  97. enabled, err := common.Mv(r, "enabled", true)
  98. if err != nil {
  99. common.SendErrorResponse(w, "enabled field can't be empty")
  100. return
  101. }
  102. autoredirect, err := common.Mv(r, "autoredirect", true)
  103. if err != nil {
  104. common.SendErrorResponse(w, "enabled field can't be empty")
  105. return
  106. }
  107. //allow empty fields if enabled is false
  108. showError := true
  109. if enabled != "true" {
  110. showError = false
  111. }
  112. //four fields to store the LDAP authentication information
  113. BindUsername, err := common.Mv(r, "bind_username", true)
  114. if err != nil {
  115. if showError {
  116. common.SendErrorResponse(w, "bind_username field can't be empty")
  117. return
  118. }
  119. }
  120. BindPassword, err := common.Mv(r, "bind_password", true)
  121. if err != nil {
  122. if showError {
  123. common.SendErrorResponse(w, "bind_password field can't be empty")
  124. return
  125. }
  126. }
  127. FQDN, err := common.Mv(r, "fqdn", true)
  128. if err != nil {
  129. if showError {
  130. common.SendErrorResponse(w, "fqdn field can't be empty")
  131. return
  132. }
  133. }
  134. BaseDN, err := common.Mv(r, "base_dn", true)
  135. if err != nil {
  136. if showError {
  137. common.SendErrorResponse(w, "base_dn field can't be empty")
  138. return
  139. }
  140. }
  141. ldap.coredb.Write("ldap", "enabled", enabled)
  142. ldap.coredb.Write("ldap", "autoredirect", autoredirect)
  143. ldap.coredb.Write("ldap", "BindUsername", BindUsername)
  144. ldap.coredb.Write("ldap", "BindPassword", BindPassword)
  145. ldap.coredb.Write("ldap", "FQDN", FQDN)
  146. ldap.coredb.Write("ldap", "BaseDN", BaseDN)
  147. //update the new authencation infromation
  148. ldap.ldapreader = ldapreader.NewLDAPReader(BindUsername, BindPassword, FQDN, BaseDN)
  149. common.SendOK(w)
  150. }
  151. //@para limit: -1 means unlimited
  152. func (ldap *ldapHandler) getAllUser(limit int) []UserAccount {
  153. var accounts []UserAccount
  154. result, _ := ldap.ldapreader.GetAllUser()
  155. //loop through the result
  156. for i, v := range result {
  157. //check the group belongs
  158. var Group []string
  159. var EquivGroup []string
  160. regexSyntax := regexp.MustCompile("cn=([^,]+),")
  161. for _, v := range v.GetAttributeValues("memberOf") {
  162. groups := regexSyntax.FindStringSubmatch(v)
  163. if len(groups) > 0 {
  164. //check if the LDAP group is already exists in ArOZOS system
  165. if ldap.permissionHandler.GroupExists(groups[1]) {
  166. EquivGroup = append(EquivGroup, groups[1])
  167. }
  168. //LDAP list
  169. Group = append(Group, groups[1])
  170. }
  171. }
  172. if len(EquivGroup) < 1 {
  173. EquivGroup = append(EquivGroup, ldap.reg.DefaultUserGroup)
  174. }
  175. account := UserAccount{
  176. Username: v.GetAttributeValue("uid"),
  177. Group: Group,
  178. EquivGroup: EquivGroup,
  179. }
  180. accounts = append(accounts, account)
  181. if i > limit && limit != -1 {
  182. break
  183. }
  184. }
  185. return accounts[1:]
  186. }
  187. func (ldap *ldapHandler) TestConnection(w http.ResponseWriter, r *http.Request) {
  188. //marshall it and return
  189. accountJSON, err := json.Marshal(ldap.getAllUser(10))
  190. if err != nil {
  191. empty, err := json.Marshal(UserAccount{})
  192. if err != nil {
  193. common.SendErrorResponse(w, "Error while marshalling information")
  194. }
  195. common.SendJSONResponse(w, string(empty))
  196. }
  197. common.SendJSONResponse(w, string(accountJSON))
  198. }
  199. func (ldap *ldapHandler) SyncorizeUser(w http.ResponseWriter, r *http.Request) {
  200. ldapUsersList := ldap.getAllUser(-1)
  201. //arozUsersList := ldap.ag.ListUsers()
  202. for _, ldapUser := range ldapUsersList {
  203. //check if user does not exist in system
  204. if !ldap.ag.UserExists(ldapUser.Username) {
  205. //TODO change password
  206. //TODO reg.GetDefaultUserGroup()
  207. ldap.ag.CreateUserAccount(ldapUser.Username, "P@ssw0rd", ldapUser.EquivGroup)
  208. } else {
  209. //if exists, then check if the user group is the same with ldap's setting
  210. //ldapUserCurrentEquivGroup, _ := ldap.permissionHandler.GetUsersPermissionGroup(ldapUser.Username)
  211. //for _, ldapUserNewEquivGroup := range ldapUser.EquivGroup {
  212. // if ldap.ag.
  213. //}
  214. }
  215. }
  216. }