]> source.dussan.org Git - gitea.git/commitdiff
ldap support
authorLunny Xiao <xiaolunwen@gmail.com>
Sat, 3 May 2014 02:48:14 +0000 (10:48 +0800)
committerLunny Xiao <xiaolunwen@gmail.com>
Sat, 3 May 2014 02:48:14 +0000 (10:48 +0800)
models/ldap.go
models/login.go
models/models.go
modules/auth/authentication.go [new file with mode: 0644]
modules/auth/ldap/ldap.go
routers/admin/admin.go
routers/admin/auths.go [new file with mode: 0644]
templates/admin/auths.tmpl [new file with mode: 0644]
templates/admin/auths/new.tmpl [new file with mode: 0644]
templates/admin/nav.tmpl
web.go

index cc9058765f8dbeead33b4d5eda598e6d387d6335..1da5b87540fe463c25d7685b6828a6b88f1ec8e7 100644 (file)
@@ -30,7 +30,7 @@ func LoginUserLdap(name, passwd string) (*User, error) {
                Email:     mail}
        _, err := RegisterUser(&user)
        if err != nil {
-               log.Debug("LDAP local user %s fond (%s) ", name, err)
+               log.Debug("LDAP local user %s found (%s) ", name, err)
        }
        // simulate local user login
        localUser, err2 := GetUserByName(user.Name)
index e8dbfc2725853c08e873674f3299f32d981f7c2d..6d9e54943f7c013a81f03b58597c83e36df6d091 100644 (file)
@@ -1,9 +1,12 @@
 package models
 
-import
+import (
+       "encoding/json"
+       "time"
 
-// Login types.
-"github.com/go-xorm/core"
+       "github.com/go-xorm/core"
+       "github.com/gogits/gogs/modules/auth/ldap"
+)
 
 /*const (
        LT_PLAIN = iota + 1
@@ -14,20 +17,54 @@ import
 var _ core.Conversion = &LDAPConfig{}
 
 type LDAPConfig struct {
+       ldap.Ldapsource
 }
 
 // implement
 func (cfg *LDAPConfig) FromDB(bs []byte) error {
-       return nil
+       return json.Unmarshal(bs, &cfg.Ldapsource)
 }
 
 func (cfg *LDAPConfig) ToDB() ([]byte, error) {
-       return nil, nil
+       return json.Marshal(cfg.Ldapsource)
 }
 
 type LoginSource struct {
-       Id   int64
-       Type int
-       Name string
-       Cfg  LDAPConfig
+       Id        int64
+       Type      int
+       Name      string
+       IsActived bool
+       Cfg       core.Conversion `xorm:"TEXT"`
+       Created   time.Time       `xorm:"created"`
+       Updated   time.Time       `xorm:"updated"`
+}
+
+func GetAuths() ([]*LoginSource, error) {
+       var auths = make([]*LoginSource, 0)
+       err := orm.Find(&auths)
+       return auths, err
+}
+
+func AddLDAPSource(name string, cfg *LDAPConfig) error {
+       _, err := orm.Insert(&LoginSource{Type: LT_LDAP,
+               Name:      name,
+               IsActived: true,
+               Cfg:       cfg,
+       })
+       return err
+}
+
+func UpdateLDAPSource(id int64, name string, cfg *LDAPConfig) error {
+       _, err := orm.AllCols().Id(id).Update(&LoginSource{
+               Id:   id,
+               Type: LT_LDAP,
+               Name: name,
+               Cfg:  cfg,
+       })
+       return err
+}
+
+func DelLoginSource(id int64) error {
+       _, err := orm.Id(id).Delete(&LoginSource{})
+       return err
 }
index 8e8835ab516e13957546e95e5cc19ce05c1fbd08..3bce76496355d9d312c0cba1d1f3a913b8c7c0a0 100644 (file)
@@ -34,7 +34,7 @@ var (
 func init() {
        tables = append(tables, new(User), new(PublicKey), new(Repository), new(Watch),
                new(Action), new(Access), new(Issue), new(Comment), new(Oauth2), new(Follow),
-               new(Mirror), new(Release))
+               new(Mirror), new(Release), new(LoginSource))
 }
 
 func LoadModelsConfig() {
diff --git a/modules/auth/authentication.go b/modules/auth/authentication.go
new file mode 100644 (file)
index 0000000..5c179f0
--- /dev/null
@@ -0,0 +1,13 @@
+package auth
+
+type AuthenticationForm struct {
+       Type       int    `form:"type"`
+       Name       string `form:"name" binding:"MaxSize(50)"`
+       Domain     string `form:"domain"`
+       Host       string `form:"host"`
+       Port       int    `form:"port"`
+       BaseDN     string `form:"base_dn"`
+       Attributes string `form:"attributes"`
+       Filter     string `form:"filter"`
+       MsAdSA     string `form:"ms_ad_sa"`
+}
index 29773cda5c3c0414c1c4c699df7f5f339a080aa1..8578e38a4d7a61568aaf46cd3ce7c5be30696ca3 100644 (file)
@@ -8,12 +8,13 @@ package ldap
 
 import (
        "fmt"
+
        "github.com/gogits/gogs/modules/log"
        goldap "github.com/juju2013/goldap"
 )
 
 // Basic LDAP authentication service
-type ldapsource struct {
+type Ldapsource struct {
        Name         string // canonical name (ie. corporate.ad)
        Host         string // LDAP host
        Port         int    // port number
@@ -26,12 +27,12 @@ type ldapsource struct {
 
 //Global LDAP directory pool
 var (
-       Authensource []ldapsource
+       Authensource []Ldapsource
 )
 
 // Add a new source (LDAP directory) to the global pool
 func AddSource(name string, host string, port int, basedn string, attributes string, filter string, msadsaformat string) {
-       ldaphost := ldapsource{name, host, port, basedn, attributes, filter, msadsaformat, true}
+       ldaphost := Ldapsource{name, host, port, basedn, attributes, filter, msadsaformat, true}
        Authensource = append(Authensource, ldaphost)
 }
 
@@ -50,7 +51,7 @@ func LoginUser(name, passwd string) (a string, r bool) {
 }
 
 // searchEntry : search an LDAP source if an entry (name, passwd) is valide and in the specific filter
-func (ls ldapsource) searchEntry(name, passwd string) (string, bool) {
+func (ls Ldapsource) searchEntry(name, passwd string) (string, bool) {
        l, err := goldap.Dial("tcp", fmt.Sprintf("%s:%d", ls.Host, ls.Port))
        if err != nil {
                log.Debug("LDAP Connect error, disabled source %s", ls.Host)
index d0f737e645e466b70bad0491cb8f7a4c9b8b520f..bd7cc98f64ff7113959be2a3cc151730def0b960 100644 (file)
@@ -120,6 +120,19 @@ func Users(ctx *middleware.Context) {
        ctx.HTML(200, "admin/users")
 }
 
+func Auths(ctx *middleware.Context) {
+       ctx.Data["Title"] = "Auth Sources"
+       ctx.Data["PageIsAuths"] = true
+
+       var err error
+       ctx.Data["Sources"], err = models.GetAuths()
+       if err != nil {
+               ctx.Handle(200, "admin.Auths", err)
+               return
+       }
+       ctx.HTML(200, "admin/auths")
+}
+
 func Repositories(ctx *middleware.Context) {
        ctx.Data["Title"] = "Repository Management"
        ctx.Data["PageIsRepos"] = true
diff --git a/routers/admin/auths.go b/routers/admin/auths.go
new file mode 100644 (file)
index 0000000..69d38db
--- /dev/null
@@ -0,0 +1,62 @@
+package admin
+
+import (
+       "strings"
+
+       "github.com/gogits/gogs/models"
+       "github.com/gogits/gogs/modules/auth"
+       "github.com/gogits/gogs/modules/auth/ldap"
+       "github.com/gogits/gogs/modules/middleware"
+       "github.com/gpmgo/gopm/log"
+)
+
+func NewAuthSource(ctx *middleware.Context) {
+       ctx.Data["Title"] = "New Authentication"
+       ctx.Data["PageIsAuths"] = true
+       ctx.HTML(200, "admin/auths/new")
+}
+
+func NewAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) {
+       ctx.Data["Title"] = "New Authentication"
+       ctx.Data["PageIsAuths"] = true
+
+       if ctx.HasError() {
+               ctx.HTML(200, "admin/auths/new")
+               return
+       }
+
+       u := &models.LDAPConfig{
+               Ldapsource: ldap.Ldapsource{
+                       Host:         form.Host,
+                       Port:         form.Port,
+                       BaseDN:       form.BaseDN,
+                       Attributes:   form.Attributes,
+                       Filter:       form.Filter,
+                       MsAdSAFormat: form.MsAdSA,
+                       Enabled:      true,
+                       Name:         form.Name,
+               },
+       }
+
+       if err := models.AddLDAPSource(form.Name, u); err != nil {
+               switch err {
+               default:
+                       ctx.Handle(500, "admin.auths.NewAuth", err)
+               }
+               return
+       }
+
+       log.Trace("%s Authentication created by admin(%s): %s", ctx.Req.RequestURI,
+               ctx.User.LowerName, strings.ToLower(form.Name))
+
+       ctx.Redirect("/admin/auths")
+}
+
+func EditAuthSource(ctx *middleware.Context) {
+}
+
+func EditAuthSourcePost(ctx *middleware.Context) {
+}
+
+func DeleteAuthSource(ctx *middleware.Context) {
+}
diff --git a/templates/admin/auths.tmpl b/templates/admin/auths.tmpl
new file mode 100644 (file)
index 0000000..813e24a
--- /dev/null
@@ -0,0 +1,43 @@
+{{template "base/head" .}}
+{{template "base/navbar" .}}
+<div id="body" class="container" data-page="admin">
+    {{template "admin/nav" .}}
+    <div id="admin-container" class="col-md-10">
+        <div class="panel panel-default">
+            <div class="panel-heading">
+                Authentication Management
+            </div>
+
+            <div class="panel-body">
+                <a href="/admin/auths/new" class="btn btn-primary">New Auth Source</a>
+                <table class="table table-striped">
+                    <thead>
+                        <tr>
+                            <th>Id</th>
+                            <th>Name</th>
+                            <th>Type</th>
+                            <th>Actived</th>
+                            <th>Updated</th>
+                            <th>Created</th>
+                            <th>Operation</th>
+                        </tr>
+                    </thead>
+                    <tbody>
+                        {{range .Sources}}
+                        <tr>
+                            <td>{{.Id}}</td>
+                            <td><a href="/admin/auths/{{.Id}}">{{.Name}}</a></td>
+                            <td>{{.Type}}</td>
+                            <td>{{.Actived}}</td>
+                            <td>{{DateFormat .Updated "M d, Y"}}</td>
+                            <td>{{DateFormat .Created "M d, Y"}}</td>
+                            <td><a href="/admin/users/{{.Id}}"><i class="fa fa-pencil-square-o"></i></a></td>
+                        </tr>
+                        {{end}}
+                    </tbody>
+                </table>
+            </div>
+        </div>
+    </div>
+</div>
+{{template "base/footer" .}}
\ No newline at end of file
diff --git a/templates/admin/auths/new.tmpl b/templates/admin/auths/new.tmpl
new file mode 100644 (file)
index 0000000..346555e
--- /dev/null
@@ -0,0 +1,93 @@
+{{template "base/head" .}}
+{{template "base/navbar" .}}
+<div id="body" class="container" data-page="admin">
+    {{template "admin/nav" .}}
+    <div id="admin-container" class="col-md-9">
+        <div class="panel panel-default">
+            <div class="panel-heading">
+                New Authentication
+            </div>
+
+            <div class="panel-body">
+               <br/>
+                               <form action="/admin/auths/new" method="post" class="form-horizontal">
+                                       {{.CsrfTokenHtml}}
+                                   {{template "base/alert" .}}
+                                   <div class="form-group">
+                                   <label class="col-md-3 control-label">Auth Type: </label>
+                                   <div class="col-md-7">
+                                   <select class="form-control">
+  <option value=2>LDAP</option>
+  <option value=3>SMTP</option>
+</select>
+       </div>
+       </div>
+                                       <div class="form-group {{if .Err_UserName}}has-error has-feedback{{end}}">
+                                               <label class="col-md-3 control-label">Name: </label>
+                                               <div class="col-md-7">
+                                                       <input name="name" class="form-control" placeholder="Type account's username" value="{{.username}}" required="required">
+                                               </div>
+                                       </div>
+
+                                       <div class="form-group {{if .Err_Email}}has-error has-feedback{{end}}">
+                                               <label class="col-md-3 control-label">Domain: </label>
+                                               <div class="col-md-7">
+                                                       <input name="domain" class="form-control" placeholder="Type account's e-mail address" value="{{.email}}" required="required" title="Email is not valid">
+                                               </div>
+                                       </div>
+
+                                       <div class="form-group {{if .Err_Email}}has-error has-feedback{{end}}">
+                                               <label class="col-md-3 control-label">Host: </label>
+                                               <div class="col-md-7">
+                                                       <input name="domain" class="form-control" placeholder="Type account's e-mail address" value="{{.email}}" required="required" title="Email is not valid">
+                                               </div>
+                                       </div>
+
+                                       <div class="form-group {{if .Err_Email}}has-error has-feedback{{end}}">
+                                               <label class="col-md-3 control-label">Port: </label>
+                                               <div class="col-md-7">
+                                                       <input name="domain" class="form-control" placeholder="Type account's e-mail address" value="{{.email}}" required="required" title="Email is not valid">
+                                               </div>
+                                       </div>
+
+                                       <div class="form-group {{if .Err_Email}}has-error has-feedback{{end}}">
+                                               <label class="col-md-3 control-label">Base DN: </label>
+                                               <div class="col-md-7">
+                                                       <input name="domain" class="form-control" placeholder="Type account's e-mail address" value="{{.email}}" required="required" title="Email is not valid">
+                                               </div>
+                                       </div>
+
+<div class="form-group {{if .Err_Email}}has-error has-feedback{{end}}">
+                                               <label class="col-md-3 control-label">Search Attributes: </label>
+                                               <div class="col-md-7">
+                                                       <input name="domain" class="form-control" placeholder="Type account's e-mail address" value="{{.email}}" required="required" title="Email is not valid">
+                                               </div>
+                                       </div>
+
+                                       <div class="form-group {{if .Err_Email}}has-error has-feedback{{end}}">
+                                               <label class="col-md-3 control-label">Search Filter: </label>
+                                               <div class="col-md-7">
+                                                       <input name="domain" class="form-control" placeholder="Type account's e-mail address" value="{{.email}}" required="required" title="Email is not valid">
+                                               </div>
+                                       </div>
+
+                                       <div class="form-group {{if .Err_Email}}has-error has-feedback{{end}}">
+                                               <label class="col-md-3 control-label">Ms Ad SA: </label>
+                                               <div class="col-md-7">
+                                                       <input name="domain" class="form-control" placeholder="Type account's e-mail address" value="{{.email}}" required="required" title="Email is not valid">
+                                               </div>
+                                       </div>
+                                       
+                                       <hr/>
+                                       <div class="form-group">
+                                           <div class="col-md-offset-3 col-md-7">
+                                               <button type="submit" class="btn btn-lg btn-primary">Create new authentication</button>
+                                           </div>
+                                       </div>
+                               </form>
+            </div>
+        </div>
+
+       </div>
+</div>
+{{template "base/footer" .}}
\ No newline at end of file
index 33ecfae5e37c9b92898cad1f558756134a5cd52b..b9542228bc60fcad1176c375b4c989678f1060b6 100644 (file)
@@ -4,5 +4,6 @@
         <li class="list-group-item{{if .PageIsUsers}} active{{end}}"><a href="/admin/users"><i class="fa fa-users fa-lg"></i> Users</a></li>
         <li class="list-group-item{{if .PageIsRepos}} active{{end}}"><a href="/admin/repos"><i class="fa fa-book fa-lg"></i> Repositories</a></li>
         <li class="list-group-item{{if .PageIsConfig}} active{{end}}"><a href="/admin/config"><i class="fa fa-cogs fa-lg"></i> Configuration</a></li>
+        <li class="list-group-item{{if .PageIsAuths}} active{{end}}"><a href="/admin/auths"><i class="fa fa-cogs fa-lg"></i> Authentication</a></li>
     </ul>
 </div>
\ No newline at end of file
diff --git a/web.go b/web.go
index 23fa10796c21030edc84919f0234b33526ae27c8..32b45c00a203d2df758e9f8a9c4d954311589bce 100644 (file)
--- a/web.go
+++ b/web.go
@@ -130,6 +130,7 @@ func runWeb(*cli.Context) {
                r.Get("/users", admin.Users)
                r.Get("/repos", admin.Repositories)
                r.Get("/config", admin.Config)
+               r.Get("/auths", admin.Auths)
        }, adminReq)
        m.Group("/admin/users", func(r martini.Router) {
                r.Get("/new", admin.NewUser)
@@ -139,6 +140,14 @@ func runWeb(*cli.Context) {
                r.Get("/:userid/delete", admin.DeleteUser)
        }, adminReq)
 
+       m.Group("/admin/auths", func(r martini.Router) {
+               r.Get("/new", admin.NewAuthSource)
+               r.Post("/new", bindIgnErr(auth.AuthenticationForm{}), admin.NewAuthSourcePost)
+               r.Get("/:authid", admin.EditAuthSource)
+               r.Post("/:authid" /*, bindIgnErr(auth.AdminEditUserForm{})*/, admin.EditAuthSourcePost)
+               r.Get("/:authid/delete", admin.DeleteAuthSource)
+       }, adminReq)
+
        if martini.Env == martini.Dev {
                m.Get("/template/**", dev.TemplatePreview)
        }