diff options
author | Lunny Xiao <xiaolunwen@gmail.com> | 2014-05-03 10:48:14 +0800 |
---|---|---|
committer | Lunny Xiao <xiaolunwen@gmail.com> | 2014-05-03 10:48:14 +0800 |
commit | 79ea34e70ebe989f1a5f8fbd71cfe3109c6f8a58 (patch) | |
tree | 066027c6a42b971030e0d8b41ff979bfaa1e25ae | |
parent | 8bab21d795a6af7c424e9f8f72d613863cf34a70 (diff) | |
download | gitea-79ea34e70ebe989f1a5f8fbd71cfe3109c6f8a58.tar.gz gitea-79ea34e70ebe989f1a5f8fbd71cfe3109c6f8a58.zip |
ldap support
-rw-r--r-- | models/ldap.go | 2 | ||||
-rw-r--r-- | models/login.go | 55 | ||||
-rw-r--r-- | models/models.go | 2 | ||||
-rw-r--r-- | modules/auth/authentication.go | 13 | ||||
-rw-r--r-- | modules/auth/ldap/ldap.go | 9 | ||||
-rw-r--r-- | routers/admin/admin.go | 13 | ||||
-rw-r--r-- | routers/admin/auths.go | 62 | ||||
-rw-r--r-- | templates/admin/auths.tmpl | 43 | ||||
-rw-r--r-- | templates/admin/auths/new.tmpl | 93 | ||||
-rw-r--r-- | templates/admin/nav.tmpl | 1 | ||||
-rw-r--r-- | web.go | 9 |
11 files changed, 287 insertions, 15 deletions
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" .}} +<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 index 0000000000..346555ea9c --- /dev/null +++ b/templates/admin/auths/new.tmpl @@ -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 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 @@ <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 @@ -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) } |