/
code.go
141 lines (123 loc) · 4.36 KB
/
code.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package impl
import (
"context"
"fmt"
"github.com/infraboard/mcube/exception"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"github.com/infraboard/keyauth/apps/system/notify"
"github.com/infraboard/keyauth/apps/system/notify/mail"
"github.com/infraboard/keyauth/apps/system/notify/sms"
"github.com/infraboard/keyauth/apps/token"
"github.com/infraboard/keyauth/apps/user"
"github.com/infraboard/keyauth/apps/verifycode"
)
func (s *service) IssueCode(ctx context.Context, req *verifycode.IssueCodeRequest) (
*verifycode.IssueCodeResponse, error) {
code, err := verifycode.NewCode(req)
if err != nil {
return nil, err
}
// 根据系统配置设置校验码过期时间
cf, err := s.system.GetConfig()
if err != nil {
s.log.Errorf("get system config error, %s", err)
} else {
code.ExpiredMinite = uint32(cf.VerifyCode.ExpireMinutes)
}
// 如果是issue by pass, 这要检测
switch req.IssueType {
case verifycode.IssueType_PASS:
_, err := s.issuer.IssueToken(ctx, token.NewIssueTokenByPassword(
req.ClientId,
req.ClientSecret,
req.Username,
req.Password),
)
if err != nil {
return nil, err
}
case verifycode.IssueType_TOKEN:
_, err := s.token.DescribeToken(ctx, token.NewDescribeTokenRequestWithAccessToken(req.AccessToken))
if err != nil {
return nil, err
}
default:
return nil, fmt.Errorf("unknown issue_type %s", req.IssueType)
}
if _, err := s.col.InsertOne(context.TODO(), code); err != nil {
return nil, exception.NewInternalServerError("inserted verify code(%s) document error, %s",
code, err)
}
msg, err := s.sendCode(ctx, code)
if err != nil {
return nil, exception.NewInternalServerError("send verify code error, %s", err)
}
return verifycode.NewIssueCodeResponse(msg), nil
}
func (s *service) sendCode(ctx context.Context, code *verifycode.Code) (string, error) {
system, err := s.system.GetConfig()
if err != nil {
return "", fmt.Errorf("query system config error, %s", err)
}
u, err := s.user.DescribeAccount(ctx, user.NewDescriptAccountRequestWithAccount(code.Username))
if err != nil {
return "", fmt.Errorf("get user error, %s", err)
}
var message string
vc := system.VerifyCode
switch vc.NotifyType {
case verifycode.NotifyType_MAIL:
sender, err := mail.NewSender(system.Email)
if err != nil {
return "", fmt.Errorf("new sms sender error, %s", err)
}
req := notify.NewSendMailRequest()
req.To = u.Profile.Email
req.Subject = "验证码"
req.Content = vc.RenderMailTemplate(code.Number, code.ExpiredMiniteString())
if err := sender.Send(req); err != nil {
return "", fmt.Errorf("send verify code by mail error, %s", err)
}
message = fmt.Sprintf("验证码已通过邮件发送到你的邮箱: %s, 请及时查收", u.Profile.Email)
s.log.Debugf("send verify code to user: %s by mail ok", code.Username)
case verifycode.NotifyType_SMS:
sender, err := sms.NewSender(system.SMS)
if err != nil {
return "", fmt.Errorf("new sms sender error, %s", err)
}
req := notify.NewSendSMSRequest()
req.AddPhone(u.Profile.Phone)
req.TemplateID = vc.SmsTemplateID
req.AddParams(code.Number, code.ExpiredMiniteString())
if err := sender.Send(req); err != nil {
return "", fmt.Errorf("send verify code by sms error, %s", err)
}
message = fmt.Sprintf("验证码已通过短信发送到你的手机: %s, 请及时查收", u.Profile.Phone)
s.log.Debugf("send verify code to user: %s by sms ok", code.Username)
default:
return "", fmt.Errorf("unknown notify type %s", vc.NotifyType)
}
return message, nil
}
func (s *service) CheckCode(ctx context.Context, req *verifycode.CheckCodeRequest) (*verifycode.Code, error) {
if err := req.Validate(); err != nil {
return nil, exception.NewBadRequest("validate check code request error, %s", err)
}
code := verifycode.NewDefaultCode()
if err := s.col.FindOne(context.TODO(), bson.M{"_id": req.HashID()}).Decode(code); err != nil {
if err == mongo.ErrNoDocuments {
return nil, exception.NewNotFound("verify code: %s not found", req.Number)
}
return nil, exception.NewInternalServerError("find system config %s error, %s", req.Number, err)
}
// 校验Token是否过期
if code.IsExpired() {
return nil, exception.NewPermissionDeny("verify code is expired")
}
// 没过去验证成功, 删除
if err := s.delete(code); err != nil {
s.log.Errorf("delete check ok verify code error, %s", err)
}
return code, nil
}