diff --git a/data/data.go b/data/data.go index f658add..a2062b8 100644 --- a/data/data.go +++ b/data/data.go @@ -33,7 +33,7 @@ var ( // IsPrimary i.e. Is Primary Node IsPrimary bool // Version of JANUSEC - Version = "1.2.5" + Version = "1.2.6" // NodeKey share with all nodes NodeKey []byte ) diff --git a/data/setting.go b/data/setting.go index 84a6db6..0ab4215 100644 --- a/data/setting.go +++ b/data/setting.go @@ -8,6 +8,7 @@ package data import ( + "encoding/hex" "encoding/json" "errors" "fmt" @@ -186,6 +187,17 @@ func InitDefaultSettings() { if !DAL.ExistsSetting("ldap_authenticator_enabled") { _ = DAL.SaveBoolSetting("ldap_authenticator_enabled", false) } + // v1.2.6 + if !DAL.ExistsSetting("ldap_bind_required") { + _ = DAL.SaveBoolSetting("ldap_bind_required", false) + } + if !DAL.ExistsSetting("ldap_base_dn") { + DAL.SaveStringSetting("ldap_base_dn", "CN=Users,DC=your_domain,DC=com") + } + if !DAL.ExistsSetting("ldap_bind_username") { + DAL.SaveStringSetting("ldap_bind_username", "administrator") + } + // AuthConfig cas2 if !DAL.ExistsSetting("cas2_display_name") { DAL.SaveStringSetting("cas2_display_name", "Login with CAS 2.0") @@ -456,6 +468,18 @@ func GetLDAPConfig() *models.LDAPConfig { dn := DAL.SelectStringSetting("ldap_dn") usingTLS := DAL.SelectBoolSetting("ldap_using_tls") authenticatorEnabled := DAL.SelectBoolSetting("ldap_authenticator_enabled") + bindRequired := DAL.SelectBoolSetting("ldap_bind_required") + baseDN := DAL.SelectStringSetting("ldap_base_dn") + bindUsername := DAL.SelectStringSetting("ldap_bind_username") + hexBindPassword := DAL.SelectStringSetting("ldap_bind_password") + var bindPassword string + if len(hexBindPassword) == 0 { + bindPassword = "" + } else { + encryptedBindPassword, _ := hex.DecodeString(hexBindPassword) + bindPasswordByte, _ := AES256Decrypt(encryptedBindPassword, false) + bindPassword = string(bindPasswordByte) + } ldapConfig := &models.LDAPConfig{ DisplayName: displayName, @@ -464,6 +488,10 @@ func GetLDAPConfig() *models.LDAPConfig { DN: dn, UsingTLS: usingTLS, AuthenticatorEnabled: authenticatorEnabled, + BindRequired: bindRequired, + BaseDN: baseDN, + BindUsername: bindUsername, + BindPassword: bindPassword, } return ldapConfig } @@ -480,12 +508,29 @@ func UpdateLDAPConfig(param map[string]interface{}, clientIP string, authUser *m dn := ldapConfig["dn"].(string) usingTLS := ldapConfig["using_tls"].(bool) authenticatorEnabled := ldapConfig["authenticator_enabled"].(bool) + bindRequired := ldapConfig["bind_required"].(bool) + baseDN := ldapConfig["base_dn"].(string) + bindUsername := ldapConfig["bind_username"].(string) + bindPassword := ldapConfig["bind_password"].(string) + DAL.SaveStringSetting("ldap_display_name", displayName) DAL.SaveStringSetting("ldap_entrance", entrance) DAL.SaveStringSetting("ldap_address", address) DAL.SaveStringSetting("ldap_dn", dn) DAL.SaveBoolSetting("ldap_using_tls", usingTLS) DAL.SaveBoolSetting("ldap_authenticator_enabled", authenticatorEnabled) + DAL.SaveBoolSetting("ldap_bind_required", bindRequired) + DAL.SaveStringSetting("ldap_base_dn", baseDN) + DAL.SaveStringSetting("ldap_bind_username", bindUsername) + var encrypedBindPassword string + if len(bindPassword) == 0 { + encrypedBindPassword = "" + } else { + encryptedPasswordBytes := AES256Encrypt([]byte(bindPassword), false) + encrypedBindPassword = hex.EncodeToString(encryptedPasswordBytes) + } + DAL.SaveStringSetting("ldap_bind_password", encrypedBindPassword) + newLDAPConfig := &models.LDAPConfig{ DisplayName: displayName, Entrance: entrance, @@ -493,6 +538,10 @@ func UpdateLDAPConfig(param map[string]interface{}, clientIP string, authUser *m DN: dn, UsingTLS: usingTLS, AuthenticatorEnabled: authenticatorEnabled, + BindRequired: bindRequired, + BaseDN: baseDN, + BindUsername: bindUsername, + BindPassword: bindPassword, } NodeSetting.AuthConfig.LDAP = newLDAPConfig go utils.OperationLog(clientIP, authUser.Username, "Update LDAP Config", displayName) @@ -607,7 +656,7 @@ func RPCGetNodeSetting() *models.NodeShareSetting { if rpcObject.Object == nil { rpcObject.Object = &models.NodeShareSetting{ SyncInterval: time.Duration(120) * time.Second, - } + } utils.DebugPrintln("RPCGetNodeSetting failed, please check config.json and server time") } return rpcObject.Object diff --git a/gateway/gateway.go b/gateway/gateway.go index a6fb84b..2661ec4 100644 --- a/gateway/gateway.go +++ b/gateway/gateway.go @@ -184,7 +184,7 @@ func ReverseHandlerFunc(w http.ResponseWriter, r *http.Request) { } captchaHitInfo.Store(hitInfo.ClientID, hitInfo) captchaURL := CaptchaEntrance + "?id=" + hitInfo.ClientID - http.Redirect(w, r, captchaURL, http.StatusTemporaryRedirect) + http.Redirect(w, r, captchaURL, http.StatusFound) return } } @@ -346,6 +346,12 @@ func ReverseHandlerFunc(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, targetFile) return } + targetFile := dest.BackendRoute + strings.Replace(r.URL.Path, dest.RequestRoute, "", 1) + if _, err := os.Stat(targetFile); os.IsNotExist(err) { + // targetFile not exists + http.Redirect(w, r, dest.RequestRoute, http.StatusFound) + return + } http.StripPrefix(dest.RequestRoute, staticHandler).ServeHTTP(w, r) return } else if dest.RouteType == models.FastCGIRoute { @@ -494,8 +500,8 @@ func ReverseHandlerFunc(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Encoding", "br") brWriter := brotli.NewWriter(w) defer brWriter.Close() - zipResponseWriter := models.ZipResponseWriter { - Writer: brWriter, + zipResponseWriter := models.ZipResponseWriter{ + Writer: brWriter, ResponseWriter: w, } http.ServeFile(zipResponseWriter, r, targetFile) @@ -503,19 +509,19 @@ func ReverseHandlerFunc(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Encoding", "gzip") gzWriter := gzip.NewWriter(w) defer gzWriter.Close() - zipResponseWriter := models.ZipResponseWriter { - Writer: gzWriter, + zipResponseWriter := models.ZipResponseWriter{ + Writer: gzWriter, ResponseWriter: w, } http.ServeFile(zipResponseWriter, r, targetFile) } else { http.ServeFile(w, r, targetFile) - } + } return } } // Has Range Header, or resource Not Found, Continue - // For static files, disable compression between gateway and backend + // For static files, disable compression between gateway and backend r.Header.Set("Accept-Encoding", "") } } diff --git a/models/data_config.go b/models/data_config.go index 9c40b55..5f2368d 100644 --- a/models/data_config.go +++ b/models/data_config.go @@ -30,8 +30,6 @@ type OAuthConfig struct { type PrimaryNodeConfig struct { Admin AdminConfig `json:"admin"` Database DBConfig `json:"database"` - // OAuth removed from v1.0.0 - // OAuth OAuthConfig `json:"oauth"` } type ReplicaNodeConfig struct { @@ -105,4 +103,13 @@ type LDAPConfig struct { DN string `json:"dn"` UsingTLS bool `json:"using_tls"` AuthenticatorEnabled bool `json:"authenticator_enabled"` + + // BindRequired v1.2.6, for active directory, usually bind an adminitrator account + BindRequired bool `json:"bind_required"` + // BaseDN + BaseDN string `json:"base_dn"` + // BindUsername v1.2.6 + BindUsername string `json:"bind_username"` + // BindPassword v1.2.6 + BindPassword string `json:"bind_password"` } diff --git a/release_batch.sh b/release_batch.sh index 91172e3..bdf72a3 100755 --- a/release_batch.sh +++ b/release_batch.sh @@ -2,7 +2,7 @@ printf "Creating installation package\n" printf "Checklist:\n" printf "* Angular Admin Version Check. \n" printf "* Janusec Version Check. \n" -version="1.2.5" +version="1.2.6" printf "Version: ${version} \n" read -r -p "Are You Sure? [Y/n] " option diff --git a/static/janusec-admin/index.html b/static/janusec-admin/index.html index b87b48d..9524abb 100644 --- a/static/janusec-admin/index.html +++ b/static/janusec-admin/index.html @@ -10,5 +10,5 @@