]> source.dussan.org Git - gitea.git/commitdiff
Set IsAdmin using LDAP
authorGirish Ramakrishnan <girish@cloudron.io>
Wed, 19 Aug 2015 04:34:03 +0000 (21:34 -0700)
committerGirish Ramakrishnan <girish@cloudron.io>
Wed, 19 Aug 2015 06:49:12 +0000 (23:49 -0700)
The IsAdmin flag is set based on whether the admin filter
returned any result. The admin filter is applied with the user dn
as the search root.

In the future, we should update IsAdmin as well on each login.
Alternately, we can have a periodic sync operation.

conf/locale/locale_en-US.ini
models/login.go
modules/auth/auth_form.go
modules/auth/ldap/ldap.go
routers/admin/auths.go
templates/admin/auth/edit.tmpl
templates/admin/auth/new.tmpl

index 9fd7c4490d20bce64a09acf1cacc6c155d224a95..b2ccee5b5041cbe08d9bf5c58af503afeaddf595 100644 (file)
@@ -761,6 +761,7 @@ auths.attribute_name = First name attribute
 auths.attribute_surname = Surname attribute
 auths.attribute_mail = E-mail attribute
 auths.filter = User Filter
+auths.admin_filter = Admin Filter
 auths.ms_ad_sa = Ms Ad SA
 auths.smtp_auth = SMTP Authorization Type
 auths.smtphost = SMTP Host
index 8ac4b827efab112517643f52c76fa09103babb3e..78a607263f921b42f4492e99d63f08d800ac5325 100644 (file)
@@ -257,7 +257,7 @@ func UserSignIn(uname, passwd string) (*User, error) {
 // Return the same LoginUserPlain semantic
 // FIXME: https://github.com/gogits/gogs/issues/672
 func LoginUserLdapSource(u *User, name, passwd string, sourceId int64, cfg *LDAPConfig, autoRegister bool) (*User, error) {
-       fn, sn, mail, logged := cfg.Ldapsource.SearchEntry(name, passwd)
+       fn, sn, mail, admin, logged := cfg.Ldapsource.SearchEntry(name, passwd)
        if !logged {
                // User not in LDAP, do nothing
                return nil, ErrUserNotExist{0, name}
@@ -281,6 +281,7 @@ func LoginUserLdapSource(u *User, name, passwd string, sourceId int64, cfg *LDAP
                LoginName:   name,
                Passwd:      passwd,
                Email:       mail,
+               IsAdmin:     admin,
                IsActive:    true,
        }
        return u, CreateUser(u)
index 94753b3eddcbb2d0ce94d782abd1562794c5efe5..bfae4b13c4d27f146c9f86101252899920a2a0c6 100644 (file)
@@ -23,6 +23,7 @@ type AuthenticationForm struct {
        AttributeSurname  string
        AttributeMail     string
        Filter            string
+       AdminFilter       string
        IsActived         bool
        SMTPAuth          string `form:"smtp_auth"`
        SMTPHost          string `form:"smtp_host"`
index 82d66fec374594927cb5dcd84e89f719a80cbc49..7596762db5ffd4ddbe199e68027aa2c995246714 100644 (file)
@@ -26,6 +26,7 @@ type Ldapsource struct {
        AttributeSurname string // Surname attribute
        AttributeMail    string // E-mail attribute
        Filter           string // Query filter to validate entry
+       AdminFilter      string // Query filter to check if user is admin
        Enabled          bool   // if this source is disabled
 }
 
@@ -77,17 +78,17 @@ func (ls Ldapsource) FindUserDN(name string) (string, bool) {
 }
 
 // searchEntry : search an LDAP source if an entry (name, passwd) is valid and in the specific filter
-func (ls Ldapsource) SearchEntry(name, passwd string) (string, string, string, bool) {
+func (ls Ldapsource) SearchEntry(name, passwd string) (string, string, string, bool, bool) {
        userDN, found := ls.FindUserDN(name)
        if !found {
-               return "", "", "", false
+               return "", "", "", false, false
        }
 
        l, err := ldapDial(ls)
        if err != nil {
                log.Error(4, "LDAP Connect error, %s:%v", ls.Host, err)
                ls.Enabled = false
-               return "", "", "", false
+               return "", "", "", false, false
        }
 
        defer l.Close()
@@ -96,7 +97,7 @@ func (ls Ldapsource) SearchEntry(name, passwd string) (string, string, string, b
        err = l.Bind(userDN, passwd)
        if err != nil {
                log.Debug("LDAP auth. failed for %s, reason: %v", userDN, err)
-               return "", "", "", false
+               return "", "", "", false, false
        }
 
        log.Trace("Bound successfully with userDN: %s", userDN)
@@ -109,16 +110,32 @@ func (ls Ldapsource) SearchEntry(name, passwd string) (string, string, string, b
        sr, err := l.Search(search)
        if err != nil {
                log.Error(4, "LDAP Search failed unexpectedly! (%v)", err)
-               return "", "", "", false
+               return "", "", "", false, false
        } else if len(sr.Entries) < 1 {
                log.Error(4, "LDAP Search failed unexpectedly! (0 entries)")
-               return "", "", "", false
+               return "", "", "", false, false
        }
 
        name_attr := sr.Entries[0].GetAttributeValue(ls.AttributeName)
        sn_attr := sr.Entries[0].GetAttributeValue(ls.AttributeSurname)
        mail_attr := sr.Entries[0].GetAttributeValue(ls.AttributeMail)
-       return name_attr, sn_attr, mail_attr, true
+
+       search = ldap.NewSearchRequest(
+               userDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, ls.AdminFilter,
+               []string{ls.AttributeName},
+               nil)
+
+       sr, err = l.Search(search)
+       admin_attr := false
+       if err != nil {
+               log.Error(4, "LDAP Admin Search failed unexpectedly! (%v)", err)
+       } else if len(sr.Entries) < 1 {
+               log.Error(4, "LDAP Admin Search failed")
+       } else {
+               admin_attr = true
+       }
+
+       return name_attr, sn_attr, mail_attr, admin_attr, true
 }
 
 func ldapDial(ls Ldapsource) (*ldap.Conn, error) {
index bb73026b7df1c25d4510578847d543c63ebb114c..8123eaaabca05e5ceca1a8f09c3309a546e50ac9 100644 (file)
@@ -71,6 +71,7 @@ func NewAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) {
                                BindPassword:      form.BindPassword,
                                UserBase:          form.UserBase,
                                Filter:            form.Filter,
+                               AdminFilter:       form.AdminFilter,
                                AttributeName:     form.AttributeName,
                                AttributeSurname:  form.AttributeSurname,
                                AttributeMail:     form.AttributeMail,
@@ -160,6 +161,7 @@ func EditAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) {
                                AttributeSurname:  form.AttributeSurname,
                                AttributeMail:     form.AttributeMail,
                                Filter:            form.Filter,
+                               AdminFilter:       form.AdminFilter,
                                Enabled:           true,
                        },
                }
index 3fd772de6351bd3d0149331f326d5ab7adb02f60..e99b163e66b05b7adecf9195b33718d14d2b3eb4 100644 (file)
                                     <label class="req" for="filter">{{.i18n.Tr "admin.auths.filter"}}</label>
                                     <input class="ipt ipt-large ipt-radius {{if .Err_Filter}}ipt-error{{end}}" id="filter" name="filter" value="{{.Source.LDAP.Filter}}" />
                                 </div>
+                                <div class="field">
+                                    <label class="req" for="filter">{{.i18n.Tr "admin.auths.admin_filter"}}</label>
+                                    <input class="ipt ipt-large ipt-radius {{if .Err_AdminFilter}}ipt-error{{end}}" id="admin_filter" name="admin_filter" value="{{.Source.LDAP.AdminFilter}}" />
+                                </div>
                                 <div class="field">
                                     <label for="attribute_name">{{.i18n.Tr "admin.auths.attribute_name"}}</label>
                                     <input class="ipt ipt-large ipt-radius {{if .Err_Attributes}}ipt-error{{end}}" id="attribute_name" name="attribute_name" value="{{.Source.LDAP.AttributeName}}" />
index 80d7c266f205069aecb1249d37d2ce87e06eb92f..3f8f3d375b6c2c4bd86c0cc2f9968b461a5283bc 100644 (file)
                                         <label class="req" for="filter">{{.i18n.Tr "admin.auths.filter"}}</label>
                                         <input class="ipt ipt-large ipt-radius {{if .Err_Filter}}ipt-error{{end}}" id="filter" name="filter" value="{{.filter}}" />
                                     </div>
+                                    <div class="field">
+                                        <label class="req" for="filter">{{.i18n.Tr "admin.auths.admin_filter"}}</label>
+                                        <input class="ipt ipt-large ipt-radius {{if .Err_AdminFilter}}ipt-error{{end}}" id="admin_filter" name="admin_filter" value="{{.admin_filter}}" />
+                                    </div>
                                     <div class="field">
                                         <label for="attribute_name">{{.i18n.Tr "admin.auths.attribute_name"}}</label>
                                         <input class="ipt ipt-large ipt-radius {{if .Err_AttributeName}}ipt-error{{end}}" id="attribute_name" name="attribute_name" value="{{.attribute_name}}" />