diff --git a/core/controllers/router.go b/core/controllers/router.go index 3fe451c5..13f0fefb 100644 --- a/core/controllers/router.go +++ b/core/controllers/router.go @@ -1,10 +1,11 @@ package controllers import ( + "net/http" + "github.com/crawlab-team/crawlab/core/middlewares" "github.com/crawlab-team/crawlab/core/models/models" "github.com/gin-gonic/gin" - "net/http" ) type RouterGroups struct { @@ -229,6 +230,16 @@ func InitRoutes(app *gin.Engine) (err error) { }, }...)) RegisterController(groups.AuthGroup, "/users", NewController[models.User]([]Action{ + { + Method: http.MethodPost, + Path: "/:id", + HandlerFunc: GetUserById, + }, + { + Method: http.MethodGet, + Path: "", + HandlerFunc: GetUserList, + }, { Method: http.MethodPost, Path: "", diff --git a/core/controllers/user.go b/core/controllers/user.go index f1b7eb0b..01def9c1 100644 --- a/core/controllers/user.go +++ b/core/controllers/user.go @@ -1,29 +1,132 @@ package controllers import ( + "errors" "github.com/crawlab-team/crawlab/core/models/models" "github.com/crawlab-team/crawlab/core/models/service" "github.com/crawlab-team/crawlab/core/utils" + "github.com/crawlab-team/crawlab/db/mongo" "github.com/gin-gonic/gin" + "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" + mongo2 "go.mongodb.org/mongo-driver/mongo" ) +func GetUserById(c *gin.Context) { + id, err := primitive.ObjectIDFromHex(c.Param("id")) + if err != nil { + HandleErrorBadRequest(c, err) + return + } + + // get user + user, err := service.NewModelService[models.User]().GetById(id) + if err != nil { + HandleErrorInternalServerError(c, err) + return + } + + // get role + if !user.RoleId.IsZero() { + role, err := service.NewModelService[models.Role]().GetById(user.RoleId) + if err != nil { + HandleErrorInternalServerError(c, err) + return + } + user.Role = role.Name + user.IsAdmin = role.Admin + } + + HandleSuccessWithData(c, user) +} + +func GetUserList(c *gin.Context) { + // params + pagination := MustGetPagination(c) + query := MustGetFilterQuery(c) + sort := MustGetSortOption(c) + + // get users + users, err := service.NewModelService[models.User]().GetMany(query, &mongo.FindOptions{ + Sort: sort, + Skip: pagination.Size * (pagination.Page - 1), + Limit: pagination.Size, + }) + if err != nil { + if errors.Is(err, mongo2.ErrNoDocuments) { + HandleSuccessWithListData(c, nil, 0) + } else { + HandleErrorInternalServerError(c, err) + } + return + } + + // get roles + var roleIds []primitive.ObjectID + for _, user := range users { + if !user.RoleId.IsZero() { + roleIds = append(roleIds, user.RoleId) + } + } + if len(roleIds) > 0 { + roles, err := service.NewModelService[models.Role]().GetMany(bson.M{ + "_id": bson.M{"$in": roleIds}, + }, nil) + if err != nil { + HandleErrorInternalServerError(c, err) + return + } + rolesMap := make(map[primitive.ObjectID]models.Role) + for _, role := range roles { + rolesMap[role.Id] = role + } + for i, user := range users { + if user.RoleId.IsZero() { + continue + } + if role, ok := rolesMap[user.RoleId]; ok { + users[i].Role = role.Name + users[i].IsAdmin = role.Admin + } + } + } + + // total count + total, err := service.NewModelService[models.User]().Count(query) + if err != nil { + HandleErrorInternalServerError(c, err) + return + } + + // response + HandleSuccessWithListData(c, users, total) +} + func PostUser(c *gin.Context) { var payload struct { - Username string `json:"username"` - Password string `json:"password"` - Role string `json:"role"` - Email string `json:"email"` + Username string `json:"username"` + Password string `json:"password"` + Role string `json:"role"` + RoleId primitive.ObjectID `json:"role_id"` + Email string `json:"email"` } if err := c.ShouldBindJSON(&payload); err != nil { HandleErrorBadRequest(c, err) return } + if !payload.RoleId.IsZero() { + _, err := service.NewModelService[models.Role]().GetById(payload.RoleId) + if err != nil { + HandleErrorBadRequest(c, err) + return + } + } u := GetUserFromContext(c) model := models.User{ Username: payload.Username, Password: utils.EncryptMd5(payload.Password), Role: payload.Role, + RoleId: payload.RoleId, Email: payload.Email, } model.SetCreated(u.Id) diff --git a/core/models/models/permission.go b/core/models/models/permission.go index 05438166..90882835 100644 --- a/core/models/models/permission.go +++ b/core/models/models/permission.go @@ -1,13 +1,14 @@ package models +import "go.mongodb.org/mongo-driver/bson/primitive" + type Permission struct { any `collection:"permissions"` BaseModel[Permission] `bson:",inline"` - Key string `json:"key" bson:"key"` - Name string `json:"name" bson:"name"` - Description string `json:"description" bson:"description"` - Type string `json:"type" bson:"type"` - Target []string `json:"target" bson:"target"` - Allow []string `json:"allow" bson:"allow"` - Deny []string `json:"deny" bson:"deny"` + Key string `json:"key" bson:"key"` + Name string `json:"name" bson:"name"` + Description string `json:"description" bson:"description"` + RoleId primitive.ObjectID `json:"role_id" bson:"role_id"` + Type string `json:"type" bson:"type"` + Routes []string `json:"routes" bson:"routes"` } diff --git a/core/models/models/role.go b/core/models/models/role.go index 068c01e2..f377d981 100644 --- a/core/models/models/role.go +++ b/core/models/models/role.go @@ -3,7 +3,9 @@ package models type Role struct { any `collection:"roles"` BaseModel[Role] `bson:",inline"` - Key string `json:"key" bson:"key"` - Name string `json:"name" bson:"name"` - Description string `json:"description" bson:"description"` + Name string `json:"name" bson:"name"` + Description string `json:"description" bson:"description"` + Routes []string `json:"routes" bson:"routes"` + Admin bool `json:"-" bson:"admin,omitempty"` + IsAdmin bool `json:"admin" bson:"-"` } diff --git a/core/models/models/user.go b/core/models/models/user.go index d84b4efa..a794e357 100644 --- a/core/models/models/user.go +++ b/core/models/models/user.go @@ -1,10 +1,14 @@ package models +import "go.mongodb.org/mongo-driver/bson/primitive" + type User struct { any `collection:"users"` BaseModel[User] `bson:",inline"` - Username string `json:"username" bson:"username"` - Password string `json:"-,omitempty" bson:"password"` - Role string `json:"role" bson:"role"` - Email string `json:"email" bson:"email"` + Username string `json:"username" bson:"username"` + Password string `json:"-" bson:"password"` + Role string `json:"role" bson:"role"` + RoleId primitive.ObjectID `json:"role_id" bson:"role_id"` + Email string `json:"email" bson:"email"` + IsAdmin bool `json:"admin" bson:"-"` }