作者 唐旭辉

角色授权

... ... @@ -29,8 +29,8 @@ log_level = "${LOG_LEVEL||debug}"
##统一用户中心相关配置
ucenter_check_alt = "rsF0pL!6DwjBO735"
ucenter_base_url = "http://suplus-ucenter-dev.fjmaimaimai.com"
ucenter_app_key = "0692f2b7e8d6dbd8526579864b87e3bfbc5d5c31"
ucenter_secret = "0692f2b7e8d6dbd8526579864b87e3bfbc5d5c31"
ucenter_app_key = "39aefef9e22744a3b2d2d3791824ae7b"
ucenter_secret = "cykbjnfqgctn"
# 审批流程修改 消息发布
message_publish = "audit_change"
#---自定义配置 结束----
\ No newline at end of file
... ...
... ... @@ -59,8 +59,15 @@ func (c *AuthController) Login() {
msg = protocol.NewReturnResponse(nil, err)
return
}
err = serveauth.ResetLoginToken(logintoken)
if err != nil {
log.Error("token 信息记录数据库失败")
}
err = serveauth.ResetLoginTokenRedis(logintoken)
msg = protocol.NewReturnResponse(logintoken, err)
if err != nil {
log.Error("token 信息记录redis失败")
}
msg = protocol.NewReturnResponse(logintoken, nil)
return
}
... ...
... ... @@ -226,6 +226,7 @@ func (c *RbacController) RoleHasMenu() {
return
}
//TODO
func (c *RbacController) GetRoleMenuAll() {
var msg *protocol.ResponseMessage
defer func() {
... ... @@ -237,6 +238,25 @@ func (c *RbacController) GetRoleMenuAll() {
return
}
//RoleMenuEdit 设置角色的菜单
//@router /role/menu/edit
func (c *RbacController) RoleMenuEdit() {
var msg *protocol.ResponseMessage
defer func() {
c.ResposeJson(msg)
}()
type Parameter struct {
RoleId int64 `json:"role_id"`
MenuIds []int64 `json:"menu_ids"`
}
var param Parameter
if err := json.Unmarshal(c.Ctx.Input.RequestBody, &param); err != nil {
log.Error("json 解析失败 err:%s", err)
msg = protocol.BadRequestParam("1")
return
}
companyid := c.GetCompanyId()
err := serverbac.RoleMenuEdit(companyid, param.RoleId, param.MenuIds)
msg = protocol.NewReturnResponse(nil, err)
return
}
... ...
... ... @@ -89,7 +89,7 @@ var AllowOption = func(ctx *context.Context) {
})
f(ctx)
ctx.Output.SetStatus(204)
ctx.Output.Body([]byte("{}"))
ctx.Output.Body(nil)
return
}
... ...
... ... @@ -38,3 +38,14 @@ func GetMenuById(id int) (v *Menu, err error) {
}
return nil, err
}
func GetMenuByIds(ids []int64) (v []*Menu, err error) {
o := orm.NewOrm()
_, err = o.QueryTable(&Menu{}).
Filter("id__in", ids).
All(&v)
if err == orm.ErrNoRows {
return v, nil
}
return v, nil
}
... ...
... ... @@ -7,7 +7,7 @@ import (
type RoleMenu struct {
Id int64 `orm:"column(id);auto" description:"主键"`
RoleId int64 `orm:"column(role_id);null" description:"role.id"`
MenuId int64 `orm:"column(menu_id);null" description:"menu.id"`
MenuId int `orm:"column(menu_id);null" description:"menu.id"`
Opption string `orm:"column(opption);size(500);null" description:"配置"`
Code string `orm:"column(code)"`
}
... ... @@ -20,14 +20,6 @@ func init() {
orm.RegisterModel(new(RoleMenu))
}
// AddRoleMenu insert a new RoleMenu into database and returns
// last inserted Id on success.
func AddRoleMenu(m *RoleMenu) (id int64, err error) {
o := orm.NewOrm()
id, err = o.Insert(m)
return
}
func GetRoleMenuByRole(roleid int64) ([]RoleMenu, error) {
var (
list []RoleMenu
... ...
... ... @@ -16,6 +16,7 @@ type User struct {
CsAccount int64 `orm:"column(cs_account)" description:"客服有话说ID"`
IsKefu int8 `orm:"column(is_kefu)" description:"是否是客服 0:否 1:是"`
ImToken string `orm:"column(im_token);size(128)" description:"网易云token"`
Accid int64 `orm:"column(accid)" description:"网易云id"`
LastLoginTime time.Time `orm:"column(last_login_time);type(timestamp)" description:"最后一次登录时间"`
CreateAt time.Time `orm:"column(create_at);type(timestamp);auto_now_add" description:"创建时间"`
EnableStatus int8 `orm:"column(enable_status)" description:"是否有效"`
... ...
... ... @@ -131,7 +131,7 @@ type TemplateItem struct {
type VisibleObject struct {
Id string `json:"id"`
Name string `json:"name",omitempty`
Name string `json:"name,omitempty"`
Type int `json:"type"` //1:部门 2:指定人员
}
... ...
... ... @@ -7,6 +7,7 @@ var errmessge ErrorMap = map[string]string{
//角色相关
"10001": "请先删除该分组下的其他角色",
"10002": "请先删除该角色下的人员",
"10003": "无效角色",
//职位相关
"10011": "该职位已被使用无法删除",
//安全认证相关
... ...
... ... @@ -38,6 +38,7 @@ func init() {
beego.NSRouter("/role/list", &controllers.RbacController{}, "post:RoleList"),
beego.NSRouter("/menu/list", &controllers.RbacController{}, "post:MenuList"),
beego.NSRouter("/role/menu", &controllers.RbacController{}, "post:RoleHasMenu"),
beego.NSRouter("/role/menu/edit", &controllers.RbacController{}, "post:RoleMenuEdit"),
),
beego.NSNamespace("/user",
beego.NSRouter("/list", &controllers.CompanyController{}, "post:UserList"),
... ...
... ... @@ -3,11 +3,13 @@ package auth
import (
"crypto/sha1"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"oppmg/common/log"
"oppmg/models"
"oppmg/protocol"
"oppmg/services/ucenter"
"oppmg/storage/redisdata"
"oppmg/utils"
"strings"
... ... @@ -79,7 +81,7 @@ func ResetLoginToken(loginToken protocol.LoginAuthToken) error {
uAuth.RefreshToken = loginToken.RefreshToken
uAuth.RefreshTokenExp = time.Unix(loginToken.RefreshExpires, 0)
uAuth.UpdateAt = nowTime
upCol := []string{"CurrentCompanyId", "AccessToken", "RefreshToken", "RefreshTokenExp", "UpdateAt"}
upCol := []string{"CurrentCompanyId", "AccessTokenExp", "RefreshTokenExp", "AccessToken", "RefreshToken", "RefreshTokenExp", "UpdateAt"}
if err = models.UpdateUserAuthById(uAuth, upCol); err != nil {
e := fmt.Errorf("UpdateUserAuthById err:%s", err)
log.Error(e.Error())
... ... @@ -189,7 +191,7 @@ func LoginAuthByUCenter(account, password string) (protocol.LoginAuthToken, erro
}
if ok := userdata.IsEnable(); !ok {
log.Debug("userdata.IsEnable()==false")
return logintoken, protocol.NewErrWithMessage("10021")
return logintoken, protocol.NewErrWithMessage("10022")
}
if companys, err = getUserCompanyReal(userdata.Id); err != nil {
log.Error("getUserCompanyReal err:%s", err)
... ... @@ -197,33 +199,55 @@ func LoginAuthByUCenter(account, password string) (protocol.LoginAuthToken, erro
}
if len(companys) == 0 {
log.Debug("no company")
return logintoken, protocol.NewErrWithMessage("10021")
return logintoken, protocol.NewErrWithMessage("10022")
}
companyid = companys[0].Id
// var uclientReturn ucenter.ResponseLogin
// param := ucenter.RequesLogin{
// Phone: account,
// Password: password,
// }
// uclient := ucenter.NewUCenterClient()
// btBody, err := uclient.Call(param)
// if err != nil {
// log.Error("统一用户中心请求失败 err:%s", err)
// return logintoken, protocol.NewErrWithMessage("1")
// }
// err = json.Unmarshal(btBody, &uclientReturn)
// if err != nil {
// log.Error("解析统一用户中心响应失败 err:%s", err)
// return logintoken, protocol.NewErrWithMessage("1")
// }
// if !(uclientReturn.Code == ucenter.ResponseCode0 &&
// uclientReturn.Msg == ucenter.ResponseMsgOk) {
// return logintoken, protocol.NewErrWithMessage("10021")
// }
var uclientReturn *ucenter.ResponseLogin
uclientReturn, err = requestUCenterLogin(account, password)
if err != nil {
return logintoken, protocol.NewErrWithMessage("10021")
}
//更新用户数据
_ = uclientReturn
userdata.Accid = uclientReturn.Data.Accid
userdata.Icon = uclientReturn.Data.Avatar
userdata.ImToken = uclientReturn.Data.Imtoken
userdata.NickName = uclientReturn.Data.NickName
userdata.CsAccount = uclientReturn.Data.CustomerAccount
userdata.LastLoginTime = time.Now()
err = models.UpdateUserById(userdata, []string{"Accid", "Icon", "ImToken", "NickName", "CsAccount", "LastLoginTime"})
if err != nil {
log.Error("更新用户数据失败:%s", err)
}
logintoken, _ = GenerateAuthToken(userdata.Id, companyid)
return logintoken, err
}
func requestUCenterLogin(account, password string) (*ucenter.ResponseLogin, error) {
var uclientReturn *ucenter.ResponseLogin
param := ucenter.RequesLogin{
Type: 1,
Phone: account,
Password: password,
}
uclient := ucenter.NewUCenterClient()
btBody, err := uclient.Call(param)
if err != nil {
log.Error("统一用户中心请求失败 err:%s", err)
return nil, protocol.NewErrWithMessage("1")
}
err = json.Unmarshal(btBody, &uclientReturn)
if err != nil {
log.Error("解析统一用户中心响应失败 err:%s", err)
return nil, protocol.NewErrWithMessage("1")
}
if !(uclientReturn.Code == ucenter.ResponseCode0 &&
uclientReturn.Msg == ucenter.ResponseMsgOk) {
return nil, protocol.NewErrWithMessage("10021")
}
return uclientReturn, nil
}
type companybase struct {
Id int64 `orm:"column(id)"`
Name string `orm:"coumn(name)"`
... ...
... ... @@ -5,6 +5,8 @@ import (
"oppmg/models"
"oppmg/protocol"
"oppmg/utils"
"github.com/astaxie/beego/orm"
)
//获取全部的权限菜单
... ... @@ -52,7 +54,7 @@ func GetRoleHasMenu(roleid int64, companyid int64) (*protocol.ResponseRoleMenus,
return nil, protocol.NewErrWithMessage("1")
}
for _, v := range rolemenu {
ids = append(ids, v.MenuId)
ids = append(ids, int64(v.MenuId))
}
data := &protocol.ResponseRoleMenus{
RoleId: roleData.Id,
... ... @@ -103,6 +105,54 @@ func GetRoleHasMenuAll(roleid int64, companyid int64) (map[string]PermissionCont
return returnList, nil
}
func RoleMenuEdit(companyid int64, roleid int64, menuids []int64) {
func RoleMenuEdit(companyid int64, roleId int64, menuids []int64) error {
roleMenus, err := GetRoleHasMenu(companyid, roleId)
if err != nil {
return err
}
var (
oldMenuIds []int64
addMenuIds []int64
delMenuIds []int64
addMenu []*models.Menu
)
oldMenuIds = roleMenus.MenuId
addMenuIds = utils.ArrayInt64Diff(menuids, oldMenuIds)
delMenuIds = utils.ArrayInt64Diff(oldMenuIds, menuids)
if len(addMenuIds) > 0 {
addMenu, err = models.GetMenuByIds(addMenuIds)
if err != nil {
log.Error("获取菜单数据失败:%s", err)
return protocol.NewErrWithMessage("1")
}
}
o := orm.NewOrm()
o.Begin()
if len(delMenuIds) > 0 {
_, err = o.QueryTable(&models.RoleMenu{}).
Filter("role_id", roleId).
Filter("menu_id__in", delMenuIds).
Delete()
if err != nil {
log.Error("删除角色和菜单关系失败:%s", err)
o.Rollback()
return protocol.NewErrWithMessage("1")
}
}
for _, v := range addMenu {
m := models.RoleMenu{
RoleId: roleId,
MenuId: v.Id,
Code: v.Code,
Opption: "{}",
}
if _, err = o.Insert(&m); err != nil {
log.Error("添加角色和菜单关系失败:%s", err)
o.Rollback()
return protocol.NewErrWithMessage("1")
}
}
o.Commit()
return nil
}
... ...
... ... @@ -158,11 +158,6 @@ func RoleGroupDelete(param protocol.RequestRoleDelete) error {
return nil
}
//CanSetRole 操作员是否可以操作角色
func CanSetRole(adminId int64, groupId int64) bool {
return false
}
func GetRoleList(companyId int64) ([]protocol.RoleGroup, error) {
var (
roleGroups []protocol.RoleGroup
... ... @@ -213,19 +208,3 @@ func getRoleGroupByCompany(companyid int64) ([]protocol.RoleInfo, error) {
err = utils.ExecuteQueryAll(&roles, datasql, companyid, models.ROLETYPES_GROUP)
return roles, err
}
func GetRoleGroup() error {
return nil
}
func RoleHasPermission() error {
return nil
}
func PermissionHasRole() error {
return nil
}
func RolsHasUser() error {
return nil
}
... ...
... ... @@ -14,6 +14,7 @@ type CommResponse struct {
//RequesLogin 用户登录
type RequesLogin struct {
Type int8 `json:"type"`
Password string `json:"password"`
Phone string `json:"phone"`
}
... ... @@ -27,7 +28,7 @@ func (r RequesLogin) Format() []byte {
//Format 实现IUCenterParam接口
func (r RequesLogin) GetPath() (string, string) {
return "/auth/login", "POST"
return "/auth/serverLogin", "POST"
}
//Format 实现IUCenterParam接口
... ... @@ -44,10 +45,13 @@ func (r RequesLogin) Valid() error {
type ResponseLogin struct {
CommResponse
Data struct {
Id int64 `json:"id"`
Phone string `json:"phone"`
NickName string `json:"nickname"` //昵称
Avatar string `json:"avatar"` //头像
Id int64 `json:"id"`
Phone string `json:"phone"`
NickName string `json:"nickname"` //昵称
Avatar string `json:"avatar"` //头像
Imtoken string `json:"imtoken"` //网易云imtoken
Accid int64 `json:"accid"`
CustomerAccount int64 `json:"customerAccount"` //客服id
} `json:"data"`
}
... ...
... ... @@ -55,7 +55,7 @@ func buildCheckSum(nowTime string) string {
//httpDo post发送json
func (client UCenterClient) httpDo(path string, mathod string, posts []byte) ([]byte, error) {
httpclient := http.Client{
Timeout: 5 * time.Second, //请求超时时间5秒
Timeout: 10 * time.Second, //请求超时时间5秒
}
reqURL := client.baseUrl + path
req, err := http.NewRequest(mathod, reqURL, bytes.NewReader(posts))
... ... @@ -64,7 +64,9 @@ func (client UCenterClient) httpDo(path string, mathod string, posts []byte) ([]
}
req.Header = client.buildHeader()
resp, err := httpclient.Do(req)
log.Info("====>Send To UCenter:%s", string(posts))
// log.Info("====>Send Header:%v", req.Header)
if err != nil {
return nil, err
}
... ...
... ... @@ -14,7 +14,7 @@ func ArrayInt64Diff(arr1 []int64, arr2 []int64) []int64 {
}
setmap := make(map[int64]bool)
for i := range arr2 {
setmap[arr1[i]] = true
setmap[arr2[i]] = true
}
var result []int64
for i := range arr1 {
... ... @@ -26,6 +26,25 @@ func ArrayInt64Diff(arr1 []int64, arr2 []int64) []int64 {
return result
}
//ArrayIntDiff 返回切片的差集:arr1-arr2
func ArrayIntDiff(arr1 []int, arr2 []int) []int {
if len(arr2) == 0 {
return arr1
}
setmap := make(map[int]bool)
for i := range arr2 {
setmap[arr1[i]] = true
}
var result []int
for i := range arr1 {
if _, ok := setmap[arr1[i]]; !ok {
result = append(result, arr1[i])
}
}
return result
}
//ArrayStringIn 检查s字符串是否在切片sl中
func ArrayStringIn(arr1 []string, s string) bool {
for _, v := range arr1 {
... ...