@@ -134,6 +134,7 @@ func runWeb(*cli.Context) { | |||||
r.Get("/users", admin.Users) | r.Get("/users", admin.Users) | ||||
r.Get("/repos", admin.Repositories) | r.Get("/repos", admin.Repositories) | ||||
r.Get("/config", admin.Config) | r.Get("/config", admin.Config) | ||||
r.Get("/auths", admin.Auths) | |||||
}, adminReq) | }, adminReq) | ||||
m.Group("/admin/users", func(r martini.Router) { | m.Group("/admin/users", func(r martini.Router) { | ||||
r.Get("/new", admin.NewUser) | r.Get("/new", admin.NewUser) | ||||
@@ -143,6 +144,14 @@ func runWeb(*cli.Context) { | |||||
r.Get("/:userid/delete", admin.DeleteUser) | r.Get("/:userid/delete", admin.DeleteUser) | ||||
}, adminReq) | }, 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.AuthenticationForm{}), admin.EditAuthSourcePost) | |||||
r.Get("/:authid/delete", admin.DeleteAuthSource) | |||||
}, adminReq) | |||||
if martini.Env == martini.Dev { | if martini.Env == martini.Dev { | ||||
m.Get("/template/**", dev.TemplatePreview) | m.Get("/template/**", dev.TemplatePreview) | ||||
} | } | ||||
@@ -195,7 +204,7 @@ func runWeb(*cli.Context) { | |||||
protocol := base.Cfg.MustValue("server", "PROTOCOL", "http") | protocol := base.Cfg.MustValue("server", "PROTOCOL", "http") | ||||
listenAddr := fmt.Sprintf("%s:%s", | 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")) | base.Cfg.MustValue("server", "HTTP_PORT", "3000")) | ||||
if protocol == "http" { | if protocol == "http" { | ||||
@@ -30,7 +30,7 @@ func LoginUserLdap(name, passwd string) (*User, error) { | |||||
Email: mail} | Email: mail} | ||||
_, err := RegisterUser(&user) | _, err := RegisterUser(&user) | ||||
if err != nil { | 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 | // simulate local user login | ||||
localUser, err2 := GetUserByName(user.Name) | localUser, err2 := GetUserByName(user.Name) | ||||
@@ -0,0 +1,117 @@ | |||||
package models | |||||
import ( | |||||
"encoding/json" | |||||
"errors" | |||||
"time" | |||||
"github.com/go-xorm/core" | |||||
"github.com/go-xorm/xorm" | |||||
"github.com/gogits/gogs/modules/auth/ldap" | |||||
) | |||||
// 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{} | |||||
type LDAPConfig struct { | |||||
ldap.Ldapsource | |||||
} | |||||
// implement | |||||
func (cfg *LDAPConfig) FromDB(bs []byte) error { | |||||
return json.Unmarshal(bs, &cfg.Ldapsource) | |||||
} | |||||
func (cfg *LDAPConfig) ToDB() ([]byte, error) { | |||||
return json.Marshal(cfg.Ldapsource) | |||||
} | |||||
type LoginSource struct { | |||||
Id int64 | |||||
Type int | |||||
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, | |||||
IsActived: true, | |||||
Cfg: cfg, | |||||
}) | |||||
return err | |||||
} | |||||
func UpdateLDAPSource(source *LoginSource) error { | |||||
_, err := orm.AllCols().Id(source.Id).Update(source) | |||||
return err | |||||
} | |||||
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 | |||||
} |
@@ -34,7 +34,7 @@ var ( | |||||
func init() { | func init() { | ||||
tables = append(tables, new(User), new(PublicKey), new(Repository), new(Watch), | tables = append(tables, new(User), new(PublicKey), new(Repository), new(Watch), | ||||
new(Action), new(Access), new(Issue), new(Comment), new(Oauth2), new(Follow), | new(Action), new(Access), new(Issue), new(Comment), new(Oauth2), new(Follow), | ||||
new(Mirror), new(Release)) | |||||
new(Mirror), new(Release), new(LoginSource)) | |||||
} | } | ||||
func LoadModelsConfig() { | func LoadModelsConfig() { | ||||
@@ -26,12 +26,6 @@ const ( | |||||
UT_ORGANIZATION | UT_ORGANIZATION | ||||
) | ) | ||||
// Login types. | |||||
const ( | |||||
LT_PLAIN = iota + 1 | |||||
LT_LDAP | |||||
) | |||||
var ( | var ( | ||||
ErrUserOwnRepos = errors.New("User still have ownership of repositories") | ErrUserOwnRepos = errors.New("User still have ownership of repositories") | ||||
ErrUserAlreadyExist = errors.New("User already exist") | ErrUserAlreadyExist = errors.New("User already exist") | ||||
@@ -50,6 +44,7 @@ type User struct { | |||||
Email string `xorm:"unique not null"` | Email string `xorm:"unique not null"` | ||||
Passwd string `xorm:"not null"` | Passwd string `xorm:"not null"` | ||||
LoginType int | LoginType int | ||||
LoginSource int64 `xorm:"not null default 0"` | |||||
Type int | Type int | ||||
NumFollowers int | NumFollowers int | ||||
NumFollowings int | NumFollowings int | ||||
@@ -16,12 +16,13 @@ import ( | |||||
) | ) | ||||
type AdminEditUserForm struct { | 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 { | func (f *AdminEditUserForm) Name(field string) string { | ||||
@@ -26,6 +26,7 @@ type RegisterForm struct { | |||||
Email string `form:"email" binding:"Required;Email;MaxSize(50)"` | Email string `form:"email" binding:"Required;Email;MaxSize(50)"` | ||||
Password string `form:"passwd" binding:"Required;MinSize(6);MaxSize(30)"` | Password string `form:"passwd" binding:"Required;MinSize(6);MaxSize(30)"` | ||||
RetypePasswd string `form:"retypepasswd"` | RetypePasswd string `form:"retypepasswd"` | ||||
LoginType string `form:"logintype"` | |||||
} | } | ||||
func (f *RegisterForm) Name(field string) string { | func (f *RegisterForm) Name(field string) string { | ||||
@@ -0,0 +1,15 @@ | |||||
package auth | |||||
type AuthenticationForm struct { | |||||
Id int64 `form:"id"` | |||||
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"` | |||||
IsActived bool `form:"is_actived"` | |||||
} |
@@ -8,12 +8,13 @@ package ldap | |||||
import ( | import ( | ||||
"fmt" | "fmt" | ||||
"github.com/gogits/gogs/modules/log" | "github.com/gogits/gogs/modules/log" | ||||
goldap "github.com/juju2013/goldap" | goldap "github.com/juju2013/goldap" | ||||
) | ) | ||||
// Basic LDAP authentication service | // Basic LDAP authentication service | ||||
type ldapsource struct { | |||||
type Ldapsource struct { | |||||
Name string // canonical name (ie. corporate.ad) | Name string // canonical name (ie. corporate.ad) | ||||
Host string // LDAP host | Host string // LDAP host | ||||
Port int // port number | Port int // port number | ||||
@@ -26,12 +27,12 @@ type ldapsource struct { | |||||
//Global LDAP directory pool | //Global LDAP directory pool | ||||
var ( | var ( | ||||
Authensource []ldapsource | |||||
Authensource []Ldapsource | |||||
) | ) | ||||
// Add a new source (LDAP directory) to the global pool | // 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) { | 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) | 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 | // 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)) | l, err := goldap.Dial("tcp", fmt.Sprintf("%s:%d", ls.Host, ls.Port)) | ||||
if err != nil { | if err != nil { | ||||
log.Debug("LDAP Connect error, disabled source %s", ls.Host) | log.Debug("LDAP Connect error, disabled source %s", ls.Host) | ||||
@@ -120,6 +120,19 @@ func Users(ctx *middleware.Context) { | |||||
ctx.HTML(200, "admin/users") | 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) { | func Repositories(ctx *middleware.Context) { | ||||
ctx.Data["Title"] = "Repository Management" | ctx.Data["Title"] = "Repository Management" | ||||
ctx.Data["PageIsRepos"] = true | ctx.Data["PageIsRepos"] = true | ||||
@@ -0,0 +1,147 @@ | |||||
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" | |||||
) | |||||
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") | |||||
} | |||||
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, 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, 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, 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") | |||||
} |
@@ -5,6 +5,8 @@ | |||||
package admin | package admin | ||||
import ( | import ( | ||||
"fmt" | |||||
"strconv" | |||||
"strings" | "strings" | ||||
"github.com/go-martini/martini" | "github.com/go-martini/martini" | ||||
@@ -19,6 +21,12 @@ import ( | |||||
func NewUser(ctx *middleware.Context) { | func NewUser(ctx *middleware.Context) { | ||||
ctx.Data["Title"] = "New Account" | ctx.Data["Title"] = "New Account" | ||||
ctx.Data["PageIsUsers"] = true | 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") | ctx.HTML(200, "admin/users/new") | ||||
} | } | ||||
@@ -40,10 +48,18 @@ func NewUserPost(ctx *middleware.Context, form auth.RegisterForm) { | |||||
} | } | ||||
u := &models.User{ | 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 | var err error | ||||
@@ -84,6 +100,12 @@ func EditUser(ctx *middleware.Context, params martini.Params) { | |||||
} | } | ||||
ctx.Data["User"] = u | 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") | 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.AvatarEmail = form.Avatar | ||||
u.IsActive = form.Active == "on" | u.IsActive = form.Active == "on" | ||||
u.IsAdmin = form.Admin == "on" | u.IsAdmin = form.Admin == "on" | ||||
u.LoginType = form.LoginType | |||||
if err := models.UpdateUser(u); err != nil { | if err := models.UpdateUser(u); err != nil { | ||||
ctx.Handle(500, "admin.user.EditUser", err) | ctx.Handle(500, "admin.user.EditUser", err) | ||||
return | return | ||||
@@ -126,7 +149,7 @@ func DeleteUser(ctx *middleware.Context, params martini.Params) { | |||||
ctx.Data["Title"] = "Delete Account" | ctx.Data["Title"] = "Delete Account" | ||||
ctx.Data["PageIsUsers"] = true | ctx.Data["PageIsUsers"] = true | ||||
log.Info("delete") | |||||
//log.Info("delete") | |||||
uid, err := base.StrTo(params["userid"]).Int() | uid, err := base.StrTo(params["userid"]).Int() | ||||
if err != nil { | if err != nil { | ||||
ctx.Handle(404, "admin.user.EditUser", err) | ctx.Handle(404, "admin.user.EditUser", err) | ||||
@@ -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>{{.TypeString}}</td> | |||||
<td><i class="fa fa{{if .IsActived}}-check{{end}}-square-o"></i></td> | |||||
<td>{{DateFormat .Updated "M d, Y"}}</td> | |||||
<td>{{DateFormat .Created "M d, Y"}}</td> | |||||
<td><a href="/admin/auths/{{.Id}}"><i class="fa fa-pencil-square-o"></i></a></td> | |||||
</tr> | |||||
{{end}} | |||||
</tbody> | |||||
</table> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
{{template "base/footer" .}} |
@@ -0,0 +1,107 @@ | |||||
{{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"> | |||||
Edit Authentication | |||||
</div> | |||||
<div class="panel-body"> | |||||
<br/> | |||||
<form action="/admin/auths/{{.Source.Id}}" method="post" class="form-horizontal"> | |||||
{{.CsrfTokenHtml}} | |||||
{{template "base/alert" .}} | |||||
<input type="hidden" value="{{.Source.Id}}" name="id"/> | |||||
<div class="form-group"> | |||||
<label class="col-md-3 control-label">Auth Type: </label> | |||||
<div class="col-md-7"> | |||||
<select class="form-control"> | |||||
{{$type := .Source.Type}} | |||||
{{range $key, $val := .LoginTypes}} | |||||
<option value="{{$key}}" {{if eq $key $type}}selected{{end}}>{{$val}}</option> | |||||
{{end}} | |||||
</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="{{.Source.Name}}" 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="{{.Source.LDAP.Name}}" 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="host" class="form-control" placeholder="Type account's e-mail address" value="{{.Source.LDAP.Host}}" 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="port" class="form-control" placeholder="Type account's e-mail address" value="{{.Source.LDAP.Port}}" 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="base_dn" class="form-control" placeholder="Type account's e-mail address" value="{{.Source.LDAP.BaseDN}}" 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="attributes" class="form-control" placeholder="Type account's e-mail address" value="{{.Source.LDAP.Attributes}}" 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="filter" class="form-control" placeholder="Type account's e-mail address" value="{{.Source.LDAP.Filter}}" 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="ms_ad_sa" class="form-control" placeholder="Type account's e-mail address" value="{{.Source.LDAP.MsAdSAFormat}}" required="required" title="Email is not valid"> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<div class="col-md-7 col-md-offset-3"> | |||||
<div class="checkbox"> | |||||
<label> | |||||
<input type="checkbox" name="is_actived" {{if .Source.IsActived}}checked{{end}}> | |||||
<strong>This authentication has activated.</strong> | |||||
</label> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<hr/> | |||||
<div class="form-group"> | |||||
<div class="col-md-offset-3 col-md-6"> | |||||
<button type="submit" class="btn btn-lg btn-primary btn-block">Update authentication config</button> | |||||
<a type="button" href="/admin/auths/{{.Source.Id}}/delete" class="btn btn-lg btn-danger btn-block">Delete this authentication</a> | |||||
</div> | |||||
</div> | |||||
</form> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
{{template "base/footer" .}} |
@@ -0,0 +1,94 @@ | |||||
{{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"> | |||||
{{range $key, $val := .LoginTypes}} | |||||
<option value="{{$key}}">{{$val}}</option> | |||||
{{end}} | |||||
</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="Authentication's name" 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="Domain name" value="{{.domain}}" 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="host" 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="port" 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="base_dn" 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="attributes" 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="filter" 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="ms_ad_sa" 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" .}} |
@@ -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 .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 .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 .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> | </ul> | ||||
</div> | </div> |
@@ -14,6 +14,18 @@ | |||||
{{.CsrfTokenHtml}} | {{.CsrfTokenHtml}} | ||||
{{template "base/alert" .}} | {{template "base/alert" .}} | ||||
<input type="hidden" value="{{.User.Id}}" name="userId"/> | <input type="hidden" value="{{.User.Id}}" name="userId"/> | ||||
<div class="form-group"> | |||||
<label class="col-md-3 control-label">Auth Source: </label> | |||||
<div class="col-md-7"> | |||||
<select name="logintype" class="form-control"> | |||||
<option value="0-0"{{if eq 0 .User.LoginSource}} selected{{end}}>Local</option> | |||||
{{$tp := .User.LoginSource}} | |||||
{{range $key, $val := .LoginSources}} | |||||
<option value="{{$val.Type}}-{{$val.Id}}"{{if eq $val.Id $tp}} selected{{end}}>{{$val.Name}}</option> | |||||
{{end}} | |||||
</select> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | <div class="form-group"> | ||||
<label class="col-md-3 control-label">Username: </label> | <label class="col-md-3 control-label">Username: </label> | ||||
<label class="control-label">{{.User.Name}}</label> | <label class="control-label">{{.User.Name}}</label> | ||||
@@ -13,6 +13,17 @@ | |||||
<form action="/admin/users/new" method="post" class="form-horizontal"> | <form action="/admin/users/new" method="post" class="form-horizontal"> | ||||
{{.CsrfTokenHtml}} | {{.CsrfTokenHtml}} | ||||
{{template "base/alert" .}} | {{template "base/alert" .}} | ||||
<div class="form-group"> | |||||
<label class="col-md-3 control-label">Auth Source: </label> | |||||
<div class="col-md-7"> | |||||
<select name="logintype" class="form-control"> | |||||
<option value="0-0">Local</option> | |||||
{{range $key, $val := .LoginSources}} | |||||
<option value="{{$val.Type}}-{{$val.Id}}">{{$val.Name}}</option> | |||||
{{end}} | |||||
</select> | |||||
</div> | |||||
</div> | |||||
<div class="form-group {{if .Err_UserName}}has-error has-feedback{{end}}"> | <div class="form-group {{if .Err_UserName}}has-error has-feedback{{end}}"> | ||||
<label class="col-md-3 control-label">Username: </label> | <label class="col-md-3 control-label">Username: </label> | ||||
<div class="col-md-7"> | <div class="col-md-7"> | ||||