feat(notify): support international mobile

This commit is contained in:
rainzm
2021-01-22 19:57:31 +08:00
parent 9e7cb17c01
commit bdb6df6e4d
6 changed files with 85 additions and 24 deletions
+37 -6
View File
@@ -15,6 +15,9 @@
package notify
import (
"fmt"
"regexp"
"yunion.io/x/onecloud/pkg/apis"
)
@@ -35,20 +38,50 @@ type ReceiverCreateInput struct {
// example: example@gmail.com
Email string `json:"email"`
// description: user mobile
// example: 17812345678
Mobile string `json:"mobile"`
InternationalMobile SInternationalMobile `json:"international_mobile"`
// description: enabled contact types for user
// example: {"email", "mobile", "feishu", "dingtalk", "workwx"}
EnabledContactTypes []string `json:"enabled_contact_types"`
}
type SInternationalMobile struct {
// description: user mobile
// example: 17812345678
Mobile string `json:"mobile"`
// description: area code of mobile
// example: 86
AreaCode string `json:"area_code"`
}
var pareser = regexp.MustCompile(`\+(\d*) (.*)`)
func ParseInternationalMobile(mobile string) SInternationalMobile {
matchs := pareser.FindStringSubmatch(mobile)
if len(matchs) == 0 {
return SInternationalMobile{
Mobile: mobile,
}
}
return SInternationalMobile{
Mobile: matchs[2],
AreaCode: matchs[1],
}
}
func (im SInternationalMobile) String() string {
if im.AreaCode == "" {
return im.Mobile
}
return fmt.Sprintf("+%s %s", im.AreaCode, im.Mobile)
}
type ReceiverDetails struct {
apis.StatusStandaloneResourceDetails
apis.DomainizedResourceInfo
SReceiver
InternationalMobile SInternationalMobile `json:"international_mobile"`
// description: enabled contact types for user
// example: eamil, mobile, feishu, dingtalk, workwx
@@ -85,9 +118,7 @@ type ReceiverUpdateInput struct {
// example: example@gmail.com
Email string `json:"email"`
// description: user mobile
// example: 17812345678
Mobile string `json:"mobile"`
InternationalMobile SInternationalMobile `json:"international_mobile"`
// description: enabled contacts for user
// example: {"email", "mobile", "feishu", "dingtalk", "workwx"}
+1 -2
View File
@@ -45,8 +45,7 @@ type SReceiver struct {
apis.SStatusStandaloneResourceBase
apis.SDomainizedResourceBase
apis.SEnabledResourceBase
Email string `json:"email"`
Mobile string `json:"mobile"`
Email string `json:"email"`
// swagger:ignore
EnabledEmail *bool `json:"enabled_email,omitempty"`
// swagger:ignore
+1 -1
View File
@@ -32,7 +32,7 @@ func init() {
NotifyReceiver = NewNotifyv2Manager(
"receiver",
"receivers",
[]string{"ID", "Name", "Email", "Mobile", "Enabled_Contact_Types", "Verified_Infos"},
[]string{"ID", "Name", "Email", "International_Mobile", "Enabled_Contact_Types", "Verified_Infos"},
[]string{},
)
register(&NotifyReceiver)
+27 -10
View File
@@ -22,11 +22,18 @@ type ReceiverCreateOptions struct {
UID string `help:"user id in keystone"`
Email string `help:"email of receiver"`
Mobile string `help:"mobile of receiver"`
MobileAreaCode string `help:"area code of mobile"`
EnabledContactTypes []string `help:"enabled contact type"`
}
func (rc *ReceiverCreateOptions) Params() (jsonutils.JSONObject, error) {
return options.StructToParams(rc)
d := jsonutils.NewDict()
d.Set("uid", jsonutils.NewString(rc.UID))
d.Set("email", jsonutils.NewString(rc.Email))
d.Set("enabled_contact_type", jsonutils.NewStringArray(rc.EnabledContactTypes))
d.Add(jsonutils.NewString(rc.Mobile), "international_mobile", "mobile")
d.Add(jsonutils.NewString(rc.MobileAreaCode), "international_mobile", "area_code")
return d, nil
}
type ReceiverOptions struct {
@@ -43,44 +50,54 @@ func (r *ReceiverOptions) Params() (jsonutils.JSONObject, error) {
type ReceiverUpdateOptions struct {
ReceiverOptions
receiverUpdateOptions
SreceiverUpdateOptions
}
type receiverUpdateOptions struct {
type SreceiverUpdateOptions struct {
Email string `help:"email of receiver"`
Mobile string `help:"mobile of receiver"`
MobileAreaCode string `help:"area code of mobile"`
EnabledContactType []string `help:"enabled contact type"`
}
func (ru *ReceiverUpdateOptions) Params() (jsonutils.JSONObject, error) {
return jsonutils.Marshal(ru.receiverUpdateOptions), nil
d := jsonutils.NewDict()
if len(ru.Email) > 0 {
d.Set("email", jsonutils.NewString(ru.Email))
}
d.Set("enabled_contact_types", jsonutils.NewStringArray(ru.EnabledContactType))
if len(ru.Mobile) > 0 {
d.Add(jsonutils.NewString(ru.Mobile), "international_mobile", "mobile")
d.Add(jsonutils.NewString(ru.MobileAreaCode), "international_mobile", "area_code")
}
return d, nil
}
type ReceiverTriggerVerifyOptions struct {
ReceiverOptions
receiverTriggerVerifyOptions
SreceiverTriggerVerifyOptions
}
type receiverTriggerVerifyOptions struct {
type SreceiverTriggerVerifyOptions struct {
ContactType string `help:"Contact type to trigger verify" choices:"email|mobile"`
}
func (rt *ReceiverTriggerVerifyOptions) Params() (jsonutils.JSONObject, error) {
return jsonutils.Marshal(rt.receiverTriggerVerifyOptions), nil
return jsonutils.Marshal(rt.SreceiverTriggerVerifyOptions), nil
}
type ReceiverVerifyOptions struct {
ReceiverOptions
receiverVerifyOptions
SreceiverVerifyOptions
}
type receiverVerifyOptions struct {
type SreceiverVerifyOptions struct {
ContactType string `help:"Contact type to trigger verify" choices:"email|mobile"`
Token string `help:"Token from verify message sent to you"`
}
func (rv *ReceiverVerifyOptions) Params() (jsonutils.JSONObject, error) {
return jsonutils.Marshal(rv.receiverVerifyOptions), nil
return jsonutils.Marshal(rv.SreceiverVerifyOptions), nil
}
type ReceiverIntellijGetOptions struct {
+13 -5
View File
@@ -97,8 +97,9 @@ type SReceiver struct {
db.SDomainizedResourceBase
db.SEnabledResourceBase
Email string `width:"64" nullable:"false" create:"optional" update:"user" get:"user" list:"user"`
Mobile string `width:"16" nullable:"false" create:"optional" update:"user" get:"user" list:"user"`
Email string `width:"64" nullable:"false" create:"optional" update:"user" get:"user" list:"user"`
// swagger:ignore
Mobile string `width:"32" nullable:"false" create:"optional"`
Lang string `width:"8" charset:"ascii" nullable:"false" list:"user" update:"user"`
// swagger:ignore
@@ -280,7 +281,7 @@ func (rm *SReceiverManager) ValidateCreateData(ctx context.Context, userCred mcc
return input, httperrors.NewInputParameterError("invalid email")
}
// validate mobile
if ok := LaxMobileRegexp.MatchString(input.Mobile); len(input.Mobile) > 0 && !ok {
if ok := LaxMobileRegexp.MatchString(input.InternationalMobile.Mobile); len(input.InternationalMobile.Mobile) > 0 && !ok {
return input, httperrors.NewInputParameterError("invalid mobile")
}
return input, nil
@@ -601,6 +602,7 @@ func (rm *SReceiverManager) FetchCustomizeColumns(ctx context.Context, userCred
rows[i].StatusStandaloneResourceDetails = sRows[i]
rows[i].DomainizedResourceInfo = dRows[i]
user := objs[i].(*SReceiver)
rows[i].InternationalMobile = api.ParseInternationalMobile(user.Mobile)
if enabledCTs, err := user.GetEnabledContactTypes(); err != nil {
log.Errorf("GetEnabledContactTypes: %v", err)
} else {
@@ -662,6 +664,7 @@ func (r *SReceiver) CustomizeCreate(ctx context.Context, userCred mcclient.Token
if input.Enabled == nil {
r.Enabled = tristate.True
}
r.Mobile = input.InternationalMobile.String()
err = r.SetEnabledContactTypes(input.EnabledContactTypes)
if err != nil {
return errors.Wrap(err, "SetEnabledContactTypes")
@@ -684,7 +687,7 @@ func (r *SReceiver) ValidateUpdateData(ctx context.Context, userCred mcclient.To
return input, httperrors.NewInputParameterError("invalid email")
}
// validate mobile
if ok := len(input.Mobile) == 0 || LaxMobileRegexp.MatchString(input.Mobile); !ok {
if ok := len(input.InternationalMobile.Mobile) == 0 || LaxMobileRegexp.MatchString(input.InternationalMobile.Mobile); !ok {
return input, httperrors.NewInputParameterError("invalid mobile")
}
return input, nil
@@ -702,6 +705,9 @@ func (r *SReceiver) PreUpdate(ctx context.Context, userCred mcclient.TokenCreden
log.Errorf("PullCache: %v", err)
}
err = r.SetEnabledContactTypes(input.EnabledContactTypes)
if err != nil {
log.Errorf("unable to SetEnabledContactTypes")
}
if len(input.Email) != 0 && input.Email != r.Email {
r.VerifiedEmail = tristate.False
for _, c := range r.subContactCache {
@@ -711,8 +717,10 @@ func (r *SReceiver) PreUpdate(ctx context.Context, userCred mcclient.TokenCreden
}
}
}
if len(input.Mobile) != 0 && input.Mobile != r.Mobile {
mobile := input.InternationalMobile.String()
if len(mobile) != 0 && mobile != r.Mobile {
r.VerifiedMobile = tristate.False
r.Mobile = mobile
for _, c := range r.subContactCache {
if c.ParentContactType == api.MOBILE {
c.Verified = tristate.False
+6
View File
@@ -31,6 +31,7 @@ import (
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/notify"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/notify"
notifyv2 "yunion.io/x/onecloud/pkg/notify"
@@ -176,6 +177,11 @@ func (self *SRpcService) RestartService(ctx context.Context, config notifyv2.SCo
func (self *SRpcService) ContactByMobile(ctx context.Context, mobile, serviceName string) (string, error) {
iMobile := api.ParseInternationalMobile(mobile)
// compatible
if iMobile.AreaCode == "86" {
mobile = iMobile.Mobile
}
args := apis.UseridByMobileParams{}
args.Mobile = mobile