| @@ -169,6 +169,7 @@ func init() { | |||||
| new(BadgeUserLog), | new(BadgeUserLog), | ||||
| new(TechConvergeBaseInfo), | new(TechConvergeBaseInfo), | ||||
| new(RepoConvergeInfo), | new(RepoConvergeInfo), | ||||
| new(UserRole), | |||||
| ) | ) | ||||
| tablesStatistic = append(tablesStatistic, | tablesStatistic = append(tablesStatistic, | ||||
| @@ -0,0 +1,68 @@ | |||||
| package models | |||||
| import ( | |||||
| "code.gitea.io/gitea/modules/timeutil" | |||||
| "fmt" | |||||
| ) | |||||
| type RoleType string | |||||
| const ( | |||||
| TechProgramAdmin RoleType = "TechProgramAdmin" | |||||
| ) | |||||
| type Role struct { | |||||
| Type RoleType | |||||
| Name string | |||||
| Description string | |||||
| } | |||||
| type UserRole struct { | |||||
| ID int64 `xorm:"pk autoincr"` | |||||
| RoleType RoleType | |||||
| UserId int64 `xorm:"INDEX"` | |||||
| CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | |||||
| } | |||||
| func NewUserRole(r UserRole) (int64, error) { | |||||
| return x.Insert(&r) | |||||
| } | |||||
| func GetUserRoleByUserAndRole(userId int64, roleType RoleType) (*UserRole, error) { | |||||
| r := &UserRole{} | |||||
| has, err := x.Where("role_type = ? and user_id = ?", roleType, userId).Get(r) | |||||
| if err != nil { | |||||
| return nil, err | |||||
| } else if !has { | |||||
| return nil, ErrRecordNotExist{} | |||||
| } | |||||
| return r, nil | |||||
| } | |||||
| func GetRoleByCode(code string) (*Role, error) { | |||||
| r := &Role{} | |||||
| has, err := x.Where("code = ?", code).Get(r) | |||||
| if err != nil { | |||||
| return nil, err | |||||
| } else if !has { | |||||
| return nil, ErrRecordNotExist{} | |||||
| } | |||||
| return r, nil | |||||
| } | |||||
| type ErrRoleNotExists struct { | |||||
| } | |||||
| func IsErrRoleNotExists(err error) bool { | |||||
| _, ok := err.(ErrRoleNotExists) | |||||
| return ok | |||||
| } | |||||
| func (err ErrRoleNotExists) Error() string { | |||||
| return fmt.Sprintf("role is not exists") | |||||
| } | |||||
| type AddRoleReq struct { | |||||
| UserName string `json:"user_name" binding:"Required"` | |||||
| RoleType RoleType `json:"role_type" binding:"Required"` | |||||
| } | |||||
| @@ -0,0 +1,23 @@ | |||||
| package admin | |||||
| import ( | |||||
| "code.gitea.io/gitea/models" | |||||
| "code.gitea.io/gitea/modules/context" | |||||
| "code.gitea.io/gitea/routers/response" | |||||
| "code.gitea.io/gitea/services/role" | |||||
| "net/http" | |||||
| ) | |||||
| func AddRole(ctx *context.APIContext, form models.AddRoleReq) { | |||||
| user, err := models.GetUserByName(form.UserName) | |||||
| if err != nil { | |||||
| ctx.JSON(http.StatusOK, response.ServerError("User not exists")) | |||||
| return | |||||
| } | |||||
| err = role.AddUserRole(user.ID, form.RoleType) | |||||
| if err != nil { | |||||
| ctx.JSON(http.StatusOK, response.ResponseError(err)) | |||||
| return | |||||
| } | |||||
| ctx.JSON(http.StatusOK, response.Success()) | |||||
| } | |||||
| @@ -59,6 +59,7 @@ | |||||
| package v1 | package v1 | ||||
| import ( | import ( | ||||
| "code.gitea.io/gitea/services/role" | |||||
| "net/http" | "net/http" | ||||
| "strings" | "strings" | ||||
| @@ -214,6 +215,16 @@ func reqSiteAdmin() macaron.Handler { | |||||
| } | } | ||||
| } | } | ||||
| // reqTechAdmin user should be the tech program admin | |||||
| func hasRole(roleType models.RoleType) macaron.Handler { | |||||
| return func(ctx *context.Context) { | |||||
| if !ctx.IsSigned || !role.UserHasRole(ctx.User.ID, roleType) { | |||||
| ctx.Error(http.StatusForbidden) | |||||
| return | |||||
| } | |||||
| } | |||||
| } | |||||
| // reqOwner user should be the owner of the repo or site admin. | // reqOwner user should be the owner of the repo or site admin. | ||||
| func reqOwner() macaron.Handler { | func reqOwner() macaron.Handler { | ||||
| return func(ctx *context.Context) { | return func(ctx *context.Context) { | ||||
| @@ -545,7 +556,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| m.Get("/repo_search", tech.SearchRepoInfo) | m.Get("/repo_search", tech.SearchRepoInfo) | ||||
| m.Post("/openi", bind(api.OpenITechRepo{}), tech.CommitOpenIRepo) | m.Post("/openi", bind(api.OpenITechRepo{}), tech.CommitOpenIRepo) | ||||
| m.Post("/no_openi", bind(api.NotOpenITechRepo{}), tech.CommitNotOpenIRepo) | m.Post("/no_openi", bind(api.NotOpenITechRepo{}), tech.CommitNotOpenIRepo) | ||||
| m.Get("/is_admin", tech.IsAdmin) | |||||
| }, reqToken()) | }, reqToken()) | ||||
| m.Group("/attachments", func() { | m.Group("/attachments", func() { | ||||
| @@ -1178,6 +1189,9 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| m.Post("/repos", bind(api.CreateRepoOption{}), admin.CreateRepo) | m.Post("/repos", bind(api.CreateRepoOption{}), admin.CreateRepo) | ||||
| }) | }) | ||||
| }) | }) | ||||
| m.Group("/role", func() { | |||||
| m.Post("", bind(models.AddRoleReq{}), admin.AddRole) | |||||
| }) | |||||
| }, reqToken(), reqSiteAdmin()) | }, reqToken(), reqSiteAdmin()) | ||||
| m.Group("/topics", func() { | m.Group("/topics", func() { | ||||
| @@ -2,6 +2,7 @@ package tech | |||||
| import ( | import ( | ||||
| "code.gitea.io/gitea/routers/response" | "code.gitea.io/gitea/routers/response" | ||||
| "code.gitea.io/gitea/services/role" | |||||
| techService "code.gitea.io/gitea/services/tech" | techService "code.gitea.io/gitea/services/tech" | ||||
| "net/http" | "net/http" | ||||
| "strconv" | "strconv" | ||||
| @@ -251,3 +252,16 @@ func FindTech(ctx *context.APIContext) { | |||||
| } | } | ||||
| ctx.JSON(http.StatusOK, response.OuterSuccessWithData(r)) | ctx.JSON(http.StatusOK, response.OuterSuccessWithData(r)) | ||||
| } | } | ||||
| func IsAdmin(ctx *context.APIContext) { | |||||
| userName := ctx.Query("user") | |||||
| user, err := models.GetUserByName(userName) | |||||
| if err != nil { | |||||
| ctx.JSON(http.StatusOK, response.ServerError("User not exists")) | |||||
| return | |||||
| } | |||||
| isAdmin := role.UserHasRole(user.ID, models.TechProgramAdmin) | |||||
| r := map[string]interface{}{} | |||||
| r["is_admin"] = isAdmin | |||||
| ctx.JSON(http.StatusOK, response.OuterSuccessWithData(r)) | |||||
| } | |||||
| @@ -0,0 +1,15 @@ | |||||
| package role | |||||
| import "code.gitea.io/gitea/models" | |||||
| var roleMap = map[models.RoleType]*models.Role{ | |||||
| models.TechProgramAdmin: { | |||||
| Type: models.TechProgramAdmin, | |||||
| Name: "科技项目管理员", | |||||
| Description: "拥有科技项目管理相关功能的管理员权限", | |||||
| }, | |||||
| } | |||||
| func GetRole(roleType models.RoleType) *models.Role { | |||||
| return roleMap[roleType] | |||||
| } | |||||
| @@ -0,0 +1,26 @@ | |||||
| package role | |||||
| import ( | |||||
| "code.gitea.io/gitea/models" | |||||
| ) | |||||
| func AddUserRole(userId int64, roleType models.RoleType) error { | |||||
| role := GetRole(roleType) | |||||
| if role == nil { | |||||
| return models.ErrRoleNotExists{} | |||||
| } | |||||
| _, err := models.NewUserRole(models.UserRole{UserId: userId, RoleType: roleType}) | |||||
| return err | |||||
| } | |||||
| func UserHasRole(userId int64, roleType models.RoleType) bool { | |||||
| role := GetRole(roleType) | |||||
| if role == nil { | |||||
| return false | |||||
| } | |||||
| _, err := models.GetUserRoleByUserAndRole(userId, roleType) | |||||
| if err != nil { | |||||
| return false | |||||
| } | |||||
| return true | |||||
| } | |||||