作者 yangfu

1.增加user access 校验

... ... @@ -6,6 +6,7 @@ require (
github.com/astaxie/beego v1.12.2
github.com/go-pg/pg/v10 v10.0.0-beta.2
github.com/tiptok/gocomm v1.0.2
github.com/GeeTeam/gt3-golang-sdk v0.0.0-20200116043922-446ca8a507d2
)
replace github.com/tiptok/gocomm v1.0.2 => F:\go\src\learn_project\gocomm
... ...
... ... @@ -4,6 +4,7 @@ import (
"github.com/astaxie/beego"
_ "gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/constant"
_ "gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/infrastructure/pg"
_ "gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/infrastructure/redis"
_ "gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/port/beego"
)
... ...
package auth
import (
"encoding/json"
"fmt"
"github.com/GeeTeam/gt3-golang-sdk/geetest"
"github.com/tiptok/gocomm/common"
"github.com/tiptok/gocomm/pkg/cache"
"github.com/tiptok/gocomm/pkg/log"
"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/application/cachex"
"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/application/factory"
"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/domain"
"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/infrastructure/dao"
"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/protocol"
protocolx "gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/protocol/auth"
"time"
)
type AuthService struct {
... ... @@ -44,6 +50,8 @@ func (svr *AuthService) Login(header *protocol.RequestHeader, request *protocolx
"accessToken": "Bearer " + token,
"expiresIn": domain.TokenExpire,
}
cache.Delete(cachex.UserRoleAccessCacheKey(user.Id))
err = transactionContext.CommitTransaction()
return
}
... ... @@ -68,13 +76,18 @@ func (svr *AuthService) Logout(header *protocol.RequestHeader, request *protocol
return
}
func (svr *AuthService) Profile(header *protocol.RequestHeader, request *protocolx.ProfileRequest) (rsp *protocolx.ProfileResponse, err error) {
func (svr *AuthService) Profile(header *protocol.RequestHeader, request *protocolx.ProfileRequest) (rsp interface{}, err error) {
var (
transactionContext, _ = factory.CreateTransactionContext(nil)
UserRepository, _ = factory.CreateUserRepository(transactionContext)
RoleRepository, _ = factory.CreateRoleRepository(transactionContext)
RoleAccessDao, _ = dao.NewRoleAccessDao(transactionContext)
AccessRepository, _ = factory.CreateAccessRepository(transactionContext)
)
rsp = &protocolx.ProfileResponse{}
if err = request.ValidateCommand(); err != nil {
err = protocol.NewCustomMessage(2, err.Error())
return
}
if err = transactionContext.StartTransaction(); err != nil {
log.Error(err)
... ... @@ -84,17 +97,43 @@ func (svr *AuthService) Profile(header *protocol.RequestHeader, request *protoco
transactionContext.RollbackTransaction()
}()
var user *domain.User
if user, err = UserRepository.FindOne(map[string]interface{}{"id": request.UserId}); err != nil {
err = protocol.NewCustomMessage(1, "用户不存在")
return
}
_, roles, _ := RoleRepository.Find(map[string]interface{}{"inRoleIds": user.Roles})
rspMap := map[string]interface{}{
"menus": struct{}{},
}
rspMap["user"] = map[string]interface{}{
"name": user.Name,
"id": user.Id,
"phone": user.Phone,
"address": user.Address,
"isAdmin": user.IsAdmin,
"roles": roles,
}
accessIds, _ := RoleAccessDao.GetRoleAccess(user.Roles...)
if len(accessIds) > 0 {
_, accesses, _ := AccessRepository.Find(map[string]interface{}{"inAccessIds": accessIds})
rspMap["menus"] = accesses
}
rsp = rspMap
err = transactionContext.CommitTransaction()
return
}
func (svr *AuthService) CaptchaInit(header *protocol.RequestHeader, request *protocolx.CaptchaInitRequest) (rsp *protocolx.CaptchaInitResponse, err error) {
func (svr *AuthService) CaptchaInit(header *protocol.RequestHeader, request *protocolx.CaptchaInitRequest) (rsp interface{}, err error) {
var (
transactionContext, _ = factory.CreateTransactionContext(nil)
)
rsp = &protocolx.CaptchaInitResponse{}
if err = request.ValidateCommand(); err != nil {
err = protocol.NewCustomMessage(2, err.Error())
return
}
if err = transactionContext.StartTransaction(); err != nil {
log.Error(err)
... ... @@ -104,6 +143,21 @@ func (svr *AuthService) CaptchaInit(header *protocol.RequestHeader, request *pro
transactionContext.RollbackTransaction()
}()
const (
captchaID = "33a2abf9c5df0d6bc3b89fb39280114b"
privateKey = "13320fd2b10199e9a2440a4fbb4d46f7"
)
newGeetest := geetest.NewGeetestLib(captchaID, privateKey, 2*time.Second)
_, responseBt := newGeetest.PreProcess("", request.UserIp)
var geetestRsp geetest.FailbackRegisterRespnse
json.Unmarshal(responseBt, &geetestRsp)
rspData := map[string]interface{}{
"success": geetestRsp.Success,
"gt": geetestRsp.GT,
"challenge": geetestRsp.Challenge,
"newCaptcha": geetestRsp.NewCaptcha,
}
rsp = rspData
err = transactionContext.CommitTransaction()
return
}
... ...
package cachex
import (
"fmt"
"github.com/tiptok/gocomm/pkg/cache"
"github.com/tiptok/gocomm/pkg/log"
"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/application/factory"
"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/domain"
"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/infrastructure/dao"
"regexp"
"strings"
)
//redis key
func UserRoleAccessCacheKey(userId int64) string {
return fmt.Sprintf("godevp:user:access:%v", userId)
}
type CacheService struct {
}
func (svr *CacheService) CacheUserAccess(userId int64) func() (interface{}, error) {
return func() (interface{}, error) {
var (
transactionContext, _ = factory.CreateTransactionContext(nil)
UserRepository, _ = factory.CreateUserRepository(transactionContext)
RoleAccessDao, _ = dao.NewRoleAccessDao(transactionContext)
AccessRepository, _ = factory.CreateAccessRepository(transactionContext)
err error
)
if err = transactionContext.StartTransaction(); err != nil {
log.Error(err)
return nil, err
}
defer func() {
transactionContext.RollbackTransaction()
}()
var user *domain.User
if user, err = UserRepository.FindOne(map[string]interface{}{"id": userId}); err != nil {
return []*domain.Access{}, nil
}
accessIds, _ := RoleAccessDao.GetRoleAccess(user.Roles...)
if len(accessIds) == 0 {
return []*domain.Access{}, nil
}
_, accesses, _ := AccessRepository.Find(map[string]interface{}{"inAccessIds": accessIds})
err = transactionContext.CommitTransaction()
return accesses, nil
}
}
func (svr *CacheService) ValidUserAccess(userId int64, object string, method string) (result bool, err error) {
var userAccess []*domain.Access
defer func() {
log.Info(fmt.Sprintf("ValidUserAccess user:%v object:%v method:%v result:%v", userId, object, method, result))
}()
cache.GetObject(UserRoleAccessCacheKey(userId), &userAccess, 3600, svr.CacheUserAccess(userId))
for i := range userAccess {
if KeyMatch3(object, userAccess[i].Object) && KeyEqual(userAccess[i].Action, method) {
result = true
return
}
}
return
}
// KeyMatch3 determines whether key1 matches the pattern of key2 (similar to RESTful path), key2 can contain a *.
// For example, "/foo/bar" matches "/foo/*", "/resource1" matches "/{resource}"
func KeyMatch3(key1 string, key2 string) bool {
key2 = strings.Replace(key2, "/*", "/.*", -1)
re := regexp.MustCompile(`\{[^/]+\}`)
key2 = re.ReplaceAllString(key2, "$1[^/]+$2")
return RegexMatch(key1, "^"+key2+"$")
}
// KeyEqual case key1='*' or key1=' ' result=true
func KeyEqual(key1 string, key2 string) bool {
if key1 == "*" {
return true
}
if len(key1) == 0 {
return true
}
key1 = strings.ToLower(strings.TrimSpace(key1))
key2 = strings.ToLower(strings.TrimSpace(key2))
return strings.EqualFold(key1, key2)
}
// RegexMatch determines whether key1 matches the pattern of key2 in regular expression.
func RegexMatch(key1 string, key2 string) bool {
res, err := regexp.MatchString(key2, key1)
if err != nil {
panic(err)
}
return res
}
... ...
... ... @@ -10,6 +10,10 @@ func CreateAccessRepository(transactionContext *transaction.TransactionContext)
return repository.NewAccessRepository(transactionContext)
}
func CreateRoleAccessRepository(transactionContext *transaction.TransactionContext) (domain.RoleAccessRepository, error) {
return repository.NewRoleAccessRepository(transactionContext)
}
func CreateMenuRepository(transactionContext *transaction.TransactionContext) (domain.MenuRepository, error) {
return repository.NewMenuRepository(transactionContext)
}
... ...
package rbac
import (
"github.com/tiptok/gocomm/pkg/log"
"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/application/factory"
"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/domain"
"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/infrastructure/dao"
"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/protocol"
protocolx "gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/protocol/rbac"
)
type RbacService struct {
}
func (svr *RbacService) Access(header *protocol.RequestHeader, request *protocolx.AccessRequest) (rsp interface{}, err error) {
var (
transactionContext, _ = factory.CreateTransactionContext(nil)
)
rsp = &protocolx.AccessResponse{}
if err = request.ValidateCommand(); err != nil {
err = protocol.NewCustomMessage(2, err.Error())
return
}
if err = transactionContext.StartTransaction(); err != nil {
log.Error(err)
return nil, err
}
defer func() {
transactionContext.RollbackTransaction()
}()
var AccessRepository, _ = factory.CreateAccessRepository(transactionContext)
var access []*domain.Access
if _, access, err = AccessRepository.Find(map[string]interface{}{}); err != nil {
return
}
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,
}
err = transactionContext.CommitTransaction()
return
}
func (svr *RbacService) RoleAccess(header *protocol.RequestHeader, request *protocolx.RoleAccessRequest) (rsp interface{}, err error) {
var (
transactionContext, _ = factory.CreateTransactionContext(nil)
RoleAccessDao, _ = dao.NewRoleAccessDao(transactionContext)
RoleRepository, _ = factory.CreateRoleRepository(transactionContext)
role *domain.Role
)
rsp = &protocolx.RoleAccessResponse{}
if err = request.ValidateCommand(); err != nil {
err = protocol.NewCustomMessage(2, err.Error())
return
}
if err = transactionContext.StartTransaction(); err != nil {
log.Error(err)
return nil, err
}
defer func() {
transactionContext.RollbackTransaction()
}()
if role, err = RoleRepository.FindOne(map[string]interface{}{"id": request.RoleId}); err != nil {
log.Error(err)
err = protocol.NewCustomMessage(1, "角色不存在")
return
}
accessIds, _ := RoleAccessDao.GetRoleAccess(request.RoleId)
rsp = map[string]interface{}{
"roleId": role.Id,
"roleName": role.RoleName,
"accessIds": accessIds,
}
err = transactionContext.CommitTransaction()
return
}
func (svr *RbacService) SetRoleAccess(header *protocol.RequestHeader, request *protocolx.SetRoleAccessRequest) (rsp *protocolx.SetRoleAccessResponse, err error) {
var (
transactionContext, _ = factory.CreateTransactionContext(nil)
AccessRepository, _ = factory.CreateAccessRepository(transactionContext)
RoleRepository, _ = factory.CreateRoleRepository(transactionContext)
RoleAccessDao, _ = dao.NewRoleAccessDao(transactionContext)
)
rsp = &protocolx.SetRoleAccessResponse{}
if err = request.ValidateCommand(); err != nil {
err = protocol.NewCustomMessage(2, err.Error())
}
if err = transactionContext.StartTransaction(); err != nil {
log.Error(err)
return nil, err
}
defer func() {
transactionContext.RollbackTransaction()
}()
if _, err = RoleRepository.FindOne(map[string]interface{}{"id": request.RoleId}); err != nil {
log.Error(err)
err = protocol.NewCustomMessage(1, "角色不存在")
return
}
var accessMap = make(map[int64]*domain.Access)
_, access, e := AccessRepository.Find(map[string]interface{}{"inAccessIds": request.AccessIds})
if e != nil {
err = e
return
}
for _, v := range access {
accessMap[v.Id] = v
}
if err = RoleAccessDao.DeleteRoleAccess(request.RoleId); err != nil {
return
}
if len(request.AccessIds) > 0 {
var roleAccess []*domain.RoleAccess
for _, v := range request.AccessIds {
item := &domain.RoleAccess{
RoleId: request.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
}
}
err = transactionContext.CommitTransaction()
return
}
func NewRbacService(options map[string]interface{}) *RbacService {
svr := &RbacService{}
return svr
}
... ...
package user
import (
"crypto/sha1"
"fmt"
"github.com/tiptok/gocomm/common"
"github.com/tiptok/gocomm/pkg/log"
"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/application/factory"
... ... @@ -19,6 +21,7 @@ func (svr *UserService) CreateUser(header *protocol.RequestHeader, request *prot
rsp = &protocolx.CreateUserResponse{}
if err = request.ValidateCommand(); err != nil {
err = protocol.NewCustomMessage(2, err.Error())
return
}
if err = transactionContext.StartTransaction(); err != nil {
log.Error(err)
... ... @@ -31,12 +34,21 @@ func (svr *UserService) CreateUser(header *protocol.RequestHeader, request *prot
Name: request.Name,
Address: request.Address,
Phone: request.Phone,
Passwd: request.Passwd,
//Passwd: request.Passwd,
Roles: request.Roles,
IsAdmin: request.IsAdmin,
}
var UserRepository, _ = factory.CreateUserRepository(transactionContext)
if request.Phone != "" {
if _, err = UserRepository.FindOne(map[string]interface{}{"phone": request.Phone}); err == nil {
err = protocol.NewCustomMessage(1, "手机号已存在")
return
}
}
if len(newUser.Passwd) == 0 {
newUser.Passwd = fmt.Sprintf("%x", sha1.Sum([]byte("123456")))
}
if m, err := UserRepository.Save(newUser); err != nil {
return nil, err
} else {
... ... @@ -53,6 +65,7 @@ func (svr *UserService) UpdateUser(header *protocol.RequestHeader, request *prot
rsp = &protocolx.UpdateUserResponse{}
if err = request.ValidateCommand(); err != nil {
err = protocol.NewCustomMessage(2, err.Error())
return
}
if err = transactionContext.StartTransaction(); err != nil {
log.Error(err)
... ... @@ -64,9 +77,16 @@ func (svr *UserService) UpdateUser(header *protocol.RequestHeader, request *prot
var UserRepository, _ = factory.CreateUserRepository(transactionContext)
var user *domain.User
if user, err = UserRepository.FindOne(common.ObjectToMap(request)); err != nil {
if user, err = UserRepository.FindOne(map[string]interface{}{"id": request.Id}); err != nil {
err = protocol.NewCustomMessage(1, "用户不存在")
return
}
if request.Phone != "" {
if _, err = UserRepository.FindOne(map[string]interface{}{"phone": request.Phone}); err == nil {
err = protocol.NewCustomMessage(1, "手机号已存在")
return
}
}
if err = user.Update(common.ObjectToMap(request)); err != nil {
return
}
... ... @@ -84,6 +104,7 @@ func (svr *UserService) GetUser(header *protocol.RequestHeader, request *protoco
rsp = &protocolx.GetUserResponse{}
if err = request.ValidateCommand(); err != nil {
err = protocol.NewCustomMessage(2, err.Error())
return
}
if err = transactionContext.StartTransaction(); err != nil {
log.Error(err)
... ... @@ -110,6 +131,7 @@ func (svr *UserService) DeleteUser(header *protocol.RequestHeader, request *prot
rsp = &protocolx.DeleteUserResponse{}
if err = request.ValidateCommand(); err != nil {
err = protocol.NewCustomMessage(2, err.Error())
return
}
if err = transactionContext.StartTransaction(); err != nil {
log.Error(err)
... ...
package constant
import "os"
var REDIS_HOST = "127.0.0.1"
var REDIS_PORT = "6379"
var REDIS_AUTH = "123456"
func init() {
if os.Getenv("REDIS_HOST") != "" {
REDIS_HOST = os.Getenv("REDIS_HOST")
REDIS_AUTH = os.Getenv("REDIS_AUTH")
}
if os.Getenv("REDIS_PORT") != "" {
REDIS_PORT = os.Getenv("REDIS_PORT")
}
if _, ok := os.LookupEnv("REDIS_AUTH"); ok {
REDIS_AUTH = os.Getenv("REDIS_AUTH")
}
}
... ...
... ... @@ -11,7 +11,7 @@ type User struct {
// 手机号
Phone string `json:"phone"`
// 密码
Passwd string `json:"passwd"`
Passwd string `json:"-"`
// 用户角色
Roles []int64 `json:"roles"`
// 是否是超级管理员 true:是 false:否
... ... @@ -33,5 +33,23 @@ func (m *User) Identify() interface{} {
}
func (m *User) Update(data map[string]interface{}) error {
if name, ok := data["name"]; ok {
m.Name = name.(string)
}
if address, ok := data["address"]; ok {
m.Address = address.(string)
}
if phone, ok := data["phone"]; ok {
m.Phone = phone.(string)
}
if Passwd, ok := data["passwd"]; ok {
m.Passwd = Passwd.(string)
}
if roles, ok := data["roles"]; ok {
m.Roles = roles.([]int64)
}
if isAdmin, ok := data["isAdmin"]; ok {
m.IsAdmin = isAdmin.(bool)
}
return nil
}
... ...
package dao
import (
"fmt"
"github.com/go-pg/pg/v10"
"github.com/tiptok/gocomm/common"
"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/domain"
"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/infrastructure/pg/models"
"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/infrastructure/pg/transaction"
)
type RoleAccessDao struct {
transactionContext *transaction.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 *transaction.TransactionContext) (*RoleAccessDao, error) {
if transactionContext == nil {
return nil, fmt.Errorf("transactionContext参数不能为nil")
} else {
return &RoleAccessDao{
transactionContext: transactionContext,
}, nil
}
}
... ...
package redis
import (
"fmt"
"github.com/tiptok/gocomm/pkg/cache"
"github.com/tiptok/gocomm/pkg/log"
"github.com/tiptok/gocomm/pkg/redis"
"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/constant"
)
func init() {
redisSource := fmt.Sprintf("%v:%v", constant.REDIS_HOST, constant.REDIS_PORT)
err := redis.InitWithDb(100, redisSource, constant.REDIS_AUTH, "0")
if err != nil {
log.Error(err)
}
cache.InitDefault(cache.WithDefaultRedisPool(redis.GetRedisPool()))
}
... ...
... ... @@ -2,6 +2,7 @@ package repository
import (
"fmt"
"github.com/go-pg/pg/v10"
"github.com/tiptok/gocomm/common"
. "github.com/tiptok/gocomm/pkg/orm/pgx"
"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/domain"
... ... @@ -66,6 +67,10 @@ func (repository *AccessRepository) Find(queryOptions map[string]interface{}) (i
query := NewQuery(tx.Model(&AccessModels), queryOptions).
SetOrder("create_time", "sortByCreateTime").
SetOrder("update_time", "sortByUpdateTime")
if inAccessIds, ok := queryOptions["inAccessIds"]; ok {
query.Where("id in (?)", pg.In(inAccessIds))
}
var err error
if query.AffectRow, err = query.SelectAndCount(); err != nil {
return 0, Accesss, err
... ...
... ... @@ -64,6 +64,7 @@ func (repository *RoleAccessRepository) Find(queryOptions map[string]interface{}
var RoleAccessModels []*models.RoleAccess
RoleAccesss := make([]*domain.RoleAccess, 0)
query := NewQuery(tx.Model(&RoleAccessModels), queryOptions).
SetWhere("role_id=?", "roleId").
SetOrder("create_time", "sortByCreateTime").
SetOrder("update_time", "sortByUpdateTime")
var err error
... ...
... ... @@ -2,6 +2,7 @@ package repository
import (
"fmt"
"github.com/go-pg/pg/v10"
"github.com/tiptok/gocomm/common"
. "github.com/tiptok/gocomm/pkg/orm/pgx"
"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/domain"
... ... @@ -68,6 +69,9 @@ func (repository *RoleRepository) Find(queryOptions map[string]interface{}) (int
SetOrder("create_time", "sortByCreateTime").
SetOrder("update_time", "sortByUpdateTime")
var err error
if inRoleIds, ok := queryOptions["inRoleIds"]; ok {
query.Where("id in (?)", pg.In(inRoleIds))
}
if query.AffectRow, err = query.SelectAndCount(); err != nil {
return 0, Roles, err
}
... ...
... ... @@ -26,6 +26,7 @@ func (repository *UserRepository) Save(dm *domain.User) (*domain.User, error) {
if err = tx.Insert(m); err != nil {
return nil, err
}
dm.Id = m.Id
return dm, nil
}
if err = tx.Update(m); err != nil {
... ... @@ -50,6 +51,7 @@ func (repository *UserRepository) FindOne(queryOptions map[string]interface{}) (
UserModel := new(models.User)
query := NewQuery(tx.Model(UserModel), queryOptions)
query.SetWhere("id = ?", "id")
query.SetWhere("phone = ?", "phone")
if err := query.First(); err != nil {
return nil, fmt.Errorf("query row not found")
}
... ...
... ... @@ -3,6 +3,7 @@ package beego
import (
"github.com/astaxie/beego"
"github.com/astaxie/beego/plugins/cors"
"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/port/beego/middleware"
_ "gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/port/beego/routers"
)
... ... @@ -14,4 +15,10 @@ func init() {
ExposeHeaders: []string{"Content-Length", "Access-Control-Allow-Origin"},
AllowCredentials: true,
}))
beego.InsertFilter("/user/*", beego.BeforeExec, middleware.InspectRoleAccess())
beego.InsertFilter("/role/*", beego.BeforeExec, middleware.InspectRoleAccess())
beego.InsertFilter("/project_module/*", beego.BeforeExec, middleware.CheckAuthorization)
beego.InsertFilter("/project_module_files/*", beego.BeforeExec, middleware.CheckAuthorization)
beego.InsertFilter("/rbac/*", beego.BeforeExec, middleware.CheckAuthorization)
}
... ...
... ... @@ -86,15 +86,12 @@ func (this *AuthController) CaptchaInit() {
var (
msg *protocol.ResponseMessage
svr = auth.NewAuthService(nil)
request *protocolx.CaptchaInitRequest
request = &protocolx.CaptchaInitRequest{}
)
defer func() {
this.Resp(msg)
}()
if err := this.JsonUnmarshal(&request); err != nil {
msg = protocol.BadRequestParam(1)
return
}
request.UserIp = this.Ctx.Input.IP()
header := this.GetRequestHeader(this.Ctx)
data, err := svr.CaptchaInit(header, request)
if err != nil {
... ...
package controllers
import (
"github.com/tiptok/gocomm/pkg/log"
"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/application/rbac"
"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/protocol"
protocolx "gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/protocol/rbac"
)
type RbacController struct {
BaseController
}
// Access
// 权限列表
func (this *RbacController) Access() {
var (
msg *protocol.ResponseMessage
svr = rbac.NewRbacService(nil)
request *protocolx.AccessRequest
)
defer func() {
this.Resp(msg)
}()
header := this.GetRequestHeader(this.Ctx)
data, err := svr.Access(header, request)
if err != nil {
log.Error(err)
}
msg = protocol.NewReturnResponse(data, err)
}
// RoleAccess
// 获取角色权限
func (this *RbacController) RoleAccess() {
var (
msg *protocol.ResponseMessage
svr = rbac.NewRbacService(nil)
request = &protocolx.RoleAccessRequest{}
)
defer func() {
this.Resp(msg)
}()
request.RoleId, _ = this.GetInt64(":roleId")
header := this.GetRequestHeader(this.Ctx)
data, err := svr.RoleAccess(header, request)
if err != nil {
log.Error(err)
}
msg = protocol.NewReturnResponse(data, err)
}
// SetRoleAccess
// 设置权限
func (this *RbacController) SetRoleAccess() {
var (
msg *protocol.ResponseMessage
svr = rbac.NewRbacService(nil)
request *protocolx.SetRoleAccessRequest
)
defer func() {
this.Resp(msg)
}()
if err := this.JsonUnmarshal(&request); err != nil {
msg = protocol.BadRequestParam(1)
return
}
header := this.GetRequestHeader(this.Ctx)
data, err := svr.SetRoleAccess(header, request)
if err != nil {
log.Error(err)
}
msg = protocol.NewReturnResponse(data, err)
}
... ...
... ... @@ -49,6 +49,7 @@ func (this *UserController) UpdateUser() {
msg = protocol.BadRequestParam(1)
return
}
request.Id, _ = this.GetInt64(":userId")
header := this.GetRequestHeader(this.Ctx)
data, err := svr.UpdateUser(header, request)
if err != nil {
... ... @@ -63,15 +64,12 @@ func (this *UserController) GetUser() {
var (
msg *protocol.ResponseMessage
svr = user.NewUserService(nil)
request *protocolx.GetUserRequest
request = &protocolx.GetUserRequest{}
)
defer func() {
this.Resp(msg)
}()
if err := this.JsonUnmarshal(&request); err != nil {
msg = protocol.BadRequestParam(1)
return
}
request.Id, _ = this.GetInt64(":userId")
header := this.GetRequestHeader(this.Ctx)
data, err := svr.GetUser(header, request)
if err != nil {
... ... @@ -86,15 +84,12 @@ func (this *UserController) DeleteUser() {
var (
msg *protocol.ResponseMessage
svr = user.NewUserService(nil)
request *protocolx.DeleteUserRequest
request = &protocolx.DeleteUserRequest{}
)
defer func() {
this.Resp(msg)
}()
if err := this.JsonUnmarshal(&request); err != nil {
msg = protocol.BadRequestParam(1)
return
}
request.Id, _ = this.GetInt64(":userId")
header := this.GetRequestHeader(this.Ctx)
data, err := svr.DeleteUser(header, request)
if err != nil {
... ...
... ... @@ -4,6 +4,7 @@ import (
"errors"
"github.com/astaxie/beego/context"
"github.com/tiptok/gocomm/common"
"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/application/cachex"
"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/protocol"
"strconv"
"strings"
... ... @@ -28,7 +29,13 @@ func CheckAuthorization(ctx *context.Context) {
msg = protocol.NewResponseMessage(1, errAuthorization.Error())
return
}
token := strings.Split(authorization, " ")[1]
var token string
splitToken := strings.Split(authorization, " ")
if len(splitToken) == 1 {
token = splitToken[0]
} else {
token = splitToken[1]
}
claim, err := common.ParseJWTToken(token)
if err != nil {
msg = protocol.NewResponseMessage(1, errAuthorizationExpire.Error())
... ... @@ -36,5 +43,39 @@ func CheckAuthorization(ctx *context.Context) {
}
userId, _ := strconv.Atoi(claim.Username)
ctx.Input.SetData("x-mmm-id", userId)
//TODO:check redis cache
return
}
func CheckRoleAccess(ctx *context.Context) {
var (
msg *protocol.ResponseMessage
)
defer func() {
if msg != nil {
ctx.Output.JSON(msg, false, false)
}
}()
userId := ctx.Input.GetData("x-mmm-id")
validUserRole := cachex.CacheService{}
if ok, _ := validUserRole.ValidUserAccess(int64(userId.(int)), ctx.Input.URL(), ctx.Input.Method()); !ok {
msg = protocol.NewResponseMessage(1, errAuthorization.Error())
return
}
return
}
func InspectRoleAccess(skipUrl ...string) func(*context.Context) {
return func(c *context.Context) {
if len(skipUrl) > 0 {
requestUrl := c.Input.URL()
for _, url := range skipUrl {
if strings.EqualFold(requestUrl, url) {
return
}
}
}
CheckAuthorization(c)
CheckRoleAccess(c)
}
}
... ...
package routers
import (
"github.com/astaxie/beego"
"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/port/beego/controllers"
)
func init() {
beego.Router("/rbac/access", &controllers.RbacController{}, "get:Access")
beego.Router("/rbac/roleAccess/:roleId", &controllers.RbacController{}, "get:RoleAccess")
beego.Router("/rbac/setRoleAccess", &controllers.RbacController{}, "post:SetRoleAccess")
}
... ...
... ... @@ -6,6 +6,7 @@ import (
)
type ProfileRequest struct {
UserId int64 `valid:"Required"`
}
func (ProfileRequest *ProfileRequest) ValidateCommand() error {
... ...
... ... @@ -6,6 +6,7 @@ import (
)
type CaptchaInitRequest struct {
UserIp string `json:"userIp" valid:"Required"`
}
func (CaptchaInitRequest *CaptchaInitRequest) ValidateCommand() error {
... ...
... ... @@ -6,8 +6,10 @@ import (
)
type CreateProjectModuleVersionRequest struct {
// 当前版本编号
CurrentVersionId int64 `json:"currentVersionId" valid:"Required"`
// 版本号
Version string `json:"version,omitempty"`
Version string `json:"version,omitempty" valid:"Required"`
// 项目描述信息
Description string `json:"description,omitempty"`
// 状态 0:正常 1:删除
... ...
package rbac
import (
"fmt"
"github.com/astaxie/beego/validation"
)
type SetRoleAccessRequest struct {
RoleId int64 `json:"roleId"`
AccessIds []int64 `json:"accessIds"`
}
func (SetRoleAccessRequest *SetRoleAccessRequest) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(SetRoleAccessRequest)
if err != nil {
return err
}
if !b {
for _, validErr := range valid.Errors {
return fmt.Errorf("%s %s", validErr.Key, validErr.Message)
}
}
return nil
}
... ...
package rbac
import (
"fmt"
"github.com/astaxie/beego/validation"
)
type SetRoleAccessResponse struct {
}
func (SetRoleAccessResponse *SetRoleAccessResponse) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(SetRoleAccessResponse)
if err != nil {
return err
}
if !b {
for _, validErr := range valid.Errors {
return fmt.Errorf("%s %s", validErr.Key, validErr.Message)
}
}
return nil
}
... ...
package rbac
import (
"fmt"
"github.com/astaxie/beego/validation"
)
type AccessRequest struct {
}
func (AccessRequest *AccessRequest) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(AccessRequest)
if err != nil {
return err
}
if !b {
for _, validErr := range valid.Errors {
return fmt.Errorf("%s %s", validErr.Key, validErr.Message)
}
}
return nil
}
... ...
package rbac
import (
"fmt"
"github.com/astaxie/beego/validation"
)
type AccessResponse struct {
}
func (AccessResponse *AccessResponse) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(AccessResponse)
if err != nil {
return err
}
if !b {
for _, validErr := range valid.Errors {
return fmt.Errorf("%s %s", validErr.Key, validErr.Message)
}
}
return nil
}
... ...
package rbac
import (
"fmt"
"github.com/astaxie/beego/validation"
)
type RoleAccessRequest struct {
RoleId int64 `json:"roleId" valid:"Required"`
}
func (RoleAccessRequest *RoleAccessRequest) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(RoleAccessRequest)
if err != nil {
return err
}
if !b {
for _, validErr := range valid.Errors {
return fmt.Errorf("%s %s", validErr.Key, validErr.Message)
}
}
return nil
}
... ...
package rbac
import (
"fmt"
"github.com/astaxie/beego/validation"
)
type RoleAccessResponse struct {
}
func (RoleAccessResponse *RoleAccessResponse) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(RoleAccessResponse)
if err != nil {
return err
}
if !b {
for _, validErr := range valid.Errors {
return fmt.Errorf("%s %s", validErr.Key, validErr.Message)
}
}
return nil
}
... ...
... ... @@ -11,7 +11,7 @@ type CreateUserRequest struct {
// 地址
Address string `json:"address,omitempty"`
// 手机号
Phone string `json:"phone,omitempty"`
Phone string `json:"phone,omitempty" valid:"Required"`
// 密码
Passwd string `json:"passwd,omitempty"`
// 用户角色
... ...
... ... @@ -6,6 +6,7 @@ import (
)
type UpdateUserRequest struct {
Id int64 `json:"-" valid:"Required"`
// 名称
Name string `json:"name,omitempty"`
// 地址
... ...