作者 唐旭辉

日常提交存储

... ... @@ -2,10 +2,10 @@
| 功能 | 完成状态 | 时间 | 接口路径 | 请求方式 |
| -------------- | ------------------ | --------------- | --------------------------------- | -------- |
| 登录 | 进行中 | | |
| 登录获取 token | 进行中 | | /auth/login | post |
| 短信验证码 | 未开始 | | |
| 获取 token | 未开始 | | |
| 刷新 token | 未开始 | | |
| 刷新 token | 未开始 | | /v1/auth/refresh_token | post |
| 切换公司 | 未开始 | | /v1/auth/change_company |
| 获取角色列表 | 完成 | | /v1/rbac/:companyid/role | get |
| 添加角色 | 完成 | 2019.11.26 | /v1/rbac/role | post |
| 编辑角色 | 完成 | 2019.11.26 | /v1/rbac/role | put |
... ...
... ... @@ -16,6 +16,10 @@ type MyConfig struct {
LogOutput string
LogFilename string
LogLevel string
UcenterCheckAlt string
UcenterBaseUrl string
UcenterSecret string
UcenterAppKey string
}
//MConfig
... ... @@ -39,6 +43,10 @@ func RestMyConfig() *MyConfig {
LogOutput: beego.AppConfig.DefaultString("log_output", "console"),
LogFilename: beego.AppConfig.DefaultString("log_filename", "./log/ability.log"),
LogLevel: beego.AppConfig.DefaultString("log_Level", "debug"),
UcenterCheckAlt: beego.AppConfig.String("ucenter_check_alt"),
UcenterBaseUrl: beego.AppConfig.String("ucenter_base_url"),
UcenterSecret: beego.AppConfig.String("ucenter_secret"),
UcenterAppKey: beego.AppConfig.String("ucenter_app_key"),
}
return MConfig
}
... ...
... ... @@ -24,4 +24,12 @@ redis_auth = ""
log_output = "file"
log_filename = "${aliyun_logs_access||./log/ability.log}"
log_level = "${LOG_LEVEL||error}"
##统一用户中心相关配置
ucenter_check_alt = "rsF0pL!6DwjBO735"
ucenter_base_url = "suplus-ucenter-dev.fjmaimaimai.com"
ucenter_secret = "12412213"
ucenter_app_key = "111222"
# 审批流程修改 消息发布
message_publish = "audit_change"
#---自定义配置 结束----
\ No newline at end of file
... ...
... ... @@ -22,4 +22,9 @@ redis_auth = ""
log_output = "file"
log_filename = "${LOG_FILENAME||./log/ability.log}"
log_level = "${LOG_LEVEL||debug}"
##统一用户中心相关配置
ucenter_app_key = ""
ucenter_base_url = ""
# 审批流程修改 消息发布
message_publish = "audit_change"
#---自定义配置 结束----
\ No newline at end of file
... ...
... ... @@ -5,6 +5,7 @@ import (
"oppmg/common/log"
"oppmg/protocol"
serveauth "oppmg/services/auth"
"oppmg/storage/redisdata"
)
type AuthController struct {
... ... @@ -61,5 +62,32 @@ func (c *AuthController) Login() {
//ChangeCompany 切换公司
//@Router /change_company [post]
func (c *AuthController) ChangeCompany() {
var msg *protocol.ResponseMessage
defer func() {
c.ResposeJson(msg)
}()
var param protocol.RequestSwapCompany
if err := json.Unmarshal(c.Ctx.Input.RequestBody, &param); err != nil {
log.Error("json 解析失败", err)
msg = protocol.BadRequestParam("1")
return
}
userid := c.GetUserId()
if param.CompanyId <= 0 {
msg = protocol.BadRequestParam("1")
return
}
logintoken, err := serveauth.ChangeLoginToken(userid, param.CompanyId)
if err != nil {
msg = protocol.NewReturnResponse(nil, err)
return
}
err = redisdata.SetLoginToken(logintoken, userid)
if err != nil {
log.Error("redisdata.SetLoginToken err:%s", err)
}
msg = protocol.NewReturnResponse(logintoken, err)
return
}
... ...
... ... @@ -13,7 +13,6 @@ import (
//BaseController 基础
type BaseController struct {
beego.Controller
// AppHead protocol.BaseHeader
}
//Prepare 实现beego.ControllerInterface 的接口
... ... @@ -25,11 +24,6 @@ func (this *BaseController) Prepare() {
func (this *BaseController) GetAppHead() (appHead protocol.BaseHeader) {
appHead.AccessToken = this.Ctx.Input.Header(protocol.HeaderAccessToken)
appHead.RefreshToken = this.Ctx.Input.Header(protocol.HeaderRefreshToken)
appHead.UID, _ = strconv.Atoi(this.Ctx.Input.Header(protocol.HeaderUID))
appHead.UUID = this.Ctx.Input.Header(protocol.HeaderUUID)
appHead.Timestamp, _ = strconv.Atoi(this.Ctx.Input.Header(protocol.HeaderTimestamp))
appHead.Devicetype = this.Ctx.Input.Header(protocol.HeaderDevicetype)
appHead.AppProject = this.Ctx.Input.Header(protocol.HeaderAppproject)
return
}
... ... @@ -50,3 +44,15 @@ func (this *BaseController) ResposeJson(msg *protocol.ResponseMessage) {
this.Data["json"] = msg
this.ServeJSON()
}
func (this *BaseController) GetCompanyId() int64 {
v := this.Ctx.Input.GetData(protocol.HeaderCompanyid)
companyid, _ := strconv.ParseInt(fmt.Sprint(v), 10, 64)
return companyid
}
func (this *BaseController) GetUserId() int64 {
v := this.Ctx.Input.GetData(protocol.HeaderUserid)
userid, _ := strconv.ParseInt(fmt.Sprint(v), 10, 64)
return userid
}
... ...
... ... @@ -76,28 +76,9 @@ var AuthToken = func(ctx *context.Context) {
return
}
if ok := serveauth.IsJwtErrorExpired(err); ok {
//token过期
mtoken, err = serveauth.ValidJWTToken(refreshToken)
if err != nil {
msg = protocol.NewMesage("10024")
ctx.Output.JSON(msg, false, false)
return
}
storetoken, err = redisdata.GetLoginToken(mtoken.UID)
if err != nil {
log.Error("err:%s", err)
msg = protocol.NewMesage("10024")
ctx.Output.JSON(msg, false, false)
return
}
if storetoken.AccessToken != accesstoken {
msg = protocol.NewMesage("10025")
ctx.Output.JSON(msg, false, false)
return
}
logintoken, _ := serveauth.GenerateAuthToken(mtoken.UID, mtoken.CompanyID)
serveauth.ResetLoginTokenRedis(logintoken)
msg = protocol.NewReturnResponse(logintoken, nil)
//token过期,刷新
logintoken, err := serveauth.RefreshLoginToken(refreshToken)
msg = protocol.NewReturnResponse(logintoken, err)
ctx.Output.JSON(msg, false, false)
return
}
... ...
... ... @@ -28,6 +28,16 @@ const (
COMPANY_ENABLE_NO int8 = 2 //无效
)
func (t *Company) IsEnable() bool {
switch t.Enable {
case COMPANY_ENABLE_YES:
return true
case COMPANY_ENABLE_NO:
return false
}
return false
}
func (t *Company) ValidateEnable(v int8) bool {
switch v {
case COMPANY_ENABLE_YES:
... ...
... ... @@ -15,12 +15,37 @@ type UserCompany struct {
CommentTotal int `orm:"column(comment_total)" description:"发表评论总数"`
CreateAt time.Time `orm:"column(create_at);type(timestamp)" description:"创建时间"`
UpdateAt time.Time `orm:"column(update_at);type(timestamp)" description:"更新时间"`
Enable int8 `orm:"column(enable)"`
DeleteAt time.Time `orm:"column(delete_at)"`
}
func (t *UserCompany) TableName() string {
return "user_company"
}
//用户的公司是否有效
const (
USERCOMPANY_ENABLE_YES int8 = 1 //有效
USERCOMPANY_ENABLE_NO int8 = 2 // 无效
)
func (t *UserCompany) IsEnable() bool {
switch t.Enable {
case USERCOMPANY_ENABLE_YES:
return true
case USERCOMPANY_ENABLE_NO:
return false
}
return false
}
func (t *UserCompany) IsDelete() bool {
if t.DeleteAt.Unix() > 0 {
return true
}
return false
}
func init() {
orm.RegisterModel(new(UserCompany))
}
... ... @@ -60,3 +85,8 @@ func GetUserCompanyBy(userid int64, companyId int64) (*UserCompany, error) {
}
return v, nil
}
func GetUserCompanyByUser(userid int64) ([]UserCompany, error) {
datasql := ``
return nil, nil
}
... ...
... ... @@ -4,12 +4,6 @@ package protocol
const (
HeaderAccessToken string = "x-mmm-accesstoken"
HeaderRefreshToken string = "x-mmm-refreshtoken"
// HeaderUID string = "x-mmm-uid"
// HeaderUUID string = "x-mmm-uuid"
// HeaderTimestamp string = "x-mmm-timestamp"
// HeaderDevicetype string = "x-mmm-devicetype"
// HeaderAppproject string = "x-mmm-appproject"
// HeaderSign string = "x-mmm-sign"
)
//用来存储从token中解析出来的内容对应的键名
... ... @@ -23,12 +17,6 @@ const (
type BaseHeader struct {
AccessToken string
RefreshToken string
AppProject string
Devicetype string
Sign string
UUID string
Timestamp int
UID int
}
//RequestLogin 登录请求
... ... @@ -51,8 +39,10 @@ type LoginAuthToken struct {
//RequestSwapCompany 切换公司
type RequestSwapCompany struct {
CompanyId int64 `json:"company_id"`
}
// ResponseSwapCompany ...
type ResponseSwapCompany struct {
LoginAuthToken
}
... ...
... ... @@ -20,4 +20,5 @@ var errmessge ErrorMap = map[string]string{
"10024": "登录凭证失效",
"10025": "该账号已在其他地方登录",
"10026": "登录凭证过期",
"10027": "无操作权限",
}
... ...
... ... @@ -32,26 +32,25 @@ func init() {
beego.NSRouter("/role_group", &controllers.RbacController{}, "delete:RoleGroupDelete"),
beego.NSRouter("/:companyid([0-9]+)/role", &controllers.RbacController{}, "get:RoleList"),
),
beego.NSNamespace("/auth",
beego.NSRouter("/change_company", &controllers.AuthController{}, "post:ChangeCompany"),
beego.NSRouter("/refresh_token", &controllers.AuthController{}, "post:RefreshToken"),
),
)
nsAuth := beego.NewNamespace("/auth",
beego.NSBefore(middleware.AllowOption),
beego.NSBefore(middleware.LogRequestData),
beego.NSRouter("/login", &controllers.AuthController{}, "post:Login"),
beego.NSNamespace("/token",
beego.NSBefore(middleware.AuthToken),
beego.NSRouter("/change_company", &controllers.AuthController{}, "post:ChangeCompany"),
beego.NSRouter("/refresh_token", &controllers.AuthController{}, "post:RefreshToken"),
),
)
beego.AddNamespace(nsV1)
beego.AddNamespace(nsAuth)
}
//routerPermission 路由对应的权限
var routerPermission = map[string]string{
"get:/v1/company/:companyid/position": "show",
"post:/v1/company/position": "add",
"put:/v1/company/position": "edit",
"delete:/v1/company/position": "delete",
}
// var routerPermission = map[string]string{
// "get:/v1/company/:companyid/position": "show",
// "post:/v1/company/position": "add",
// "put:/v1/company/position": "edit",
// "delete:/v1/company/position": "delete",
// }
... ...
... ... @@ -3,12 +3,14 @@ package auth
import (
"crypto/sha1"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"oppmg/common/config"
"oppmg/common/log"
"oppmg/models"
"oppmg/protocol"
"oppmg/services/ucenter"
"oppmg/storage/redisdata"
"strings"
"time"
... ... @@ -155,3 +157,102 @@ func ResetLoginTokenRedis(loginToken protocol.LoginAuthToken) error {
return nil
}
func ChangeLoginToken(userid, companyid int64) (protocol.LoginAuthToken, error) {
var (
logintoken protocol.LoginAuthToken
err error
usercompany *models.UserCompany
companydata *models.Company
)
usercompany, err = models.GetUserCompanyBy(userid, companyid)
if err != nil {
log.Error("GetUserCompanyBy(userid, companyid) err:%s", err)
return logintoken, protocol.NewErrWithMessage("1")
}
if ok := usercompany.IsEnable(); !ok {
log.Debug("公司禁用此用户")
return logintoken, protocol.NewErrWithMessage("10027")
}
if ok := usercompany.IsDelete(); !ok {
log.Debug("公司删除此用户")
return logintoken, protocol.NewErrWithMessage("10027")
}
companydata, err = models.GetCompanyById(usercompany.CompanyId)
if err != nil {
log.Error("GetCompanyById(%d) err:%s", usercompany.CompanyId, err)
return logintoken, protocol.NewErrWithMessage("1")
}
if ok := companydata.IsEnable(); !ok {
log.Debug("无效公司")
return logintoken, protocol.NewErrWithMessage("10027")
}
logintoken, err = GenerateAuthToken(userid, companydata.Id)
if err != nil {
log.Error("GenerateAuthToken err:%s", err)
return logintoken, protocol.NewErrWithMessage("1")
}
return logintoken, nil
}
func RefreshLoginToken(refreshtoken string) (protocol.LoginAuthToken, error) {
var (
logintoken protocol.LoginAuthToken
mtoken *MyToken
err error
storetoken protocol.LoginAuthToken
)
mtoken, err = ValidJWTToken(refreshtoken)
if err != nil {
log.Debug("token失效 err:%s", err)
return logintoken, protocol.NewErrWithMessage("10024")
}
storetoken, err = redisdata.GetLoginToken(mtoken.UID)
if err != nil {
log.Error("redis err:%s", err)
return logintoken, protocol.NewErrWithMessage("10024")
}
if storetoken.RefreshToken != refreshtoken {
return logintoken, protocol.NewErrWithMessage("10024")
}
logintoken, _ = GenerateAuthToken(mtoken.UID, mtoken.CompanyID)
ResetLoginTokenRedis(logintoken)
return logintoken, nil
}
func LoginAuthByUCenter(account, password string) (protocol.LoginAuthToken, error) {
var (
err error
logintoken protocol.LoginAuthToken
uclientReturn ucenter.ResponseLogin
)
_, err := models.GetUserByPhone(account)
if err != nil {
log.Debug("GetUserByPhone(%s) err:%s", account, err)
return logintoken, protocol.NewErrWithMessage("10021")
}
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")
}
return logintoken, err
}
... ...
... ... @@ -323,6 +323,7 @@ func DepartmentDelete(param protocol.RequestDepartmentDelete) error {
}
}
o.Commit()
return nil
}
... ... @@ -334,7 +335,7 @@ func DepartmentListAll(companyId int64) ([]protocol.ResponseDepartmentInfo, erro
err error
)
const (
datasql0 string = `SELECT id, company_id,name,parent_id,member,managers ` +
datasql0 string = `SELECT id, company_id,name,parent_id,member,managers,delete_at ` +
` FROM department WHERE company_id = ? AND delete_at = 0`
)
err = utils.ExecuteQueryAll(&departmodels, datasql0, companyId)
... ...
... ... @@ -5,6 +5,12 @@ import (
"errors"
)
//CommResponse 公共响应结构
type CommResponse struct {
Code int `json:"code"`
Msg string `json:"msg"`
}
type RequesLogin struct {
Password string `json:"password"`
Phone string `json:"phone"`
... ... @@ -33,6 +39,16 @@ func (r RequesLogin) Valid() error {
return nil
}
type ResponseLogin struct {
CommResponse
Data struct {
Id int64 `json:"id"`
Phone string `json:"phone"`
NickName string `json:"nickname"` //昵称
Avatar string `json:"avatar"` //头像
} `json:"data"`
}
type RequestAddUser struct {
Phone string `json:"phone"`
RegIm bool `json:"regIm"`
... ...
... ... @@ -2,11 +2,20 @@ package ucenter
import (
"bytes"
"crypto/sha1"
"fmt"
"io/ioutil"
"net/http"
mconfig "oppmg/common/config"
"oppmg/common/log"
"time"
)
const (
ResponseCode0 int = 0
ResponseMsgOk string = "ok"
)
type IUCenterParam interface {
Format() []byte
GetPath() (string, string) //返回请求路径path,请求方式mathod
... ... @@ -18,13 +27,31 @@ type UCenterClient struct {
baseUrl string
}
func NewUCenterClient() *UCenterClient {
return &UCenterClient{
appKey: mconfig.MConfig.UcenterAppKey,
baseUrl: mconfig.MConfig.UcenterBaseUrl,
}
}
func (client UCenterClient) buildHeader() http.Header {
var h = http.Header{}
nowTime := fmt.Sprint(time.Now().Unix())
checksum := buildCheckSum(nowTime)
h.Set("Content-Type", "application/json")
h.Set("appKey", client.appKey)
h.Set("nonce", "")
h.Set("curTime", nowTime)
h.Set("checkSum", checksum)
return h
}
func buildCheckSum(nowTime string) string {
str := fmt.Sprintf("%s%s%s", nowTime, mconfig.MConfig.UcenterSecret, mconfig.MConfig.UcenterCheckAlt)
bt := sha1.Sum([]byte(str))
return fmt.Sprintf("%x", bt)
}
//httpDo post发送json
func (client UCenterClient) httpDo(path string, mathod string, posts []byte) ([]byte, error) {
httpclient := http.Client{
... ... @@ -45,7 +72,8 @@ func (client UCenterClient) httpDo(path string, mathod string, posts []byte) ([]
if err != nil {
return nil, err
}
log.Info("====>Send To UCenter:%s", string(posts))
log.Info("<====UCenter Return:%s", string(body))
return body, nil
}
... ...
package memery
import (
"sync"
)
//内存存储
type StoreAuditChange struct {
data sync.Map
}
func (s *StoreAuditChange) SetKey(key, value string) {
s.data.Store(key, value)
}
func (s *StoreAuditChange) DeleteKey(key string) {
s.data.Delete(key)
}
... ...
... ... @@ -56,3 +56,5 @@ func ExistLoginToken(userid int64) bool {
}
return false
}
//消息发布订阅
... ...