Files
jx-callback/controllers/auth2.go
2020-01-06 15:36:33 +08:00

307 lines
12 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package controllers
import (
"encoding/base64"
"fmt"
"net/http"
"strings"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/auth2"
"git.rosy.net.cn/jx-callback/business/auth2/authprovider/dingding"
_ "git.rosy.net.cn/jx-callback/business/auth2/authprovider/mobile" // 强制导入mobile认证方式
"git.rosy.net.cn/jx-callback/business/auth2/authprovider/password"
"git.rosy.net.cn/jx-callback/business/auth2/authprovider/weixin"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/model/dao"
"git.rosy.net.cn/jx-callback/globals"
"github.com/astaxie/beego"
)
func GetComposedCode(c *beego.Controller, code string) (composedCode string) {
if code != "" {
composedCode = code
referer := c.Ctx.Request.Referer()
globals.SugarLogger.Debugf("GetComposedCode referer:%s", referer)
index := strings.Index(referer, "//")
if index > 0 {
list := strings.Split(referer[index+2:], "/")
if len(list) >= 2 {
composedCode = strings.Join([]string{
list[1],
code,
}, ",")
}
}
}
return composedCode
}
type Auth2Controller struct {
beego.Controller
}
// @Title 生成captcha
// @Description 生成captcha
// @Param width formData int true "图片宽"
// @Param height formData int true "图片高"
// @Param captchaLen formData int false captcha码长度"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /CreateCaptcha [post]
func (c *Auth2Controller) CreateCaptcha() {
c.callCreateCaptcha(func(params *tAuth2CreateCaptchaParams) (retVal interface{}, errCode string, err error) {
retVal, err = auth2.CreateCaptcha(params.Width, params.Height, params.CaptchaLen)
return retVal, "", err
})
}
// @Title 发送验证码
// @Description 发送验证码captcha码与authToken二者必须至少有一个
// @Param captchaID formData string false "captcha码ID"
// @Param captchaValue formData string false "captcha码值"
// @Param authToken formData string false "之前的认证信息"
// @Param authID formData string true "手机号或邮件"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /SendVerifyCode [post]
func (c *Auth2Controller) SendVerifyCode() {
c.callSendVerifyCode(func(params *tAuth2SendVerifyCodeParams) (retVal interface{}, errCode string, err error) {
code, authInfo, err := auth2.SendVerifyCode(params.AuthToken, params.CaptchaID, params.CaptchaValue, params.AuthID)
if err == nil && authInfo != nil {
user, err2 := dao.GetUserByID(dao.GetDB(), "user_id", authInfo.GetID())
if err2 == nil && user.Type&(model.UserTypeBoss|model.UserTypeOperator) != 0 {
retVal = code
}
}
return retVal, "", err
})
}
// @Title 登录接口
// @Description 登录接口(微信与公众号登录不能直接调用此接口)
// @Param authType formData string true "登录类型,当前支持[localpass本地账号密码mobile手机短信wxqrcode:微信登录weixinsns微信公众号weixinmini小程序ddstaff钉钉企业ddqrcode钉钉扫码]"
// @Param authSecret formData string true "不同登录类型的登录秘密如果是localpass登录类型是md5后的值空串不要md5"
// @Param authID formData string false "登录ID登录类型为localpass时依赖于authIDType其它为相应登录类型的id"
// @Param authIDType formData string false "只有在登录类型为localpass时才有意义分别为userid2用户名emailmobile"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /Login [post]
func (c *Auth2Controller) Login() {
c.callLogin(func(params *tAuth2LoginParams) (retVal interface{}, errCode string, err error) {
if params.AuthType == auth2.AuthTypeMobile {
params.AuthIDType = auth2.UserIDMobile
} else if params.AuthType == auth2.AuthTypeEmail {
params.AuthIDType = auth2.UserIDEmail
}
if params.AuthType == weixin.AuthTypeMini {
params.AuthSecret = GetComposedCode(&c.Controller, params.AuthSecret)
}
ctx := auth2.NewContext(c.Ctx.ResponseWriter, c.Ctx.Request)
retVal, err = auth2.Login(ctx, params.AuthType, params.AuthID, params.AuthIDType, params.AuthSecret)
return retVal, "", err
})
}
// @Title 得到自己登录token的信息
// @Description 得到自己登录token的信息
// @Param token header string true "认证token"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /GetTokenInfo [get]
func (c *Auth2Controller) GetTokenInfo() {
c.callGetTokenInfo(func(params *tAuth2GetTokenInfoParams) (retVal interface{}, errCode string, err error) {
if true { //auth2.IsV2Token(params.Token) {
retVal, err = auth2.GetTokenInfo(params.Token)
} else {
// retVal, err = auth.GetUserInfo(params.Token)
}
if err == model.ErrTokenIsInvalid {
errCode = model.ErrCodeTokenIsInvalid
}
return retVal, errCode, err
})
}
// @Title 微信扫码认证回调接口
// @Description 微信扫码认证回调接口,自己不能直接调用
// @Param code query string true "客户同意后得到的code"
// @Param block query string true "回调地址"
// @Param state query string false "微信回调的登录状态"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /WeixinOAuth2 [get]
func (c *Auth2Controller) WeixinOAuth2() {
var (
redirectURL string
callResult *CallResult
)
c.callWeixinOAuth2(func(params *tAuth2WeixinOAuth2Params) (retVal interface{}, errCode string, err error) {
ctx := auth2.NewContext(c.Ctx.ResponseWriter, c.Ctx.Request)
authInfo, err := auth2.Login(ctx, weixin.AuthTypeWeixin, params.State, "", params.Code)
if err == nil {
callResult = &CallResult{
Code: model.ErrCodeSuccess,
Data: string(utils.MustMarshal(authInfo)),
}
} else {
callResult = &CallResult{
Code: model.ErrCodeGeneralFailed,
Desc: err.Error(),
}
}
redirectURL = fmt.Sprintf("%s?info=%s", params.Block, base64.StdEncoding.EncodeToString(utils.MustMarshal(callResult)))
return retVal, model.ErrorCodeIgnore, err
})
globals.SugarLogger.Debugf("WeixinOAuth2, callResult:%s, redirectURL:%s", utils.Format4Output(callResult, true), redirectURL)
c.Redirect(redirectURL, http.StatusTemporaryRedirect)
}
// @Title 微信公众号认证回调接口
// @Description 微信公众号认证回调接口,自己不能直接调用
// @Param code query string true "客户同意后得到的code"
// @Param block query string true "回调地址"
// @Param state query string false "微信回调的登录状态"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /WeixinMPOAuth2 [get]
func (c *Auth2Controller) WeixinMPOAuth2() {
var (
redirectURL string
callResult *CallResult
)
c.callWeixinMPOAuth2(func(params *tAuth2WeixinMPOAuth2Params) (retVal interface{}, errCode string, err error) {
ctx := auth2.NewContext(c.Ctx.ResponseWriter, c.Ctx.Request)
authInfo, err := auth2.Login(ctx, weixin.AuthTypeMP, params.State, "", params.Code)
if err == nil {
callResult = &CallResult{
Code: model.ErrCodeSuccess,
Data: string(utils.MustMarshal(authInfo)),
}
} else {
callResult = &CallResult{
Code: model.ErrCodeGeneralFailed,
Desc: err.Error(),
}
}
redirectURL = fmt.Sprintf("%s?info=%s", params.Block, base64.StdEncoding.EncodeToString(utils.MustMarshal(callResult)))
return retVal, model.ErrorCodeIgnore, err
})
globals.SugarLogger.Debugf("WeixinMPOAuth2, callResult:%s, redirectURL:%s", utils.Format4Output(callResult, true), redirectURL)
c.Redirect(redirectURL, http.StatusTemporaryRedirect)
}
// @Title 钉钉认证回调接口
// @Description 钉钉认证回调接口,自己不能直接调用
// @Param code query string true "客户同意后得到的code"
// @Param block query string false "回调地址"
// @Param state query string false "微信回调的登录状态"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /DingDingOAuth2 [get]
func (c *Auth2Controller) DingDingOAuth2() {
var (
redirectURL string
callResult *CallResult
)
c.callDingDingOAuth2(func(params *tAuth2DingDingOAuth2Params) (retVal interface{}, errCode string, err error) {
if params.Block == "" {
params.Block = params.State
params.State = ""
}
ctx := auth2.NewContext(c.Ctx.ResponseWriter, c.Ctx.Request)
authInfo, err := auth2.Login(ctx, dingding.AuthTypeQRCode, params.State, "", params.Code)
if err == nil {
callResult = &CallResult{
Code: model.ErrCodeSuccess,
Data: string(utils.MustMarshal(authInfo)),
}
} else {
callResult = &CallResult{
Code: model.ErrCodeGeneralFailed,
Desc: err.Error(),
}
}
if params.Block != "" {
redirectURL = fmt.Sprintf("%s?info=%s", params.Block, base64.StdEncoding.EncodeToString(utils.MustMarshal(callResult)))
}
return retVal, model.ErrorCodeIgnore, err
})
globals.SugarLogger.Debugf("DingDingOAuth2, callResult:%s, redirectURL:%s", utils.Format4Output(callResult, true), redirectURL)
if redirectURL != "" {
c.Redirect(redirectURL, http.StatusTemporaryRedirect)
}
}
// @Title 登出接口
// @Description 登出接口此接口兼容V1的TOKEN
// @Param token header string true "认证token"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /Logout [delete]
func (c *Auth2Controller) Logout() {
c.callLogout(func(params *tAuth2LogoutParams) (retVal interface{}, errCode string, err error) {
if authInfo, ok := params.Ctx.GetLoginInfo().(*auth2.AuthInfo); ok {
err = auth2.Logout(authInfo)
} else {
// err = auth.Logout(params.Token)
}
return nil, "", err
})
}
// @Title 绑定认证方式
// @Description 绑定认证方式
// @Param token header string true "认证token"
// @Param authToken formData string true "之前通过login得到的新认证TOKEN"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /AddAuthBind [post]
func (c *Auth2Controller) AddAuthBind() {
c.callAddAuthBind(func(params *tAuth2AddAuthBindParams) (retVal interface{}, errCode string, err error) {
authInfo, err2 := params.Ctx.GetV2AuthInfo()
if err := err2; err == nil {
newAuthInfo, err2 := auth2.GetTokenInfo(params.AuthToken)
if err = err2; err == nil {
err = auth2.AddAuthBind(authInfo, newAuthInfo)
}
}
return retVal, "", err
})
}
// @Title 删除认证方式
// @Description 删除认证方式
// @Param token header string true "认证token"
// @Param authType query string true "登录类型参见Login的描述"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /RemoveAuthBind [delete]
func (c *Auth2Controller) RemoveAuthBind() {
c.callRemoveAuthBind(func(params *tAuth2RemoveAuthBindParams) (retVal interface{}, errCode string, err error) {
authInfo, err2 := params.Ctx.GetV2AuthInfo()
if err = err2; err == nil {
err = auth2.UnbindAuth(authInfo.GetID(), params.AuthType, params.Ctx.GetUserName())
}
return retVal, "", err
})
}
// @Title 修改(或初始化)密码
// @Description 修改(或初始化)密码
// @Param token header string true "认证token"
// @Param oldPwd query string false "原密码md5如果是重置或新设为空"
// @Param newPwd query string true "新密码md5"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /ChangePassword [put]
func (c *Auth2Controller) ChangePassword() {
c.callChangePassword(func(params *tAuth2ChangePasswordParams) (retVal interface{}, errCode string, err error) {
authInfo, err := params.Ctx.GetV2AuthInfo()
if err == nil {
err = password.AutherObj.ChangePassword(authInfo.GetID(), params.Ctx.GetUserName(), params.OldPwd, params.NewPwd)
}
return retVal, "", err
})
}