mirror of https://github.com/go-gitea/gitea.git
Merge branch 'dev-ldap' into dev
commit
d8136c9c3c
@ -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
|
||||
}
|
@ -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"`
|
||||
}
|
@ -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")
|
||||
}
|
@ -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" .}}
|
Loading…
Reference in New Issue