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