浏览代码

ldap integration

AY's Macbook Pro 3 年之前
父节点
当前提交
065a13ac19
共有 7 个文件被更改,包括 114 次插入51 次删除
  1. 4 1
      ldap.go
  2. 2 1
      main.router.go
  3. 45 2
      mod/auth/ldap/ldap.go
  4. 17 4
      mod/auth/ldap/ldapreader/reader.go
  5. 7 6
      mod/common/template.go
  6. 37 36
      system.resetpw.go
  7. 2 1
      web/login.system

+ 4 - 1
ldap.go

@@ -9,7 +9,7 @@ import (
 
 
 func ldapInit() {
 func ldapInit() {
 	//ldap
 	//ldap
-	ldapHandler := ldap.NewLdapHandler(authAgent, registerHandler, sysdb, permissionHandler, userHandler)
+	ldapHandler := ldap.NewLdapHandler(authAgent, registerHandler, sysdb, permissionHandler, userHandler, iconSystem)
 
 
 	//add a entry to the system settings
 	//add a entry to the system settings
 	adminRouter := prout.NewModuleRouter(prout.RouterOption{
 	adminRouter := prout.NewModuleRouter(prout.RouterOption{
@@ -34,4 +34,7 @@ func ldapInit() {
 	adminRouter.HandleFunc("/system/auth/ldap/config/testConnection", ldapHandler.TestConnection)
 	adminRouter.HandleFunc("/system/auth/ldap/config/testConnection", ldapHandler.TestConnection)
 	adminRouter.HandleFunc("/system/auth/ldap/config/syncorizeUser", ldapHandler.SynchronizeUser)
 	adminRouter.HandleFunc("/system/auth/ldap/config/syncorizeUser", ldapHandler.SynchronizeUser)
 
 
+	//login interface and login handler
+	http.HandleFunc("/system/auth/ldap/login", ldapHandler.HandleLogin)
+	http.HandleFunc("/ldapLogin.system", ldapHandler.HandleLoginPage)
 }
 }

+ 2 - 1
main.router.go

@@ -37,10 +37,11 @@ func mrouter(h http.Handler) http.Handler {
 				imgsrc = "./web/img/public/auth_icon.png"
 				imgsrc = "./web/img/public/auth_icon.png"
 			}
 			}
 			imageBase64, _ := LoadImageAsBase64(imgsrc)
 			imageBase64, _ := LoadImageAsBase64(imgsrc)
-			parsedPage, err := template_load("web/login.system", map[string]interface{}{
+			parsedPage, err := common.Templateload("web/login.system", map[string]interface{}{
 				"redirection_addr": red,
 				"redirection_addr": red,
 				"usercount":        strconv.Itoa(authAgent.GetUserCounts()),
 				"usercount":        strconv.Itoa(authAgent.GetUserCounts()),
 				"service_logo":     imageBase64,
 				"service_logo":     imageBase64,
+				"login_addr":       "system/auth/login",
 			})
 			})
 			if err != nil {
 			if err != nil {
 				panic("Error. Unable to parse login page. Is web directory data exists?")
 				panic("Error. Unable to parse login page. Is web directory data exists?")

+ 45 - 2
mod/auth/ldap/ldap.go

@@ -23,6 +23,7 @@ type ldapHandler struct {
 	coredb            *db.Database
 	coredb            *db.Database
 	permissionHandler *permission.PermissionHandler
 	permissionHandler *permission.PermissionHandler
 	userHandler       *user.UserHandler
 	userHandler       *user.UserHandler
+	iconSystem        string
 }
 }
 
 
 type Config struct {
 type Config struct {
@@ -46,7 +47,7 @@ TODO: stop user to syncorize if the current user will lost admin access
 */
 */
 
 
 //NewLdapHandler xxx
 //NewLdapHandler xxx
-func NewLdapHandler(authAgent *auth.AuthAgent, register *reg.RegisterHandler, coreDb *db.Database, permissionHandler *permission.PermissionHandler, userHandler *user.UserHandler) *ldapHandler {
+func NewLdapHandler(authAgent *auth.AuthAgent, register *reg.RegisterHandler, coreDb *db.Database, permissionHandler *permission.PermissionHandler, userHandler *user.UserHandler, iconSystem string) *ldapHandler {
 	//ldap handler init
 	//ldap handler init
 	log.Println("Starting LDAP client...")
 	log.Println("Starting LDAP client...")
 	err := coreDb.NewTable("ldap")
 	err := coreDb.NewTable("ldap")
@@ -68,6 +69,7 @@ func NewLdapHandler(authAgent *auth.AuthAgent, register *reg.RegisterHandler, co
 		coredb:            coreDb,
 		coredb:            coreDb,
 		permissionHandler: permissionHandler,
 		permissionHandler: permissionHandler,
 		userHandler:       userHandler,
 		userHandler:       userHandler,
+		iconSystem:        iconSystem,
 	}
 	}
 
 
 	return &LDAPHandler
 	return &LDAPHandler
@@ -196,7 +198,7 @@ func (ldap *ldapHandler) getAllUser(limit int) []UserAccount {
 			EquivGroup = append(EquivGroup, ldap.reg.DefaultUserGroup)
 			EquivGroup = append(EquivGroup, ldap.reg.DefaultUserGroup)
 		}
 		}
 		account := UserAccount{
 		account := UserAccount{
-			Username:   v.GetAttributeValue("uid"),
+			Username:   v.GetAttributeValue("cn"),
 			Group:      Group,
 			Group:      Group,
 			EquivGroup: EquivGroup,
 			EquivGroup: EquivGroup,
 		}
 		}
@@ -281,3 +283,44 @@ func (ldap *ldapHandler) SynchronizeUser(w http.ResponseWriter, r *http.Request)
 	}
 	}
 	common.SendOK(w)
 	common.SendOK(w)
 }
 }
+
+//LOGIN related command
+
+func (ldap *ldapHandler) HandleLoginPage(w http.ResponseWriter, r *http.Request) {
+	red, _ := common.Mv(r, "redirect", false)
+
+	//Append the redirection addr into the template
+	imgsrc := "./web/" + ldap.iconSystem
+	if !common.FileExists(imgsrc) {
+		imgsrc = "./web/img/public/auth_icon.png"
+	}
+	imageBase64, _ := common.LoadImageAsBase64(imgsrc)
+	parsedPage, err := common.Templateload("web/login.system", map[string]interface{}{
+		"redirection_addr": red,
+		"usercount":        strconv.Itoa(ldap.ag.GetUserCounts()),
+		"service_logo":     imageBase64,
+		"login_addr":       "system/ldap/auth/login",
+	})
+	if err != nil {
+		panic("Error. Unable to parse login page. Is web directory data exists?")
+	}
+	w.Header().Add("Content-Type", "text/html; charset=UTF-8")
+	w.Write([]byte(parsedPage))
+}
+
+func (ldap *ldapHandler) HandleLogin(w http.ResponseWriter, r *http.Request) {
+	username, err := common.Mv(r, "username", true)
+	if err != nil {
+		common.SendErrorResponse(w, err.Error())
+		return
+	}
+	password, err := common.Mv(r, "password", true)
+	if err != nil {
+		common.SendErrorResponse(w, err.Error())
+		return
+	}
+	loginInfo, err := ldap.ldapreader.Authenticate(username, password)
+	//authencate successful
+	//common
+
+}

+ 17 - 4
mod/auth/ldap/ldapreader/reader.go

@@ -27,7 +27,7 @@ func NewLDAPReader(username string, password string, server string, basedn strin
 }
 }
 
 
 func (handler *LdapReader) GetUser(username string) (*ldap.Entry, error) {
 func (handler *LdapReader) GetUser(username string) (*ldap.Entry, error) {
-	returnVal, err := handler.retrieveInformation("uid="+username+","+handler.basedn, "(objectClass=*)", ldap.ScopeBaseObject)
+	returnVal, err := handler.retrieveInformation("uid="+username+","+handler.basedn, "(objectClass=*)", ldap.ScopeBaseObject, handler.username, handler.password)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -38,17 +38,30 @@ func (handler *LdapReader) GetUser(username string) (*ldap.Entry, error) {
 }
 }
 
 
 func (handler *LdapReader) GetAllUser() ([]*ldap.Entry, error) {
 func (handler *LdapReader) GetAllUser() ([]*ldap.Entry, error) {
-	return handler.retrieveInformation(handler.basedn, "(objectClass=*)", ldap.ScopeWholeSubtree)
+	return handler.retrieveInformation(handler.basedn, "(objectClass=*)", ldap.ScopeWholeSubtree, handler.username, handler.password)
 }
 }
 
 
-func (handler *LdapReader) retrieveInformation(dn string, filter string, typeOfSearch int) ([]*ldap.Entry, error) {
+func (handler *LdapReader) Authenticate(username string, password string) (bool, error) {
+	userInformation, err := handler.retrieveInformation("uid="+username+","+handler.basedn, "(objectClass=*)", ldap.ScopeBaseObject, handler.username, handler.password)
+	if err != nil {
+		return false, err
+	}
+	if len(userInformation) > 0 {
+		if userInformation[0].GetAttributeValue("cn") == username {
+			return true, nil
+		}
+	}
+	return false, nil
+}
+
+func (handler *LdapReader) retrieveInformation(dn string, filter string, typeOfSearch int, username string, password string) ([]*ldap.Entry, error) {
 	ldapURL, err := ldap.DialURL(fmt.Sprintf("ldap://%s:389", handler.server))
 	ldapURL, err := ldap.DialURL(fmt.Sprintf("ldap://%s:389", handler.server))
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 	defer ldapURL.Close()
 	defer ldapURL.Close()
 
 
-	ldapURL.Bind(handler.username, handler.password)
+	ldapURL.Bind(username, password)
 	searchReq := ldap.NewSearchRequest(
 	searchReq := ldap.NewSearchRequest(
 		dn,
 		dn,
 		typeOfSearch,
 		typeOfSearch,

+ 7 - 6
template.go → mod/common/template.go

@@ -1,8 +1,9 @@
-package main
+package common
 
 
 import (
 import (
-	"github.com/valyala/fasttemplate"
 	"io/ioutil"
 	"io/ioutil"
+
+	"github.com/valyala/fasttemplate"
 )
 )
 
 
 /*
 /*
@@ -11,12 +12,12 @@ import (
 	This is the main system core module that perform function similar to what PHP did.
 	This is the main system core module that perform function similar to what PHP did.
 	To replace part of the content of any file, use {{paramter}} to replace it.
 	To replace part of the content of any file, use {{paramter}} to replace it.
 
 
-	
+
 */
 */
 
 
-func template_load(filename string, replacement map[string]interface{}) (string, error){
+func Templateload(filename string, replacement map[string]interface{}) (string, error) {
 	content, err := ioutil.ReadFile(filename)
 	content, err := ioutil.ReadFile(filename)
-	if (err != nil){
+	if err != nil {
 		return "", nil
 		return "", nil
 	}
 	}
 	t := fasttemplate.New(string(content), "{{", "}}")
 	t := fasttemplate.New(string(content), "{{", "}}")
@@ -24,7 +25,7 @@ func template_load(filename string, replacement map[string]interface{}) (string,
 	return string(s), nil
 	return string(s), nil
 }
 }
 
 
-func template_apply(templateString string, replacement map[string]interface{}) string{
+func TemplateApply(templateString string, replacement map[string]interface{}) string {
 	t := fasttemplate.New(templateString, "{{", "}}")
 	t := fasttemplate.New(templateString, "{{", "}}")
 	s := t.ExecuteString(replacement)
 	s := t.ExecuteString(replacement)
 	return string(s)
 	return string(s)

+ 37 - 36
system.resetpw.go

@@ -1,11 +1,12 @@
 package main
 package main
 
 
 import (
 import (
-	"net/http"
-	"log"
 	"errors"
 	"errors"
+	"log"
+	"net/http"
 
 
 	auth "imuslab.com/arozos/mod/auth"
 	auth "imuslab.com/arozos/mod/auth"
+	"imuslab.com/arozos/mod/common"
 )
 )
 
 
 /*
 /*
@@ -14,20 +15,20 @@ import (
 	This module exists to serve the password restart page with security check
 	This module exists to serve the password restart page with security check
 */
 */
 
 
-func system_resetpw_init(){
-	http.HandleFunc("/system/reset/validateResetKey", system_resetpw_validateResetKeyHandler);
-	http.HandleFunc("/system/reset/confirmPasswordReset", system_resetpw_confirmReset);
+func system_resetpw_init() {
+	http.HandleFunc("/system/reset/validateResetKey", system_resetpw_validateResetKeyHandler)
+	http.HandleFunc("/system/reset/confirmPasswordReset", system_resetpw_confirmReset)
 }
 }
 
 
 //Validate if the ysername and rkey is valid
 //Validate if the ysername and rkey is valid
-func system_resetpw_validateResetKeyHandler(w http.ResponseWriter, r *http.Request){
+func system_resetpw_validateResetKeyHandler(w http.ResponseWriter, r *http.Request) {
 	username, err := mv(r, "username", true)
 	username, err := mv(r, "username", true)
-	if err != nil{
+	if err != nil {
 		sendErrorResponse(w, "Invalid username or key")
 		sendErrorResponse(w, "Invalid username or key")
 		return
 		return
 	}
 	}
 	rkey, err := mv(r, "rkey", true)
 	rkey, err := mv(r, "rkey", true)
-	if err != nil{
+	if err != nil {
 		sendErrorResponse(w, "Invalid username or key")
 		sendErrorResponse(w, "Invalid username or key")
 		return
 		return
 	}
 	}
@@ -39,7 +40,7 @@ func system_resetpw_validateResetKeyHandler(w http.ResponseWriter, r *http.Reque
 
 
 	//Check if the pair is valid
 	//Check if the pair is valid
 	err = system_resetpw_validateResetKey(username, rkey)
 	err = system_resetpw_validateResetKey(username, rkey)
-	if err != nil{
+	if err != nil {
 		sendErrorResponse(w, err.Error())
 		sendErrorResponse(w, err.Error())
 		return
 		return
 	}
 	}
@@ -48,68 +49,68 @@ func system_resetpw_validateResetKeyHandler(w http.ResponseWriter, r *http.Reque
 
 
 }
 }
 
 
-func system_resetpw_confirmReset(w http.ResponseWriter, r *http.Request){
+func system_resetpw_confirmReset(w http.ResponseWriter, r *http.Request) {
 	username, _ := mv(r, "username", true)
 	username, _ := mv(r, "username", true)
 	rkey, _ := mv(r, "rkey", true)
 	rkey, _ := mv(r, "rkey", true)
 	newpw, _ := mv(r, "pw", true)
 	newpw, _ := mv(r, "pw", true)
-	if (username == "" || rkey == "" || newpw == ""){
+	if username == "" || rkey == "" || newpw == "" {
 		sendErrorResponse(w, "Internal Server Error")
 		sendErrorResponse(w, "Internal Server Error")
 		return
 		return
 	}
 	}
 
 
 	//Check user exists
 	//Check user exists
-	if !authAgent.UserExists(username){
+	if !authAgent.UserExists(username) {
 		sendErrorResponse(w, "Username not exists")
 		sendErrorResponse(w, "Username not exists")
 		return
 		return
 	}
 	}
 
 
 	//Validate rkey
 	//Validate rkey
 	err := system_resetpw_validateResetKey(username, rkey)
 	err := system_resetpw_validateResetKey(username, rkey)
-	if err != nil{
+	if err != nil {
 		sendErrorResponse(w, err.Error())
 		sendErrorResponse(w, err.Error())
 		return
 		return
 	}
 	}
 
 
 	//OK to procced
 	//OK to procced
 	newHashedPassword := auth.Hash(newpw)
 	newHashedPassword := auth.Hash(newpw)
-	err = sysdb.Write("auth", "passhash/" + username, newHashedPassword)
-	if err != nil{
+	err = sysdb.Write("auth", "passhash/"+username, newHashedPassword)
+	if err != nil {
 		sendErrorResponse(w, err.Error())
 		sendErrorResponse(w, err.Error())
 		return
 		return
 	}
 	}
 
 
-	sendOK(w);
+	sendOK(w)
 
 
 }
 }
 
 
-func system_resetpw_validateResetKey(username string, key string) error{
+func system_resetpw_validateResetKey(username string, key string) error {
 	//Get current password from db
 	//Get current password from db
 	passwordInDB := ""
 	passwordInDB := ""
-	err := sysdb.Read("auth", "passhash/" + username, &passwordInDB)
-	if err != nil{
+	err := sysdb.Read("auth", "passhash/"+username, &passwordInDB)
+	if err != nil {
 		return err
 		return err
 	}
 	}
 
 
 	//Get hashed user key
 	//Get hashed user key
 	hashedKey := auth.Hash(key)
 	hashedKey := auth.Hash(key)
-	if (passwordInDB != hashedKey){
+	if passwordInDB != hashedKey {
 		return errors.New("Invalid Password Reset Key")
 		return errors.New("Invalid Password Reset Key")
 	}
 	}
 
 
 	return nil
 	return nil
 }
 }
 
 
-func system_resetpw_handlePasswordReset(w http.ResponseWriter, r *http.Request){
+func system_resetpw_handlePasswordReset(w http.ResponseWriter, r *http.Request) {
 	//Check if the user click on this link with reset password key string. If not, ask the user to input one
 	//Check if the user click on this link with reset password key string. If not, ask the user to input one
 	acc, err := mv(r, "acc", false)
 	acc, err := mv(r, "acc", false)
 	if err != nil || acc == "" {
 	if err != nil || acc == "" {
-		system_resetpw_serveIdEnterInterface(w,r);
+		system_resetpw_serveIdEnterInterface(w, r)
 		return
 		return
 	}
 	}
 
 
 	resetkey, err := mv(r, "rkey", false)
 	resetkey, err := mv(r, "rkey", false)
 	if err != nil || resetkey == "" {
 	if err != nil || resetkey == "" {
-		system_resetpw_serveIdEnterInterface(w,r);
+		system_resetpw_serveIdEnterInterface(w, r)
 		return
 		return
 	}
 	}
 
 
@@ -122,28 +123,28 @@ func system_resetpw_handlePasswordReset(w http.ResponseWriter, r *http.Request){
 
 
 	//OK. Create the New Password Entering UI
 	//OK. Create the New Password Entering UI
 	imageBase64, _ := LoadImageAsBase64("./web/" + iconVendor)
 	imageBase64, _ := LoadImageAsBase64("./web/" + iconVendor)
-	template, err := template_load("system/reset/resetPasswordTemplate.html",map[string]interface{}{
+	template, err := common.Templateload("system/reset/resetPasswordTemplate.html", map[string]interface{}{
 		"vendor_logo": imageBase64,
 		"vendor_logo": imageBase64,
-		"host_name": *host_name,
-		"username": acc,
-		"rkey": resetkey,
-	});
-	if err != nil{
-		log.Fatal(err);
+		"host_name":   *host_name,
+		"username":    acc,
+		"rkey":        resetkey,
+	})
+	if err != nil {
+		log.Fatal(err)
 	}
 	}
 	w.Header().Set("Content-Type", "text/html; charset=UTF-8")
 	w.Header().Set("Content-Type", "text/html; charset=UTF-8")
 	w.Write([]byte(template))
 	w.Write([]byte(template))
 }
 }
 
 
-func system_resetpw_serveIdEnterInterface(w http.ResponseWriter, r *http.Request){
+func system_resetpw_serveIdEnterInterface(w http.ResponseWriter, r *http.Request) {
 	//Reset Key or Username not found, Serve entering interface
 	//Reset Key or Username not found, Serve entering interface
 	imageBase64, _ := LoadImageAsBase64("./web/" + iconVendor)
 	imageBase64, _ := LoadImageAsBase64("./web/" + iconVendor)
-	template, err := template_load("system/reset/resetCodeTemplate.html",map[string]interface{}{
+	template, err := common.Templateload("system/reset/resetCodeTemplate.html", map[string]interface{}{
 		"vendor_logo": imageBase64,
 		"vendor_logo": imageBase64,
-		"host_name": *host_name,
-	});
-	if err != nil{
-		log.Fatal(err);
+		"host_name":   *host_name,
+	})
+	if err != nil {
+		log.Fatal(err)
 	}
 	}
 	w.Header().Set("Content-Type", "text/html; charset=UTF-8")
 	w.Header().Set("Content-Type", "text/html; charset=UTF-8")
 	w.Write([]byte(template))
 	w.Write([]byte(template))

+ 2 - 1
web/login.system

@@ -135,6 +135,7 @@
         
         
     <script>
     <script>
         var redirectionAddress = "{{redirection_addr}}";
         var redirectionAddress = "{{redirection_addr}}";
+        var loginAddress = "{{login_addr}}";
         var systemUserCount = "{{usercount}}" - 0; //Magic way to convert string to int :)
         var systemUserCount = "{{usercount}}" - 0; //Magic way to convert string to int :)
         var autoRedirectTimer;
         var autoRedirectTimer;
         var isMobile = false; //initiate as false
         var isMobile = false; //initiate as false
@@ -254,7 +255,7 @@
             var magic = $("#magic").val();
             var magic = $("#magic").val();
             var rmbme = document.getElementById("rmbme").checked;
             var rmbme = document.getElementById("rmbme").checked;
             $("input").addClass('disabled');
             $("input").addClass('disabled');
-            $.post("system/auth/login", {"username": username, "password": magic, "rmbme": rmbme}).done(function(data){
+            $.post(loginAddress, {"username": username, "password": magic, "rmbme": rmbme}).done(function(data){
                 if (data.error !== undefined){
                 if (data.error !== undefined){
                     //Something went wrong during the login
                     //Something went wrong during the login
                     $("#errmsg").text(data.error);
                     $("#errmsg").text(data.error);