bugfix(notify): Fix the bug of notify config and verify

1. 优化了报错信息
2. 将验证信息的发送由异步改成了同步,这样前端可以方便的展示验证消息发送失败的原因
3. 主动初始化webconsole的配置信息,使得websocket能够马上正常工作
4. 修复了验证信息发送失败之后联系方式状态不正确的bug
5. 去掉有关email回调地址的api
6. 修复了 update config 首次不起作用的 bug
This commit is contained in:
Rain
2019-12-18 18:29:50 +08:00
parent 2a8a9d69be
commit 1cc8dacfa6
8 changed files with 65 additions and 79 deletions

View File

@@ -118,9 +118,10 @@ func (self *NotifyModelDispatcher) UpdateConfig(ctx context.Context, body jsonut
createData.Add(jsonutils.NewString(key), "key_text")
createData.Add(jsonutils.NewString(contactType), "type")
_, err := self.Create(ctx, jsonutils.JSONNull, createData, nil)
config[key] = tmp.String()
value, _ := tmp.GetString()
config[key] = value
if err != nil {
return errors.Wrapf(err, "Create config (%s, %s, %s) failed", contactType, key, tmp)
return errors.Wrapf(err, "Create config (%s, %s, %s) failed", contactType, key, value)
}
}
// update config
@@ -250,7 +251,10 @@ func (self *NotifyModelDispatcher) VerifyTrigger(ctx context.Context, params map
return nil, httperrors.NewGeneralError(err)
}
processID := verification.ID
models.SendVerifyMessage(userCred, verification, uid, contactType, contact)
err := models.SendVerifyMessage(ctx, userCred, verification, &scontact)
if err != nil {
return nil, err
}
ret := map[string]map[string]string{
"contact": {
"process_id": processID,

View File

@@ -18,7 +18,6 @@ import (
"context"
"fmt"
"net/http"
"net/url"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
@@ -182,38 +181,6 @@ func AddNotifyDispatcher(prefix string, app *appsrv.Application) {
app.AddHandler2("POST",
fmt.Sprintf("%s/%s/delete-template", prefix, modelDispatcher.KeywordPlural()),
middleware(deleteTemplateHandler), metadata, "delete", tags)
app.AddHandler2("POST",
fmt.Sprintf("%s/%s/email-url", prefix, modelDispatcher.KeywordPlural()),
middleware(updateEmailUrlHandler), metadata, "update_email_url", tags)
app.AddHandler2("GET",
fmt.Sprintf("%s/%s/email-url", prefix, modelDispatcher.KeywordPlural()),
middleware(getEmailUrlHandler), metadata, "get_email_url", tags)
}
func updateEmailUrlHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
userCred := policy.FetchUserCredential(ctx)
if !userCred.HasSystemAdminPrivilege() {
httperrors.ForbiddenError(w, "only system admin can update email url")
return
}
_, _, _, body := fetchEnv(ctx, w, r)
if !body.Contains("email_url") {
httperrors.InputParameterError(w, "miss email_url")
}
emailUrl, _ := body.GetString("email_url")
eUrl, err := url.Parse(emailUrl)
if err != nil {
httperrors.InputParameterError(w, "invalid url")
}
models.TemplateManager.SetEmailUrl(eUrl.String())
}
func getEmailUrlHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
ret := jsonutils.NewDict()
ret.Add(jsonutils.NewString(models.TemplateManager.GetEmailUrl()), "email_url")
appsrv.Send(w, ret.PrettyString())
}
func templateUpdateHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {

View File

@@ -25,6 +25,7 @@ import (
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/mcclient"
_interface "yunion.io/x/onecloud/pkg/notify/interface"
"yunion.io/x/onecloud/pkg/notify/options"
)
type SConfigManager struct {
@@ -89,6 +90,47 @@ func (self *SConfigManager) InitializeData() error {
sql = fmt.Sprintf("update %s set type='mobile' where type='sms_aliyun'", self.TableSpec().Name())
q = sqlchemy.NewRawQuery(sql, "")
q.Row()
// init webconsole's config
q = self.Query().Equals("type", "webconsole")
n, err := q.CountWithError()
if err != nil {
return err
}
if n >= 4 {
return nil
}
sql = fmt.Sprintf("update %s set deleted='1' where type='webconsole'", self.TableSpec().Name())
q = sqlchemy.NewRawQuery(sql)
q.Row()
configs := []SConfig{
{
Type: "webconsole",
KeyText: "auth_uri",
ValueText: options.Options.AuthURL,
},
{
Type: "webconsole",
KeyText: "admin_user",
ValueText: options.Options.AdminUser,
},
{
Type: "webconsole",
KeyText: "admin_password",
ValueText: options.Options.AdminPassword,
},
{
Type: "webconsole",
KeyText: "admin_tenant_name",
ValueText: options.Options.AdminProject,
},
}
for _, config := range configs {
err := self.TableSpec().Insert(&config)
if err != nil {
return err
}
}
return nil
}

View File

@@ -22,7 +22,6 @@ import (
"io/ioutil"
"os"
"strings"
"sync"
ptem "text/template"
"yunion.io/x/jsonutils"
@@ -31,6 +30,7 @@ import (
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/notify/options"
"yunion.io/x/onecloud/pkg/notify/rpc/apis"
"yunion.io/x/onecloud/pkg/notify/template"
)
@@ -58,12 +58,6 @@ const (
TEMPLATE_TYPE_REMOTE = "remote"
)
var (
DefaultEmailUrl = ""
EmailUrl = ""
EmailUrlLock sync.RWMutex
)
type STemplate struct {
SStandaloneResourceBase
@@ -76,18 +70,7 @@ type STemplate struct {
}
func (tm *STemplateManager) GetEmailUrl() string {
EmailUrlLock.RLock()
defer EmailUrlLock.RUnlock()
if len(EmailUrl) == 0 {
return DefaultEmailUrl
}
return EmailUrl
}
func (tm *STemplateManager) SetEmailUrl(url string) {
EmailUrlLock.Lock()
defer EmailUrlLock.Unlock()
EmailUrl = url
return options.Options.VerifyEmailUrl
}
func (tm *STemplateManager) InitializeData() error {

View File

@@ -22,12 +22,11 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/appsrv"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/notifyclient"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/modules/notify"
"yunion.io/x/onecloud/pkg/notify/utils"
)
@@ -69,25 +68,19 @@ func RestartService(config map[string]string, serviceName string) {
}, nil, nil)
}
func SendVerifyMessage(userCred mcclient.TokenCredential, verify *SVerify, uid, contactType, contact string) {
workMan.Run(func() {
sendVerifyMessage(context.Background(), userCred, verify, uid, contactType, contact)
}, nil, nil)
}
func sendVerifyMessage(ctx context.Context, userCred mcclient.TokenCredential, verify *SVerify, uid, contactType,
contact string) {
func SendVerifyMessage(ctx context.Context, userCred mcclient.TokenCredential, verify *SVerify,
contact *SContact) error {
var (
err error
msg string
)
processId, token := verify.ID, verify.Token
if contactType == "email" {
if contact.ContactType == "email" {
emailUrl := strings.Replace(TemplateManager.GetEmailUrl(), "{0}", processId, 1)
emailUrl = strings.Replace(emailUrl, "{1}", token, 1)
// get uName
uName, err := utils.GetUsernameByID(ctx, uid)
uName, err := utils.GetUsernameByID(ctx, contact.UID)
if err != nil || len(uName) == 0 {
uName = "用户"
}
@@ -96,23 +89,23 @@ func sendVerifyMessage(ctx context.Context, userCred mcclient.TokenCredential, v
Link string
}{uName, emailUrl}
msg = jsonutils.Marshal(data).String()
} else if contactType == "mobile" {
} else if contact.ContactType == "mobile" {
msg = fmt.Sprintf(`{"code": "%s"}`, token)
} else {
// todo
return
return nil
}
err = NotifyService.Send(ctx, contactType, contact, "verify", msg, "")
err = NotifyService.Send(ctx, contact.ContactType, contact.Contact, "verify", msg, "")
if err != nil {
verify.SetStatus(userCred, VERIFICATION_SENT_FAIL, "")
// notify the uid through the webconsole
notifyclient.RawNotify([]string{uid}, false, notify.NotifyByWebConsole, notify.NotifyPriorityCritical,
"Send Verify Message Failed", jsonutils.NewString(err.Error()))
// set contact's status as "init"
contact.SetStatus(userCred, CONTACT_INIT, "send verify message failed")
log.Errorf("Send verify message failed: %s.", err.Error())
return
return errors.Wrap(err, "Send Verify Message Failed")
}
verify.SetStatus(userCred, VERIFICATION_SENT, "")
return nil
}
func UpdateDingtalk(uid string) {

View File

@@ -27,7 +27,7 @@ type NotifyOption struct {
UpdateInterval int `help:"Update send services interval(unit:s)" default:"30"`
VerifyEmailUrl string `help:"url of verify email"`
ReSendScope int `help:"Resend all messages that have not been sent successfully within ReSendScope
seconds"`
seconds" default:"30"`
InitNotificationScope int `help:"initialize data of notification with in InitNotificationScope hours" default:"100"`
}

View File

@@ -124,7 +124,7 @@ func (self *SRpcService) Send(ctx context.Context, contactType, contact, topic,
_, err = self.execute(ctx, f, contactType)
if err != nil {
return errors.Wrapf(err, "contactType: %s", contactType)
return errors.Wrapf(err, "contactType '%s'", contactType)
}
return nil
}

View File

@@ -43,9 +43,6 @@ func StartService() {
baseOpts := &options.Options.BaseOptions
common_options.ParseOptions(opts, os.Args, "notify.conf", "notify")
// init email url
models.TemplateManager.SetEmailUrl(options.Options.VerifyEmailUrl)
// init auth
app.InitAuth(commonOpts, func() {
log.Infof("Auth complete!")