ldap support
This commit is contained in:
		
							parent
							
								
									8bab21d795
								
							
						
					
					
						commit
						79ea34e70e
					
				
					 11 changed files with 287 additions and 15 deletions
				
			
		|  | @ -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) | ||||||
|  |  | ||||||
|  | @ -1,9 +1,12 @@ | ||||||
| package models | 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 ( | /*const ( | ||||||
| 	LT_PLAIN = iota + 1 | 	LT_PLAIN = iota + 1 | ||||||
|  | @ -14,20 +17,54 @@ import | ||||||
| var _ core.Conversion = &LDAPConfig{} | var _ core.Conversion = &LDAPConfig{} | ||||||
| 
 | 
 | ||||||
| type LDAPConfig struct { | type LDAPConfig struct { | ||||||
|  | 	ldap.Ldapsource | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // implement
 | // implement
 | ||||||
| func (cfg *LDAPConfig) FromDB(bs []byte) error { | func (cfg *LDAPConfig) FromDB(bs []byte) error { | ||||||
| 	return nil | 	return json.Unmarshal(bs, &cfg.Ldapsource) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (cfg *LDAPConfig) ToDB() ([]byte, error) { | func (cfg *LDAPConfig) ToDB() ([]byte, error) { | ||||||
| 	return nil, nil | 	return json.Marshal(cfg.Ldapsource) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type LoginSource struct { | type LoginSource struct { | ||||||
| 	Id   int64 | 	Id        int64 | ||||||
| 	Type int | 	Type      int | ||||||
| 	Name string | 	Name      string | ||||||
| 	Cfg  LDAPConfig | 	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 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -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() { | ||||||
|  |  | ||||||
							
								
								
									
										13
									
								
								modules/auth/authentication.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								modules/auth/authentication.go
									
									
									
									
									
										Normal file
									
								
							|  | @ -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"` | ||||||
|  | } | ||||||
|  | @ -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 | ||||||
|  |  | ||||||
							
								
								
									
										62
									
								
								routers/admin/auths.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								routers/admin/auths.go
									
									
									
									
									
										Normal file
									
								
							|  | @ -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) { | ||||||
|  | } | ||||||
							
								
								
									
										43
									
								
								templates/admin/auths.tmpl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								templates/admin/auths.tmpl
									
									
									
									
									
										Normal file
									
								
							|  | @ -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" .}} | ||||||
							
								
								
									
										93
									
								
								templates/admin/auths/new.tmpl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								templates/admin/auths/new.tmpl
									
									
									
									
									
										Normal file
									
								
							|  | @ -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" .}} | ||||||
|  | @ -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> | ||||||
							
								
								
									
										9
									
								
								web.go
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								web.go
									
									
									
									
									
								
							|  | @ -130,6 +130,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) | ||||||
|  | @ -139,6 +140,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.AdminEditUserForm{})*/, 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) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue