APIs: admin users
This commit is contained in:
parent
bf26808fb3
commit
978dc00305
8 changed files with 207 additions and 32 deletions
|
@ -528,3 +528,23 @@ func IsErrAttachmentNotExist(err error) bool {
|
||||||
func (err ErrAttachmentNotExist) Error() string {
|
func (err ErrAttachmentNotExist) Error() string {
|
||||||
return fmt.Sprintf("attachment does not exist [id: %d, uuid: %s]", err.ID, err.UUID)
|
return fmt.Sprintf("attachment does not exist [id: %d, uuid: %s]", err.ID, err.UUID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// _____ __ .__ __ .__ __ .__
|
||||||
|
// / _ \ __ ___/ |_| |__ ____ _____/ |_|__| ____ _____ _/ |_|__| ____ ____
|
||||||
|
// / /_\ \| | \ __\ | \_/ __ \ / \ __\ |/ ___\\__ \\ __\ |/ _ \ / \
|
||||||
|
// / | \ | /| | | Y \ ___/| | \ | | \ \___ / __ \| | | ( <_> ) | \
|
||||||
|
// \____|__ /____/ |__| |___| /\___ >___| /__| |__|\___ >____ /__| |__|\____/|___| /
|
||||||
|
// \/ \/ \/ \/ \/ \/ \/
|
||||||
|
|
||||||
|
type ErrAuthenticationNotExist struct {
|
||||||
|
ID int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsErrAuthenticationNotExist(err error) bool {
|
||||||
|
_, ok := err.(ErrAuthenticationNotExist)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err ErrAuthenticationNotExist) Error() string {
|
||||||
|
return fmt.Sprintf("Authentication does not exist [id: %d]", err.ID)
|
||||||
|
}
|
||||||
|
|
|
@ -36,7 +36,6 @@ const (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrAuthenticationAlreadyExist = errors.New("Authentication already exist")
|
ErrAuthenticationAlreadyExist = errors.New("Authentication already exist")
|
||||||
ErrAuthenticationNotExist = errors.New("Authentication does not exist")
|
|
||||||
ErrAuthenticationUserUsed = errors.New("Authentication has been used by some users")
|
ErrAuthenticationUserUsed = errors.New("Authentication has been used by some users")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -191,13 +190,14 @@ func LoginSources() ([]*LoginSource, error) {
|
||||||
return auths, x.Find(&auths)
|
return auths, x.Find(&auths)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetLoginSourceByID returns login source by given ID.
|
||||||
func GetLoginSourceByID(id int64) (*LoginSource, error) {
|
func GetLoginSourceByID(id int64) (*LoginSource, error) {
|
||||||
source := new(LoginSource)
|
source := new(LoginSource)
|
||||||
has, err := x.Id(id).Get(source)
|
has, err := x.Id(id).Get(source)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if !has {
|
} else if !has {
|
||||||
return nil, ErrAuthenticationNotExist
|
return nil, ErrAuthenticationNotExist{id}
|
||||||
}
|
}
|
||||||
return source, nil
|
return source, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -460,7 +460,7 @@ func DeletePublicKey(doer *User, id int64) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if user has access to delete this key.
|
// Check if user has access to delete this key.
|
||||||
if doer.Id != key.OwnerID {
|
if !doer.IsAdmin && doer.Id != key.OwnerID {
|
||||||
return ErrKeyAccessDenied{doer.Id, key.ID, "public"}
|
return ErrKeyAccessDenied{doer.Id, key.ID, "public"}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -672,6 +672,7 @@ func DeleteDeployKey(doer *User, id int64) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if user has access to delete this key.
|
// Check if user has access to delete this key.
|
||||||
|
if !doer.IsAdmin {
|
||||||
repo, err := GetRepositoryByID(key.RepoID)
|
repo, err := GetRepositoryByID(key.RepoID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("GetRepositoryByID: %v", err)
|
return fmt.Errorf("GetRepositoryByID: %v", err)
|
||||||
|
@ -682,6 +683,7 @@ func DeleteDeployKey(doer *User, id int64) error {
|
||||||
} else if !yes {
|
} else if !yes {
|
||||||
return ErrKeyAccessDenied{doer.Id, key.ID, "deploy"}
|
return ErrKeyAccessDenied{doer.Id, key.ID, "deploy"}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sess := x.NewSession()
|
sess := x.NewSession()
|
||||||
defer sessionRelease(sess)
|
defer sessionRelease(sess)
|
||||||
|
|
|
@ -18,7 +18,7 @@ type AuthenticationForm struct {
|
||||||
BindDN string
|
BindDN string
|
||||||
BindPassword string
|
BindPassword string
|
||||||
UserBase string
|
UserBase string
|
||||||
UserDN string `form:"user_dn"`
|
UserDN string
|
||||||
AttributeUsername string
|
AttributeUsername string
|
||||||
AttributeName string
|
AttributeName string
|
||||||
AttributeSurname string
|
AttributeSurname string
|
||||||
|
@ -32,7 +32,7 @@ type AuthenticationForm struct {
|
||||||
AllowedDomains string
|
AllowedDomains string
|
||||||
TLS bool
|
TLS bool
|
||||||
SkipVerify bool
|
SkipVerify bool
|
||||||
PAMServiceName string `form:"pam_service_name"`
|
PAMServiceName string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *AuthenticationForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
func (f *AuthenticationForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||||
|
|
148
routers/api/v1/admin/users.go
Normal file
148
routers/api/v1/admin/users.go
Normal file
|
@ -0,0 +1,148 @@
|
||||||
|
// Copyright 2015 The Gogs Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package admin
|
||||||
|
|
||||||
|
import (
|
||||||
|
api "github.com/gogits/go-gogs-client"
|
||||||
|
|
||||||
|
"github.com/gogits/gogs/models"
|
||||||
|
"github.com/gogits/gogs/modules/log"
|
||||||
|
"github.com/gogits/gogs/modules/mailer"
|
||||||
|
"github.com/gogits/gogs/modules/middleware"
|
||||||
|
"github.com/gogits/gogs/modules/setting"
|
||||||
|
"github.com/gogits/gogs/routers/api/v1/user"
|
||||||
|
to "github.com/gogits/gogs/routers/api/v1/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func parseLoginSource(ctx *middleware.Context, u *models.User, sourceID int64, loginName string) {
|
||||||
|
if sourceID == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
source, err := models.GetLoginSourceByID(sourceID)
|
||||||
|
if err != nil {
|
||||||
|
if models.IsErrAuthenticationNotExist(err) {
|
||||||
|
ctx.APIError(422, "", err)
|
||||||
|
} else {
|
||||||
|
ctx.APIError(500, "GetLoginSourceByID", err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
u.LoginType = source.Type
|
||||||
|
u.LoginSource = source.ID
|
||||||
|
u.LoginName = loginName
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateUser(ctx *middleware.Context, form api.CreateUserOption) {
|
||||||
|
u := &models.User{
|
||||||
|
Name: form.Username,
|
||||||
|
Email: form.Email,
|
||||||
|
Passwd: form.Password,
|
||||||
|
IsActive: true,
|
||||||
|
LoginType: models.PLAIN,
|
||||||
|
}
|
||||||
|
|
||||||
|
parseLoginSource(ctx, u, form.SourceID, form.LoginName)
|
||||||
|
if ctx.Written() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := models.CreateUser(u); err != nil {
|
||||||
|
if models.IsErrUserAlreadyExist(err) ||
|
||||||
|
models.IsErrEmailAlreadyUsed(err) ||
|
||||||
|
models.IsErrNameReserved(err) ||
|
||||||
|
models.IsErrNamePatternNotAllowed(err) {
|
||||||
|
ctx.APIError(422, "", err)
|
||||||
|
} else {
|
||||||
|
ctx.APIError(500, "CreateUser", err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Trace("Account created by admin (%s): %s", ctx.User.Name, u.Name)
|
||||||
|
|
||||||
|
// Send e-mail notification.
|
||||||
|
if form.SendNotify && setting.MailService != nil {
|
||||||
|
mailer.SendRegisterNotifyMail(ctx.Context, u)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.JSON(201, to.ApiUser(u))
|
||||||
|
}
|
||||||
|
|
||||||
|
func EditUser(ctx *middleware.Context, form api.EditUserOption) {
|
||||||
|
u := user.GetUserByParams(ctx)
|
||||||
|
if ctx.Written() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
parseLoginSource(ctx, u, form.SourceID, form.LoginName)
|
||||||
|
if ctx.Written() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(form.Password) > 0 {
|
||||||
|
u.Passwd = form.Password
|
||||||
|
u.Salt = models.GetUserSalt()
|
||||||
|
u.EncodePasswd()
|
||||||
|
}
|
||||||
|
|
||||||
|
u.LoginName = form.LoginName
|
||||||
|
u.FullName = form.FullName
|
||||||
|
u.Email = form.Email
|
||||||
|
u.Website = form.Website
|
||||||
|
u.Location = form.Location
|
||||||
|
if form.Active != nil {
|
||||||
|
u.IsActive = *form.Active
|
||||||
|
}
|
||||||
|
if form.Admin != nil {
|
||||||
|
u.IsAdmin = *form.Admin
|
||||||
|
}
|
||||||
|
if form.AllowGitHook != nil {
|
||||||
|
u.AllowGitHook = *form.AllowGitHook
|
||||||
|
}
|
||||||
|
if form.AllowImportLocal != nil {
|
||||||
|
u.AllowImportLocal = *form.AllowImportLocal
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := models.UpdateUser(u); err != nil {
|
||||||
|
if models.IsErrEmailAlreadyUsed(err) {
|
||||||
|
ctx.APIError(422, "", err)
|
||||||
|
} else {
|
||||||
|
ctx.APIError(500, "UpdateUser", err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Trace("Account profile updated by admin (%s): %s", ctx.User.Name, u.Name)
|
||||||
|
|
||||||
|
ctx.JSON(200, to.ApiUser(u))
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteUser(ctx *middleware.Context) {
|
||||||
|
u := user.GetUserByParams(ctx)
|
||||||
|
if ctx.Written() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := models.DeleteUser(u); err != nil {
|
||||||
|
if models.IsErrUserOwnRepos(err) ||
|
||||||
|
models.IsErrUserHasOrgs(err) {
|
||||||
|
ctx.APIError(422, "", err)
|
||||||
|
} else {
|
||||||
|
ctx.APIError(500, "DeleteUser", err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Trace("Account deleted by admin(%s): %s", ctx.User.Name, u.Name)
|
||||||
|
|
||||||
|
ctx.Status(204)
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreatePublicKey(ctx *middleware.Context, form api.CreateKeyOption) {
|
||||||
|
u := user.GetUserByParams(ctx)
|
||||||
|
if ctx.Written() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
user.CreateUserPublicKey(ctx, form, u.Id)
|
||||||
|
}
|
|
@ -15,6 +15,7 @@ import (
|
||||||
"github.com/gogits/gogs/models"
|
"github.com/gogits/gogs/models"
|
||||||
"github.com/gogits/gogs/modules/auth"
|
"github.com/gogits/gogs/modules/auth"
|
||||||
"github.com/gogits/gogs/modules/middleware"
|
"github.com/gogits/gogs/modules/middleware"
|
||||||
|
"github.com/gogits/gogs/routers/api/v1/admin"
|
||||||
"github.com/gogits/gogs/routers/api/v1/misc"
|
"github.com/gogits/gogs/routers/api/v1/misc"
|
||||||
"github.com/gogits/gogs/routers/api/v1/repo"
|
"github.com/gogits/gogs/routers/api/v1/repo"
|
||||||
"github.com/gogits/gogs/routers/api/v1/user"
|
"github.com/gogits/gogs/routers/api/v1/user"
|
||||||
|
@ -132,8 +133,7 @@ func RegisterRoutes(m *macaron.Macaron) {
|
||||||
|
|
||||||
m.Group("/users", func() {
|
m.Group("/users", func() {
|
||||||
m.Group("/:username", func() {
|
m.Group("/:username", func() {
|
||||||
m.Combo("/keys").Get(user.ListPublicKeys).
|
m.Get("/keys", user.ListPublicKeys)
|
||||||
Post(ReqAdmin(), user.CreateUserPublicKey)
|
|
||||||
})
|
})
|
||||||
}, ReqToken())
|
}, ReqToken())
|
||||||
|
|
||||||
|
@ -179,5 +179,17 @@ func RegisterRoutes(m *macaron.Macaron) {
|
||||||
m.Any("/*", func(ctx *middleware.Context) {
|
m.Any("/*", func(ctx *middleware.Context) {
|
||||||
ctx.Error(404)
|
ctx.Error(404)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
m.Group("/admin", func() {
|
||||||
|
m.Group("/users", func() {
|
||||||
|
m.Post("", bind(api.CreateUserOption{}), admin.CreateUser)
|
||||||
|
|
||||||
|
m.Group("/:username", func() {
|
||||||
|
m.Combo("").Patch(bind(api.EditUserOption{}), admin.EditUser).
|
||||||
|
Delete(admin.DeleteUser)
|
||||||
|
m.Post("/keys", admin.CreatePublicKey)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}, ReqAdmin())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,8 @@ import (
|
||||||
to "github.com/gogits/gogs/routers/api/v1/utils"
|
to "github.com/gogits/gogs/routers/api/v1/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getUserByParams(ctx *middleware.Context) *models.User {
|
// GetUserByParams returns user whose name is presented in URL paramenter.
|
||||||
|
func GetUserByParams(ctx *middleware.Context) *models.User {
|
||||||
user, err := models.GetUserByName(ctx.Params(":username"))
|
user, err := models.GetUserByName(ctx.Params(":username"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if models.IsErrUserNotExist(err) {
|
if models.IsErrUserNotExist(err) {
|
||||||
|
@ -54,7 +55,7 @@ func ListMyPublicKeys(ctx *middleware.Context) {
|
||||||
|
|
||||||
// https://github.com/gogits/go-gogs-client/wiki/Users-Public-Keys#list-public-keys-for-a-user
|
// https://github.com/gogits/go-gogs-client/wiki/Users-Public-Keys#list-public-keys-for-a-user
|
||||||
func ListPublicKeys(ctx *middleware.Context) {
|
func ListPublicKeys(ctx *middleware.Context) {
|
||||||
user := getUserByParams(ctx)
|
user := GetUserByParams(ctx)
|
||||||
if ctx.Written() {
|
if ctx.Written() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -77,7 +78,8 @@ func GetPublicKey(ctx *middleware.Context) {
|
||||||
ctx.JSON(200, to.ApiPublicKey(apiLink, key))
|
ctx.JSON(200, to.ApiPublicKey(apiLink, key))
|
||||||
}
|
}
|
||||||
|
|
||||||
func createUserPublicKey(ctx *middleware.Context, form api.CreateKeyOption, uid int64) {
|
// CreateUserPublicKey creates new public key to given user by ID.
|
||||||
|
func CreateUserPublicKey(ctx *middleware.Context, form api.CreateKeyOption, uid int64) {
|
||||||
content, err := models.CheckPublicKeyString(form.Key)
|
content, err := models.CheckPublicKeyString(form.Key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
repo.HandleCheckKeyStringError(ctx, err)
|
repo.HandleCheckKeyStringError(ctx, err)
|
||||||
|
@ -93,18 +95,9 @@ func createUserPublicKey(ctx *middleware.Context, form api.CreateKeyOption, uid
|
||||||
ctx.JSON(201, to.ApiPublicKey(apiLink, key))
|
ctx.JSON(201, to.ApiPublicKey(apiLink, key))
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/gogits/go-gogs-client/wiki/Users-Public-Keys#create-a-public-key-for-user
|
|
||||||
func CreateUserPublicKey(ctx *middleware.Context, form api.CreateKeyOption) {
|
|
||||||
user := getUserByParams(ctx)
|
|
||||||
if ctx.Written() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
createUserPublicKey(ctx, form, user.Id)
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://github.com/gogits/go-gogs-client/wiki/Users-Public-Keys#create-a-public-key
|
// https://github.com/gogits/go-gogs-client/wiki/Users-Public-Keys#create-a-public-key
|
||||||
func CreatePublicKey(ctx *middleware.Context, form api.CreateKeyOption) {
|
func CreatePublicKey(ctx *middleware.Context, form api.CreateKeyOption) {
|
||||||
createUserPublicKey(ctx, form, ctx.User.Id)
|
CreateUserPublicKey(ctx, form, ctx.User.Id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/gogits/go-gogs-client/wiki/Users-Public-Keys#delete-a-public-key
|
// https://github.com/gogits/go-gogs-client/wiki/Users-Public-Keys#delete-a-public-key
|
||||||
|
|
Reference in a new issue