From 79ea34e70ebe989f1a5f8fbd71cfe3109c6f8a58 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sat, 3 May 2014 10:48:14 +0800 Subject: [PATCH] ldap support --- models/ldap.go | 2 +- models/login.go | 55 ++++++++++++++++---- models/models.go | 2 +- modules/auth/authentication.go | 13 +++++ modules/auth/ldap/ldap.go | 9 ++-- routers/admin/admin.go | 13 +++++ routers/admin/auths.go | 62 +++++++++++++++++++++++ templates/admin/auths.tmpl | 43 ++++++++++++++++ templates/admin/auths/new.tmpl | 93 ++++++++++++++++++++++++++++++++++ templates/admin/nav.tmpl | 1 + web.go | 9 ++++ 11 files changed, 287 insertions(+), 15 deletions(-) create mode 100644 modules/auth/authentication.go create mode 100644 routers/admin/auths.go create mode 100644 templates/admin/auths.tmpl create mode 100644 templates/admin/auths/new.tmpl diff --git a/models/ldap.go b/models/ldap.go index cc9058765f..1da5b87540 100644 --- a/models/ldap.go +++ b/models/ldap.go @@ -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) diff --git a/models/login.go b/models/login.go index e8dbfc2725..6d9e54943f 100644 --- a/models/login.go +++ b/models/login.go @@ -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 } diff --git a/models/models.go b/models/models.go index 8e8835ab51..3bce764963 100644 --- a/models/models.go +++ b/models/models.go @@ -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 index 0000000000..5c179f0fc0 --- /dev/null +++ b/modules/auth/authentication.go @@ -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"` +} diff --git a/modules/auth/ldap/ldap.go b/modules/auth/ldap/ldap.go index 29773cda5c..8578e38a4d 100644 --- a/modules/auth/ldap/ldap.go +++ b/modules/auth/ldap/ldap.go @@ -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) diff --git a/routers/admin/admin.go b/routers/admin/admin.go index d0f737e645..bd7cc98f64 100644 --- a/routers/admin/admin.go +++ b/routers/admin/admin.go @@ -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 index 0000000000..69d38db5d4 --- /dev/null +++ b/routers/admin/auths.go @@ -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 index 0000000000..813e24ad0c --- /dev/null +++ b/templates/admin/auths.tmpl @@ -0,0 +1,43 @@ +{{template "base/head" .}} +{{template "base/navbar" .}} +
+ {{template "admin/nav" .}} +
+
+
+ Authentication Management +
+ +
+ New Auth Source + + + + + + + + + + + + + + {{range .Sources}} + + + + + + + + + + {{end}} + +
IdNameTypeActivedUpdatedCreatedOperation
{{.Id}}{{.Name}}{{.Type}}{{.Actived}}{{DateFormat .Updated "M d, Y"}}{{DateFormat .Created "M d, Y"}}
+
+
+
+
+{{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 index 0000000000..346555ea9c --- /dev/null +++ b/templates/admin/auths/new.tmpl @@ -0,0 +1,93 @@ +{{template "base/head" .}} +{{template "base/navbar" .}} +
+ {{template "admin/nav" .}} +
+
+
+ New Authentication +
+ +
+
+
+ {{.CsrfTokenHtml}} + {{template "base/alert" .}} +
+ +
+ +
+
+
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+
+
+ +
+
+
+
+
+ +
+
+{{template "base/footer" .}} \ No newline at end of file diff --git a/templates/admin/nav.tmpl b/templates/admin/nav.tmpl index 33ecfae5e3..b9542228bc 100644 --- a/templates/admin/nav.tmpl +++ b/templates/admin/nav.tmpl @@ -4,5 +4,6 @@
  • Users
  • Repositories
  • Configuration
  • +
  • Authentication
  • \ No newline at end of file diff --git a/web.go b/web.go index 23fa10796c..32b45c00a2 100644 --- 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) }