mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	Use SecurityProtocol to replace UseSSL in LDAP config
Initially proposed by #2376 and fixes #3068 as well.
This commit is contained in:
		@@ -3,7 +3,7 @@ Gogs - Go Git Service [
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
##### Current tip version: 0.9.36 (see [Releases](https://github.com/gogits/gogs/releases) for binary versions)
 | 
					##### Current tip version: 0.9.37 (see [Releases](https://github.com/gogits/gogs/releases) for binary versions)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| Web | UI  | Preview  |
 | 
					| Web | UI  | Preview  |
 | 
				
			||||||
|:-------------:|:-------:|:-------:|
 | 
					|:-------------:|:-------:|:-------:|
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -919,6 +919,7 @@ auths.enabled = Enabled
 | 
				
			|||||||
auths.updated = Updated
 | 
					auths.updated = Updated
 | 
				
			||||||
auths.auth_type = Authentication Type
 | 
					auths.auth_type = Authentication Type
 | 
				
			||||||
auths.auth_name = Authentication Name
 | 
					auths.auth_name = Authentication Name
 | 
				
			||||||
 | 
					auths.security_protocol = Security Protocol
 | 
				
			||||||
auths.domain = Domain
 | 
					auths.domain = Domain
 | 
				
			||||||
auths.host = Host
 | 
					auths.host = Host
 | 
				
			||||||
auths.port = Port
 | 
					auths.port = Port
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								glide.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								glide.lock
									
									
									
										generated
									
									
									
								
							@@ -6,7 +6,7 @@ imports:
 | 
				
			|||||||
  subpackages:
 | 
					  subpackages:
 | 
				
			||||||
  - memcache
 | 
					  - memcache
 | 
				
			||||||
- name: github.com/codegangsta/cli
 | 
					- name: github.com/codegangsta/cli
 | 
				
			||||||
  version: e5bef42c62aa7d25aba4880dc02b7624f01e9e19
 | 
					  version: 1efa31f08b9333f1bd4882d61f9d668a70cd902e
 | 
				
			||||||
- name: github.com/go-macaron/binding
 | 
					- name: github.com/go-macaron/binding
 | 
				
			||||||
  version: bd00823a7e9aa00cb3b1738fde244573ba7cce2c
 | 
					  version: bd00823a7e9aa00cb3b1738fde244573ba7cce2c
 | 
				
			||||||
- name: github.com/go-macaron/cache
 | 
					- name: github.com/go-macaron/cache
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							@@ -17,7 +17,7 @@ import (
 | 
				
			|||||||
	"github.com/gogits/gogs/modules/setting"
 | 
						"github.com/gogits/gogs/modules/setting"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const APP_VER = "0.9.36.0704"
 | 
					const APP_VER = "0.9.37.0708"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	runtime.GOMAXPROCS(runtime.NumCPU())
 | 
						runtime.GOMAXPROCS(runtime.NumCPU())
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,6 +23,11 @@ import (
 | 
				
			|||||||
	"github.com/gogits/gogs/modules/log"
 | 
						"github.com/gogits/gogs/modules/log"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var (
 | 
				
			||||||
 | 
						ErrAuthenticationAlreadyExist = errors.New("Authentication already exist")
 | 
				
			||||||
 | 
						ErrAuthenticationUserUsed     = errors.New("Authentication has been used by some users")
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type LoginType int
 | 
					type LoginType int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Note: new type must be added at the end of list to maintain compatibility.
 | 
					// Note: new type must be added at the end of list to maintain compatibility.
 | 
				
			||||||
@@ -35,11 +40,6 @@ const (
 | 
				
			|||||||
	LOGIN_DLDAP            // 5
 | 
						LOGIN_DLDAP            // 5
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					 | 
				
			||||||
	ErrAuthenticationAlreadyExist = errors.New("Authentication already exist")
 | 
					 | 
				
			||||||
	ErrAuthenticationUserUsed     = errors.New("Authentication has been used by some users")
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var LoginNames = map[LoginType]string{
 | 
					var LoginNames = map[LoginType]string{
 | 
				
			||||||
	LOGIN_LDAP:  "LDAP (via BindDN)",
 | 
						LOGIN_LDAP:  "LDAP (via BindDN)",
 | 
				
			||||||
	LOGIN_DLDAP: "LDAP (simple auth)", // Via direct bind
 | 
						LOGIN_DLDAP: "LDAP (simple auth)", // Via direct bind
 | 
				
			||||||
@@ -47,6 +47,12 @@ var LoginNames = map[LoginType]string{
 | 
				
			|||||||
	LOGIN_PAM:   "PAM",
 | 
						LOGIN_PAM:   "PAM",
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var SecurityProtocolNames = map[ldap.SecurityProtocol]string{
 | 
				
			||||||
 | 
						ldap.SECURITY_PROTOCOL_UNENCRYPTED: "Unencrypted",
 | 
				
			||||||
 | 
						ldap.SECURITY_PROTOCOL_LDAPS:       "LDAPS",
 | 
				
			||||||
 | 
						ldap.SECURITY_PROTOCOL_START_TLS:   "StartTLS",
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Ensure structs implemented interface.
 | 
					// Ensure structs implemented interface.
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
	_ core.Conversion = &LDAPConfig{}
 | 
						_ core.Conversion = &LDAPConfig{}
 | 
				
			||||||
@@ -66,6 +72,10 @@ func (cfg *LDAPConfig) ToDB() ([]byte, error) {
 | 
				
			|||||||
	return json.Marshal(cfg)
 | 
						return json.Marshal(cfg)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (cfg *LDAPConfig) SecurityProtocolName() string {
 | 
				
			||||||
 | 
						return SecurityProtocolNames[cfg.SecurityProtocol]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type SMTPConfig struct {
 | 
					type SMTPConfig struct {
 | 
				
			||||||
	Auth           string
 | 
						Auth           string
 | 
				
			||||||
	Host           string
 | 
						Host           string
 | 
				
			||||||
@@ -173,10 +183,16 @@ func (source *LoginSource) IsPAM() bool {
 | 
				
			|||||||
	return source.Type == LOGIN_PAM
 | 
						return source.Type == LOGIN_PAM
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (source *LoginSource) HasTLS() bool {
 | 
				
			||||||
 | 
						return ((source.IsLDAP() || source.IsDLDAP()) &&
 | 
				
			||||||
 | 
							source.LDAP().SecurityProtocol > ldap.SECURITY_PROTOCOL_UNENCRYPTED) ||
 | 
				
			||||||
 | 
							source.IsSMTP()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (source *LoginSource) UseTLS() bool {
 | 
					func (source *LoginSource) UseTLS() bool {
 | 
				
			||||||
	switch source.Type {
 | 
						switch source.Type {
 | 
				
			||||||
	case LOGIN_LDAP, LOGIN_DLDAP:
 | 
						case LOGIN_LDAP, LOGIN_DLDAP:
 | 
				
			||||||
		return source.LDAP().UseSSL
 | 
							return source.LDAP().SecurityProtocol != ldap.SECURITY_PROTOCOL_UNENCRYPTED
 | 
				
			||||||
	case LOGIN_SMTP:
 | 
						case LOGIN_SMTP:
 | 
				
			||||||
		return source.SMTP().TLS
 | 
							return source.SMTP().TLS
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -59,14 +59,15 @@ type Version struct {
 | 
				
			|||||||
// If you want to "retire" a migration, remove it from the top of the list and
 | 
					// If you want to "retire" a migration, remove it from the top of the list and
 | 
				
			||||||
// update _MIN_VER_DB accordingly
 | 
					// update _MIN_VER_DB accordingly
 | 
				
			||||||
var migrations = []Migration{
 | 
					var migrations = []Migration{
 | 
				
			||||||
	NewMigration("fix locale file load panic", fixLocaleFileLoadPanic),                 // V4 -> V5:v0.6.0
 | 
						NewMigration("fix locale file load panic", fixLocaleFileLoadPanic),                           // V4 -> V5:v0.6.0
 | 
				
			||||||
	NewMigration("trim action compare URL prefix", trimCommitActionAppUrlPrefix),       // V5 -> V6:v0.6.3
 | 
						NewMigration("trim action compare URL prefix", trimCommitActionAppUrlPrefix),                 // V5 -> V6:v0.6.3
 | 
				
			||||||
	NewMigration("generate issue-label from issue", issueToIssueLabel),                 // V6 -> V7:v0.6.4
 | 
						NewMigration("generate issue-label from issue", issueToIssueLabel),                           // V6 -> V7:v0.6.4
 | 
				
			||||||
	NewMigration("refactor attachment table", attachmentRefactor),                      // V7 -> V8:v0.6.4
 | 
						NewMigration("refactor attachment table", attachmentRefactor),                                // V7 -> V8:v0.6.4
 | 
				
			||||||
	NewMigration("rename pull request fields", renamePullRequestFields),                // V8 -> V9:v0.6.16
 | 
						NewMigration("rename pull request fields", renamePullRequestFields),                          // V8 -> V9:v0.6.16
 | 
				
			||||||
	NewMigration("clean up migrate repo info", cleanUpMigrateRepoInfo),                 // V9 -> V10:v0.6.20
 | 
						NewMigration("clean up migrate repo info", cleanUpMigrateRepoInfo),                           // V9 -> V10:v0.6.20
 | 
				
			||||||
	NewMigration("generate rands and salt for organizations", generateOrgRandsAndSalt), // V10 -> V11:v0.8.5
 | 
						NewMigration("generate rands and salt for organizations", generateOrgRandsAndSalt),           // V10 -> V11:v0.8.5
 | 
				
			||||||
	NewMigration("convert date to unix timestamp", convertDateToUnix),                  // V11 -> V12:v0.9.2
 | 
						NewMigration("convert date to unix timestamp", convertDateToUnix),                            // V11 -> V12:v0.9.2
 | 
				
			||||||
 | 
						NewMigration("convert LDAP UseSSL option to SecurityProtocol", ldapUseSSLToSecurityProtocol), // V12 -> V13:v0.9.37
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Migrate database to current version
 | 
					// Migrate database to current version
 | 
				
			||||||
@@ -580,6 +581,7 @@ type TWebhook struct {
 | 
				
			|||||||
func (t *TWebhook) TableName() string { return "webhook" }
 | 
					func (t *TWebhook) TableName() string { return "webhook" }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func convertDateToUnix(x *xorm.Engine) (err error) {
 | 
					func convertDateToUnix(x *xorm.Engine) (err error) {
 | 
				
			||||||
 | 
						log.Info("This migration could take up to minutes, please be patient.")
 | 
				
			||||||
	type Bean struct {
 | 
						type Bean struct {
 | 
				
			||||||
		ID         int64 `xorm:"pk autoincr"`
 | 
							ID         int64 `xorm:"pk autoincr"`
 | 
				
			||||||
		Created    time.Time
 | 
							Created    time.Time
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										52
									
								
								models/migrations/v13.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								models/migrations/v13.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
				
			|||||||
 | 
					// Copyright 2016 The Gogs Authors. All rights reserved.
 | 
				
			||||||
 | 
					// Use of this source code is governed by a MIT-style
 | 
				
			||||||
 | 
					// license that can be found in the LICENSE file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package migrations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/Unknwon/com"
 | 
				
			||||||
 | 
						"github.com/go-xorm/xorm"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func ldapUseSSLToSecurityProtocol(x *xorm.Engine) error {
 | 
				
			||||||
 | 
						results, err := x.Query("SELECT `id`,`cfg` FROM `login_source` WHERE `type` = 2 OR `type` = 5")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							if strings.Contains(err.Error(), "no such column") {
 | 
				
			||||||
 | 
								return nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return fmt.Errorf("select LDAP login sources: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sess := x.NewSession()
 | 
				
			||||||
 | 
						defer sessionRelease(sess)
 | 
				
			||||||
 | 
						if err = sess.Begin(); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, result := range results {
 | 
				
			||||||
 | 
							cfg := map[string]interface{}{}
 | 
				
			||||||
 | 
							if err = json.Unmarshal(result["cfg"], &cfg); err != nil {
 | 
				
			||||||
 | 
								return fmt.Errorf("decode JSON config: %v", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if com.ToStr(cfg["UseSSL"]) == "true" {
 | 
				
			||||||
 | 
								cfg["SecurityProtocol"] = 1 // LDAPS
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							delete(cfg, "UseSSL")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							data, err := json.Marshal(&cfg)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return fmt.Errorf("encode JSON config: %v", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if _, err = sess.Exec("UPDATE `login_source` SET `cfg`=? WHERE `id`=?",
 | 
				
			||||||
 | 
								string(data), com.StrTo(result["id"]).MustInt64()); err != nil {
 | 
				
			||||||
 | 
								return fmt.Errorf("update config column: %v", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return sess.Commit()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -31,6 +31,7 @@ type AuthenticationForm struct {
 | 
				
			|||||||
	SMTPHost          string
 | 
						SMTPHost          string
 | 
				
			||||||
	SMTPPort          int
 | 
						SMTPPort          int
 | 
				
			||||||
	AllowedDomains    string
 | 
						AllowedDomains    string
 | 
				
			||||||
 | 
						SecurityProtocol  int `binding:"Range(0,2)"`
 | 
				
			||||||
	TLS               bool
 | 
						TLS               bool
 | 
				
			||||||
	SkipVerify        bool
 | 
						SkipVerify        bool
 | 
				
			||||||
	PAMServiceName    string
 | 
						PAMServiceName    string
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,12 +16,21 @@ import (
 | 
				
			|||||||
	"github.com/gogits/gogs/modules/log"
 | 
						"github.com/gogits/gogs/modules/log"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type SecurityProtocol int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Note: new type must be added at the end of list to maintain compatibility.
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						SECURITY_PROTOCOL_UNENCRYPTED SecurityProtocol = iota
 | 
				
			||||||
 | 
						SECURITY_PROTOCOL_LDAPS
 | 
				
			||||||
 | 
						SECURITY_PROTOCOL_START_TLS
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Basic LDAP authentication service
 | 
					// Basic LDAP authentication service
 | 
				
			||||||
type Source struct {
 | 
					type Source struct {
 | 
				
			||||||
	Name              string // canonical name (ie. corporate.ad)
 | 
						Name              string // canonical name (ie. corporate.ad)
 | 
				
			||||||
	Host              string // LDAP host
 | 
						Host              string // LDAP host
 | 
				
			||||||
	Port              int    // port number
 | 
						Port              int    // port number
 | 
				
			||||||
	UseSSL            bool   // Use SSL
 | 
						SecurityProtocol  SecurityProtocol
 | 
				
			||||||
	SkipVerify        bool
 | 
						SkipVerify        bool
 | 
				
			||||||
	BindDN            string // DN to bind with
 | 
						BindDN            string // DN to bind with
 | 
				
			||||||
	BindPassword      string // Bind DN password
 | 
						BindPassword      string // Bind DN password
 | 
				
			||||||
@@ -102,9 +111,46 @@ func (ls *Source) findUserDN(l *ldap.Conn, name string) (string, bool) {
 | 
				
			|||||||
	return userDN, true
 | 
						return userDN, true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func dial(ls *Source) (*ldap.Conn, error) {
 | 
				
			||||||
 | 
						log.Trace("Dialing LDAP with security protocol (%v) without verifying: %v", ls.SecurityProtocol, ls.SkipVerify)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tlsCfg := &tls.Config{
 | 
				
			||||||
 | 
							ServerName:         ls.Host,
 | 
				
			||||||
 | 
							InsecureSkipVerify: ls.SkipVerify,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if ls.SecurityProtocol == SECURITY_PROTOCOL_LDAPS {
 | 
				
			||||||
 | 
							return ldap.DialTLS("tcp", fmt.Sprintf("%s:%d", ls.Host, ls.Port), tlsCfg)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						conn, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", ls.Host, ls.Port))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("Dial: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ls.SecurityProtocol == SECURITY_PROTOCOL_START_TLS {
 | 
				
			||||||
 | 
							if err = conn.StartTLS(tlsCfg); err != nil {
 | 
				
			||||||
 | 
								conn.Close()
 | 
				
			||||||
 | 
								return nil, fmt.Errorf("StartTLS: %v", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return conn, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func bindUser(l *ldap.Conn, userDN, passwd string) error {
 | 
				
			||||||
 | 
						log.Trace("Binding with userDN: %s", userDN)
 | 
				
			||||||
 | 
						err := l.Bind(userDN, passwd)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Debug("LDAP auth. failed for %s, reason: %v", userDN, err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						log.Trace("Bound successfully with userDN: %s", userDN)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// searchEntry : search an LDAP source if an entry (name, passwd) is valid and in the specific filter
 | 
					// searchEntry : search an LDAP source if an entry (name, passwd) is valid and in the specific filter
 | 
				
			||||||
func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, string, string, string, bool, bool) {
 | 
					func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, string, string, string, bool, bool) {
 | 
				
			||||||
	l, err := ldapDial(ls)
 | 
						l, err := dial(ls)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Error(4, "LDAP Connect error, %s:%v", ls.Host, err)
 | 
							log.Error(4, "LDAP Connect error, %s:%v", ls.Host, err)
 | 
				
			||||||
		ls.Enabled = false
 | 
							ls.Enabled = false
 | 
				
			||||||
@@ -197,26 +243,3 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) (string, str
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	return username_attr, name_attr, sn_attr, mail_attr, admin_attr, true
 | 
						return username_attr, name_attr, sn_attr, mail_attr, admin_attr, true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
func bindUser(l *ldap.Conn, userDN, passwd string) error {
 | 
					 | 
				
			||||||
	log.Trace("Binding with userDN: %s", userDN)
 | 
					 | 
				
			||||||
	err := l.Bind(userDN, passwd)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Debug("LDAP auth. failed for %s, reason: %v", userDN, err)
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	log.Trace("Bound successfully with userDN: %s", userDN)
 | 
					 | 
				
			||||||
	return err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func ldapDial(ls *Source) (*ldap.Conn, error) {
 | 
					 | 
				
			||||||
	if ls.UseSSL {
 | 
					 | 
				
			||||||
		log.Debug("Using TLS for LDAP without verifying: %v", ls.SkipVerify)
 | 
					 | 
				
			||||||
		return ldap.DialTLS("tcp", fmt.Sprintf("%s:%d", ls.Host, ls.Port), &tls.Config{
 | 
					 | 
				
			||||||
			ServerName:         ls.Host,
 | 
					 | 
				
			||||||
			InsecureSkipVerify: ls.SkipVerify,
 | 
					 | 
				
			||||||
		})
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		return ldap.Dial("tcp", fmt.Sprintf("%s:%d", ls.Host, ls.Port))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@@ -612,6 +612,13 @@ function initAdmin() {
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function onSecurityProtocolChange() {
 | 
				
			||||||
 | 
					        if ($('#security_protocol').val() > 0) {
 | 
				
			||||||
 | 
					            $('.has-tls').show();
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $('.has-tls').hide();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // New authentication
 | 
					    // New authentication
 | 
				
			||||||
    if ($('.admin.new.authentication').length > 0) {
 | 
					    if ($('.admin.new.authentication').length > 0) {
 | 
				
			||||||
@@ -620,6 +627,7 @@ function initAdmin() {
 | 
				
			|||||||
            $('.dldap').hide();
 | 
					            $('.dldap').hide();
 | 
				
			||||||
            $('.smtp').hide();
 | 
					            $('.smtp').hide();
 | 
				
			||||||
            $('.pam').hide();
 | 
					            $('.pam').hide();
 | 
				
			||||||
 | 
					            $('.has-tls').hide();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var auth_type = $(this).val();
 | 
					            var auth_type = $(this).val();
 | 
				
			||||||
            switch (auth_type) {
 | 
					            switch (auth_type) {
 | 
				
			||||||
@@ -628,6 +636,7 @@ function initAdmin() {
 | 
				
			|||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
                case '3':     // SMTP
 | 
					                case '3':     // SMTP
 | 
				
			||||||
                    $('.smtp').show();
 | 
					                    $('.smtp').show();
 | 
				
			||||||
 | 
					                    $('.has-tls').show();
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
                case '4':     // PAM
 | 
					                case '4':     // PAM
 | 
				
			||||||
                    $('.pam').show();
 | 
					                    $('.pam').show();
 | 
				
			||||||
@@ -636,7 +645,19 @@ function initAdmin() {
 | 
				
			|||||||
                    $('.dldap').show();
 | 
					                    $('.dldap').show();
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (auth_type == '2' || auth_type == '5') {
 | 
				
			||||||
 | 
					                onSecurityProtocolChange()
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					        $('#security_protocol').change(onSecurityProtocolChange)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    // Edit authentication
 | 
				
			||||||
 | 
					    if ($('.admin.edit.authentication').length > 0) {
 | 
				
			||||||
 | 
					        var auth_type = $('#auth_type').val();
 | 
				
			||||||
 | 
					        if (auth_type == '2' || auth_type == '5') {
 | 
				
			||||||
 | 
					            $('#security_protocol').change(onSecurityProtocolChange);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Notice
 | 
					    // Notice
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,17 +41,24 @@ func Authentications(ctx *context.Context) {
 | 
				
			|||||||
	ctx.HTML(200, AUTHS)
 | 
						ctx.HTML(200, AUTHS)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type AuthSource struct {
 | 
					type dropdownItem struct {
 | 
				
			||||||
	Name string
 | 
						Name string
 | 
				
			||||||
	Type models.LoginType
 | 
						Type interface{}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var authSources = []AuthSource{
 | 
					var (
 | 
				
			||||||
	{models.LoginNames[models.LOGIN_LDAP], models.LOGIN_LDAP},
 | 
						authSources = []dropdownItem{
 | 
				
			||||||
	{models.LoginNames[models.LOGIN_DLDAP], models.LOGIN_DLDAP},
 | 
							{models.LoginNames[models.LOGIN_LDAP], models.LOGIN_LDAP},
 | 
				
			||||||
	{models.LoginNames[models.LOGIN_SMTP], models.LOGIN_SMTP},
 | 
							{models.LoginNames[models.LOGIN_DLDAP], models.LOGIN_DLDAP},
 | 
				
			||||||
	{models.LoginNames[models.LOGIN_PAM], models.LOGIN_PAM},
 | 
							{models.LoginNames[models.LOGIN_SMTP], models.LOGIN_SMTP},
 | 
				
			||||||
}
 | 
							{models.LoginNames[models.LOGIN_PAM], models.LOGIN_PAM},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						securityProtocols = []dropdownItem{
 | 
				
			||||||
 | 
							{models.SecurityProtocolNames[ldap.SECURITY_PROTOCOL_UNENCRYPTED], ldap.SECURITY_PROTOCOL_UNENCRYPTED},
 | 
				
			||||||
 | 
							{models.SecurityProtocolNames[ldap.SECURITY_PROTOCOL_LDAPS], ldap.SECURITY_PROTOCOL_LDAPS},
 | 
				
			||||||
 | 
							{models.SecurityProtocolNames[ldap.SECURITY_PROTOCOL_START_TLS], ldap.SECURITY_PROTOCOL_START_TLS},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewAuthSource(ctx *context.Context) {
 | 
					func NewAuthSource(ctx *context.Context) {
 | 
				
			||||||
	ctx.Data["Title"] = ctx.Tr("admin.auths.new")
 | 
						ctx.Data["Title"] = ctx.Tr("admin.auths.new")
 | 
				
			||||||
@@ -59,10 +66,12 @@ func NewAuthSource(ctx *context.Context) {
 | 
				
			|||||||
	ctx.Data["PageIsAdminAuthentications"] = true
 | 
						ctx.Data["PageIsAdminAuthentications"] = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx.Data["type"] = models.LOGIN_LDAP
 | 
						ctx.Data["type"] = models.LOGIN_LDAP
 | 
				
			||||||
	ctx.Data["CurTypeName"] = models.LoginNames[models.LOGIN_LDAP]
 | 
						ctx.Data["CurrentTypeName"] = models.LoginNames[models.LOGIN_LDAP]
 | 
				
			||||||
 | 
						ctx.Data["CurrentSecurityProtocol"] = models.SecurityProtocolNames[ldap.SECURITY_PROTOCOL_UNENCRYPTED]
 | 
				
			||||||
	ctx.Data["smtp_auth"] = "PLAIN"
 | 
						ctx.Data["smtp_auth"] = "PLAIN"
 | 
				
			||||||
	ctx.Data["is_active"] = true
 | 
						ctx.Data["is_active"] = true
 | 
				
			||||||
	ctx.Data["AuthSources"] = authSources
 | 
						ctx.Data["AuthSources"] = authSources
 | 
				
			||||||
 | 
						ctx.Data["SecurityProtocols"] = securityProtocols
 | 
				
			||||||
	ctx.Data["SMTPAuths"] = models.SMTPAuths
 | 
						ctx.Data["SMTPAuths"] = models.SMTPAuths
 | 
				
			||||||
	ctx.HTML(200, AUTH_NEW)
 | 
						ctx.HTML(200, AUTH_NEW)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -73,7 +82,7 @@ func parseLDAPConfig(form auth.AuthenticationForm) *models.LDAPConfig {
 | 
				
			|||||||
			Name:              form.Name,
 | 
								Name:              form.Name,
 | 
				
			||||||
			Host:              form.Host,
 | 
								Host:              form.Host,
 | 
				
			||||||
			Port:              form.Port,
 | 
								Port:              form.Port,
 | 
				
			||||||
			UseSSL:            form.TLS,
 | 
								SecurityProtocol:  ldap.SecurityProtocol(form.SecurityProtocol),
 | 
				
			||||||
			SkipVerify:        form.SkipVerify,
 | 
								SkipVerify:        form.SkipVerify,
 | 
				
			||||||
			BindDN:            form.BindDN,
 | 
								BindDN:            form.BindDN,
 | 
				
			||||||
			UserDN:            form.UserDN,
 | 
								UserDN:            form.UserDN,
 | 
				
			||||||
@@ -107,21 +116,21 @@ func NewAuthSourcePost(ctx *context.Context, form auth.AuthenticationForm) {
 | 
				
			|||||||
	ctx.Data["PageIsAdmin"] = true
 | 
						ctx.Data["PageIsAdmin"] = true
 | 
				
			||||||
	ctx.Data["PageIsAdminAuthentications"] = true
 | 
						ctx.Data["PageIsAdminAuthentications"] = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx.Data["CurTypeName"] = models.LoginNames[models.LoginType(form.Type)]
 | 
						ctx.Data["CurrentTypeName"] = models.LoginNames[models.LoginType(form.Type)]
 | 
				
			||||||
 | 
						ctx.Data["CurrentSecurityProtocol"] = models.SecurityProtocolNames[ldap.SecurityProtocol(form.SecurityProtocol)]
 | 
				
			||||||
	ctx.Data["AuthSources"] = authSources
 | 
						ctx.Data["AuthSources"] = authSources
 | 
				
			||||||
 | 
						ctx.Data["SecurityProtocols"] = securityProtocols
 | 
				
			||||||
	ctx.Data["SMTPAuths"] = models.SMTPAuths
 | 
						ctx.Data["SMTPAuths"] = models.SMTPAuths
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ctx.HasError() {
 | 
						hasTLS := false
 | 
				
			||||||
		ctx.HTML(200, AUTH_NEW)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var config core.Conversion
 | 
						var config core.Conversion
 | 
				
			||||||
	switch models.LoginType(form.Type) {
 | 
						switch models.LoginType(form.Type) {
 | 
				
			||||||
	case models.LOGIN_LDAP, models.LOGIN_DLDAP:
 | 
						case models.LOGIN_LDAP, models.LOGIN_DLDAP:
 | 
				
			||||||
		config = parseLDAPConfig(form)
 | 
							config = parseLDAPConfig(form)
 | 
				
			||||||
 | 
							hasTLS = ldap.SecurityProtocol(form.SecurityProtocol) > ldap.SECURITY_PROTOCOL_UNENCRYPTED
 | 
				
			||||||
	case models.LOGIN_SMTP:
 | 
						case models.LOGIN_SMTP:
 | 
				
			||||||
		config = parseSMTPConfig(form)
 | 
							config = parseSMTPConfig(form)
 | 
				
			||||||
 | 
							hasTLS = true
 | 
				
			||||||
	case models.LOGIN_PAM:
 | 
						case models.LOGIN_PAM:
 | 
				
			||||||
		config = &models.PAMConfig{
 | 
							config = &models.PAMConfig{
 | 
				
			||||||
			ServiceName: form.PAMServiceName,
 | 
								ServiceName: form.PAMServiceName,
 | 
				
			||||||
@@ -130,6 +139,12 @@ func NewAuthSourcePost(ctx *context.Context, form auth.AuthenticationForm) {
 | 
				
			|||||||
		ctx.Error(400)
 | 
							ctx.Error(400)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						ctx.Data["HasTLS"] = hasTLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ctx.HasError() {
 | 
				
			||||||
 | 
							ctx.HTML(200, AUTH_NEW)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := models.CreateSource(&models.LoginSource{
 | 
						if err := models.CreateSource(&models.LoginSource{
 | 
				
			||||||
		Type:      models.LoginType(form.Type),
 | 
							Type:      models.LoginType(form.Type),
 | 
				
			||||||
@@ -152,6 +167,7 @@ func EditAuthSource(ctx *context.Context) {
 | 
				
			|||||||
	ctx.Data["PageIsAdmin"] = true
 | 
						ctx.Data["PageIsAdmin"] = true
 | 
				
			||||||
	ctx.Data["PageIsAdminAuthentications"] = true
 | 
						ctx.Data["PageIsAdminAuthentications"] = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx.Data["SecurityProtocols"] = securityProtocols
 | 
				
			||||||
	ctx.Data["SMTPAuths"] = models.SMTPAuths
 | 
						ctx.Data["SMTPAuths"] = models.SMTPAuths
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	source, err := models.GetLoginSourceByID(ctx.ParamsInt64(":authid"))
 | 
						source, err := models.GetLoginSourceByID(ctx.ParamsInt64(":authid"))
 | 
				
			||||||
@@ -160,6 +176,8 @@ func EditAuthSource(ctx *context.Context) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	ctx.Data["Source"] = source
 | 
						ctx.Data["Source"] = source
 | 
				
			||||||
 | 
						ctx.Data["HasTLS"] = source.HasTLS()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx.HTML(200, AUTH_EDIT)
 | 
						ctx.HTML(200, AUTH_EDIT)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -176,6 +194,7 @@ func EditAuthSourcePost(ctx *context.Context, form auth.AuthenticationForm) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	ctx.Data["Source"] = source
 | 
						ctx.Data["Source"] = source
 | 
				
			||||||
 | 
						ctx.Data["HasTLS"] = source.HasTLS()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ctx.HasError() {
 | 
						if ctx.HasError() {
 | 
				
			||||||
		ctx.HTML(200, AUTH_EDIT)
 | 
							ctx.HTML(200, AUTH_EDIT)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1 +1 @@
 | 
				
			|||||||
0.9.36.0704
 | 
					0.9.37.0708
 | 
				
			||||||
@@ -14,7 +14,7 @@
 | 
				
			|||||||
						<input type="hidden" name="id" value="{{.Source.ID}}">
 | 
											<input type="hidden" name="id" value="{{.Source.ID}}">
 | 
				
			||||||
						<div class="inline field">
 | 
											<div class="inline field">
 | 
				
			||||||
							<label>{{$.i18n.Tr "admin.auths.auth_type"}}</label>
 | 
												<label>{{$.i18n.Tr "admin.auths.auth_type"}}</label>
 | 
				
			||||||
							<input type="hidden" name="type" value="{{.Source.Type}}">
 | 
												<input type="hidden" id="auth_type" name="type" value="{{.Source.Type}}">
 | 
				
			||||||
							<span>{{.Source.TypeName}}</span>
 | 
												<span>{{.Source.TypeName}}</span>
 | 
				
			||||||
						</div>
 | 
											</div>
 | 
				
			||||||
						<div class="required inline field {{if .Err_Name}}error{{end}}">
 | 
											<div class="required inline field {{if .Err_Name}}error{{end}}">
 | 
				
			||||||
@@ -25,6 +25,19 @@
 | 
				
			|||||||
						<!-- LDAP and DLDAP -->
 | 
											<!-- LDAP and DLDAP -->
 | 
				
			||||||
						{{if or .Source.IsLDAP .Source.IsDLDAP}}
 | 
											{{if or .Source.IsLDAP .Source.IsDLDAP}}
 | 
				
			||||||
							{{ $cfg:=.Source.LDAP }}
 | 
												{{ $cfg:=.Source.LDAP }}
 | 
				
			||||||
 | 
												<div class="inline required field {{if .Err_SecurityProtocol}}error{{end}}">
 | 
				
			||||||
 | 
													<label>{{.i18n.Tr "admin.auths.security_protocol"}}</label>
 | 
				
			||||||
 | 
													<div class="ui selection security-protocol dropdown">
 | 
				
			||||||
 | 
														<input type="hidden" id="security_protocol" name="security_protocol" value="{{$cfg.SecurityProtocol}}">
 | 
				
			||||||
 | 
														<div class="text">{{$cfg.SecurityProtocolName}}</div>
 | 
				
			||||||
 | 
														<i class="dropdown icon"></i>
 | 
				
			||||||
 | 
														<div class="menu">
 | 
				
			||||||
 | 
															{{range .SecurityProtocols}}
 | 
				
			||||||
 | 
																<div class="item" data-value="{{.Type}}">{{.Name}}</div>
 | 
				
			||||||
 | 
															{{end}}
 | 
				
			||||||
 | 
														</div>
 | 
				
			||||||
 | 
													</div>
 | 
				
			||||||
 | 
												</div>
 | 
				
			||||||
							<div class="required field">
 | 
												<div class="required field">
 | 
				
			||||||
								<label for="host">{{.i18n.Tr "admin.auths.host"}}</label>
 | 
													<label for="host">{{.i18n.Tr "admin.auths.host"}}</label>
 | 
				
			||||||
								<input id="host" name="host" value="{{$cfg.Host}}" placeholder="e.g. mydomain.com" required>
 | 
													<input id="host" name="host" value="{{$cfg.Host}}" placeholder="e.g. mydomain.com" required>
 | 
				
			||||||
@@ -129,13 +142,13 @@
 | 
				
			|||||||
							</div>
 | 
												</div>
 | 
				
			||||||
						{{end}}
 | 
											{{end}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
						<div class="inline field {{if not (or (or .Source.IsLDAP .Source.IsDLDAP) .Source.IsSMTP)}}hide{{end}}">
 | 
											<div class="inline field {{if not .Source.IsSMTP}}hide{{end}}">
 | 
				
			||||||
							<div class="ui checkbox">
 | 
												<div class="ui checkbox">
 | 
				
			||||||
								<label><strong>{{.i18n.Tr "admin.auths.enable_tls"}}</strong></label>
 | 
													<label><strong>{{.i18n.Tr "admin.auths.enable_tls"}}</strong></label>
 | 
				
			||||||
								<input name="tls" type="checkbox" {{if .Source.UseTLS}}checked{{end}}>
 | 
													<input name="tls" type="checkbox" {{if .Source.UseTLS}}checked{{end}}>
 | 
				
			||||||
							</div>
 | 
												</div>
 | 
				
			||||||
						</div>
 | 
											</div>
 | 
				
			||||||
						<div class="inline field {{if not (or (or .Source.IsLDAP .Source.IsDLDAP) .Source.IsSMTP)}}hide{{end}}">
 | 
											<div class="has-tls inline field {{if not .HasTLS}}hide{{end}}">
 | 
				
			||||||
							<div class="ui checkbox">
 | 
												<div class="ui checkbox">
 | 
				
			||||||
								<label><strong>{{.i18n.Tr "admin.auths.skip_tls_verify"}}</strong></label>
 | 
													<label><strong>{{.i18n.Tr "admin.auths.skip_tls_verify"}}</strong></label>
 | 
				
			||||||
								<input name="skip_verify" type="checkbox" {{if .Source.SkipVerify}}checked{{end}}>
 | 
													<input name="skip_verify" type="checkbox" {{if .Source.SkipVerify}}checked{{end}}>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,7 @@
 | 
				
			|||||||
							<label>{{.i18n.Tr "admin.auths.auth_type"}}</label>
 | 
												<label>{{.i18n.Tr "admin.auths.auth_type"}}</label>
 | 
				
			||||||
							<div class="ui selection type dropdown">
 | 
												<div class="ui selection type dropdown">
 | 
				
			||||||
								<input type="hidden" id="auth_type" name="type" value="{{.type}}">
 | 
													<input type="hidden" id="auth_type" name="type" value="{{.type}}">
 | 
				
			||||||
								<div class="text">{{.CurTypeName}}</div>
 | 
													<div class="text">{{.CurrentTypeName}}</div>
 | 
				
			||||||
								<i class="dropdown icon"></i>
 | 
													<i class="dropdown icon"></i>
 | 
				
			||||||
								<div class="menu">
 | 
													<div class="menu">
 | 
				
			||||||
									{{range .AuthSources}}
 | 
														{{range .AuthSources}}
 | 
				
			||||||
@@ -32,6 +32,19 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
						<!-- LDAP and DLDAP -->
 | 
											<!-- LDAP and DLDAP -->
 | 
				
			||||||
						<div class="ldap dldap field {{if not (or (eq .type 2) (eq .type 5))}}hide{{end}}">
 | 
											<div class="ldap dldap field {{if not (or (eq .type 2) (eq .type 5))}}hide{{end}}">
 | 
				
			||||||
 | 
												<div class="inline required field {{if .Err_SecurityProtocol}}error{{end}}">
 | 
				
			||||||
 | 
													<label>{{.i18n.Tr "admin.auths.security_protocol"}}</label>
 | 
				
			||||||
 | 
													<div class="ui selection security-protocol dropdown">
 | 
				
			||||||
 | 
														<input type="hidden" id="security_protocol" name="security_protocol" value="{{.security_protocol}}">
 | 
				
			||||||
 | 
														<div class="text">{{.CurrentSecurityProtocol}}</div>
 | 
				
			||||||
 | 
														<i class="dropdown icon"></i>
 | 
				
			||||||
 | 
														<div class="menu">
 | 
				
			||||||
 | 
															{{range .SecurityProtocols}}
 | 
				
			||||||
 | 
																<div class="item" data-value="{{.Type}}">{{.Name}}</div>
 | 
				
			||||||
 | 
															{{end}}
 | 
				
			||||||
 | 
														</div>
 | 
				
			||||||
 | 
													</div>
 | 
				
			||||||
 | 
												</div>
 | 
				
			||||||
							<div class="required field">
 | 
												<div class="required field">
 | 
				
			||||||
								<label for="host">{{.i18n.Tr "admin.auths.host"}}</label>
 | 
													<label for="host">{{.i18n.Tr "admin.auths.host"}}</label>
 | 
				
			||||||
								<input id="host" name="host" value="{{.host}}" placeholder="e.g. mydomain.com">
 | 
													<input id="host" name="host" value="{{.host}}" placeholder="e.g. mydomain.com">
 | 
				
			||||||
@@ -126,13 +139,13 @@
 | 
				
			|||||||
								<input name="attributes_in_bind" type="checkbox" {{if .attributes_in_bind}}checked{{end}}>
 | 
													<input name="attributes_in_bind" type="checkbox" {{if .attributes_in_bind}}checked{{end}}>
 | 
				
			||||||
							</div>
 | 
												</div>
 | 
				
			||||||
						</div>
 | 
											</div>
 | 
				
			||||||
						<div class="ldap dldap smtp inline field {{if not (or (or (eq .type 2) (eq .type 5)) (eq .type 3))}}hide{{end}}">
 | 
											<div class="smtp inline field {{if not (eq .type 3)}}hide{{end}}">
 | 
				
			||||||
							<div class="ui checkbox">
 | 
												<div class="ui checkbox">
 | 
				
			||||||
								<label><strong>{{.i18n.Tr "admin.auths.enable_tls"}}</strong></label>
 | 
													<label><strong>{{.i18n.Tr "admin.auths.enable_tls"}}</strong></label>
 | 
				
			||||||
								<input name="tls" type="checkbox" {{if .tls}}checked{{end}}>
 | 
													<input name="tls" type="checkbox" {{if .tls}}checked{{end}}>
 | 
				
			||||||
							</div>
 | 
												</div>
 | 
				
			||||||
						</div>
 | 
											</div>
 | 
				
			||||||
						<div class="ldap dldap smtp inline field {{if not (or (or (eq .type 2) (eq .type 5)) (eq .type 3))}}hide{{end}}">
 | 
											<div class="has-tls inline field {{if not .HasTLS}}hide{{end}}">
 | 
				
			||||||
							<div class="ui checkbox">
 | 
												<div class="ui checkbox">
 | 
				
			||||||
								<label><strong>{{.i18n.Tr "admin.auths.skip_tls_verify"}}</strong></label>
 | 
													<label><strong>{{.i18n.Tr "admin.auths.skip_tls_verify"}}</strong></label>
 | 
				
			||||||
								<input name="skip_verify" type="checkbox" {{if .skip_verify}}checked{{end}}>
 | 
													<input name="skip_verify" type="checkbox" {{if .skip_verify}}checked{{end}}>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user