From 529a02ac7582babc634e6f9cddab126f5f962efb Mon Sep 17 00:00:00 2001 From: eson <474420502@qq.com> Date: Thu, 27 Jul 2023 00:03:38 +0800 Subject: [PATCH] =?UTF-8?q?=E9=9C=80=E8=A6=81=E5=90=88=E5=B9=B6=E6=96=B0?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- goctl_template/api/logic.tpl | 11 +- server/auth/internal/handler/routes.go | 5 + .../handler/useremailconfirmationhandler.go | 35 ++++ .../logic/useremailconfirmationlogic.go | 43 +++++ .../internal/logic/usergoogleloginlogic.go | 165 +++++++++--------- server/auth/internal/types/types.go | 6 +- .../internal/handler/getcloudlisthandler.go | 2 +- server_api/auth.api | 15 +- 8 files changed, 190 insertions(+), 92 deletions(-) create mode 100644 server/auth/internal/handler/useremailconfirmationhandler.go create mode 100644 server/auth/internal/logic/useremailconfirmationlogic.go diff --git a/goctl_template/api/logic.tpl b/goctl_template/api/logic.tpl index 63413717..306889e3 100644 --- a/goctl_template/api/logic.tpl +++ b/goctl_template/api/logic.tpl @@ -25,14 +25,15 @@ func New{{.logic}}(ctx context.Context, svcCtx *svc.ServiceContext) *{{.logic}} // func (l *{{.logic}}) BeforeLogic(w http.ResponseWriter, r *http.Request) { // } -// 处理逻辑后 w,r 如:重定向, resp 必须重新处理 -// func (l *{{.logic}}) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) { -// // httpx.OkJsonCtx(r.Context(), w, resp) -// } - func (l *{{.logic}}) {{.function}}({{.request}}, userinfo *auth.UserInfo) (resp *basic.Response) { // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) // userinfo 传入值时, 一定不为null {{.returnString}} resp.SetStatus(basic.CodeOK) } + +// 处理逻辑后 w,r 如:重定向, resp 必须重新处理 +// func (l *{{.logic}}) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) { +// // httpx.OkJsonCtx(r.Context(), w, resp) +// } + diff --git a/server/auth/internal/handler/routes.go b/server/auth/internal/handler/routes.go index a635db67..2206deba 100644 --- a/server/auth/internal/handler/routes.go +++ b/server/auth/internal/handler/routes.go @@ -27,6 +27,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { Path: "/api/auth/oauth2/login/google", Handler: UserGoogleLoginHandler(serverCtx), }, + { + Method: http.MethodGet, + Path: "/api/auth/email/confirmation", + Handler: UserEmailConfirmationHandler(serverCtx), + }, { Method: http.MethodGet, Path: "/api/auth/oauth2/register", diff --git a/server/auth/internal/handler/useremailconfirmationhandler.go b/server/auth/internal/handler/useremailconfirmationhandler.go new file mode 100644 index 00000000..60e3a340 --- /dev/null +++ b/server/auth/internal/handler/useremailconfirmationhandler.go @@ -0,0 +1,35 @@ +package handler + +import ( + "net/http" + "reflect" + + "fusenapi/utils/basic" + + "fusenapi/server/auth/internal/logic" + "fusenapi/server/auth/internal/svc" + "fusenapi/server/auth/internal/types" +) + +func UserEmailConfirmationHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + + var req types.RequestEmailConfirmation + userinfo, err := basic.RequestParse(w, r, svcCtx.SharedState, &req) + if err != nil { + return + } + + // 创建一个业务逻辑层实例 + l := logic.NewUserEmailConfirmationLogic(r.Context(), svcCtx) + + rl := reflect.ValueOf(l) + basic.BeforeLogic(w, r, rl) + + resp := l.UserEmailConfirmation(&req, userinfo) + + if !basic.AfterLogic(w, r, rl, resp) { + basic.NormalAfterLogic(w, r, resp) + } + } +} diff --git a/server/auth/internal/logic/useremailconfirmationlogic.go b/server/auth/internal/logic/useremailconfirmationlogic.go new file mode 100644 index 00000000..d7436c14 --- /dev/null +++ b/server/auth/internal/logic/useremailconfirmationlogic.go @@ -0,0 +1,43 @@ +package logic + +import ( + "fusenapi/utils/auth" + "fusenapi/utils/basic" + + "context" + + "fusenapi/server/auth/internal/svc" + "fusenapi/server/auth/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type UserEmailConfirmationLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewUserEmailConfirmationLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserEmailConfirmationLogic { + return &UserEmailConfirmationLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +// 处理进入前逻辑w,r +// func (l *UserEmailConfirmationLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) { +// } + +func (l *UserEmailConfirmationLogic) UserEmailConfirmation(req *types.RequestEmailConfirmation, userinfo *auth.UserInfo) (resp *basic.Response) { + // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) + // userinfo 传入值时, 一定不为null + + return resp.SetStatus(basic.CodeOK) +} + +// 处理逻辑后 w,r 如:重定向, resp 必须重新处理 +// func (l *UserEmailConfirmationLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) { +// // httpx.OkJsonCtx(r.Context(), w, resp) +// } diff --git a/server/auth/internal/logic/usergoogleloginlogic.go b/server/auth/internal/logic/usergoogleloginlogic.go index 60aa28f6..f6e4db07 100644 --- a/server/auth/internal/logic/usergoogleloginlogic.go +++ b/server/auth/internal/logic/usergoogleloginlogic.go @@ -46,6 +46,90 @@ func NewUserGoogleLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *U // func (l *UserGoogleLoginLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) { // } +func (l *UserGoogleLoginLogic) UserGoogleLogin(req *types.RequestGoogleLogin, userinfo *auth.UserInfo) (resp *basic.Response) { + // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) + // userinfo 传入值时, 一定不为null + + dialer, err := proxy.SOCKS5("tcp", "127.0.0.1:1080", nil, proxy.Direct) + if err != nil { + log.Fatal(err) + } + + customClient := &http.Client{ + Transport: &http.Transport{ + Dial: dialer.Dial, + }, + } + + ctx := context.WithValue(context.Background(), oauth2.HTTPClient, customClient) + + var googleOauthConfig = &oauth2.Config{ + RedirectURL: "http://localhost:9900/api/user/oauth2/login/google", + ClientID: l.svcCtx.Config.OAuth.Google.Appid, + ClientSecret: l.svcCtx.Config.OAuth.Google.Secret, + Scopes: []string{"https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile"}, + Endpoint: google.Endpoint, + } + + token, err := googleOauthConfig.Exchange(ctx, req.Code) + if err != nil { + logx.Error(err) + resp.SetStatus(basic.CodeApiErr) + } + ses := requests.NewSession() + ses.Config().SetProxy("socks5://127.0.0.1:1080") // 代理 为了测试功能 + + r, err := ses.Get("https://www.googleapis.com/oauth2/v2/userinfo?access_token=" + token.AccessToken).Execute() + if err != nil { + logx.Error(err) + return resp.SetStatus(basic.CodeOAuthGoogleApiErr) + } + + log.Println(r.Json()) + + googleId := r.Json().Get("id").Int() + user, err := l.svcCtx.AllModels.FsUser.FindUserByGoogleId(context.TODO(), googleId) + if err != nil { + if err != gorm.ErrRecordNotFound { + logx.Error(err) + return resp.SetStatus(basic.CodeDbSqlErr) + } + + l.isRegistered = false + l.registerToken = // + + // 进入邮件注册流程 + // if req.Email == "" { + // return resp.SetStatus(basic.CodeOK) + // } + + // // 这里是注册模块, 发邮件, 通过邮件注册确认邮箱存在 + + // // 邮箱验证格式错误 + // if !auth.ValidateEmail(req.Email) { + // return resp.SetStatus(basic.CodeOAuthEmailErr) + // } + + // EmailManager.EmailTasks <- req.Email // email进入队 + + return resp.SetStatus(basic.CodeOK) + } + + // 如果密码匹配,则生成 JWT Token。 + nowSec := time.Now().Unix() + jwtToken, err := auth.GenerateJwtToken(&l.svcCtx.Config.Auth.AccessSecret, l.svcCtx.Config.Auth.AccessExpire, nowSec, user.Id, 0) + + // 如果生成 JWT Token 失败,则抛出错误并返回未认证的状态码。 + if err != nil { + logx.Error(err) + return resp.SetStatus(basic.CodeServiceErr) + } + + l.token = jwtToken + + return resp.SetStatus(basic.CodeOK) +} + // 处理逻辑后 w,r 如:重定向, resp 必须重新处理 func (l *UserGoogleLoginLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) { @@ -96,84 +180,3 @@ func (l *UserGoogleLoginLogic) AfterLogic(w http.ResponseWriter, r *http.Request } } - -func (l *UserGoogleLoginLogic) UserGoogleLogin(req *types.RequestGoogleLogin, userinfo *auth.UserInfo) (resp *basic.Response) { - // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) - // userinfo 传入值时, 一定不为null - - dialer, err := proxy.SOCKS5("tcp", "127.0.0.1:1080", nil, proxy.Direct) - if err != nil { - log.Fatal(err) - } - - customClient := &http.Client{ - Transport: &http.Transport{ - Dial: dialer.Dial, - }, - } - - ctx := context.WithValue(context.Background(), oauth2.HTTPClient, customClient) - - var googleOauthConfig = &oauth2.Config{ - RedirectURL: "http://localhost:9900/api/user/oauth2/login/google", - ClientID: l.svcCtx.Config.OAuth.Google.Appid, - ClientSecret: l.svcCtx.Config.OAuth.Google.Secret, - Scopes: []string{"https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile"}, - Endpoint: google.Endpoint, - } - - token, err := googleOauthConfig.Exchange(ctx, req.Code) - if err != nil { - logx.Error(err) - resp.SetStatus(basic.CodeApiErr) - } - ses := requests.NewSession() - ses.Config().SetProxy("socks5://127.0.0.1:1080") // 代理 为了测试功能 - - r, err := ses.Get("https://www.googleapis.com/oauth2/v2/userinfo?access_token=" + token.AccessToken).Execute() - if err != nil { - logx.Error(err) - return resp.SetStatus(basic.CodeOAuthGoogleApiErr) - } - - log.Println(r.Json()) - - googleId := r.Json().Get("id").Int() - user, err := l.svcCtx.AllModels.FsUser.FindUserByGoogleId(context.TODO(), googleId) - if err != nil { - if err != gorm.ErrRecordNotFound { - logx.Error(err) - return resp.SetStatus(basic.CodeDbSqlErr) - } - - // 进入邮件注册流程 - if req.Email == "" { - return resp.SetStatus(basic.CodeOK) - } - - // 这里是注册模块, 发邮件, 通过邮件注册确认邮箱存在 - - // 邮箱验证格式错误 - if !auth.ValidateEmail(req.Email) { - return resp.SetStatus(basic.CodeOAuthEmailErr) - } - - EmailManager.EmailTasks <- req.Email // email进入队 - - return resp.SetStatus(basic.CodeOK) - } - - // 如果密码匹配,则生成 JWT Token。 - nowSec := time.Now().Unix() - jwtToken, err := auth.GenerateJwtToken(&l.svcCtx.Config.Auth.AccessSecret, l.svcCtx.Config.Auth.AccessExpire, nowSec, user.Id, 0) - - // 如果生成 JWT Token 失败,则抛出错误并返回未认证的状态码。 - if err != nil { - logx.Error(err) - return resp.SetStatus(basic.CodeServiceErr) - } - - l.token = jwtToken - - return resp.SetStatus(basic.CodeOK) -} diff --git a/server/auth/internal/types/types.go b/server/auth/internal/types/types.go index ccb83ca7..56bf3d43 100644 --- a/server/auth/internal/types/types.go +++ b/server/auth/internal/types/types.go @@ -15,7 +15,11 @@ type RequestGoogleLogin struct { Scope string `form:"scope"` AuthUser string `form:"authuser"` Prompt string `form:"prompt"` - Email string `form:"email,optional"` +} + +type RequestEmailConfirmation struct { + Email string `json:"email"` // 要确认的email + Token string `json:"token"` // 操作Token } type RequestEmailRegister struct { diff --git a/server/inventory/internal/handler/getcloudlisthandler.go b/server/inventory/internal/handler/getcloudlisthandler.go index 90708969..c6b5badc 100644 --- a/server/inventory/internal/handler/getcloudlisthandler.go +++ b/server/inventory/internal/handler/getcloudlisthandler.go @@ -15,7 +15,7 @@ func GetCloudListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var req types.GetCloudListReq - userinfo, err := basic.RequestParse(w, r, svcCtx, &req) + userinfo, err := basic.RequestParse(w, r, svcCtx.SharedState, &req) if err != nil { return } diff --git a/server_api/auth.api b/server_api/auth.api index 1f4265c9..5003e8d9 100644 --- a/server_api/auth.api +++ b/server_api/auth.api @@ -12,13 +12,16 @@ import "basic.api" service auth { @handler UserLoginHandler post /api/auth/login(RequestUserLogin) returns (response); - + @handler AcceptCookieHandler post /api/auth/accept-cookie(request) returns (response); - + @handler UserGoogleLoginHandler get /api/auth/oauth2/login/google(RequestGoogleLogin) returns (response); - + + @handler UserEmailConfirmationHandler + get /api/auth/email/confirmation(RequestEmailConfirmation) returns (response); + @handler UserEmailRegisterHandler get /api/auth/oauth2/register(RequestEmailRegister) returns (response); } @@ -34,7 +37,11 @@ type RequestGoogleLogin { Scope string `form:"scope"` AuthUser string `form:"authuser"` Prompt string `form:"prompt"` - Email string `form:"email,optional"` +} + +type RequestEmailConfirmation { + Email string `json:"email"` // 要确认的email + Token string `json:"token"` // 操作Token } type RequestEmailRegister {