package service import ( "context" "crypto/rsa" "encoding/json" "fmt" "reflect" "time" cda "git.loafle.net/commons/di-go/annotation" cdr "git.loafle.net/commons/di-go/registry" "git.loafle.net/commons/logging-go" "git.loafle.net/commons/server-go" _ "git.loafle.net/overflow/commons-go/core/annotation" "git.loafle.net/overflow/gateway/external/grpc" "github.com/valyala/fasthttp" "net/url" "github.com/dgrijalva/jwt-go" ) var MemberServiceType = reflect.TypeOf((*MemberService)(nil)) func init() { cdr.RegisterType(MemberServiceType) } type MemberService struct { cda.TypeAnnotation `annotation:"@overflow:RESTService()"` VerifyKey *rsa.PublicKey `annotation:"@Resource(name='VerifyKey')"` SignKey *rsa.PrivateKey `annotation:"@Resource(name='SignKey')"` _Signin cda.MethodAnnotation `annotation:"@overflow:RequestMapping(method='POST', entry='/account/signin', params='[signinID, signinPW]')"` _SigninByCookie cda.MethodAnnotation `annotation:"@overflow:RequestMapping(method='POST', entry='/account/signin_cookie', params='[authToken]')"` _Signup cda.MethodAnnotation `annotation:"@overflow:RequestMapping(method='POST', entry='/account/signup', params='[member, password]')"` _EmailConfirm cda.MethodAnnotation `annotation:"@overflow:RequestMapping(method='GET', entry='/account/email_confirm', params='[token]')"` _ForgotPassword cda.MethodAnnotation `annotation:"@overflow:RequestMapping(method='POST', entry='/account/forgot_password', params='[signinID]')"` _ResetPwConfirm cda.MethodAnnotation `annotation:"@overflow:RequestMapping(method='POST', entry='/account/reset_pw_confirm', params='[pw, key]')"` } func (ms *MemberService) EmailConfirm(servletCtx server.ServletCtx, ctx *fasthttp.RequestCtx, token string) error { var c fasthttp.Cookie c.SetKey("cookie-name") c.SetValue("cookie-value") ctx.Response.Header.SetCookie(&c) ctx.SetBody([]byte("DDDDDDD")) return nil } type SigninResult struct { AuthToken string `json:"authToken"` DomainMember interface{} `json:"domainMember"` } func (ms *MemberService) Signin(servletCtx server.ServletCtx, ctx *fasthttp.RequestCtx, signinID string, signinPW string) error { gRPCCtx := context.Background() r, err := grpc.Exec(gRPCCtx, "MemberService.signin", signinID, signinPW) if nil != err { return err } token := jwt.New(jwt.SigningMethodRS512) /* Create a map to store our claims */ claims := token.Claims.(jwt.MapClaims) // expireTime := time.Now().Add(time.Hour * 24) /* Set token claims */ claims["iss"] = "overFlow" claims["iat"] = time.Now().Unix() claims["exp"] = time.Now().Add(time.Hour * 24).Unix() claims["aud"] = "www.overflow.cloud" claims["sub"] = signinID /* Sign the token with our secret */ tokenString, err := token.SignedString(ms.SignKey) if nil != err { return err } var domainMember interface{} err = json.Unmarshal([]byte(r), &domainMember) if nil != err { return err } signInResult := &SigninResult{ AuthToken: tokenString, DomainMember: domainMember, } buf, err := json.Marshal(signInResult) if nil != err { return err } ctx.SetBody(buf) return nil } func (ms *MemberService) SigninByCookie(servletCtx server.ServletCtx, ctx *fasthttp.RequestCtx, authToken string) error { token, err := jwt.Parse(authToken, func(token *jwt.Token) (interface{}, error) { // Don't forget to validate the alg is what you expect: if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok { return nil, fmt.Errorf("Webapp: Unexpected signing method: %v", token.Header["alg"]) } // hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key") return ms.VerifyKey, nil }) if nil != err { return err } var ok bool var claims jwt.MapClaims if claims, ok = token.Claims.(jwt.MapClaims); !ok || !token.Valid { logging.Logger().Warnf("Token is not valid %v", token) return fmt.Errorf("authToken is not valid") } params := []string{claims["sub"].(string)} gRPCCtx := context.Background() r, err := grpc.Exec(gRPCCtx, "DomainMemberService.readByMemberEmail", params...) if nil != err { return err } ctx.SetBody([]byte(r)) return nil } func (ms *MemberService) Signup(servletCtx server.ServletCtx, ctx *fasthttp.RequestCtx, member string, pw string) error { gRPCCtx := context.Background() r, err := grpc.Exec(gRPCCtx, "MemberService.signup", member, pw) if nil != err { return err } ctx.SetBody([]byte(r)) return nil } func (ms *MemberService) ForgotPassword(servletCtx server.ServletCtx, ctx *fasthttp.RequestCtx, signinID string) error { gRPCCtx := context.Background() r, err := grpc.Exec(gRPCCtx, "MemberService.sendEmailForPassword", signinID) if nil != err { return err } ctx.SetBody([]byte(r)) return nil } // Todo id QueryEscape Test func (ms *MemberService) ResetPwConfirm(servletCtx server.ServletCtx, ctx *fasthttp.RequestCtx, pw string, key string) error { gRPCCtx := context.Background() r, err := grpc.Exec(gRPCCtx, "MemberService.resetPassword", url.QueryEscape(key), pw) if nil != err { return err } ctx.SetBody([]byte(r)) return nil }