作者 yangfu

增加 rbac 服务

... ... @@ -2,6 +2,7 @@ package factory
import (
"github.com/linmadan/egglib-go/transaction/pg"
"github.com/tiptok/godevp/pkg/domain"
"github.com/tiptok/godevp/pkg/domain/role"
"github.com/tiptok/godevp/pkg/domain/users"
"github.com/tiptok/godevp/pkg/infrastructure/repository"
... ... @@ -22,3 +23,19 @@ func CreateRoleRepository(options map[string]interface{}) (role.RoleRepository,
}
return repository.NewRoleRepository(transactionContext)
}
func CreateAccessRepository(options map[string]interface{}) (domain.AccessRepository, error) {
var transactionContext *pg.TransactionContext
if value, ok := options["transactionContext"]; ok {
transactionContext = value.(*pg.TransactionContext)
}
return repository.NewAccessRepository(transactionContext)
}
func CreateRoleAccessRepository(options map[string]interface{}) (domain.RoleAccessRepository, error) {
var transactionContext *pg.TransactionContext
if value, ok := options["transactionContext"]; ok {
transactionContext = value.(*pg.TransactionContext)
}
return repository.NewRoleAccessRepository(transactionContext)
}
... ...
package command
import (
"fmt"
"github.com/astaxie/beego/validation"
)
type SetRoleAccessCommand struct {
// 角色id
RoleId int64 `json:"roleId,omitempty"`
// 权限编号列表
AccessIds []int64 `json:"accessIds,omitempty"`
}
func (setRoleAccessCommand *SetRoleAccessCommand) Valid(validation *validation.Validation) {
validation.SetError("CustomValid", "未实现的自定义认证")
}
func (setRoleAccessCommand *SetRoleAccessCommand) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(setRoleAccessCommand)
if err != nil {
return err
}
if !b {
for _, validErr := range valid.Errors {
return fmt.Errorf("%s %s", validErr.Key, validErr.Message)
}
}
return nil
}
... ...
package query
import (
"fmt"
"github.com/astaxie/beego/validation"
)
type AccessQuery struct {
}
func (accessQuery *AccessQuery) Valid(validation *validation.Validation) {
validation.SetError("CustomValid", "未实现的自定义认证")
}
func (accessQuery *AccessQuery) ValidateQuery() error {
valid := validation.Validation{}
b, err := valid.Valid(accessQuery)
if err != nil {
return err
}
if !b {
for _, validErr := range valid.Errors {
return fmt.Errorf("%s %s", validErr.Key, validErr.Message)
}
}
return nil
}
... ...
package query
import (
"fmt"
"github.com/astaxie/beego/validation"
)
type RoleAccessQuery struct {
// 角色id
RoleId int64 `json:"roleId" valid:"Required"`
}
func (roleAccessQuery *RoleAccessQuery) Valid(validation *validation.Validation) {
validation.SetError("CustomValid", "未实现的自定义认证")
}
func (roleAccessQuery *RoleAccessQuery) ValidateQuery() error {
valid := validation.Validation{}
b, err := valid.Valid(roleAccessQuery)
if err != nil {
return err
}
if !b {
for _, validErr := range valid.Errors {
return fmt.Errorf("%s %s", validErr.Key, validErr.Message)
}
}
return nil
}
... ...
package service
import (
"github.com/linmadan/egglib-go/core/application"
"github.com/linmadan/egglib-go/transaction/pg"
"github.com/tiptok/godevp/pkg/application/factory"
"github.com/tiptok/godevp/pkg/application/rbac/command"
"github.com/tiptok/godevp/pkg/application/rbac/query"
"github.com/tiptok/godevp/pkg/domain"
role2 "github.com/tiptok/godevp/pkg/domain/role"
"github.com/tiptok/godevp/pkg/infrastructure/dao"
)
// 权限服务
type RbacService struct {
}
// 获取菜单列表
func (rbacService *RbacService) Access(accessQuery *query.AccessQuery) (interface{}, error) {
if err := accessQuery.ValidateQuery(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
transactionContext, err := factory.CreateTransactionContext(nil)
if err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
if err := transactionContext.StartTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
defer func() {
transactionContext.RollbackTransaction()
}()
var AccessRepository, _ = factory.CreateAccessRepository(map[string]interface{}{"transactionContext": transactionContext})
var access []*domain.Access
if _, access, err = AccessRepository.Find(map[string]interface{}{"sortByParentId": "ASC", "sortBySort": "ASC"}); err != nil {
return nil, err
}
var rspList []interface{}
for _, item := range access {
rspList = append(rspList, map[string]interface{}{
"id": item.Id,
"name": item.AccessName,
"icon": "",
"parentId": item.ParentId,
"sort": item.Sort,
"code": item.AccessCode,
})
}
rsp := map[string]interface{}{
"lists": rspList,
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return rsp, nil
}
// 角色权限
func (rbacService *RbacService) RoleAccess(roleAccessQuery *query.RoleAccessQuery) (interface{}, error) {
if err := roleAccessQuery.ValidateQuery(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
transactionContext, err := factory.CreateTransactionContext(nil)
if err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
if err := transactionContext.StartTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
defer func() {
transactionContext.RollbackTransaction()
}()
RoleAccessDao, _ := dao.NewRoleAccessDao(transactionContext.(*pg.TransactionContext))
RoleRepository, _ := factory.CreateRoleRepository(map[string]interface{}{"transactionContext": transactionContext})
var role *role2.Role
if role, err = RoleRepository.FindOne(map[string]interface{}{"id": roleAccessQuery.RoleId}); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, "角色不存在")
}
accessIds, _ := RoleAccessDao.GetRoleAccess(roleAccessQuery.RoleId)
rsp := map[string]interface{}{
"roleId": role.Id,
"roleName": role.RoleName,
"accessIds": accessIds,
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return rsp, nil
}
// 设置角色权限
func (rbacService *RbacService) SetRoleAccess(setRoleAccessCommand *command.SetRoleAccessCommand) (interface{}, error) {
if err := setRoleAccessCommand.ValidateCommand(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
transactionContext, err := factory.CreateTransactionContext(nil)
if err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
if err := transactionContext.StartTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
defer func() {
transactionContext.RollbackTransaction()
}()
AccessRepository, _ := factory.CreateAccessRepository(map[string]interface{}{"transactionContext": transactionContext})
RoleRepository, _ := factory.CreateRoleRepository(map[string]interface{}{"transactionContext": transactionContext})
RoleAccessDao, _ := dao.NewRoleAccessDao(transactionContext.(*pg.TransactionContext))
if _, err = RoleRepository.FindOne(map[string]interface{}{"id": setRoleAccessCommand.RoleId}); err != nil {
return nil, application.ThrowError(application.RES_NO_FIND_ERROR, "角色不存在")
}
var accessMap = make(map[int64]*domain.Access)
_, access, _ := AccessRepository.Find(map[string]interface{}{"inAccessIds": setRoleAccessCommand.AccessIds})
for _, v := range access {
accessMap[v.Id] = v
}
if err = RoleAccessDao.DeleteRoleAccess(setRoleAccessCommand.RoleId); err != nil {
return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
}
if len(setRoleAccessCommand.AccessIds) > 0 {
var roleAccess []*domain.RoleAccess
for _, v := range setRoleAccessCommand.AccessIds {
item := &domain.RoleAccess{
RoleId: setRoleAccessCommand.RoleId,
AccessId: v,
}
if accessItem, ok := accessMap[v]; ok {
item.Object = accessItem.Object
item.Action = accessItem.Action
item.Option = accessItem.AccessCode
}
roleAccess = append(roleAccess, item)
}
if err = RoleAccessDao.SaveRoleAccess(roleAccess); err != nil {
return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
}
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return nil, nil
}
func NewRbacService(options map[string]interface{}) *RbacService {
newRbacService := &RbacService{}
return newRbacService
}
... ...
package domain
// 权限
type Access struct {
// dcc
Id int64 `json:"id"`
// 父级Id
ParentId int64 `json:"parentId"`
// 权限名称
AccessName string `json:"accessName"`
// 权限名称
AccessCode string `json:"accessCode"`
// 权限类型 menu button data
AccessType string `json:"accessType"`
// 排序
Sort int `json:"sort"`
// 请求对象 接口地址/对象
Object string `json:"object"`
// 操作方法 httpMethod/read/write
Action string `json:"action"`
// 所属功能模块
Module string `json:"module"`
// 图标
Icon string `json:"icon"`
// 状态 1-启用 0-禁用
Status int `json:"status"`
}
type AccessRepository interface {
Save(access *Access) (*Access, error)
Remove(access *Access) (*Access, error)
FindOne(queryOptions map[string]interface{}) (*Access, error)
Find(queryOptions map[string]interface{}) (int64, []*Access, error)
}
func (access *Access) Identify() interface{} {
if access.Id == 0 {
return nil
}
return access.Id
}
func (access *Access) Update(data map[string]interface{}) error {
if ParentId, ok := data["ParentId"]; ok {
access.ParentId = ParentId.(int64)
}
if AccessName, ok := data["AccessName"]; ok {
access.AccessName = AccessName.(string)
}
if AccessCode, ok := data["AccessCode"]; ok {
access.AccessCode = AccessCode.(string)
}
if AccessType, ok := data["AccessType"]; ok {
access.AccessType = AccessType.(string)
}
if Sort, ok := data["Sort"]; ok {
access.Sort = Sort.(int)
}
if Object, ok := data["Object"]; ok {
access.Object = Object.(string)
}
if Action, ok := data["Action"]; ok {
access.Action = Action.(string)
}
if Module, ok := data["Module"]; ok {
access.Module = Module.(string)
}
if Icon, ok := data["Icon"]; ok {
access.Icon = Icon.(string)
}
if Status, ok := data["Status"]; ok {
access.Status = Status.(int)
}
return nil
}
... ...
package domain
// 角色权限
type RoleAccess struct {
// dcc
Id int64 `json:"id"`
// 角色id
RoleId int64 `json:"roleId"`
// 权限编号
AccessId int64 `json:"accessId"`
// 请求对象 接口地址/对象
Object string `json:"object"`
// 操作方法 httpMethod/read/write
Action string `json:"action"`
// 可选对象
Option string `json:"option"`
}
type RoleAccessRepository interface {
Save(roleAccess *RoleAccess) (*RoleAccess, error)
Remove(roleAccess *RoleAccess) (*RoleAccess, error)
FindOne(queryOptions map[string]interface{}) (*RoleAccess, error)
Find(queryOptions map[string]interface{}) (int64, []*RoleAccess, error)
}
func (roleAccess *RoleAccess) Identify() interface{} {
if roleAccess.Id == 0 {
return nil
}
return roleAccess.Id
}
func (roleAccess *RoleAccess) Update(data map[string]interface{}) error {
if RoleId, ok := data["RoleId"]; ok {
roleAccess.RoleId = RoleId.(int64)
}
if AccessId, ok := data["AccessId"]; ok {
roleAccess.AccessId = AccessId.(int64)
}
if Object, ok := data["Object"]; ok {
roleAccess.Object = Object.(string)
}
if Action, ok := data["Action"]; ok {
roleAccess.Action = Action.(string)
}
if Option, ok := data["Option"]; ok {
roleAccess.Option = Option.(string)
}
return nil
}
... ...
package dao
import (
"fmt"
"github.com/go-pg/pg/v10"
pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
"github.com/tiptok/gocomm/common"
"github.com/tiptok/godevp/pkg/domain"
"github.com/tiptok/godevp/pkg/infrastructure/pg/models"
)
type RoleAccessDao struct {
transactionContext *pgTransaction.TransactionContext
}
func (dao *RoleAccessDao) DeleteRoleAccess(roleId int64) error {
tx := dao.transactionContext.PgTx
q := tx.Model(new(models.RoleAccess))
q.Where("role_id=?", roleId)
_, err := q.Delete()
return err
}
func (dao *RoleAccessDao) GetRoleAccess(roleId ...int64) ([]int64, error) {
if len(roleId) == 0 {
return []int64{}, nil
}
tx := dao.transactionContext.PgDd
q := tx.Model(new(models.RoleAccess))
q.Column("access_id")
if len(roleId) == 1 {
q.Where("role_id=?", roleId[0])
} else {
q.Where("role_id in (?)", pg.In(roleId))
}
var accessIds []int64
err := q.Distinct().Select(&accessIds)
return accessIds, err
}
func (dao *RoleAccessDao) SaveRoleAccess(roleAccess []*domain.RoleAccess) error {
if len(roleAccess) == 0 {
return nil
}
tx := dao.transactionContext.PgTx
var modelsRoleAccess []*models.RoleAccess
for i := range roleAccess {
var item *models.RoleAccess
common.GobModelTransform(&item, roleAccess[i])
if item == nil {
continue
}
modelsRoleAccess = append(modelsRoleAccess, item)
}
_, err := tx.Model(&modelsRoleAccess).Insert()
return err
}
func NewRoleAccessDao(transactionContext *pgTransaction.TransactionContext) (*RoleAccessDao, error) {
if transactionContext == nil {
return nil, fmt.Errorf("transactionContext参数不能为nil")
} else {
return &RoleAccessDao{
transactionContext: transactionContext,
}, nil
}
}
... ...
package models
type Access struct {
TableName string `pg:"access,alias:access"`
// dcc
Id int64
// 父级Id
ParentId int64
// 权限名称
AccessName string
// 权限名称
AccessCode string
// 权限类型 menu button data
AccessType string
// 排序
Sort int
// 请求对象 接口地址/对象
Object string
// 操作方法 httpMethod/read/write
Action string
// 所属功能模块
Module string
// 图标
Icon string
// 状态 1-启用 0-禁用
Status int
}
... ...
package models
type RoleAccess struct {
TableName string `pg:"role_access,alias:role_access"`
// dcc
Id int64
// 角色id
RoleId int64
// 权限编号
AccessId int64
// 请求对象 接口地址/对象
Object string
// 操作方法 httpMethod/read/write
Action string
// 可选对象
Option string
}
... ...
package repository
import (
"fmt"
"github.com/go-pg/pg/v10"
pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
"github.com/tiptok/godevp/pkg/domain"
"github.com/tiptok/godevp/pkg/infrastructure/pg/models"
)
type AccessRepository struct {
transactionContext *pgTransaction.TransactionContext
}
func (repository *AccessRepository) nextIdentify() (int64, error) {
return 0, nil
}
func (repository *AccessRepository) Save(access *domain.Access) (*domain.Access, error) {
tx := repository.transactionContext.PgTx
if access.Identify() == nil {
_, err := repository.nextIdentify()
if err != nil {
return access, err
}
if _, err := tx.QueryOne(
pg.Scan(&access.Id, &access.ParentId, &access.AccessName, &access.AccessCode, &access.AccessType, &access.Sort, &access.Object, &access.Action, &access.Module, &access.Icon, &access.Status),
"INSERT INTO access (id, parent_id, access_name, access_code, access_type, sort, object, action, module, icon, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING id, parent_id, access_name, access_code, access_type, sort, object, action, module, icon, status",
access.Id, access.ParentId, access.AccessName, access.AccessCode, access.AccessType, access.Sort, access.Object, access.Action, access.Module, access.Icon, access.Status); err != nil {
return access, err
}
} else {
if _, err := tx.QueryOne(
pg.Scan(&access.Id, &access.ParentId, &access.AccessName, &access.AccessCode, &access.AccessType, &access.Sort, &access.Object, &access.Action, &access.Module, &access.Icon, &access.Status),
"UPDATE access SET id=?, parent_id=?, access_name=?, access_code=?, access_type=?, sort=?, object=?, action=?, module=?, icon=?, status=? WHERE id=? RETURNING id, parent_id, access_name, access_code, access_type, sort, object, action, module, icon, status",
access.Id, access.ParentId, access.AccessName, access.AccessCode, access.AccessType, access.Sort, access.Object, access.Action, access.Module, access.Icon, access.Status, access.Identify()); err != nil {
return access, err
}
}
return access, nil
}
func (repository *AccessRepository) Remove(access *domain.Access) (*domain.Access, error) {
tx := repository.transactionContext.PgTx
accessModel := new(models.Access)
accessModel.Id = access.Identify().(int64)
if _, err := tx.Model(accessModel).WherePK().Delete(); err != nil {
return access, err
}
return access, nil
}
func (repository *AccessRepository) FindOne(queryOptions map[string]interface{}) (*domain.Access, error) {
tx := repository.transactionContext.PgTx
accessModel := new(models.Access)
query := tx.Model(accessModel)
if accessId, ok := queryOptions["id"]; ok {
query = query.Where("access.id = ?", accessId)
}
if err := query.First(); err != nil {
if err.Error() == "pg: no rows in result set" {
return nil, fmt.Errorf("没有此资源")
} else {
return nil, err
}
}
if accessModel.Id == 0 {
return nil, nil
} else {
return repository.transformPgModelToDomainModel(accessModel)
}
}
func (repository *AccessRepository) Find(queryOptions map[string]interface{}) (int64, []*domain.Access, error) {
tx := repository.transactionContext.PgTx
var accessModels []*models.Access
accesss := make([]*domain.Access, 0)
query := tx.Model(&accessModels)
if offset, ok := queryOptions["offset"]; ok {
offset := offset.(int)
if offset > -1 {
query = query.Offset(offset)
}
} else {
query = query.Offset(0)
}
if limit, ok := queryOptions["limit"]; ok {
limit := limit.(int)
if limit > -1 {
query = query.Limit(limit)
}
} else {
query = query.Limit(20)
}
if inAccessIds, ok := queryOptions["inAccessIds"]; ok {
query.Where("id in (?)", pg.In(inAccessIds))
}
if sortByParentId, ok := queryOptions["sortByParentId"]; ok {
query.Order(fmt.Sprintf("%v %v", "parent_id", sortByParentId))
}
if sortBySort, ok := queryOptions["sortBySort"]; ok {
query.Order(fmt.Sprintf("%v %v", "sort", sortBySort))
}
if count, err := query.Order("id DESC").SelectAndCount(); err != nil {
return 0, accesss, err
} else {
for _, accessModel := range accessModels {
if access, err := repository.transformPgModelToDomainModel(accessModel); err != nil {
return 0, accesss, err
} else {
accesss = append(accesss, access)
}
}
return int64(count), accesss, nil
}
}
func (repository *AccessRepository) transformPgModelToDomainModel(accessModel *models.Access) (*domain.Access, error) {
return &domain.Access{
Id: accessModel.Id,
ParentId: accessModel.ParentId,
AccessName: accessModel.AccessName,
AccessCode: accessModel.AccessCode,
AccessType: accessModel.AccessType,
Sort: accessModel.Sort,
Object: accessModel.Object,
Action: accessModel.Action,
Module: accessModel.Module,
Icon: accessModel.Icon,
Status: accessModel.Status,
}, nil
}
func NewAccessRepository(transactionContext *pgTransaction.TransactionContext) (*AccessRepository, error) {
if transactionContext == nil {
return nil, fmt.Errorf("transactionContext参数不能为nil")
} else {
return &AccessRepository{
transactionContext: transactionContext,
}, nil
}
}
... ...
package repository
import (
"fmt"
"github.com/go-pg/pg/v10"
pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
"github.com/tiptok/godevp/pkg/domain"
"github.com/tiptok/godevp/pkg/infrastructure/pg/models"
)
type RoleAccessRepository struct {
transactionContext *pgTransaction.TransactionContext
}
func (repository *RoleAccessRepository) nextIdentify() (int64, error) {
return 0, nil
}
func (repository *RoleAccessRepository) Save(roleAccess *domain.RoleAccess) (*domain.RoleAccess, error) {
tx := repository.transactionContext.PgTx
if roleAccess.Identify() == nil {
_, err := repository.nextIdentify()
if err != nil {
return roleAccess, err
}
if _, err := tx.QueryOne(
pg.Scan(&roleAccess.Id, &roleAccess.RoleId, &roleAccess.AccessId, &roleAccess.Object, &roleAccess.Action, &roleAccess.Option),
"INSERT INTO role_access (id, role_id, access_id, object, action, option) VALUES (?, ?, ?, ?, ?, ?) RETURNING id, role_id, access_id, object, action, option",
roleAccess.Id, roleAccess.RoleId, roleAccess.AccessId, roleAccess.Object, roleAccess.Action, roleAccess.Option); err != nil {
return roleAccess, err
}
} else {
if _, err := tx.QueryOne(
pg.Scan(&roleAccess.Id, &roleAccess.RoleId, &roleAccess.AccessId, &roleAccess.Object, &roleAccess.Action, &roleAccess.Option),
"UPDATE role_access SET id=?, role_id=?, access_id=?, object=?, action=?, option=? WHERE id=? RETURNING id, role_id, access_id, object, action, option",
roleAccess.Id, roleAccess.RoleId, roleAccess.AccessId, roleAccess.Object, roleAccess.Action, roleAccess.Option, roleAccess.Identify()); err != nil {
return roleAccess, err
}
}
return roleAccess, nil
}
func (repository *RoleAccessRepository) Remove(roleAccess *domain.RoleAccess) (*domain.RoleAccess, error) {
tx := repository.transactionContext.PgTx
roleAccessModel := new(models.RoleAccess)
roleAccessModel.Id = roleAccess.Identify().(int64)
if _, err := tx.Model(roleAccessModel).WherePK().Delete(); err != nil {
return roleAccess, err
}
return roleAccess, nil
}
func (repository *RoleAccessRepository) FindOne(queryOptions map[string]interface{}) (*domain.RoleAccess, error) {
tx := repository.transactionContext.PgTx
roleAccessModel := new(models.RoleAccess)
query := tx.Model(roleAccessModel)
if roleAccessId, ok := queryOptions["id"]; ok {
query = query.Where("role_access.id = ?", roleAccessId)
}
if err := query.First(); err != nil {
if err.Error() == "pg: no rows in result set" {
return nil, fmt.Errorf("没有此资源")
} else {
return nil, err
}
}
if roleAccessModel.Id == 0 {
return nil, nil
} else {
return repository.transformPgModelToDomainModel(roleAccessModel)
}
}
func (repository *RoleAccessRepository) Find(queryOptions map[string]interface{}) (int64, []*domain.RoleAccess, error) {
tx := repository.transactionContext.PgTx
var roleAccessModels []*models.RoleAccess
roleAccesss := make([]*domain.RoleAccess, 0)
query := tx.Model(&roleAccessModels)
if roleId, ok := queryOptions["roleId"]; ok {
query = query.Where("role_id = ?", roleId)
}
if offset, ok := queryOptions["offset"]; ok {
offset := offset.(int)
if offset > -1 {
query = query.Offset(offset)
}
} else {
query = query.Offset(0)
}
if limit, ok := queryOptions["limit"]; ok {
limit := limit.(int)
if limit > -1 {
query = query.Limit(limit)
}
} else {
query = query.Limit(20)
}
if count, err := query.Order("id DESC").SelectAndCount(); err != nil {
return 0, roleAccesss, err
} else {
for _, roleAccessModel := range roleAccessModels {
if roleAccess, err := repository.transformPgModelToDomainModel(roleAccessModel); err != nil {
return 0, roleAccesss, err
} else {
roleAccesss = append(roleAccesss, roleAccess)
}
}
return int64(count), roleAccesss, nil
}
}
func (repository *RoleAccessRepository) transformPgModelToDomainModel(roleAccessModel *models.RoleAccess) (*domain.RoleAccess, error) {
return &domain.RoleAccess{
Id: roleAccessModel.Id,
RoleId: roleAccessModel.RoleId,
AccessId: roleAccessModel.AccessId,
Object: roleAccessModel.Object,
Action: roleAccessModel.Action,
Option: roleAccessModel.Option,
}, nil
}
func NewRoleAccessRepository(transactionContext *pgTransaction.TransactionContext) (*RoleAccessRepository, error) {
if transactionContext == nil {
return nil, fmt.Errorf("transactionContext参数不能为nil")
} else {
return &RoleAccessRepository{
transactionContext: transactionContext,
}, nil
}
}
... ...
package controllers
import (
"encoding/json"
"github.com/astaxie/beego"
"github.com/linmadan/egglib-go/web/beego/utils"
"github.com/tiptok/godevp/pkg/application/rbac/command"
"github.com/tiptok/godevp/pkg/application/rbac/query"
"github.com/tiptok/godevp/pkg/application/rbac/service"
)
type RbacController struct {
beego.Controller
}
func (controller *RbacController) Access() {
rbacService := service.NewRbacService(nil)
accessQuery := &query.AccessQuery{}
data, err := rbacService.Access(accessQuery)
var response utils.JsonResponse
if err != nil {
response = utils.ResponseError(controller.Ctx, err)
} else {
response = utils.ResponseData(controller.Ctx, data)
}
controller.Data["json"] = response
controller.ServeJSON()
}
func (controller *RbacController) RoleAccess() {
rbacService := service.NewRbacService(nil)
roleAccessQuery := &query.RoleAccessQuery{}
roleId, _ := controller.GetInt64(":roleId")
roleAccessQuery.RoleId = roleId
data, err := rbacService.RoleAccess(roleAccessQuery)
var response utils.JsonResponse
if err != nil {
response = utils.ResponseError(controller.Ctx, err)
} else {
response = utils.ResponseData(controller.Ctx, data)
}
controller.Data["json"] = response
controller.ServeJSON()
}
func (controller *RbacController) SetRoleAccess() {
rbacService := service.NewRbacService(nil)
setRoleAccessCommand := &command.SetRoleAccessCommand{}
json.Unmarshal(controller.Ctx.Input.GetData("requestBody").([]byte), setRoleAccessCommand)
data, err := rbacService.SetRoleAccess(setRoleAccessCommand)
var response utils.JsonResponse
if err != nil {
response = utils.ResponseError(controller.Ctx, err)
} else {
response = utils.ResponseData(controller.Ctx, data)
}
controller.Data["json"] = response
controller.ServeJSON()
}
... ...
package routers
import (
"github.com/astaxie/beego"
"github.com/tiptok/godevp/pkg/port/beego/controllers"
)
func init() {
beego.Router("/rbacs/access", &controllers.RbacController{}, "Get:Access")
beego.Router("/rbacs/roleAccess/:roleId", &controllers.RbacController{}, "Get:RoleAccess")
beego.Router("/rbacs/setRoleAccess", &controllers.RbacController{}, "Post:SetRoleAccess")
}
... ...
package model
import (
"github.com/tiptok/gocomm/common"
domain "github.com/tiptok/godevp/pkg/domain/users"
"testing"
"time"
"unsafe"
)
func TestUsers(t *testing.T) {
var u = &Users{}
var user = &domain.Users{
Name: "tiptok",
Phone: "1886018",
Roles: []int64{7, 8},
Status: 1,
CreateTime: time.Now(),
}
// 方法一:直接赋值
u.Name = &(user.Name)
// 方法二:使用unsafe.Pointer
u.Status = (*int)(unsafe.Pointer(&user.Status))
// 方法三: json-transfer
common.JsonUnmarshal(common.JsonAssertString(user), u)
if *(u.Name) != "tiptok" {
}
}
... ...
package rbac
import (
"net/http"
"github.com/gavv/httpexpect"
"github.com/go-pg/pg"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
pG "github.com/tiptok/godevp/pkg/infrastructure/pg"
)
var _ = Describe("获取菜单列表", func() {
var Id int64
BeforeEach(func() {
_, err := pG.DB.QueryOne(
pg.Scan(&Id),
"INSERT INTO s () VALUES () RETURNING id",
)
Expect(err).NotTo(HaveOccurred())
})
Describe("获取菜单列表", func() {
Context("", func() {
It("", func() {
httpExpect := httpexpect.New(GinkgoT(), server.URL)
httpExpect.GET("/rbacs/access").
Expect().
Status(http.StatusOK).
JSON().
Object().
ContainsKey("code").ValueEqual("code", 0).
ContainsKey("msg").ValueEqual("msg", "ok").
ContainsKey("data").Value("data").Object()
})
})
})
AfterEach(func() {
_, err := pG.DB.Exec("DELETE FROM s WHERE true")
Expect(err).NotTo(HaveOccurred())
})
})
... ...
package rbac
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/astaxie/beego"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
_ "github.com/tiptok/godevp/pkg/infrastructure/pg"
_ "github.com/tiptok/godevp/pkg/port/beego"
)
func TestRbac(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Beego Port Rbac Correlations Test Case Suite")
}
var handler http.Handler
var server *httptest.Server
var _ = BeforeSuite(func() {
handler = beego.BeeApp.Handlers
server = httptest.NewServer(handler)
})
var _ = AfterSuite(func() {
server.Close()
})
... ...
package rbac
import (
"net/http"
"github.com/gavv/httpexpect"
"github.com/go-pg/pg"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
pG "github.com/tiptok/godevp/pkg/infrastructure/pg"
)
var _ = Describe("角色权限", func() {
var Id int64
BeforeEach(func() {
_, err := pG.DB.QueryOne(
pg.Scan(&Id),
"INSERT INTO s () VALUES () RETURNING id",
)
Expect(err).NotTo(HaveOccurred())
})
Describe("角色权限", func() {
Context("", func() {
It("", func() {
httpExpect := httpexpect.New(GinkgoT(), server.URL)
httpExpect.GET("/rbacs/roleAccess/{roleId}").
Expect().
Status(http.StatusOK).
JSON().
Object().
ContainsKey("code").ValueEqual("code", 0).
ContainsKey("msg").ValueEqual("msg", "ok").
ContainsKey("data").Value("data").Object()
})
})
})
AfterEach(func() {
_, err := pG.DB.Exec("DELETE FROM s WHERE true")
Expect(err).NotTo(HaveOccurred())
})
})
... ...
package rbac
import (
"net/http"
"github.com/gavv/httpexpect"
"github.com/go-pg/pg"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
pG "github.com/tiptok/godevp/pkg/infrastructure/pg"
)
var _ = Describe("设置角色权限", func() {
var Id int64
BeforeEach(func() {
_, err := pG.DB.QueryOne(
pg.Scan(&Id),
"INSERT INTO s () VALUES () RETURNING id",
)
Expect(err).NotTo(HaveOccurred())
})
Describe("设置角色权限", func() {
Context("", func() {
It("", func() {
httpExpect := httpexpect.New(GinkgoT(), server.URL)
body := map[string]interface{}{
"roleId": "int64",
"accessIds": "array",
}
httpExpect.POST("/rbacs/setRoleAccess").
WithJSON(body).
Expect().
Status(http.StatusOK).
JSON().
Object().
ContainsKey("code").ValueEqual("code", 0).
ContainsKey("msg").ValueEqual("msg", "ok").
ContainsKey("data").Value("data").Object()
})
})
})
AfterEach(func() {
_, err := pG.DB.Exec("DELETE FROM s WHERE true")
Expect(err).NotTo(HaveOccurred())
})
})
... ...