change code for user and logapi

This commit is contained in:
wemeya 2016-05-25 14:21:01 +08:00
parent f3ae27649b
commit 25a88f8e29
7 changed files with 129 additions and 117 deletions

View File

@ -162,8 +162,8 @@ func (p *ProjectAPI) Get() {
p.ServeJSON()
}
// Put ...
func (p *ProjectAPI) Put() {
// ToggleProjectPublic handles request POST /api/projects/:id/toggle_project_public
func (p *ProjectAPI) ToggleProjectPublic() {
var req projectReq
var public int
@ -252,5 +252,11 @@ func validateProjectReq(req projectReq) error {
if len(pn) > projectNameMaxLen {
return fmt.Errorf("Project name is too long")
}
if isIllegalLength(req.ProjectName, 4, 30) {
return fmt.Errorf("project name is illegal in length. (greater than 4 or less than 30)")
}
if isContainIllegalChar(req.ProjectName, []string{"~", "-", "$", "\\", "[", "]", "{", "}", "(", ")", "&", "^", "%", "*", "<", ">", "\"", "'", "/", "?", "@"}) {
return fmt.Errorf("project name contains illegal characters")
}
return nil
}

View File

@ -16,8 +16,10 @@
package api
import (
"fmt"
"net/http"
"os"
"regexp"
"strconv"
"strings"
@ -133,14 +135,40 @@ func (ua *UserAPI) Get() {
}
// Put ...
func (ua *UserAPI) Put() { //currently only for toggle admin, so no request body
func (ua *UserAPI) Put() {
ldapAdminUser := (ua.AuthMode == "ldap_auth" && ua.userID == 1 && ua.userID == ua.currentUserID)
if !(ua.AuthMode == "db_auth" || ldapAdminUser) {
ua.CustomAbort(http.StatusForbidden, "")
}
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")
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.")
}
}
user := models.User{UserID: ua.userID}
ua.DecodeJSONReq(&user)
err := commonValidate(user)
if err != nil {
log.Errorf("Bad request in change user profile: %v", err)
ua.RenderError(http.StatusBadRequest, "change user profile error:"+err.Error())
return
}
userQuery := models.User{UserID: ua.userID}
dao.ToggleUserAdminRole(userQuery)
emailExist, err := dao.UserExists(user, "email")
if err != nil {
log.Errorf("Error occurred in change user profile: %v", err)
ua.RenderError(http.StatusInternalServerError, "Internal error.")
return
}
if emailExist {
log.Warning("email has already been used!")
ua.CustomAbort(http.StatusForbidden, "email has already been used!")
}
if err := dao.ChangeUserProfile(user); err != nil {
log.Errorf("Failed to update user profile, error: %v", err)
ua.CustomAbort(http.StatusInternalServerError, err.Error())
}
}
// Post ...
@ -157,7 +185,22 @@ func (ua *UserAPI) Post() {
user := models.User{}
ua.DecodeJSONReq(&user)
err := validate(user)
if err != nil {
log.Errorf("Bad request in Register: %v", err)
ua.RenderError(http.StatusBadRequest, "register error:"+err.Error())
return
}
userExist, err := dao.UserExists(user, "username")
if err != nil {
log.Errorf("Error occurred in Register: %v", err)
ua.RenderError(http.StatusInternalServerError, "Internal error.")
return
}
if userExist {
log.Warning("username has already been used!")
ua.CustomAbort(http.StatusForbidden, "username has already been used!")
}
userID, err := dao.Register(user)
if err != nil {
log.Errorf("Error occurred in Register: %v", err)
@ -228,23 +271,75 @@ func (ua *UserAPI) ChangePassword() {
}
}
// ChangeProfile handles PUT api/users/{}/profile
func (ua *UserAPI) ChangeProfile() {
ldapAdminUser := (ua.AuthMode == "ldap_auth" && ua.userID == 1 && ua.userID == ua.currentUserID)
if !(ua.AuthMode == "db_auth" || ldapAdminUser) {
ua.CustomAbort(http.StatusForbidden, "")
}
// ToggleUserAdminRole handles Post api/users/{}/toggleadmin
func (ua *UserAPI) ToggleUserAdminRole() {
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.")
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
}
}
user := models.User{UserID: ua.userID}
ua.DecodeJSONReq(&user)
if err := dao.ChangeUserProfile(user); err != nil {
log.Errorf("Failed to update user profile, error: %v", err)
ua.CustomAbort(http.StatusInternalServerError, err.Error())
userQuery := models.User{UserID: ua.userID}
if err := dao.ToggleUserAdminRole(userQuery); err != nil {
log.Errorf("Error occurred in ToggleUserAdminRole: %v", err)
ua.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
}
func validate(user models.User) error {
if isIllegalLength(user.Username, 0, 20) {
return fmt.Errorf("Username with illegal length.")
}
if isContainIllegalChar(user.Username, []string{",", "~", "#", "$", "%"}) {
return fmt.Errorf("Username contains illegal characters.")
}
if isIllegalLength(user.Password, 0, 20) {
return fmt.Errorf("Password with illegal length.")
}
if err := commonValidate(user); err != nil {
return err
}
return nil
}
//commonValidate validates information when user register or change their profile
func commonValidate(user models.User) error {
if len(user.Email) > 0 {
if m, _ := regexp.MatchString(`^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$`, user.Email); !m {
return fmt.Errorf("Email with illegal format.")
}
}
if isIllegalLength(user.Realname, 0, 20) {
return fmt.Errorf("Realname with illegal length.")
}
if isContainIllegalChar(user.Realname, []string{",", "~", "#", "$", "%"}) {
return fmt.Errorf("Realname contains illegal characters.")
}
if isIllegalLength(user.Comment, -1, 30) {
return fmt.Errorf("Comment with illegal length.")
}
return nil
}
func isIllegalLength(s string, min int, max int) bool {
if min == -1 {
return (len(s) > max)
}
if max == -1 {
return (len(s) <= min)
}
return (len(s) < min || len(s) > max)
}
func isContainIllegalChar(s string, illegalChar []string) bool {
for _, c := range illegalChar {
if strings.Index(s, c) >= 0 {
return true
}
}
return false
}

View File

@ -19,7 +19,6 @@ import (
"net"
"os"
"strings"
"time"
"github.com/astaxie/beego/orm"
@ -31,25 +30,6 @@ import (
// NonExistUserID : if a user does not exist, the ID of the user will be 0.
const NonExistUserID = 0
func isIllegalLength(s string, min int, max int) bool {
if min == -1 {
return (len(s) > max)
}
if max == -1 {
return (len(s) <= min)
}
return (len(s) < min || len(s) > max)
}
func isContainIllegalChar(s string, illegalChar []string) bool {
for _, c := range illegalChar {
if strings.Index(s, c) >= 0 {
return true
}
}
return false
}
// GenerateRandomString generates a random string
func GenerateRandomString() (string, error) {
o := orm.NewOrm()

View File

@ -18,7 +18,6 @@ package dao
import (
"github.com/vmware/harbor/models"
"errors"
"fmt"
"time"
@ -30,14 +29,6 @@ import (
// AddProject adds a project to the database along with project roles information and access log records.
func AddProject(project models.Project) (int64, error) {
if isIllegalLength(project.Name, 4, 30) {
return 0, errors.New("project name is illegal in length. (greater than 4 or less than 30)")
}
if isContainIllegalChar(project.Name, []string{"~", "-", "$", "\\", "[", "]", "{", "}", "(", ")", "&", "^", "%", "*", "<", ">", "\"", "'", "/", "?", "@"}) {
return 0, errors.New("project name contains illegal characters")
}
o := orm.NewOrm()
p, err := o.Raw("insert into project (owner_id, name, creation_time, update_time, deleted, public) values (?, ?, ?, ?, ?, ?)").Prepare()

View File

@ -17,7 +17,6 @@ package dao
import (
"errors"
"regexp"
"time"
"github.com/vmware/harbor/models"
@ -29,11 +28,6 @@ import (
// Register is used for user to register, the password is encrypted before the record is inserted into database.
func Register(user models.User) (int64, error) {
err := validate(user)
if err != nil {
return 0, err
}
o := orm.NewOrm()
p, err := o.Raw("insert into user (username, password, realname, email, comment, salt, sysadmin_flag, creation_time, update_time) values (?, ?, ?, ?, ?, ?, ?, ?, ?)").Prepare()
@ -61,56 +55,6 @@ func Register(user models.User) (int64, error) {
return userID, nil
}
func validate(user models.User) error {
if isIllegalLength(user.Username, 0, 20) {
return errors.New("Username with illegal length.")
}
if isContainIllegalChar(user.Username, []string{",", "~", "#", "$", "%"}) {
return errors.New("Username contains illegal characters.")
}
if exist, _ := UserExists(models.User{Username: user.Username}, "username"); exist {
return errors.New("Username already exists.")
}
if isIllegalLength(user.Password, 0, 20) {
return errors.New("Password with illegal length.")
}
if err := commonValidate(user); err != nil {
return err
}
return nil
}
//commonValidate validates information when user register or change their profile
func commonValidate(user models.User) error {
if len(user.Email) > 0 {
if m, _ := regexp.MatchString(`^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$`, user.Email); !m {
return errors.New("Email with illegal format.")
}
if exist, _ := UserExists(models.User{Email: user.Email}, "email"); exist {
return errors.New("Email already exists.")
}
} else {
return errors.New("Email can't be empty")
}
if isIllegalLength(user.Realname, 0, 20) {
return errors.New("Realname with illegal length.")
}
if isContainIllegalChar(user.Realname, []string{",", "~", "#", "$", "%"}) {
return errors.New("Realname contains illegal characters.")
}
if isIllegalLength(user.Comment, -1, 30) {
return errors.New("Comment with illegal length.")
}
return nil
}
// UserExists returns whether a user exists according username or Email.
func UserExists(user models.User, target string) (bool, error) {

View File

@ -113,7 +113,7 @@ func ListUsers(query models.User) ([]models.User, error) {
func ToggleUserAdminRole(u models.User) error {
o := orm.NewOrm()
sql := `update user set sysadmin_flag =not sysadmin_flag where user_id = ?`
sql := `update user set sysadmin_flag = not sysadmin_flag where user_id = ?`
r, err := o.Raw(sql, u.UserID).Exec()
if err != nil {
@ -233,13 +233,8 @@ func DeleteUser(userID int) error {
// ChangeUserProfile ...
func ChangeUserProfile(user models.User) error {
err := commonValidate(user)
if err != nil {
log.Errorf("user check failed! error: %v", err)
return err
}
o := orm.NewOrm()
if _, err = o.Update(&user, "Email", "Realname", "Comment"); err != nil {
if _, err := o.Update(&user, "Email", "Realname", "Comment"); err != nil {
log.Errorf("update user failed, error: %v", err)
return err
}

View File

@ -54,12 +54,13 @@ func initRouters() {
beego.Router("/api/search", &api.SearchAPI{})
beego.Router("/api/projects/:pid/members/?:mid", &api.ProjectMemberAPI{})
beego.Router("/api/projects/?:id", &api.ProjectAPI{})
beego.Router("/api/projects/:id/toggle_project_public", &api.ProjectAPI{}, "post:ToggleProjectPublic")
beego.Router("/api/statistics", &api.StatisticAPI{})
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/users/:id/profile", &api.UserAPI{}, "put:ChangeProfile")
beego.Router("/api/users/:id/toggle_user_admin", &api.UserAPI{}, "post:ToggleUserAdminRole")
beego.Router("/api/repositories", &api.RepositoryAPI{})
beego.Router("/api/repositories/tags", &api.RepositoryAPI{}, "get:GetTags")
beego.Router("/api/repositories/manifests", &api.RepositoryAPI{}, "get:GetManifests")