@@ -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 | |||||
} |