mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-23 10:45:45 +01:00
change code for user and logapi
This commit is contained in:
parent
f3ae27649b
commit
25a88f8e29
@ -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
|
||||
}
|
||||
|
137
api/user.go
137
api/user.go
@ -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
|
||||
}
|
||||
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.")
|
||||
}
|
||||
}
|
||||
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())
|
||||
|
||||
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
|
||||
}
|
||||
|
20
dao/base.go
20
dao/base.go
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -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) {
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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")
|
||||
|
Loading…
Reference in New Issue
Block a user