diff --git a/api/user.go b/api/user.go index 482ab319b..58aa29ec3 100644 --- a/api/user.go +++ b/api/user.go @@ -17,7 +17,9 @@ package api import ( "net/http" + "os" "strconv" + "strings" "github.com/vmware/harbor/dao" "github.com/vmware/harbor/models" @@ -27,13 +29,35 @@ import ( // UserAPI handles request to /api/users/{} type UserAPI struct { BaseAPI - currentUserID int - userID int + currentUserID int + userID int + SelfRegistration bool + IsAdmin bool + AuthMode string } // Prepare validates the URL and parms func (ua *UserAPI) Prepare() { + authMode := strings.ToLower(os.Getenv("AUTH_MODE")) + if authMode == "" { + authMode = "db_auth" + } + ua.AuthMode = authMode + + selfRegistration := strings.ToLower(os.Getenv("SELF_REGISTRATION")) + if selfRegistration == "on" { + ua.SelfRegistration = true + } + + if ua.Ctx.Input.IsPost() { + sessionUserID := ua.GetSession("userId") + _, _, ok := ua.Ctx.Request.BasicAuth() + if sessionUserID == nil && !ok { + return + } + } + ua.currentUserID = ua.ValidateUser() id := ua.Ctx.Input.Param(":id") if id == "current" { @@ -56,18 +80,20 @@ func (ua *UserAPI) Prepare() { ua.CustomAbort(http.StatusNotFound, "") } } + + var err error + ua.IsAdmin, err = dao.IsAdminRole(ua.currentUserID) + if err != nil { + log.Errorf("Error occurred in IsAdminRole:%v", err) + ua.CustomAbort(http.StatusInternalServerError, "Internal error.") + } + } // Get ... func (ua *UserAPI) Get() { - exist, err := dao.IsAdminRole(ua.currentUserID) - if err != nil { - log.Errorf("Error occurred in IsAdminRole, error: %v", err) - ua.CustomAbort(http.StatusInternalServerError, "Internal error.") - } - if ua.userID == 0 { //list users - if !exist { + if !ua.IsAdmin { log.Errorf("Current user, id: %d does not have admin role, can not list users", ua.currentUserID) ua.RenderError(http.StatusForbidden, "User does not have admin role") return @@ -85,7 +111,7 @@ func (ua *UserAPI) Get() { } ua.Data["json"] = userList - } else if ua.userID == ua.currentUserID || exist { + } else if ua.userID == ua.currentUserID || ua.IsAdmin { userQuery := models.User{UserID: ua.userID} u, err := dao.GetUser(userQuery) if err != nil { @@ -103,12 +129,7 @@ func (ua *UserAPI) Get() { // Put ... func (ua *UserAPI) Put() { //currently only for toggle admin, so no request body - exist, err := dao.IsAdminRole(ua.currentUserID) - if err != nil { - log.Errorf("Error occurred in IsAdminRole, error: %v", err) - ua.CustomAbort(http.StatusInternalServerError, "Internal error.") - } - if !exist { + if !ua.IsAdmin { log.Warningf("current user, id: %d does not have admin role, can not update other user's role", ua.currentUserID) ua.RenderError(http.StatusForbidden, "User does not have admin role") return @@ -117,18 +138,38 @@ func (ua *UserAPI) Put() { //currently only for toggle admin, so no request body dao.ToggleUserAdminRole(userQuery) } +// Post ... +func (ua *UserAPI) Post() { + + if !(ua.AuthMode == "db_auth") { + ua.CustomAbort(http.StatusForbidden, "") + } + + if !(ua.SelfRegistration || ua.IsAdmin) { + log.Warning("Registration can only be used by admin role user when self-registration is off.") + ua.CustomAbort(http.StatusForbidden, "") + } + + user := models.User{} + ua.DecodeJSONReq(&user) + + _, err := dao.Register(user) + if err != nil { + log.Errorf("Error occurred in Register: %v", err) + ua.RenderError(http.StatusInternalServerError, "Internal error.") + return + } + +} + // Delete ... func (ua *UserAPI) Delete() { - exist, err := dao.IsAdminRole(ua.currentUserID) - if err != nil { - log.Errorf("Error occurred in IsAdminRole, error: %v", err) - ua.CustomAbort(http.StatusInternalServerError, "Internal error.") - } - if !exist { + if !ua.IsAdmin { log.Warningf("current user, id: %d does not have admin role, can not remove user", ua.currentUserID) ua.RenderError(http.StatusForbidden, "User does not have admin role") return } + var err error err = dao.DeleteUser(ua.userID) if err != nil { log.Errorf("Failed to delete data from database, error: %v", err) diff --git a/controllers/register.go b/controllers/register.go index dd1a80eab..d8ed05715 100644 --- a/controllers/register.go +++ b/controllers/register.go @@ -17,7 +17,6 @@ package controllers import ( "net/http" - "strings" "github.com/vmware/harbor/dao" "github.com/vmware/harbor/models" @@ -65,33 +64,6 @@ func (ac *AddUserController) Get() { } } -// SignUp insert data into DB based on data in form. -func (cc *CommonController) SignUp() { - - if !(cc.AuthMode == "db_auth") { - cc.CustomAbort(http.StatusForbidden, "") - } - - if !(cc.SelfRegistration || cc.IsAdmin) { - log.Warning("Registration can only be used by admin role user when self-registration is off.") - cc.CustomAbort(http.StatusForbidden, "") - } - - username := strings.TrimSpace(cc.GetString("username")) - email := strings.TrimSpace(cc.GetString("email")) - realname := strings.TrimSpace(cc.GetString("realname")) - password := strings.TrimSpace(cc.GetString("password")) - comment := strings.TrimSpace(cc.GetString("comment")) - - user := models.User{Username: username, Email: email, Realname: realname, Password: password, Comment: comment} - - _, err := dao.Register(user) - if err != nil { - log.Errorf("Error occurred in Register: %v", err) - cc.CustomAbort(http.StatusInternalServerError, "Internal error.") - } -} - // UserExists checks if user exists when user input value in sign in form. func (cc *CommonController) UserExists() { target := cc.GetString("target") diff --git a/models/user.go b/models/user.go index 82b8bc221..29fb41c13 100644 --- a/models/user.go +++ b/models/user.go @@ -22,11 +22,11 @@ import ( // User holds the details of a user. type User struct { UserID int `orm:"column(user_id)" json:"UserId"` - Username string `orm:"column(username)"` - Email string `orm:"column(email)"` - Password string `orm:"column(password)"` - Realname string `orm:"column(realname)"` - Comment string `orm:"column(comment)"` + Username string `orm:"column(username)" json:"username"` + Email string `orm:"column(email)" json:"email"` + Password string `orm:"column(password)" json:"password"` + Realname string `orm:"column(realname)" json:"realname"` + Comment string `orm:"column(comment)" json:"comment"` Deleted int `orm:"column(deleted)"` Rolename string RoleID int `json:"RoleId"` diff --git a/static/resources/js/register.js b/static/resources/js/register.js index e8fe31d35..8f970946f 100644 --- a/static/resources/js/register.js +++ b/static/resources/js/register.js @@ -38,14 +38,25 @@ jQuery(function(){ var comment = $.trim($("#Comment").val()); var isAdmin = $("#isAdmin").val(); - $.ajax({ - url : '/signUp', - data:{username: username, password: password, realname: realname, comment: comment, email: email}, + new AjaxUtil({ + url : "/api/users", + data: {"username": username, "password": password, "realname": realname, "comment": comment, "email": email}, type: "POST", beforeSend: function(e){ $("#btnPageSignUp").prop("disabled", true); }, - success: function(data, status, xhr){ + error:function(jqxhr, status, error){ + $("#dlgModal") + .dialogModal({ + "title": i18n.getMessage("title_sign_up"), + "content": i18n.getMessage("internal_error"), + "callback": function(){ + return; + } + }); + }, + complete: function(xhr, status){ + $("#btnPageSignUp").prop("disabled", false); if(xhr && xhr.status == 200){ $("#dlgModal") .dialogModal({ @@ -60,21 +71,8 @@ jQuery(function(){ } }); } - }, - error:function(jqxhr, status, error){ - $("#dlgModal") - .dialogModal({ - "title": i18n.getMessage("title_sign_up"), - "content": i18n.getMessage("internal_error"), - "callback": function(){ - return; - } - }); - }, - complete: function(){ - $("#btnPageSignUp").prop("disabled", false); } - }); + }).exec(); }); }); }); \ No newline at end of file diff --git a/ui/router.go b/ui/router.go index 4eb04108b..a1f9067c1 100644 --- a/ui/router.go +++ b/ui/router.go @@ -32,7 +32,6 @@ func initRouters() { beego.Router("/login", &controllers.CommonController{}, "post:Login") beego.Router("/logout", &controllers.CommonController{}, "get:Logout") beego.Router("/language", &controllers.CommonController{}, "get:SwitchLanguage") - beego.Router("/signUp", &controllers.CommonController{}, "post:SignUp") beego.Router("/userExists", &controllers.CommonController{}, "post:UserExists") beego.Router("/reset", &controllers.CommonController{}, "post:ResetPassword") beego.Router("/sendEmail", &controllers.CommonController{}, "get:SendEmail") @@ -56,6 +55,7 @@ func initRouters() { beego.Router("/api/projects/:pid/members/?:mid", &api.ProjectMemberAPI{}) beego.Router("/api/projects/?:id", &api.ProjectAPI{}) beego.Router("/api/projects/:id/logs/filter", &api.ProjectAPI{}, "post:FilterAccessLog") + beego.Router("/api/users", &api.UserAPI{}) beego.Router("/api/users/?:id", &api.UserAPI{}) beego.Router("/api/repositories", &api.RepositoryAPI{}) beego.Router("/api/repositories/tags", &api.RepositoryAPI{}, "get:GetTags")