diff --git a/api/user.go b/api/user.go index 58aa29ec3..1f4882e1c 100644 --- a/api/user.go +++ b/api/user.go @@ -36,6 +36,11 @@ type UserAPI struct { AuthMode string } +type passwordReq struct { + OldPassword string `json:"old_password"` + NewPassword string `json:"new_password"` +} + // Prepare validates the URL and parms func (ua *UserAPI) Prepare() { @@ -177,3 +182,46 @@ func (ua *UserAPI) Delete() { return } } + +// ChangePassword handles PUT to /api/users/{}/password +func (ua *UserAPI) ChangePassword() { + + if !(ua.AuthMode == "db_auth") { + ua.CustomAbort(http.StatusForbidden, "") + } + + if !ua.IsAdmin { + if ua.userID != ua.currentUserID { + log.Error("Guests can only change their own account.") + ua.CustomAbort(http.StatusForbidden, "Guests can only change their own account.") + } + } + + var req passwordReq + ua.DecodeJSONReq(&req) + if req.OldPassword == "" { + log.Error("Old password is blank") + ua.CustomAbort(http.StatusBadRequest, "Old password is blank") + } + + queryUser := models.User{UserID: ua.userID, Password: req.OldPassword} + user, err := dao.CheckUserPassword(queryUser) + if err != nil { + log.Errorf("Error occurred in CheckUserPassword: %v", err) + ua.CustomAbort(http.StatusInternalServerError, "Internal error.") + } + if user == nil { + log.Warning("Password input is not correct") + ua.CustomAbort(http.StatusForbidden, "old_password_is_not_correct") + } + + if req.NewPassword == "" { + ua.CustomAbort(http.StatusBadRequest, "please_input_new_password") + } + updateUser := models.User{UserID: ua.userID, Password: req.NewPassword, Salt: user.Salt} + err = dao.ChangeUserPassword(updateUser, req.OldPassword) + if err != nil { + log.Errorf("Error occurred in ChangeUserPassword: %v", err) + ua.CustomAbort(http.StatusInternalServerError, "Internal error.") + } +} diff --git a/controllers/password.go b/controllers/password.go index 3d569b6d9..210e5cf9f 100644 --- a/controllers/password.go +++ b/controllers/password.go @@ -46,47 +46,6 @@ func (cpc *ChangePasswordController) Get() { cpc.ForwardTo("page_title_change_password", "change-password") } -// UpdatePassword handles UI request to update user's password, it only works when the auth mode is db_auth. -func (cc *CommonController) UpdatePassword() { - - sessionUserID := cc.GetSession("userId") - - if sessionUserID == nil { - log.Warning("User does not login.") - cc.CustomAbort(http.StatusUnauthorized, "please_login_first") - } - - oldPassword := cc.GetString("old_password") - if oldPassword == "" { - log.Error("Old password is blank") - cc.CustomAbort(http.StatusBadRequest, "Old password is blank") - } - - queryUser := models.User{UserID: sessionUserID.(int), Password: oldPassword} - user, err := dao.CheckUserPassword(queryUser) - if err != nil { - log.Errorf("Error occurred in CheckUserPassword: %v", err) - cc.CustomAbort(http.StatusInternalServerError, "Internal error.") - } - - if user == nil { - log.Warning("Password input is not correct") - cc.CustomAbort(http.StatusForbidden, "old_password_is_not_correct") - } - - password := cc.GetString("password") - if password != "" { - updateUser := models.User{UserID: sessionUserID.(int), Password: password, Salt: user.Salt} - err = dao.ChangeUserPassword(updateUser, oldPassword) - if err != nil { - log.Errorf("Error occurred in ChangeUserPassword: %v", err) - cc.CustomAbort(http.StatusInternalServerError, "Internal error.") - } - } else { - cc.CustomAbort(http.StatusBadRequest, "please_input_new_password") - } -} - // ForgotPasswordController handles request to /forgotPassword type ForgotPasswordController struct { BaseController diff --git a/static/resources/js/change-password.js b/static/resources/js/change-password.js index a09e298b3..4c8c2efdc 100644 --- a/static/resources/js/change-password.js +++ b/static/resources/js/change-password.js @@ -56,16 +56,18 @@ jQuery(function(){ validateOptions.Validate(function(){ var oldPassword = $("#OldPassword").val(); var password = $("#Password").val(); - $.ajax({ - "url": "/updatePassword", - "type": "post", - "data": {"old_password": oldPassword, "password" : password}, - "beforeSend": function(e){ + new AjaxUtil({ + url: "/api/users/current/password", + type: "put", + data: {"old_password": oldPassword, "new_password" : password}, + beforeSend: function(e){ unbindEnterKey(); $("h1").append(spinner.el); $("#btnSubmit").prop("disabled", true); }, - "success": function(data, status, xhr){ + complete: function(xhr, status){ + spinner.stop(); + $("#btnSubmit").prop("disabled", false); if(xhr && xhr.status == 200){ $("#dlgModal") .dialogModal({ @@ -77,22 +79,20 @@ jQuery(function(){ }); } }, - "error": function(jqXhr, status, error){ - $("#dlgModal") - .dialogModal({ - "title": i18n.getMessage("title_change_password"), - "content": i18n.getMessage(jqXhr.responseText), - "callback": function(){ - bindEnterKey(); - return; - } - }); - }, - "complete": function(){ - spinner.stop(); - $("#btnSubmit").prop("disabled", false); + error: function(jqXhr, status, error){ + if(jqXhr && jqXhr.responseText.length){ + $("#dlgModal") + .dialogModal({ + "title": i18n.getMessage("title_change_password"), + "content": i18n.getMessage(jqXhr.responseText), + "callback": function(){ + bindEnterKey(); + return; + } + }); + } } - }); + }).exec(); }); }); }); \ No newline at end of file diff --git a/ui/router.go b/ui/router.go index fe3ee5d8f..401745410 100644 --- a/ui/router.go +++ b/ui/router.go @@ -36,7 +36,6 @@ func initRouters() { beego.Router("/userExists", &controllers.CommonController{}, "post:UserExists") beego.Router("/reset", &controllers.CommonController{}, "post:ResetPassword") beego.Router("/sendEmail", &controllers.CommonController{}, "get:SendEmail") - beego.Router("/updatePassword", &controllers.CommonController{}, "post:UpdatePassword") beego.Router("/", &controllers.IndexController{}) beego.Router("/signIn", &controllers.SignInController{}) @@ -58,6 +57,7 @@ func initRouters() { 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/users/:id/password", &api.UserAPI{}, "put:ChangePassword") beego.Router("/api/repositories", &api.RepositoryAPI{}) beego.Router("/api/repositories/tags", &api.RepositoryAPI{}, "get:GetTags") beego.Router("/api/repositories/manifests", &api.RepositoryAPI{}, "get:GetManifests")