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/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) { err = auth2.SendVerifyCode(params.AuthToken, params.CaptchaID, params.CaptchaValue, params.AuthID) 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:用户名,email,mobile" // @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 }) }