APIs: admin users
This commit is contained in:
		
							parent
							
								
									bf26808fb3
								
							
						
					
					
						commit
						978dc00305
					
				| @ -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
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user