From 1652dd5068f2f3ae1851bc2321832c88af85d570 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 5 May 2014 16:40:25 +0800 Subject: [PATCH] basic authentications --- models/login.go | 73 ++++++++++++++++++---- models/user.go | 7 +-- modules/auth/admin.go | 13 ++-- modules/auth/auth.go | 1 + modules/auth/authentication.go | 2 + routers/admin/auths.go | 91 ++++++++++++++++++++++++++- routers/admin/user.go | 33 ++++++++-- templates/admin/auths.tmpl | 6 +- templates/admin/auths/edit.tmpl | 107 ++++++++++++++++++++++++++++++++ templates/admin/auths/new.tmpl | 23 +++---- templates/admin/users/edit.tmpl | 12 ++++ templates/admin/users/new.tmpl | 11 ++++ web.go | 4 +- 13 files changed, 334 insertions(+), 49 deletions(-) create mode 100644 templates/admin/auths/edit.tmpl diff --git a/models/login.go b/models/login.go index 6d9e54943f..d5905eb36b 100644 --- a/models/login.go +++ b/models/login.go @@ -2,17 +2,31 @@ package models import ( "encoding/json" + "errors" "time" "github.com/go-xorm/core" + "github.com/go-xorm/xorm" "github.com/gogits/gogs/modules/auth/ldap" ) -/*const ( +// Login types. +const ( LT_PLAIN = iota + 1 LT_LDAP LT_SMTP -)*/ +) + +var ( + ErrAuthenticationAlreadyExist = errors.New("Authentication already exist") + ErrAuthenticationNotExist = errors.New("Authentication is not exist") + ErrAuthenticationUserUsed = errors.New("Authentication has been used by some users") +) + +var LoginTypes = map[int]string{ + LT_LDAP: "LDAP", + LT_SMTP: "SMTP", +} var _ core.Conversion = &LDAPConfig{} @@ -32,19 +46,50 @@ func (cfg *LDAPConfig) ToDB() ([]byte, error) { type LoginSource struct { Id int64 Type int - Name string - IsActived bool + Name string `xorm:"unique"` + IsActived bool `xorm:"not null default false"` Cfg core.Conversion `xorm:"TEXT"` Created time.Time `xorm:"created"` Updated time.Time `xorm:"updated"` } +func (source *LoginSource) TypeString() string { + return LoginTypes[source.Type] +} + +func (source *LoginSource) LDAP() *LDAPConfig { + return source.Cfg.(*LDAPConfig) +} + +// for xorm callback +func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) { + if colName == "type" { + ty := (*val).(int64) + switch ty { + case LT_LDAP: + source.Cfg = new(LDAPConfig) + } + } +} + func GetAuths() ([]*LoginSource, error) { var auths = make([]*LoginSource, 0) err := orm.Find(&auths) return auths, err } +func GetLoginSourceById(id int64) (*LoginSource, error) { + source := new(LoginSource) + has, err := orm.Id(id).Get(source) + if err != nil { + return nil, err + } + if !has { + return nil, ErrAuthenticationNotExist + } + return source, nil +} + func AddLDAPSource(name string, cfg *LDAPConfig) error { _, err := orm.Insert(&LoginSource{Type: LT_LDAP, Name: name, @@ -54,17 +99,19 @@ func AddLDAPSource(name string, cfg *LDAPConfig) error { 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, - }) +func UpdateLDAPSource(source *LoginSource) error { + _, err := orm.AllCols().Id(source.Id).Update(source) return err } -func DelLoginSource(id int64) error { - _, err := orm.Id(id).Delete(&LoginSource{}) +func DelLoginSource(source *LoginSource) error { + cnt, err := orm.Count(&User{LoginSource: source.Id}) + if err != nil { + return err + } + if cnt > 0 { + return ErrAuthenticationUserUsed + } + _, err = orm.Id(source.Id).Delete(&LoginSource{}) return err } diff --git a/models/user.go b/models/user.go index df1eb985c2..3372d75497 100644 --- a/models/user.go +++ b/models/user.go @@ -26,12 +26,6 @@ const ( UT_ORGANIZATION ) -// Login types. -const ( - LT_PLAIN = iota + 1 - LT_LDAP -) - var ( ErrUserOwnRepos = errors.New("User still have ownership of repositories") ErrUserAlreadyExist = errors.New("User already exist") @@ -49,6 +43,7 @@ type User struct { Email string `xorm:"unique not null"` Passwd string `xorm:"not null"` LoginType int + LoginSource int64 `xorm:"not null default 0"` Type int NumFollowers int NumFollowings int diff --git a/modules/auth/admin.go b/modules/auth/admin.go index 877af19af3..e2dc0fd218 100644 --- a/modules/auth/admin.go +++ b/modules/auth/admin.go @@ -15,12 +15,13 @@ import ( ) type AdminEditUserForm struct { - Email string `form:"email" binding:"Required;Email;MaxSize(50)"` - Website string `form:"website" binding:"MaxSize(50)"` - Location string `form:"location" binding:"MaxSize(50)"` - Avatar string `form:"avatar" binding:"Required;Email;MaxSize(50)"` - Active string `form:"active"` - Admin string `form:"admin"` + Email string `form:"email" binding:"Required;Email;MaxSize(50)"` + Website string `form:"website" binding:"MaxSize(50)"` + Location string `form:"location" binding:"MaxSize(50)"` + Avatar string `form:"avatar" binding:"Required;Email;MaxSize(50)"` + Active string `form:"active"` + Admin string `form:"admin"` + LoginType int `form:"login_type"` } func (f *AdminEditUserForm) Name(field string) string { diff --git a/modules/auth/auth.go b/modules/auth/auth.go index 350ef4fcbf..49ace507b7 100644 --- a/modules/auth/auth.go +++ b/modules/auth/auth.go @@ -25,6 +25,7 @@ type RegisterForm struct { Email string `form:"email" binding:"Required;Email;MaxSize(50)"` Password string `form:"passwd" binding:"Required;MinSize(6);MaxSize(30)"` RetypePasswd string `form:"retypepasswd"` + LoginType string `form:"logintype"` } func (f *RegisterForm) Name(field string) string { diff --git a/modules/auth/authentication.go b/modules/auth/authentication.go index 5c179f0fc0..d9c61b9d79 100644 --- a/modules/auth/authentication.go +++ b/modules/auth/authentication.go @@ -1,6 +1,7 @@ package auth type AuthenticationForm struct { + Id int64 `form:"id"` Type int `form:"type"` Name string `form:"name" binding:"MaxSize(50)"` Domain string `form:"domain"` @@ -10,4 +11,5 @@ type AuthenticationForm struct { Attributes string `form:"attributes"` Filter string `form:"filter"` MsAdSA string `form:"ms_ad_sa"` + IsActived bool `form:"is_actived"` } diff --git a/routers/admin/auths.go b/routers/admin/auths.go index 69d38db5d4..892413049e 100644 --- a/routers/admin/auths.go +++ b/routers/admin/auths.go @@ -3,9 +3,11 @@ package admin import ( "strings" + "github.com/go-martini/martini" "github.com/gogits/gogs/models" "github.com/gogits/gogs/modules/auth" "github.com/gogits/gogs/modules/auth/ldap" + "github.com/gogits/gogs/modules/base" "github.com/gogits/gogs/modules/middleware" "github.com/gpmgo/gopm/log" ) @@ -13,6 +15,7 @@ import ( func NewAuthSource(ctx *middleware.Context) { ctx.Data["Title"] = "New Authentication" ctx.Data["PageIsAuths"] = true + ctx.Data["LoginTypes"] = models.LoginTypes ctx.HTML(200, "admin/auths/new") } @@ -52,11 +55,93 @@ func NewAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) { ctx.Redirect("/admin/auths") } -func EditAuthSource(ctx *middleware.Context) { +func EditAuthSource(ctx *middleware.Context, params martini.Params) { + ctx.Data["Title"] = "Edit Authentication" + ctx.Data["PageIsAuths"] = true + id, err := base.StrTo(params["authid"]).Int64() + if err != nil { + ctx.Handle(404, "admin.auths.EditAuthSource", err) + return + } + u, err := models.GetLoginSourceById(id) + if err != nil { + ctx.Handle(500, "admin.user.EditUser", err) + return + } + ctx.Data["Source"] = u + ctx.Data["LoginTypes"] = models.LoginTypes + ctx.HTML(200, "admin/auths/edit") } -func EditAuthSourcePost(ctx *middleware.Context) { +func EditAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) { + ctx.Data["Title"] = "Edit Authentication" + ctx.Data["PageIsAuths"] = true + + if ctx.HasError() { + ctx.HTML(200, "admin/auths/edit") + return + } + + u := models.LoginSource{ + Name: form.Name, + IsActived: form.IsActived, + Type: models.LT_LDAP, + Cfg: &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.UpdateLDAPSource(&u); err != nil { + switch err { + default: + ctx.Handle(500, "admin.auths.EditAuth", err) + } + return + } + + log.Trace("%s Authentication changed by admin(%s): %s", ctx.Req.RequestURI, + ctx.User.LowerName, strings.ToLower(form.Name)) + + ctx.Redirect("/admin/auths") } -func DeleteAuthSource(ctx *middleware.Context) { +func DeleteAuthSource(ctx *middleware.Context, params martini.Params) { + ctx.Data["Title"] = "Delete Authentication" + ctx.Data["PageIsAuths"] = true + + id, err := base.StrTo(params["authid"]).Int64() + if err != nil { + ctx.Handle(404, "admin.auths.DeleteAuth", err) + return + } + + a, err := models.GetLoginSourceById(id) + if err != nil { + ctx.Handle(500, "admin.auths.DeleteAuth", err) + return + } + + if err = models.DelLoginSource(a); err != nil { + switch err { + case models.ErrAuthenticationUserUsed: + ctx.Flash.Error("This authentication still has used by some users, you should move them and then delete again.") + ctx.Redirect("/admin/auths/" + params["authid"]) + default: + ctx.Handle(500, "admin.auths.DeleteAuth", err) + } + return + } + log.Trace("%s Authentication deleted by admin(%s): %s", ctx.Req.RequestURI, + ctx.User.LowerName, ctx.User.LowerName) + + ctx.Redirect("/admin/auths") } diff --git a/routers/admin/user.go b/routers/admin/user.go index fee692202e..14c17e9756 100644 --- a/routers/admin/user.go +++ b/routers/admin/user.go @@ -5,6 +5,8 @@ package admin import ( + "fmt" + "strconv" "strings" "github.com/go-martini/martini" @@ -19,6 +21,12 @@ import ( func NewUser(ctx *middleware.Context) { ctx.Data["Title"] = "New Account" ctx.Data["PageIsUsers"] = true + auths, err := models.GetAuths() + if err != nil { + ctx.Handle(500, "admin.user.NewUser", err) + return + } + ctx.Data["LoginSources"] = auths ctx.HTML(200, "admin/users/new") } @@ -40,10 +48,18 @@ func NewUserPost(ctx *middleware.Context, form auth.RegisterForm) { } u := &models.User{ - Name: form.UserName, - Email: form.Email, - Passwd: form.Password, - IsActive: true, + Name: form.UserName, + Email: form.Email, + Passwd: form.Password, + IsActive: true, + LoginType: models.LT_PLAIN, + } + + if len(form.LoginType) > 0 { + fields := strings.Split(form.LoginType, "-") + u.LoginType, _ = strconv.Atoi(fields[0]) + u.LoginSource, _ = strconv.ParseInt(fields[1], 10, 64) + fmt.Println(u.LoginSource) } var err error @@ -84,6 +100,12 @@ func EditUser(ctx *middleware.Context, params martini.Params) { } ctx.Data["User"] = u + auths, err := models.GetAuths() + if err != nil { + ctx.Handle(500, "admin.user.NewUser", err) + return + } + ctx.Data["LoginSources"] = auths ctx.HTML(200, "admin/users/edit") } @@ -110,6 +132,7 @@ func EditUserPost(ctx *middleware.Context, params martini.Params, form auth.Admi u.AvatarEmail = form.Avatar u.IsActive = form.Active == "on" u.IsAdmin = form.Admin == "on" + u.LoginType = form.LoginType if err := models.UpdateUser(u); err != nil { ctx.Handle(500, "admin.user.EditUser", err) return @@ -126,7 +149,7 @@ func DeleteUser(ctx *middleware.Context, params martini.Params) { ctx.Data["Title"] = "Delete Account" ctx.Data["PageIsUsers"] = true - log.Info("delete") + //log.Info("delete") uid, err := base.StrTo(params["userid"]).Int() if err != nil { ctx.Handle(404, "admin.user.EditUser", err) diff --git a/templates/admin/auths.tmpl b/templates/admin/auths.tmpl index 813e24ad0c..87baeafd62 100644 --- a/templates/admin/auths.tmpl +++ b/templates/admin/auths.tmpl @@ -27,11 +27,11 @@ {{.Id}} {{.Name}} - {{.Type}} - {{.Actived}} + {{.TypeString}} + {{DateFormat .Updated "M d, Y"}} {{DateFormat .Created "M d, Y"}} - + {{end}} diff --git a/templates/admin/auths/edit.tmpl b/templates/admin/auths/edit.tmpl new file mode 100644 index 0000000000..1a2548fbeb --- /dev/null +++ b/templates/admin/auths/edit.tmpl @@ -0,0 +1,107 @@ +{{template "base/head" .}} +{{template "base/navbar" .}} +
+ {{template "admin/nav" .}} +
+
+
+ Edit Authentication +
+ +
+
+
+ {{.CsrfTokenHtml}} + {{template "base/alert" .}} + +
+ +
+ +
+
+
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+
+
+ +
+
+
+
+
+
+ + Delete this authentication +
+
+
+
+
+ +
+
+{{template "base/footer" .}} \ No newline at end of file diff --git a/templates/admin/auths/new.tmpl b/templates/admin/auths/new.tmpl index 346555ea9c..a5da93bd2a 100644 --- a/templates/admin/auths/new.tmpl +++ b/templates/admin/auths/new.tmpl @@ -17,64 +17,65 @@
+ {{range $key, $val := .LoginTypes}} + + {{end}} +
- +
- +
- +
- +
- +
- +
- +
- +
diff --git a/templates/admin/users/edit.tmpl b/templates/admin/users/edit.tmpl index da9a67cfae..9c9c36a28c 100644 --- a/templates/admin/users/edit.tmpl +++ b/templates/admin/users/edit.tmpl @@ -14,6 +14,18 @@ {{.CsrfTokenHtml}} {{template "base/alert" .}} +
+ +
+ +
+
diff --git a/templates/admin/users/new.tmpl b/templates/admin/users/new.tmpl index 4c851e3144..c19cd53c0a 100644 --- a/templates/admin/users/new.tmpl +++ b/templates/admin/users/new.tmpl @@ -13,6 +13,17 @@
{{.CsrfTokenHtml}} {{template "base/alert" .}} +
+ +
+ +
+
diff --git a/web.go b/web.go index 32b45c00a2..4222be9b13 100644 --- a/web.go +++ b/web.go @@ -144,7 +144,7 @@ func runWeb(*cli.Context) { 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.Post("/:authid", bindIgnErr(auth.AuthenticationForm{}), admin.EditAuthSourcePost) r.Get("/:authid/delete", admin.DeleteAuthSource) }, adminReq) @@ -196,7 +196,7 @@ func runWeb(*cli.Context) { protocol := base.Cfg.MustValue("server", "PROTOCOL", "http") listenAddr := fmt.Sprintf("%s:%s", - base.Cfg.MustValue("server", "HTTP_ADDR"), + base.Cfg.MustValue("server", "HTTP_ADDR", "0.0.0.0"), base.Cfg.MustValue("server", "HTTP_PORT", "3000")) if protocol == "http" {