| @@ -169,6 +169,7 @@ func init() { | |||
| new(BadgeUserLog), | |||
| new(TechConvergeBaseInfo), | |||
| new(RepoConvergeInfo), | |||
| new(UserRole), | |||
| ) | |||
| 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 | |||
| import ( | |||
| "code.gitea.io/gitea/services/role" | |||
| "net/http" | |||
| "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. | |||
| func reqOwner() macaron.Handler { | |||
| return func(ctx *context.Context) { | |||
| @@ -545,7 +556,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| m.Get("/repo_search", tech.SearchRepoInfo) | |||
| m.Post("/openi", bind(api.OpenITechRepo{}), tech.CommitOpenIRepo) | |||
| m.Post("/no_openi", bind(api.NotOpenITechRepo{}), tech.CommitNotOpenIRepo) | |||
| m.Get("/is_admin", tech.IsAdmin) | |||
| }, reqToken()) | |||
| m.Group("/attachments", func() { | |||
| @@ -1178,6 +1189,9 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| m.Post("/repos", bind(api.CreateRepoOption{}), admin.CreateRepo) | |||
| }) | |||
| }) | |||
| m.Group("/role", func() { | |||
| m.Post("", bind(models.AddRoleReq{}), admin.AddRole) | |||
| }) | |||
| }, reqToken(), reqSiteAdmin()) | |||
| m.Group("/topics", func() { | |||
| @@ -2,6 +2,7 @@ package tech | |||
| import ( | |||
| "code.gitea.io/gitea/routers/response" | |||
| "code.gitea.io/gitea/services/role" | |||
| techService "code.gitea.io/gitea/services/tech" | |||
| "net/http" | |||
| "strconv" | |||
| @@ -251,3 +252,16 @@ func FindTech(ctx *context.APIContext) { | |||
| } | |||
| 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 | |||
| } | |||