]> source.dussan.org Git - gitea.git/commitdiff
APIs: admin users
authorUnknwon <u@gogs.io>
Sat, 5 Dec 2015 22:13:13 +0000 (17:13 -0500)
committerUnknwon <u@gogs.io>
Sat, 5 Dec 2015 22:13:13 +0000 (17:13 -0500)
models/error.go
models/login.go
models/publickey.go
modules/auth/auth_form.go
routers/admin/users.go
routers/api/v1/admin/users.go [new file with mode: 0644]
routers/api/v1/api.go
routers/api/v1/user/keys.go

index 561252e84ac41060d37f2e3eea0e05888d10c3d4..54d32d15466434c87e3608b70b1f8917ec7d63ea 100644 (file)
@@ -528,3 +528,23 @@ func IsErrAttachmentNotExist(err error) bool {
 func (err ErrAttachmentNotExist) Error() string {
        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)
+}
index 1ec5309db4089d7e730045f0e997207d14d5d1d3..5e2601064783c6bbf444fe2b8ef00c0050c64657 100644 (file)
@@ -36,7 +36,6 @@ const (
 
 var (
        ErrAuthenticationAlreadyExist = errors.New("Authentication already exist")
-       ErrAuthenticationNotExist     = errors.New("Authentication does not exist")
        ErrAuthenticationUserUsed     = errors.New("Authentication has been used by some users")
 )
 
@@ -191,13 +190,14 @@ func LoginSources() ([]*LoginSource, error) {
        return auths, x.Find(&auths)
 }
 
+// GetLoginSourceByID returns login source by given ID.
 func GetLoginSourceByID(id int64) (*LoginSource, error) {
        source := new(LoginSource)
        has, err := x.Id(id).Get(source)
        if err != nil {
                return nil, err
        } else if !has {
-               return nil, ErrAuthenticationNotExist
+               return nil, ErrAuthenticationNotExist{id}
        }
        return source, nil
 }
index ac0ec71f4474ae601f56629b18b71b9058de4fac..68389478142fc808d6adb0bba60f71e537e96cbe 100644 (file)
@@ -460,7 +460,7 @@ func DeletePublicKey(doer *User, id int64) (err error) {
        }
 
        // 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"}
        }
 
@@ -672,15 +672,17 @@ func DeleteDeployKey(doer *User, id int64) error {
        }
 
        // Check if user has access to delete this key.
-       repo, err := GetRepositoryByID(key.RepoID)
-       if err != nil {
-               return fmt.Errorf("GetRepositoryByID: %v", err)
-       }
-       yes, err := HasAccess(doer, repo, ACCESS_MODE_ADMIN)
-       if err != nil {
-               return fmt.Errorf("HasAccess: %v", err)
-       } else if !yes {
-               return ErrKeyAccessDenied{doer.Id, key.ID, "deploy"}
+       if !doer.IsAdmin {
+               repo, err := GetRepositoryByID(key.RepoID)
+               if err != nil {
+                       return fmt.Errorf("GetRepositoryByID: %v", err)
+               }
+               yes, err := HasAccess(doer, repo, ACCESS_MODE_ADMIN)
+               if err != nil {
+                       return fmt.Errorf("HasAccess: %v", err)
+               } else if !yes {
+                       return ErrKeyAccessDenied{doer.Id, key.ID, "deploy"}
+               }
        }
 
        sess := x.NewSession()
index 1604792a66510e858be80f40889b50c6636cd98e..68a9688303a87da2f989912cc3d70b0e395849d3 100644 (file)
@@ -18,7 +18,7 @@ type AuthenticationForm struct {
        BindDN            string
        BindPassword      string
        UserBase          string
-       UserDN            string `form:"user_dn"`
+       UserDN            string
        AttributeUsername string
        AttributeName     string
        AttributeSurname  string
@@ -32,7 +32,7 @@ type AuthenticationForm struct {
        AllowedDomains    string
        TLS               bool
        SkipVerify        bool
-       PAMServiceName    string `form:"pam_service_name"`
+       PAMServiceName    string
 }
 
 func (f *AuthenticationForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
index d5358553cefa4e1d2afca1dcbd53b0fbdc27a9ef..ae17a99cd96fe8cf6190b6e7743ff70fa6807a37 100644 (file)
@@ -121,7 +121,7 @@ func NewUserPost(ctx *middleware.Context, form auth.AdminCrateUserForm) {
                }
                return
        }
-       log.Trace("Account created by admin(%s): %s", ctx.User.Name, u.Name)
+       log.Trace("Account created by admin (%s): %s", ctx.User.Name, u.Name)
 
        // Send e-mail notification.
        if form.SendNotify && setting.MailService != nil {
@@ -224,7 +224,7 @@ func EditUserPost(ctx *middleware.Context, form auth.AdminEditUserForm) {
                }
                return
        }
-       log.Trace("Account profile updated by admin(%s): %s", ctx.User.Name, u.Name)
+       log.Trace("Account profile updated by admin (%s): %s", ctx.User.Name, u.Name)
 
        ctx.Flash.Success(ctx.Tr("admin.users.update_profile_success"))
        ctx.Redirect(setting.AppSubUrl + "/admin/users/" + ctx.Params(":userid"))
@@ -254,7 +254,7 @@ func DeleteUser(ctx *middleware.Context) {
                }
                return
        }
-       log.Trace("Account deleted by admin(%s): %s", ctx.User.Name, u.Name)
+       log.Trace("Account deleted by admin (%s): %s", ctx.User.Name, u.Name)
 
        ctx.Flash.Success(ctx.Tr("admin.users.deletion_success"))
        ctx.JSON(200, map[string]interface{}{
diff --git a/routers/api/v1/admin/users.go b/routers/api/v1/admin/users.go
new file mode 100644 (file)
index 0000000..c203a09
--- /dev/null
@@ -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)
+}
index 01577bba7d72a73e1642534a72b543323392a5fb..1ac60c26b97d7bf9d3fdf8fedc6c7bc7ddd19dc1 100644 (file)
@@ -15,6 +15,7 @@ import (
        "github.com/gogits/gogs/models"
        "github.com/gogits/gogs/modules/auth"
        "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/repo"
        "github.com/gogits/gogs/routers/api/v1/user"
@@ -132,8 +133,7 @@ func RegisterRoutes(m *macaron.Macaron) {
 
                m.Group("/users", func() {
                        m.Group("/:username", func() {
-                               m.Combo("/keys").Get(user.ListPublicKeys).
-                                       Post(ReqAdmin(), user.CreateUserPublicKey)
+                               m.Get("/keys", user.ListPublicKeys)
                        })
                }, ReqToken())
 
@@ -179,5 +179,17 @@ func RegisterRoutes(m *macaron.Macaron) {
                m.Any("/*", func(ctx *middleware.Context) {
                        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())
        })
 }
index 597ee9f1e26b507c4f368440c6c7e62cc6aa55c6..213631e14644901e1fd94bca29a3cb6747563add 100644 (file)
@@ -14,7 +14,8 @@ import (
        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"))
        if err != nil {
                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
 func ListPublicKeys(ctx *middleware.Context) {
-       user := getUserByParams(ctx)
+       user := GetUserByParams(ctx)
        if ctx.Written() {
                return
        }
@@ -77,7 +78,8 @@ func GetPublicKey(ctx *middleware.Context) {
        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)
        if err != nil {
                repo.HandleCheckKeyStringError(ctx, err)
@@ -93,18 +95,9 @@ func createUserPublicKey(ctx *middleware.Context, form api.CreateKeyOption, uid
        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
 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