Create & Init Project...

This commit is contained in:
2019-04-22 18:49:16 +08:00
commit fc4fa37393
25440 changed files with 4054998 additions and 0 deletions

View File

@@ -0,0 +1,69 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"account_test.go",
"bfs_test.go",
"commercial_test.go",
"official_test.go",
"settings_test.go",
"sms_test.go",
"vip_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/account/conf:go_default_library",
"//library/ecode:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"account.go",
"bfs.go",
"commercial.go",
"official.go",
"settings.go",
"sms.go",
"vip.go",
],
importpath = "go-common/app/interface/main/account/dao/account",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/account/conf:go_default_library",
"//app/interface/main/account/model:go_default_library",
"//library/cache/memcache:go_default_library",
"//library/cache/redis:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/xstr:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,45 @@
package account
import (
"go-common/app/interface/main/account/conf"
"go-common/library/cache/memcache"
"go-common/library/cache/redis"
bm "go-common/library/net/http/blademaster"
xhttp "net/http"
"time"
)
// consts
const (
_cmIsBusinessAccount = "/basc/api/open_api/v1/up/business_account/is_sign_up"
_cmBusinessAccountInfo = "/basc/api/open_api/v1/up/bus_account_info"
)
// Dao dao
type Dao struct {
c *conf.Config
client *bm.Client
accCom string
accCo string
vipHost string
smsSendURI string
bfsClient *xhttp.Client
mc *memcache.Pool
redis *redis.Pool
}
// New new
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
client: bm.NewClient(c.HTTPClient.Normal),
accCom: c.Host.AccCom,
accCo: c.Host.AccCo,
vipHost: c.Host.Vip,
smsSendURI: c.Host.API + _smsSendURI,
bfsClient: &xhttp.Client{Timeout: time.Duration(c.BFS.Timeout)},
mc: memcache.NewPool(c.AccMemcache),
redis: redis.NewPool(c.AccRedis),
}
return
}

View File

@@ -0,0 +1,35 @@
package account
import (
"flag"
"go-common/app/interface/main/account/conf"
"os"
"testing"
)
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.account.account-interface")
flag.Set("conf_token", "967eef77ad40b478234f11b0d489d6d6")
flag.Set("tree_id", "3815")
flag.Set("conf_version", "docker-1")
flag.Set("deploy_env", "uat")
flag.Set("conf_host", "config.bilibili.co")
flag.Set("conf_path", "/tmp")
flag.Set("region", "sh")
flag.Set("zone", "sh001")
} else {
flag.Set("conf", "../../cmd/account-interface-example.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
m.Run()
os.Exit(0)
}

View File

@@ -0,0 +1,75 @@
package account
import (
"bytes"
"context"
"crypto/hmac"
"crypto/sha1"
"encoding/base64"
"fmt"
"hash"
"net/http"
"strconv"
"time"
"go-common/app/interface/main/account/conf"
"go-common/library/ecode"
"go-common/library/log"
"github.com/pkg/errors"
)
// UploadImage upload bfs.
func (d *Dao) UploadImage(c context.Context, fileType string, bs []byte, bfs *conf.BFS) (location string, err error) {
url := bfs.URL + bfs.Bucket + "/"
req, err := http.NewRequest(bfs.Method, url, bytes.NewBuffer(bs))
if err != nil {
log.Error("account-interface: http.NewRequest error (%v) | fileType(%s)", err, fileType)
return
}
expire := time.Now().Unix()
authorization := authorize(bfs.Key, bfs.Secret, bfs.Method, bfs.Bucket, expire)
req.Header.Set("Host", url)
req.Header.Add("Date", fmt.Sprint(expire))
req.Header.Add("Authorization", authorization)
req.Header.Add("Content-Type", fileType)
// timeout
ctx, cancel := context.WithTimeout(c, time.Duration(d.c.BFS.Timeout))
req = req.WithContext(ctx)
defer cancel()
resp, err := d.bfsClient.Do(req)
if err != nil {
log.Error("account-interface: d.Client.Do error(%v) | url(%s)", err, url)
err = ecode.BfsUploadServiceUnavailable
return
}
if resp.StatusCode != http.StatusOK {
log.Error("account-interface: Upload http.StatusCode nq http.StatusOK (%d) | url(%s)", resp.StatusCode, d.c.BFS.URL)
err = errors.New("Upload failed")
return
}
header := resp.Header
code := header.Get("Code")
if code != strconv.Itoa(http.StatusOK) {
log.Error("account-interface: strconv.Itoa err, code(%s) | url(%s)", code, url)
err = errors.New("Upload failed")
return
}
location = header.Get("Location")
return
}
// authorize returns authorization for upload file to bfs
func authorize(key, secret, method, bucket string, expire int64) (authorization string) {
var (
content string
mac hash.Hash
signature string
)
content = fmt.Sprintf("%s\n%s\n\n%d\n", method, bucket, expire)
mac = hmac.New(sha1.New, []byte(secret))
mac.Write([]byte(content))
signature = base64.StdEncoding.EncodeToString(mac.Sum(nil))
authorization = fmt.Sprintf("%s:%s:%d", key, signature, expire)
return
}

View File

@@ -0,0 +1,39 @@
package account
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestAccountUploadImage(t *testing.T) {
var (
c = context.Background()
fileType = "jpg"
bs = []byte("dangerous")
)
convey.Convey("UploadImage", t, func(ctx convey.C) {
location, err := d.UploadImage(c, fileType, bs, d.c.BFS)
ctx.Convey("Then err should be nil.location should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(location, convey.ShouldNotBeNil)
})
})
}
func TestAccountauthorize(t *testing.T) {
var (
key = ""
secret = ""
method = ""
bucket = ""
expire = int64(0)
)
convey.Convey("authorize", t, func(ctx convey.C) {
authorization := authorize(key, secret, method, bucket, expire)
ctx.Convey("Then authorization should not be nil.", func(ctx convey.C) {
ctx.So(authorization, convey.ShouldNotBeNil)
})
})
}

View File

@@ -0,0 +1,149 @@
package account
import (
"context"
"crypto/md5"
"encoding/hex"
"net/http"
"net/url"
"strconv"
"strings"
"time"
"go-common/app/interface/main/account/model"
"go-common/library/log"
"go-common/library/xstr"
"github.com/pkg/errors"
)
// CommercialSign is
// 商业产品部专用签名
func CommercialSign(params url.Values) (query string, err error) {
if len(params) == 0 {
return
}
if params.Get("appkey") == "" {
err = errors.New("utils http get must have parameter appkey")
return
}
if params.Get("appsecret") == "" {
err = errors.New("utils http get must have parameter appsecret")
return
}
if params.Get("sign") != "" {
err = errors.New("utils http get must have not parameter sign")
return
}
// sign
secret := params.Get("appsecret")
params.Del("appsecret")
tmp := params.Encode()
if strings.IndexByte(tmp, '+') > -1 {
tmp = strings.Replace(tmp, "+", "%20", -1)
}
mh := md5.Sum([]byte(tmp + secret))
params.Set("sign", hex.EncodeToString(mh[:]))
query = params.Encode()
return
}
func (d *Dao) isBusinessAccount(ctx context.Context, mids []int64) (map[int64]bool, error) {
cm := d.c.HTTPClient.Normal.Host[d.c.Host.CM]
params := url.Values{}
params.Set("mids", xstr.JoinInts(mids))
params.Set("appkey", cm.Key)
params.Set("appsecret", cm.Secret)
params.Set("ts", strconv.FormatInt(time.Now().UnixNano()/1000000, 10))
query, err := CommercialSign(params)
if err != nil {
return nil, err
}
u, err := url.Parse(d.c.Host.CM)
if err != nil {
return nil, errors.WithStack(err)
}
u.Path = _cmIsBusinessAccount
u.RawQuery = query
req, err := http.NewRequest("GET", u.String(), nil)
if err != nil {
return nil, errors.WithStack(err)
}
req.Header.Set("Accept", "application/json")
resp := &struct {
Code int `json:"int"`
Success bool `json:"success"`
Message string `json:"message"`
Data map[string]bool `json:"data"`
}{}
if err := d.client.Do(ctx, req, resp); err != nil {
return nil, errors.WithStack(err)
}
if !resp.Success {
return nil, errors.Errorf("Failed to request cm api: %+v", resp)
}
res := make(map[int64]bool, len(resp.Data))
for smid, isBus := range resp.Data {
mid, err := strconv.ParseInt(smid, 10, 64)
if err != nil {
log.Warn("Failed to parse mid: %s: %+v", smid, err)
continue
}
res[mid] = isBus
}
return res, nil
}
// IsBusinessAccount is
func (d *Dao) IsBusinessAccount(ctx context.Context, mid int64) bool {
res, err := d.isBusinessAccount(ctx, []int64{mid})
if err != nil {
log.Error("Failed to check is business account with mid: %d: %+v", mid, err)
return false
}
return res[mid]
}
// BusinessAccountInfo is
func (d *Dao) BusinessAccountInfo(ctx context.Context, mid int64) (*model.CMAccountInfo, error) {
cm := d.c.HTTPClient.Normal.Host[d.c.Host.CM]
params := url.Values{}
params.Set("mid", strconv.FormatInt(mid, 10))
params.Set("appkey", cm.Key)
params.Set("appsecret", cm.Secret)
params.Set("ts", strconv.FormatInt(time.Now().UnixNano()/1000000, 10))
query, err := CommercialSign(params)
if err != nil {
return nil, err
}
u, err := url.Parse(d.c.Host.CM)
if err != nil {
return nil, errors.WithStack(err)
}
u.Path = _cmBusinessAccountInfo
u.RawQuery = query
req, err := http.NewRequest("GET", u.String(), nil)
if err != nil {
return nil, errors.WithStack(err)
}
req.Header.Set("Accept", "application/json")
res := &struct {
Code int `json:"int"`
Success bool `json:"success"`
Message string `json:"message"`
Data model.CMAccountInfo `json:"data"`
}{}
if err := d.client.Do(ctx, req, res); err != nil {
return nil, errors.WithStack(err)
}
if !res.Success {
return nil, errors.Errorf("Failed to request cm api: %+v", res)
}
return &res.Data, nil
}

View File

@@ -0,0 +1,75 @@
package account
import (
"context"
"net/url"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestAccountCommercialSign(t *testing.T) {
var (
params = url.Values{}
)
params.Set("appkey", "test")
params.Set("appsecret", "e6c4c252dc7e3d8a90805eecd7c73396")
params.Set("key", "value")
result := url.Values{}
result.Set("appkey", "test")
result.Set("key", "value")
result.Set("sign", "f5c7329e9078e94ebf7d5852dfcd64f9")
convey.Convey("CommercialSign", t, func(ctx convey.C) {
query, err := CommercialSign(params)
ctx.Convey("Then err should be nil.query should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(query, convey.ShouldEqual, result.Encode())
})
})
}
func TestAccountisBusinessAccount(t *testing.T) {
var (
mids = []int64{1, 2, 3}
)
convey.Convey("isBusinessAccount", t, func(ctx convey.C) {
p1, err := d.isBusinessAccount(context.Background(), mids)
ctx.Convey("Then err should be nil.p1 should not be nil.", func(ctx convey.C) {
if err != nil {
ctx.Printf("Failed to validate business account: %+v\n", err)
return
}
// ctx.So(err, convey.ShouldBeNil)
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestAccountIsBusinessAccount(t *testing.T) {
var (
mid = int64(0)
)
convey.Convey("IsBusinessAccount", t, func(ctx convey.C) {
p1 := d.IsBusinessAccount(context.Background(), mid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestAccountBusinessAccountInfo(t *testing.T) {
var (
mid = int64(0)
)
convey.Convey("BusinessAccountInfo", t, func(ctx convey.C) {
p1, err := d.BusinessAccountInfo(context.Background(), mid)
ctx.Convey("Then err should be nil.p1 should not be nil.", func(ctx convey.C) {
if err != nil {
ctx.Printf("Failed to get business account info: %+v\n", err)
return
}
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}

View File

@@ -0,0 +1,54 @@
package account
import (
"context"
"fmt"
"time"
"go-common/library/cache/redis"
)
const (
_oneMonth = 31 * 24 * 60 * 60
)
func keyMonthlyOfficialSubmittedTimes(t time.Time, mid int64) string {
return fmt.Sprintf("ot_%d_%d", t.Month(), mid)
}
// IncreaseMonthlyOfficialSubmittedTimes is
func (d *Dao) IncreaseMonthlyOfficialSubmittedTimes(ctx context.Context, mid int64) (int64, error) {
key := keyMonthlyOfficialSubmittedTimes(time.Now(), mid)
conn := d.redis.Get(ctx)
defer conn.Close()
conn.Send("INCR", key)
conn.Send("EXPIRE", key, _oneMonth)
if err := conn.Flush(); err != nil {
return 0, err
}
new, err := redis.Int64(conn.Receive())
if err != nil {
return 0, err
}
conn.Receive() // drain the pipe line
return new, nil
}
// GetMonthlyOfficialSubmittedTimes is
func (d *Dao) GetMonthlyOfficialSubmittedTimes(ctx context.Context, mid int64) (int64, error) {
key := keyMonthlyOfficialSubmittedTimes(time.Now(), mid)
conn := d.redis.Get(ctx)
defer conn.Close()
v, err := redis.Int64(conn.Do("GET", key))
if err != nil {
if err == redis.ErrNil {
return 0, nil
}
return 0, err
}
return v, nil
}

View File

@@ -0,0 +1,38 @@
package account
import (
"context"
"fmt"
"testing"
"time"
"github.com/smartystreets/goconvey/convey"
)
func TestKeyMonthlyOfficialSubmittedTimes(t *testing.T) {
convey.Convey("keyMonthlyOfficialSubmittedTimes", t, func(ctx convey.C) {
now := time.Now()
key := keyMonthlyOfficialSubmittedTimes(now, 1)
ctx.So(key, convey.ShouldEqual, fmt.Sprintf("ot_%d_%d", now.Month(), 1))
})
}
func TestIncreaseMonthlyOfficialSubmittedTimes(t *testing.T) {
convey.Convey("IncreaseMonthlyOfficialSubmittedTimes", t, func(ctx convey.C) {
p1, err := d.IncreaseMonthlyOfficialSubmittedTimes(context.Background(), 1)
ctx.Convey("Then err should be nil.p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestGetMonthlyOfficialSubmittedTimes(t *testing.T) {
convey.Convey("GetMonthlyOfficialSubmittedTimes", t, func(ctx convey.C) {
p1, err := d.GetMonthlyOfficialSubmittedTimes(context.Background(), 1)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
ctx.So(err, convey.ShouldBeNil)
})
})
}

View File

@@ -0,0 +1,238 @@
package account
import (
"bytes"
"context"
"crypto/md5"
"encoding/hex"
xhttp "net/http"
"net/url"
"strconv"
"strings"
"time"
"go-common/app/interface/main/account/model"
"go-common/library/ecode"
"go-common/library/log"
)
var (
updateFaceURI = "/api/user/updateFace"
identifyURI = "/api/internal/identify/info"
updateBirthURI = "/api/internal/member/updateBirthday"
updateSexURI = "/api/internal/member/updateSex"
// updatePerson = "/api/internal/member/updatePerson"
// updateUnameURI = "/api/internal/member/updateUname"
)
// UpdateBirthday is
func (d *Dao) UpdateBirthday(c context.Context, mid int64, ip, birthday string) (err error) {
params := url.Values{}
params.Set("mid", strconv.FormatInt(mid, 10))
params.Set("birthday", birthday)
var res struct {
Code int `json:"code"`
}
if err = d.client.Post(c, d.accCo+updateBirthURI, ip, params, &res); err != nil {
log.Error("UpdateBirthday url(%s) error(%v)", updateBirthURI+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
log.Error("UpdateBirthday url(%s) code(%v)", updateBirthURI+"?"+params.Encode(), res.Code)
err = ecode.Int(res.Code)
}
return
}
// UpdateSign update sign.
// func (d *Dao) UpdateSign(c context.Context, mid int64, ip, sign string) (err error) {
// params := url.Values{}
// params.Set("mid", strconv.FormatInt(mid, 10))
// params.Set("user_sign", sign)
// var res struct {
// Code int `json:"code"`
// }
// if err = d.client.Post(c, d.accCo+updateSignURI, ip, params, &res); err != nil {
// log.Error("UpdateSign url(%s) error(%v)", updateBirthURI+"?"+params.Encode(), err)
// return
// }
// if res.Code != 0 {
// log.Error("UpdateSign url(%s) code(%v)", updateBirthURI+"?"+params.Encode(), res.Code)
// err = ParseJavaCode(res.Code)
// }
// return
// }
// UpdateSex update sex
func (d *Dao) UpdateSex(c context.Context, mid, sex int64, ip string) (err error) {
params := url.Values{}
params.Set("mid", strconv.FormatInt(mid, 10))
params.Set("sex", strconv.FormatInt(sex, 10))
var res struct {
Code int `json:"code"`
}
if err = d.client.Post(c, d.accCo+updateSexURI, ip, params, &res); err != nil {
log.Error("UpdateSex url(%s) error(%v)", updateSexURI+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
log.Error("UpdateSex url(%s) error(%v)", updateSexURI+"?"+params.Encode(), res.Code)
err = ecode.Int(res.Code)
}
return
}
// UpdatePerson update sex
// func (d *Dao) UpdatePerson(c context.Context, mid int64, birthday, ip string, datingType, marital, place int64) (err error) {
// params := url.Values{}
// params.Set("mid", strconv.FormatInt(mid, 10))
// params.Set("birthday", birthday)
// params.Set("datingtype", strconv.FormatInt(datingType, 10))
// params.Set("marital", strconv.FormatInt(marital, 10))
// params.Set("place", strconv.FormatInt(place, 10))
// var res struct {
// Code int `json:"code"`
// }
// if err = d.client.Post(c, d.accCo+updatePerson, ip, params, &res); err != nil {
// log.Error("UpdatePerson url(%s) error(%v)", updatePerson+"?"+params.Encode(), err)
// return
// }
// if res.Code != 0 {
// log.Error("UpdatePerson url(%s) error(%v)", updatePerson+"?"+params.Encode(), res.Code)
// err = ecode.Int(res.Code)
// }
// return
// }
// UpdateUname update uname.
// func (d *Dao) UpdateUname(c context.Context, mid int64, ip, uname string, isUpNickFree bool) (err error) {
// params := url.Values{}
// params.Set("mid", strconv.FormatInt(mid, 10))
// params.Set("uname", uname)
// params.Set("isupnick_free", strconv.FormatBool(isUpNickFree))
// var res struct {
// Code int `json:"code"`
// }
// if err = d.client.Post(c, d.accCo+updateUnameURI, ip, params, &res); err != nil {
// log.Error("UpdateUname url(%s) error(%v)", updateUnameURI+"?"+params.Encode(), err)
// return
// }
// if res.Code != 0 {
// log.Error("UpdateUname url(%s) code(%v)", updateUnameURI+"?"+params.Encode(), res.Code)
// err = ParseJavaCode(res.Code)
// }
// return
// }
// UpdateFace update face
func (d *Dao) UpdateFace(c context.Context, mid int64, face string, ip, cookie, accessKey string) (faceURL string, err error) {
var (
params = url.Values{}
fu = url.Values{}
req *xhttp.Request
)
log.Info("start UpdateFace %d,cookie: %v", mid, cookie)
params.Set("mid", strconv.FormatInt(mid, 10))
params.Set("ts", strconv.FormatInt(time.Now().Unix(), 10))
params.Set("access_key", accessKey)
var url = d.accCom + updateFaceURI + "?" + d.sign(&params)
fu.Set("face", face)
if req, err = xhttp.NewRequest("POST", url, bytes.NewBuffer([]byte(fu.Encode()))); err != nil {
log.Error("http.NewRequest, err(%v)", err)
return
}
req.Header.Set("Cookie", cookie)
req.Header.Set("content-type", "application/x-www-form-urlencoded")
var res struct {
Code int `json:"code"`
Data struct {
Face string `json:"face"`
} `json:"data"`
Message string `json:"message"`
}
if err = d.client.Do(c, req, &res); err != nil {
log.Error("UpdateFace url(%v), err(%v)", url, err)
return
}
if res.Code != 0 {
log.Error("UpdateFace failed, url(%v) res(%v)", url, res)
err = ParseJavaCode(res.Code)
return
}
faceURL = res.Data.Face
log.Info("end success UpdateFace %d, %v", mid, faceURL)
return
}
// ParseJavaCode is
func ParseJavaCode(code int) (err error) {
switch code {
case -617:
err = ecode.UpdateUnameHadLocked
case -618:
err = ecode.UpdateUnameRepeated
case -655:
err = ecode.UpdateUnameMoneyIsNot
case -610:
err = ecode.MemberBlocked
case -602:
err = ecode.UpdateUnameTooShort
case -603:
err = ecode.UpdateUnameSensitive
case -601:
err = ecode.UpdateUnameTooLong
case -605:
err = ecode.UpdateUnameFormat
case -1001:
err = ecode.MemberSignHasEmoji
case -40012:
err = ecode.UpdateFaceFormat
case -40013:
err = ecode.UpdateFaceSize
default:
err = ecode.Int(code)
}
return
}
func (d *Dao) sign(params *url.Values) (query string) {
params.Set("appkey", d.c.App.Key)
tmp := params.Encode()
if strings.IndexByte(tmp, '+') > -1 {
tmp = strings.Replace(tmp, "+", "%20", -1)
}
var b bytes.Buffer
b.WriteString(tmp)
b.WriteString(d.c.App.Secret)
mh := md5.Sum(b.Bytes())
// query
var qb bytes.Buffer
qb.WriteString(tmp)
qb.WriteString("&sign=")
qb.WriteString(hex.EncodeToString(mh[:]))
query = qb.String()
return
}
// IdentifyInfo get identify info by calling api.
func (d *Dao) IdentifyInfo(c context.Context, mid int64, ip string) (idt *model.IdentifyInfo, err error) {
params := url.Values{}
params.Set("mid", strconv.FormatInt(mid, 10))
var res struct {
Code int `json:"code"`
Data *model.IdentifyInfo `json:"data"`
}
err = d.client.Get(c, d.accCo+identifyURI, ip, params, &res)
if err != nil {
log.Error("dao.client.Get(%s) error(%v)", d.accCo+identifyURI+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
log.Error("identifyInfo url(%s) error(%v)", d.accCo+identifyURI+"?"+params.Encode(), err)
err = ecode.Int(res.Code)
return
}
idt = res.Data
return
}

View File

@@ -0,0 +1,131 @@
package account
import (
"context"
"go-common/library/ecode"
"net/url"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestAccountUpdateBirthday(t *testing.T) {
var (
c = context.Background()
mid = int64(2345)
ip = ""
birthday = "2018-01-01"
)
convey.Convey("UpdateBirthday", t, func(ctx convey.C) {
err := d.UpdateBirthday(c, mid, ip, birthday)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
// func TestAccountUpdateSex(t *testing.T) {
// var (
// c = context.Background()
// mid = int64(0)
// sex = int64(0)
// ip = ""
// )
// convey.Convey("UpdateSex", t, func(ctx convey.C) {
// err := d.UpdateSex(c, mid, sex, ip)
// ctx.Convey("Then err should be nil.", func(ctx convey.C) {
// ctx.So(err, convey.ShouldBeNil)
// })
// })
// }
// func TestAccountUpdatePerson(t *testing.T) {
// var (
// c = context.Background()
// mid = int64(2345)
// birthday = "2018-01-01"
// ip = ""
// datingType = int64(1)
// marital = int64(2)
// place = int64(3)
// )
// convey.Convey("UpdatePerson", t, func(ctx convey.C) {
// err := d.UpdatePerson(c, mid, birthday, ip, datingType, marital, place)
// ctx.Convey("Then err should be nil.", func(ctx convey.C) {
// ctx.So(err, convey.ShouldBeNil)
// })
// })
// }
// func TestAccountUpdateUname(t *testing.T) {
// var (
// c = context.Background()
// mid = int64(2345)
// ip = ""
// uname = "dangerous" + strconv.FormatInt(rand.Intn(10))
// isUpNickFree = true
// )
// convey.Convey("UpdateUname", t, func(ctx convey.C) {
// err := d.UpdateUname(c, mid, ip, uname, isUpNickFree)
// ctx.Convey("Then err should be nil.", func(ctx convey.C) {
// ctx.So(err, convey.ShouldBeNil)
// })
// })
// }
// func TestAccountUpdateFace(t *testing.T) {
// var (
// c = context.Background()
// mid = int64(0)
// face = ""
// ip = ""
// cookie = ""
// accessKey = ""
// )
// convey.Convey("UpdateFace", t, func(ctx convey.C) {
// faceURL, err := d.UpdateFace(c, mid, face, ip, cookie, accessKey)
// ctx.Convey("Then err should be nil.faceURL should not be nil.", func(ctx convey.C) {
// ctx.So(err, convey.ShouldBeNil)
// ctx.So(faceURL, convey.ShouldNotBeNil)
// })
// })
// }
func TestAccountParseJavaCode(t *testing.T) {
var (
code = int(-617)
)
convey.Convey("ParseJavaCode", t, func(ctx convey.C) {
err := ParseJavaCode(code)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldEqual, ecode.UpdateUnameHadLocked)
})
})
}
func TestAccountsign(t *testing.T) {
var (
params = &url.Values{}
)
convey.Convey("sign", t, func(ctx convey.C) {
query := d.sign(params)
ctx.Convey("Then query should not be nil.", func(ctx convey.C) {
ctx.So(query, convey.ShouldNotBeNil)
})
})
}
func TestAccountIdentifyInfo(t *testing.T) {
var (
c = context.Background()
mid = int64(2345)
ip = ""
)
convey.Convey("IdentifyInfo", t, func(ctx convey.C) {
idt, err := d.IdentifyInfo(c, mid, ip)
ctx.Convey("Then err should be nil.idt should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(idt, convey.ShouldNotBeNil)
})
})
}

View File

@@ -0,0 +1,99 @@
package account
import (
"context"
"encoding/json"
"fmt"
"math/rand"
"net/url"
"strconv"
"go-common/library/cache/memcache"
"go-common/library/ecode"
"go-common/library/log"
)
const (
_smsSendURI = "/x/internal/sms/send"
_offTcode = "acc_20"
_vcExpire = 30 * 60 // 30min
)
func vcodeKey(mid int64, mobile string) string {
return fmt.Sprintf("mv_%d_%s", mid, mobile)
}
// SendMobileVerify is.
func (d *Dao) SendMobileVerify(ctx context.Context, vcode, country int64, mobile, ip string) error {
params := url.Values{}
// params.Set("mid", strconv.FormatInt(mid, 10))
params.Set("mobile", mobile)
params.Set("country", strconv.FormatInt(country, 10))
params.Set("tcode", _offTcode)
tparam, err := OffiVerifyParam(vcode)
if err != nil {
return err
}
params.Set("tparam", tparam)
var res struct {
Code int `json:"code"`
}
if err := d.client.Post(ctx, d.smsSendURI, ip, params, &res); err != nil {
log.Error("Failed to send sms send request: %+v: %+v", params, err)
return err
}
if res.Code != 0 {
log.Error("Failed to send sms send requets: %+v: %d", params, res.Code)
return ecode.Int(res.Code)
}
return nil
}
// OffiVerifyParam is.
func OffiVerifyParam(vcode int64) (string, error) {
p := map[string]string{
"identify_code": strconv.FormatInt(vcode, 10),
}
ps, err := json.Marshal(p)
return string(ps), err
}
// GenVerifyCode is.
func (d *Dao) GenVerifyCode(ctx context.Context, mid int64, mobile string) (int64, error) {
vcode := int64(rand.Intn(9999-1000) + 1000)
key := vcodeKey(mid, mobile)
conn := d.mc.Get(ctx)
vcs := strconv.FormatInt(vcode, 10)
defer conn.Close()
if err := conn.Set(&memcache.Item{
Key: key,
Value: []byte(vcs),
Expiration: _vcExpire,
}); err != nil {
log.Error("conn.Set(%s, %d) error(%v)", key, vcode, err)
return 0, err
}
return vcode, nil
}
// GetVerifyCode is.
func (d *Dao) GetVerifyCode(ctx context.Context, mid int64, mobile string) (int64, error) {
key := vcodeKey(mid, mobile)
conn := d.mc.Get(ctx)
defer conn.Close()
item, err := conn.Get(key)
if err != nil {
return 0, err
}
return strconv.ParseInt(string(item.Value), 10, 64)
}
// DelVerifyCode is.
func (d *Dao) DelVerifyCode(ctx context.Context, mid int64, mobile string) error {
key := vcodeKey(mid, mobile)
conn := d.mc.Get(ctx)
defer conn.Close()
return conn.Delete(key)
}

View File

@@ -0,0 +1,90 @@
package account
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestAccountvcodeKey(t *testing.T) {
var (
mid = int64(0)
mobile = ""
)
convey.Convey("vcodeKey", t, func(ctx convey.C) {
p1 := vcodeKey(mid, mobile)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestAccountSendMobileVerify(t *testing.T) {
var (
vcode = int64(1234)
country = int64(86)
mobile = "13488888888"
ip = ""
)
convey.Convey("SendMobileVerify", t, func(ctx convey.C) {
err := d.SendMobileVerify(context.Background(), vcode, country, mobile, ip)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestAccountOffiVerifyParam(t *testing.T) {
var (
vcode = int64(0)
)
convey.Convey("OffiVerifyParam", t, func(ctx convey.C) {
p1, err := OffiVerifyParam(vcode)
ctx.Convey("Then err should be nil.p1 should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestAccountGenVerifyCode(t *testing.T) {
var (
mid = int64(0)
mobile = ""
)
convey.Convey("GenVerifyCode", t, func(ctx convey.C) {
p1, err := d.GenVerifyCode(context.Background(), mid, mobile)
ctx.Convey("Then err should be nil.p1 should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestAccountGetVerifyCode(t *testing.T) {
var (
mid = int64(0)
mobile = ""
)
convey.Convey("GetVerifyCode", t, func(ctx convey.C) {
p1, err := d.GetVerifyCode(context.Background(), mid, mobile)
ctx.Convey("Then err should be nil.p1 should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestAccountDelVerifyCode(t *testing.T) {
var (
mid = int64(0)
mobile = ""
)
convey.Convey("DelVerifyCode", t, func(ctx convey.C) {
err := d.DelVerifyCode(context.Background(), mid, mobile)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}

View File

@@ -0,0 +1,36 @@
package account
import (
"context"
"net/url"
"strconv"
"go-common/library/ecode"
"go-common/library/log"
)
var (
_vipPointBalance = "/internal/v1/point/"
)
// VipPointBalance vip point
func (d *Dao) VipPointBalance(c context.Context, mid int64, ip string) (pointBalance int64, err error) {
params := url.Values{}
var res struct {
Code int `json:"code"`
Data struct {
PointBalance int64 `json:"pointBalance"`
} `json:"data"`
}
if err = d.client.Get(c, d.vipHost+_vipPointBalance+strconv.FormatInt(mid, 10), ip, params, &res); err != nil {
log.Error("VipPointBalance() failed url(%v), err(%v)", d.vipHost+_vipPointBalance, err)
return
}
if res.Code != 0 {
log.Error("VipPointBalance() url(%v), res(%v)", d.vipHost+_vipPointBalance, res)
err = ecode.Int(res.Code)
return
}
pointBalance = res.Data.PointBalance
return
}

View File

@@ -0,0 +1,23 @@
package account
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestAccountVipPointBalance(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
ip = ""
)
convey.Convey("VipPointBalance", t, func(ctx convey.C) {
pointBalance, err := d.VipPointBalance(c, mid, ip)
ctx.Convey("Then err should be nil.pointBalance should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(pointBalance, convey.ShouldNotBeNil)
})
})
}

View File

@@ -0,0 +1,49 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
name = "go_default_library",
srcs = ["geetest.go"],
importpath = "go-common/app/interface/main/account/dao/geetest",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/account/conf:go_default_library",
"//app/interface/main/account/model:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/metadata:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
go_test(
name = "go_default_test",
srcs = ["geetest_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/account/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)

View File

@@ -0,0 +1,159 @@
package geetest
import (
"context"
"crypto/tls"
"io/ioutil"
"net"
"net/http"
"net/url"
"strconv"
"strings"
"time"
"go-common/app/interface/main/account/conf"
"go-common/app/interface/main/account/model"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/metadata"
"github.com/pkg/errors"
)
const (
_register = "http://api.geetest.com/register.php"
_validate = "http://api.geetest.com/validate.php"
)
// Dao is account dao.
type Dao struct {
c *conf.Config
// url
registerURI string
validateURI string
// http client
client *http.Client
clientx *bm.Client
}
// New new a dao.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
registerURI: _register,
validateURI: _validate,
// http client
client: NewClient(c.HTTPClient),
clientx: bm.NewClient(c.HTTPClient.Slow),
}
return
}
// PreProcess preprocessing the geetest and get to challenge
func (d *Dao) PreProcess(c context.Context, mid int64, geeType string, gc conf.GeetestConfig, newCaptcha int) (challenge string, err error) {
var (
req *http.Request
res *http.Response
bs []byte
params url.Values
)
params = url.Values{}
params.Set("user_id", strconv.FormatInt(mid, 10))
params.Set("new_captcha", strconv.Itoa(newCaptcha))
params.Set("ip_address", metadata.String(c, metadata.RemoteIP))
params.Set("client_type", geeType)
params.Set("gt", gc.CaptchaID)
if req, err = http.NewRequest("GET", d.registerURI+"?"+params.Encode(), nil); err != nil {
log.Error("d.preprocess uri(%s) params(%s) error(%v)", d.registerURI, params.Encode(), err)
return
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
if res, err = d.client.Do(req); err != nil {
log.Error("client.Do(%s) error(%v)", d.registerURI+"?"+params.Encode(), err)
return
}
defer res.Body.Close()
if res.StatusCode >= http.StatusInternalServerError {
err = errors.New("http status code 5xx")
log.Error("gtServerErr uri(%s) error(%v)", d.validateURI+"?"+params.Encode(), err)
return
}
if bs, err = ioutil.ReadAll(res.Body); err != nil {
log.Error("ioutil.ReadAll(%s) uri(%s) error(%v)", bs, d.validateURI+"?"+params.Encode(), err)
return
}
if len(bs) != 32 {
log.Error("d.preprocess len(%s) the length not equate 32byte", string(bs))
return
}
challenge = string(bs)
return
}
// Validate recheck the challenge code and get to seccode
func (d *Dao) Validate(c context.Context, challenge, seccode, clientType, captchaID string, mid int64) (res *model.ValidateRes, err error) {
params := url.Values{}
params.Set("seccode", seccode)
params.Set("challenge", challenge)
params.Set("captchaid", captchaID)
params.Set("client_type", clientType)
params.Set("ip_address", metadata.String(c, metadata.RemoteIP))
params.Set("json_format", "1")
params.Set("sdk", "golang_3.0.0")
params.Set("user_id", strconv.FormatInt(mid, 10))
params.Set("timestamp", strconv.FormatInt(time.Now().Unix(), 10))
req, err := http.NewRequest("POST", d.validateURI, strings.NewReader(params.Encode()))
if err != nil {
log.Error("http.NewRequest error(%v) | uri(%s) params(%s)", err, d.validateURI, params.Encode())
return
}
log.Info("Validate(%v) start", params)
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
res = new(model.ValidateRes)
if err = d.clientx.Do(c, req, &res); err != nil {
log.Error("d.client.Do error(%v) | uri(%s) params(%s) res(%v)", err, d.validateURI, params.Encode(), res)
return
}
log.Info("Validate(%v) suc", res)
return
}
// NewClient new a http client.
func NewClient(c *conf.HTTPClient) (client *http.Client) {
var (
transport *http.Transport
dialer *net.Dialer
)
dialer = &net.Dialer{
Timeout: time.Duration(c.Slow.Dial),
KeepAlive: time.Duration(c.Slow.KeepAlive),
}
transport = &http.Transport{
DialContext: dialer.DialContext,
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client = &http.Client{
Transport: transport,
}
return
}
// GeeConfig get geetest config.
func (d *Dao) GeeConfig(ct string, c *conf.Geetest) (gc conf.GeetestConfig, clientType string) {
if ct == "" {
return c.PC, "web"
}
switch ct {
case "web":
gc = c.PC
clientType = "web"
case "h5":
gc = c.H5
clientType = "h5"
default:
gc = c.PC
clientType = "web"
}
return
}

View File

@@ -0,0 +1,78 @@
package geetest
import (
"context"
"flag"
"os"
"testing"
"go-common/app/interface/main/account/conf"
"github.com/smartystreets/goconvey/convey"
)
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.account.account-interface")
flag.Set("conf_token", "967eef77ad40b478234f11b0d489d6d6")
flag.Set("tree_id", "3815")
flag.Set("conf_version", "docker-1")
flag.Set("deploy_env", "uat")
flag.Set("conf_host", "config.bilibili.co")
flag.Set("conf_path", "/tmp")
flag.Set("region", "sh")
flag.Set("zone", "sh001")
} else {
flag.Set("conf", "../../cmd/account-interface-example.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
m.Run()
os.Exit(0)
}
func TestGeetestPreProcess(t *testing.T) {
convey.Convey("PreProcess", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(11)
geeType = ""
gc = d.c.Geetest.PC
newCaptcha = int(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
challenge, err := d.PreProcess(c, mid, geeType, gc, newCaptcha)
ctx.Convey("Then err should be nil.challenge should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(challenge, convey.ShouldNotBeNil)
})
})
})
}
func TestGeetestValidate(t *testing.T) {
convey.Convey("Validate", t, func(ctx convey.C) {
var (
c = context.Background()
challenge = "ac7e67bb9b8e3e567186159e63df2153cs"
seccode = "7bda121544bd035032b2b5e390bce5d7"
clientType = "web"
captchaID = "0926f406a4a5433a45faf33ae9a721c3"
mid = int64(11)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.Validate(c, challenge, seccode, clientType, captchaID, mid)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,49 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["passport_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/account/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["passport.go"],
importpath = "go-common/app/interface/main/account/dao/passport",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/account/conf:go_default_library",
"//app/interface/main/account/dao/account:go_default_library",
"//app/interface/main/account/model:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,143 @@
package passport
import (
"context"
"net/url"
"strconv"
"go-common/app/interface/main/account/conf"
"go-common/app/interface/main/account/dao/account"
"go-common/app/interface/main/account/model"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
var (
fastRegUri = "/intranet/acc/user/source"
useridUri = "/intranet/acc/userid"
testUsername = "/api/reg/testUserName"
queryByMidUri = "/intranet/acc/queryByMid"
updateName = "/intranet/acc/updateUname"
)
// Dao dao
type Dao struct {
c *conf.Config
client *bm.Client
}
// New new
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
client: bm.NewClient(c.HTTPClient.Normal),
}
return
}
func (d *Dao) FastReg(c context.Context, mid int64, ip string) (isRegFast bool, err error) {
params := url.Values{}
params.Set("mid", strconv.FormatInt(mid, 10))
var res struct {
Code int `json:"code"`
Data struct {
FastReg bool `json:"fastReg"`
} `json:"data"`
Message string `json:"message"`
}
if err = d.client.Get(c, d.c.Host.Passport+fastRegUri, ip, params, &res); err != nil {
log.Error("fastReg url(%s) error(%v)", fastRegUri+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
log.Error("fastReg url(%s) res(%v)", fastRegUri+"?"+params.Encode(), res)
err = ecode.Int(res.Code)
return
}
isRegFast = res.Data.FastReg
return
}
//UserID user id.
func (d *Dao) UserID(c context.Context, mid int64, ip string) (userID string, err error) {
params := url.Values{}
params.Set("mid", strconv.FormatInt(mid, 10))
var res struct {
Code int `json:"code"`
Data struct {
UserID string `json:"userid"`
} `json:"data"`
Message string `json:"message"`
}
if err = d.client.Get(c, d.c.Host.Passport+useridUri, ip, params, &res); err != nil {
log.Error("UserID url(%s) error(%v)", useridUri+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
log.Error("userID url(%s) res(%v)", useridUri+"?"+params.Encode(), res)
err = ecode.Int(res.Code)
return
}
userID = res.Data.UserID
return
}
// TestUserName is.
func (d *Dao) TestUserName(c context.Context, name string, mid int64, ip string) error {
params := url.Values{}
params.Set("user_name", name)
params.Set("mid", strconv.FormatInt(mid, 10))
var res struct {
Code int `json:"code"`
}
if err := d.client.Get(c, d.c.Host.Passport+testUsername, ip, params, &res); err != nil {
log.Error("Failed to test username: %+v: %+v", params, err)
return err
}
if res.Code != 0 {
log.Error("Failed to test username with code: %+v: %d", params, res.Code)
return account.ParseJavaCode(res.Code)
}
return nil
}
// QueryByMid is.
func (d *Dao) QueryByMid(c context.Context, mid int64, ip string) (*model.PassportProfile, error) {
params := url.Values{}
params.Set("mid", strconv.FormatInt(mid, 10))
var res struct {
Code int `json:"code"`
Data *model.PassportProfile `json:"data"`
}
if err := d.client.Get(c, d.c.Host.Passport+queryByMidUri, ip, params, &res); err != nil {
log.Error("Failed to query by mid: %+v: %+v", params, err)
return nil, err
}
if res.Code != 0 {
log.Error("Failed to query by mid with code: %+v: %d", params, res.Code)
return nil, account.ParseJavaCode(res.Code)
}
return res.Data, nil
}
// UpdateName is.
func (d *Dao) UpdateName(c context.Context, mid int64, name, ip string) error {
params := url.Values{}
params.Set("mid", strconv.FormatInt(mid, 10))
params.Set("uname", name)
var res struct {
Code int `json:"code"`
}
if err := d.client.Post(c, d.c.Host.Passport+updateName, ip, params, &res); err != nil {
log.Error("Failed to update uname params: %+v: %v", params, err)
return err
}
if res.Code != 0 {
log.Error("Failed to update uname, params: %+v,code: %d", params, res.Code)
return account.ParseJavaCode(res.Code)
}
return nil
}

View File

@@ -0,0 +1,39 @@
package passport
import (
"context"
"flag"
"testing"
"go-common/app/interface/main/account/conf"
"github.com/smartystreets/goconvey/convey"
)
var d *Dao
func init() {
flag.Parse()
flag.Set("conf", "../../cmd/account-interface-example.toml")
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
}
func TestDao_UserID(t *testing.T) {
convey.Convey("ReplyHistoryList", t, func() {
id, err := d.UserID(context.TODO(), 1, "")
convey.So(err, convey.ShouldBeNil)
convey.So(id, convey.ShouldNotBeEmpty)
})
}
func TestDao_FastReg(t *testing.T) {
convey.Convey("ReplyHistoryList", t, func() {
fastReg, err := d.FastReg(context.TODO(), 111001347, "")
convey.So(err, convey.ShouldBeNil)
convey.So(fastReg, convey.ShouldNotBeEmpty)
})
}

View File

@@ -0,0 +1,55 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
go_library(
name = "go_default_library",
srcs = [
"alipay.go",
"antispam.go",
"geetest.go",
"realname.go",
],
importpath = "go-common/app/interface/main/account/dao/realname",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/account/conf:go_default_library",
"//library/cache/memcache:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/metadata:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = ["realname_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/account/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)

View File

@@ -0,0 +1,91 @@
package realname
import (
"context"
"net/http"
"net/url"
"go-common/app/interface/main/account/conf"
"go-common/library/log"
"github.com/pkg/errors"
)
type respAlipay struct {
Code string `json:"code"`
Msg string `json:"msg"`
SubCode string `json:"sub_code"`
SubMsg string `json:"sub_msg"`
}
func (r *respAlipay) Error() error {
if r.Code == "10000" {
return nil
}
return errors.Errorf("alipay response failed , code : %s, msg : %s, sub_code : %s, sub_msg : %s", r.Code, r.Msg, r.SubCode, r.SubMsg)
}
// AlipayInit .
func (d *Dao) AlipayInit(c context.Context, param url.Values) (bizno string, err error) {
var (
req *http.Request
)
url := conf.Conf.Realname.Alipay.Gateway + "?" + param.Encode()
if req, err = http.NewRequest("GET", url, nil); err != nil {
err = errors.Wrapf(err, "http.NewRequest(GET,%s)", url)
return
}
var resp struct {
Resp struct {
respAlipay
Bizno string `json:"biz_no"`
} `json:"zhima_customer_certification_initialize_response"`
Sign string `json:"sign"`
}
if err = d.client.Do(c, req, &resp); err != nil {
return
}
log.Info("Realname alipay init \n\tparam : %+v \n\tresp : %+v", param, resp)
if err = resp.Resp.Error(); err != nil {
return
}
bizno = resp.Resp.Bizno
return
}
// AlipayQuery .
func (d *Dao) AlipayQuery(c context.Context, param url.Values) (pass bool, reason string, err error) {
var (
req *http.Request
)
url := conf.Conf.Realname.Alipay.Gateway + "?" + param.Encode()
if req, err = http.NewRequest("GET", url, nil); err != nil {
err = errors.Wrapf(err, "http.NewRequest(GET,%s)", url)
return
}
var resp struct {
Resp struct {
respAlipay
Passed string `json:"passed"`
FailedReason string `json:"failed_reason"`
IdentityInfo string `json:"identity_info"`
AttributeInfo string `json:"attribute_info"`
ChannelStatuses string `json:"channel_statuses"`
} `json:"zhima_customer_certification_query_response"`
Sign string `json:"sign"`
}
if err = d.client.Do(c, req, &resp); err != nil {
return
}
log.Info("Realname alipay query \n\tparam : %+v \n\tresp : %+v", param, resp)
if err = resp.Resp.Error(); err != nil {
return
}
if resp.Resp.Passed == "true" {
pass = true
} else {
pass = false
}
reason = resp.Resp.FailedReason
return
}

View File

@@ -0,0 +1,105 @@
package realname
import (
"context"
"fmt"
"go-common/app/interface/main/account/conf"
"go-common/library/cache/memcache"
"github.com/pkg/errors"
)
func alipayAntispamKey(mid int64) string {
return fmt.Sprintf("raa_%d", mid)
}
//AlipayAntispamValue 最低位为pass flag ,高位为计数
//计数:判断用户的申请次数
//flag:是否通过本次防刷验证(极验是否通过)
type AlipayAntispamValue int
// IncreaseCount add antispam count
func (a *AlipayAntispamValue) IncreaseCount() {
*a = AlipayAntispamValue((a.Count()+1)<<1 + a.Flag())
}
// SetPass set is antispam verified (such as when geetest passed)
func (a *AlipayAntispamValue) SetPass(pass bool) {
var flag int
if pass {
flag = 1
}
*a = AlipayAntispamValue(a.Count()<<1 + flag)
}
// Count return antispam hit count
func (a *AlipayAntispamValue) Count() int {
return int(*a) >> 1
}
// Flag return antispam pass flag
func (a *AlipayAntispamValue) Flag() int {
return int(*a) & 0x1
}
// Pass return is antispam passed (such as when geetest passed)
func (a *AlipayAntispamValue) Pass() bool {
return a.Flag() > 0
}
// AlipayAntispam get alipay antispam count by mid
func (d *Dao) AlipayAntispam(c context.Context, mid int64) (value *AlipayAntispamValue, err error) {
var (
key = alipayAntispamKey(mid)
conn = d.mc.Get(c)
item *memcache.Item
)
defer conn.Close()
if item, err = conn.Get(key); err != nil {
if err == memcache.ErrNotFound {
err = nil
return
}
err = errors.Wrapf(err, "conn.Get(%s)", key)
return
}
value = new(AlipayAntispamValue)
if err = conn.Scan(item, &value); err != nil {
err = errors.Wrapf(err, "conn.Scan(%+v)", item)
return
}
return
}
// SetAlipayAntispam set alipay antispam count by mid
func (d *Dao) SetAlipayAntispam(c context.Context, mid int64, value *AlipayAntispamValue) (err error) {
var (
key = alipayAntispamKey(mid)
conn = d.mc.Get(c)
)
defer conn.Close()
if err = conn.Set(&memcache.Item{Key: key, Object: value, Flags: memcache.FlagJSON, Expiration: conf.Conf.Realname.AlipayAntispamTTL}); err != nil {
err = errors.Wrapf(err, "conn.Set(%s,%+v)", key, value)
return
}
return
}
// DeleteAlipayAntispam delete alipay antispam count by mid
func (d *Dao) DeleteAlipayAntispam(c context.Context, mid int64) (err error) {
var (
key = alipayAntispamKey(mid)
conn = d.mc.Get(c)
)
defer conn.Close()
if err = conn.Delete(key); err != nil {
if err == memcache.ErrNotFound {
err = nil
return
}
err = errors.Wrapf(err, "conn.Delete(%s)", key)
return
}
return
}

View File

@@ -0,0 +1,79 @@
package realname
import (
"context"
"net/http"
"net/url"
"strconv"
"strings"
"time"
"go-common/app/interface/main/account/conf"
"go-common/library/log"
"go-common/library/net/metadata"
"github.com/pkg/errors"
)
// RealnameCaptchaGTRegister register a geetest apply
func (d *Dao) RealnameCaptchaGTRegister(c context.Context, mid int64, ip, clientType string, newCaptcha int) (challenge string, err error) {
var (
params = url.Values{}
req *http.Request
url = conf.Conf.Realname.Geetest.RegisterURL
)
params.Set("user_id", strconv.FormatInt(mid, 10))
params.Set("new_captcha", strconv.Itoa(newCaptcha))
params.Set("ip_address", ip)
params.Set("client_type", clientType)
params.Set("gt", conf.Conf.Realname.Geetest.CaptchaID)
if req, err = http.NewRequest("GET", url+"?"+params.Encode(), nil); err != nil {
err = errors.Wrapf(err, "dao.RealnameCaptchaGTRegister url(%s) params(%s)", url, params.Encode())
return
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
var challengeBytes []byte
if challengeBytes, err = d.client.Raw(c, req); err != nil {
return
}
challenge = string(challengeBytes)
if len(challenge) != 32 {
log.Error("dao.RealnameCaptchaGTRegister challenge : %s ,length not equate 32bit", challenge)
}
return
}
// RealnameCaptchaGTRegisterValidate recheck the challenge code and get to seccode
func (d *Dao) RealnameCaptchaGTRegisterValidate(c context.Context, challenge, seccode, clientType, ip, captchaID string, mid int64) (realSeccode string, err error) {
var (
params = url.Values{}
req *http.Request
url = conf.Conf.Realname.Geetest.ValidateURL
)
params.Set("seccode", seccode)
params.Set("challenge", challenge)
params.Set("captchaid", captchaID)
params.Set("client_type", clientType)
params.Set("ip_address", metadata.String(c, metadata.RemoteIP))
params.Set("json_format", "1")
params.Set("sdk", "golang_3.0.0")
params.Set("user_id", strconv.FormatInt(mid, 10))
params.Set("timestamp", strconv.FormatInt(time.Now().Unix(), 10))
log.Info("gt validate url : %s , params : %s", url, params.Encode())
if req, err = http.NewRequest("POST", url, strings.NewReader(params.Encode())); err != nil {
err = errors.Wrapf(err, "dao.RealnameCaptchaGTRegister url(%s) params(%s)", url, params.Encode())
return
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
var resp struct {
Seccode string `json:"seccode"`
}
if err = d.client.Do(c, req, &resp); err != nil {
return
}
realSeccode = resp.Seccode
return
}

View File

@@ -0,0 +1,60 @@
package realname
import (
"context"
"fmt"
"net/url"
"go-common/app/interface/main/account/conf"
"go-common/library/cache/memcache"
"go-common/library/ecode"
bm "go-common/library/net/http/blademaster"
"github.com/pkg/errors"
)
var (
telInfoURI = "/intranet/acc/telInfo/mid"
)
// Dao dao
type Dao struct {
c *conf.Config
client *bm.Client
mc *memcache.Pool
}
// New new
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
client: bm.NewClient(c.HTTPClient.Normal),
mc: memcache.NewPool(c.AccMemcache),
}
return
}
// TelInfo tel info.
func (d *Dao) TelInfo(c context.Context, mid int64) (tel string, err error) {
params := url.Values{}
params.Set("mid", fmt.Sprintf("%d", mid))
var resp struct {
Code int `json:"code"`
Data struct {
Mid int64 `json:"mid"`
Tel string `json:"tel"`
JoinIP string `json:"join_ip"`
JoinTime int64 `json:"join_time"`
} `json:"data"`
}
if err = d.client.Get(c, d.c.Host.Passport+telInfoURI, "", params, &resp); err != nil {
err = errors.Errorf("realname TelInfo d.httpClient.Do() error(%+v)", err)
return
}
if resp.Code != 0 {
err = errors.Errorf("realname TelInfo url(%s) res(%+v) err(%+v)", telInfoURI+"?"+params.Encode(), resp, ecode.Int(resp.Code))
return
}
tel = resp.Data.Tel
return
}

View File

@@ -0,0 +1,50 @@
package realname
import (
"context"
"flag"
"testing"
"go-common/app/interface/main/account/conf"
"github.com/smartystreets/goconvey/convey"
)
var d *Dao
func init() {
flag.Parse()
flag.Set("conf", "../../cmd/account-interface-example.toml")
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
}
func TestTelInfo(t *testing.T) {
convey.Convey("ReplyHistoryList", t, func() {
res, err := d.TelInfo(context.TODO(), 46333)
convey.So(err, convey.ShouldBeNil)
convey.So(res, convey.ShouldNotBeNil)
})
}
func TestAntispam(t *testing.T) {
convey.Convey("antispam", t, func() {
anti := new(AlipayAntispamValue)
anti.IncreaseCount()
c := anti.Count()
convey.So(c, convey.ShouldEqual, 1)
p := anti.Pass()
convey.So(p, convey.ShouldBeFalse)
anti.IncreaseCount()
c = anti.Count()
convey.So(c, convey.ShouldEqual, 2)
anti.SetPass(true)
p = anti.Pass()
convey.So(p, convey.ShouldBeTrue)
})
}

View File

@@ -0,0 +1,49 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
name = "go_default_library",
srcs = ["relation.go"],
importpath = "go-common/app/interface/main/account/dao/relation",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/account/conf:go_default_library",
"//app/interface/main/account/model:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
go_test(
name = "go_default_test",
srcs = ["relation_test.go"],
embed = [":go_default_library"],
tags = ["automanaged"],
deps = [
"//app/interface/main/account/conf:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
"//vendor/gopkg.in/h2non/gock.v1:go_default_library",
],
)

View File

@@ -0,0 +1,112 @@
package relation
import (
"context"
"net/url"
"strconv"
"go-common/app/interface/main/account/conf"
"go-common/app/interface/main/account/model"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
// Dao is
type Dao struct {
conf *conf.Config
httpClient *bm.Client
recommendURL string
}
const (
_recommendURI = "/main/recommend"
)
// New is
func New(conf *conf.Config) *Dao {
return &Dao{
conf: conf,
httpClient: bm.NewClient(conf.HTTPClient.Normal),
recommendURL: conf.Host.Search + _recommendURI,
}
}
func paltform(device *bm.Device) string {
if device.RawMobiApp == "" {
return "web"
}
if device.IsAndroid() {
return "android"
}
if device.IsIOS() {
return "ios"
}
return "web"
}
func buvid(device *bm.Device) string {
if device.RawMobiApp == "" {
return device.Buvid3
}
return device.Buvid
}
// Recommend is
func (d *Dao) Recommend(ctx context.Context, mid int64, serviceArea string, mainTids string, subTids string, device *bm.Device, pagesize int64, ip string) (*model.RecommendResponse, error) {
params := url.Values{}
params.Set("platform", paltform(device))
params.Set("mobi_app", device.MobiApp())
params.Set("device", device.Device)
params.Set("build", strconv.FormatInt(device.Build, 10))
params.Set("clientip", ip)
params.Set("userid", strconv.FormatInt(mid, 10))
params.Set("buvid", buvid(device))
params.Set("pagesize", strconv.FormatInt(pagesize, 10))
params.Set("rec_type", "up_rec")
params.Set("service_area", serviceArea)
if mainTids != "" {
params.Set("main_tids", mainTids)
}
if subTids != "" {
params.Set("sub_tids", subTids)
}
resp := &model.RecommendResponse{}
if err := d.httpClient.Get(ctx, d.recommendURL, ip, params, resp); err != nil {
return nil, err
}
if resp.Code != 0 {
log.Error("Failed to call recommendation service with error code: %d, params: %+v, trackid(%s)", resp.Code, params, resp.TrackID)
return nil, ecode.Int(int(resp.Code))
}
return resp, nil
}
// TagSuggestRecommend is
func (d *Dao) TagSuggestRecommend(ctx context.Context, mid int64, contextID string, tagname string, device *bm.Device, pagesize int64, ip string) (*model.TagSuggestRecommendResponse, error) {
params := url.Values{}
params.Set("platform", paltform(device))
params.Set("mobi_app", device.MobiApp())
params.Set("device", device.Device)
params.Set("build", strconv.FormatInt(device.Build, 10))
params.Set("clientip", ip)
params.Set("userid", strconv.FormatInt(mid, 10))
params.Set("buvid", buvid(device))
params.Set("pagesize", strconv.FormatInt(pagesize, 10))
params.Set("rec_type", "tagup_rec")
params.Set("service_area", "tag_suggest")
params.Set("context_id", contextID)
if tagname != "" {
params.Set("tagname", tagname)
}
resp := &model.TagSuggestRecommendResponse{}
if err := d.httpClient.Get(ctx, d.recommendURL, ip, params, resp); err != nil {
return nil, err
}
if resp.Code != 0 {
log.Error("Failed to call recommendation service with error code: %d, params: %+v, trackid(%s)", resp.Code, params, resp.TrackID)
return nil, ecode.Int(int(resp.Code))
}
return resp, nil
}

View File

@@ -0,0 +1,117 @@
package relation
import (
"context"
"flag"
"os"
"strings"
"testing"
"go-common/app/interface/main/account/conf"
bm "go-common/library/net/http/blademaster"
"github.com/smartystreets/goconvey/convey"
"gopkg.in/h2non/gock.v1"
)
var (
d *Dao
)
func httpMock(method, url string) *gock.Request {
r := gock.New(url)
r.Method = strings.ToUpper(method)
return r
}
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.account.account-interface")
flag.Set("conf_token", "967eef77ad40b478234f11b0d489d6d6")
flag.Set("tree_id", "3815")
flag.Set("conf_version", "docker-1")
flag.Set("deploy_env", "uat")
flag.Set("conf_host", "config.bilibili.co")
flag.Set("conf_path", "/tmp")
flag.Set("region", "sh")
flag.Set("zone", "sh001")
} else {
flag.Set("conf", "../../cmd/account-interface-example.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
d.httpClient.SetTransport(gock.DefaultTransport)
m.Run()
os.Exit(0)
}
func TestRelationpaltform(t *testing.T) {
var (
device = &bm.Device{}
)
convey.Convey("paltform", t, func(ctx convey.C) {
p1 := paltform(device)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestRelationbuvid(t *testing.T) {
var (
device = &bm.Device{}
)
convey.Convey("buvid", t, func(ctx convey.C) {
p1 := buvid(device)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestRelationRecommend(t *testing.T) {
var (
ctx = context.Background()
mid = int64(0)
serviceArea = ""
mainTids = ""
subTids = ""
device = &bm.Device{}
pagesize = int64(0)
ip = ""
)
convey.Convey("Recommend", t, func(c convey.C) {
httpMock("GET", d.recommendURL).Reply(200).JSON(`{"code":0,"message":"0","data":[]}`)
defer gock.OffAll()
p1, err := d.Recommend(ctx, mid, serviceArea, mainTids, subTids, device, pagesize, ip)
c.Convey("Then err should be nil.p1 should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestRelationTagSuggestRecommend(t *testing.T) {
var (
ctx = context.Background()
mid = int64(0)
contextID = ""
tagname = ""
device = &bm.Device{}
pagesize = int64(0)
ip = ""
)
convey.Convey("TagSuggestRecommend", t, func(c convey.C) {
httpMock("GET", d.recommendURL).Reply(200).JSON(`{"code":0,"message":"0","data":[]}`)
defer gock.OffAll()
p1, err := d.TagSuggestRecommend(ctx, mid, contextID, tagname, device, pagesize, ip)
c.Convey("Then err should be nil.p1 should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(p1, convey.ShouldNotBeNil)
})
})
}

View File

@@ -0,0 +1,49 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["reply_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/account/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["reply.go"],
importpath = "go-common/app/interface/main/account/dao/reply",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/account/conf:go_default_library",
"//app/interface/main/account/model:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/xstr:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,160 @@
package reply
import (
"context"
xhttp "net/http"
"net/url"
"strconv"
"go-common/app/interface/main/account/conf"
"go-common/app/interface/main/account/model"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/xstr"
)
var (
_replyHistoryURI = "/x/internal/v2/reply/record"
_activityPagesURI = "/activity/pages"
)
// Dao dao
type Dao struct {
c *conf.Config
client *bm.Client
replyHistory string
activityPages string
}
// New Dao
func New(c *conf.Config) (d *Dao) {
return &Dao{
c: c,
client: bm.NewClient(c.HTTPClient.Normal),
replyHistory: c.Host.API + _replyHistoryURI,
activityPages: c.Host.WWW + _activityPagesURI,
}
}
// ReplyHistoryList reply history list
func (d *Dao) ReplyHistoryList(c context.Context, mid int64, stime, etime, order, sort string, pn, ps int64, accessKey, cookie, ip string) (rhl *model.ReplyHistory, err error) {
params := url.Values{}
params.Set("mid", strconv.FormatInt(mid, 10))
params.Set("stime", stime)
params.Set("etime", etime)
params.Set("order", order)
params.Set("sort", sort)
params.Set("pn", strconv.FormatInt(pn, 10))
params.Set("ps", strconv.FormatInt(ps, 10))
params.Set("access_key", accessKey)
req, err := d.client.NewRequest(xhttp.MethodGet, d.replyHistory, ip, params)
if err != nil {
return
}
var res struct {
Code int `json:"code"`
Data struct {
Page struct {
Num int `json:"num"`
Size int `json:"size"`
Total int `json:"total"`
} `json:"page"`
Records []struct {
ID int `json:"id"`
Oid int64 `json:"oid"`
Type int64 `json:"type"`
Floor int `json:"floor"`
Like int `json:"like"`
Rcount int `json:"rcount"`
Mid int64 `json:"mid"`
State int `json:"state"`
Message string `json:"message"`
Ctime string `json:"ctime"`
Members []*model.Info `json:"members"`
} `json:"records"`
} `json:"data"`
Message string `json:"message"`
TTL int `json:"ttl"`
}
if err = d.client.Do(c, req, &res); err != nil {
log.Error("member interface reply request reply history list failed, err(%v)", err)
return
}
if res.Code != 0 {
log.Error("member interface reply request reply history list code(%d), err(%v)", res.Code, err)
err = ecode.Int(res.Code)
return
}
rhl = &model.ReplyHistory{
Page: res.Data.Page,
Records: make([]*model.Record, 0),
}
for _, v := range res.Data.Records {
tme := make([]*model.Member, 0)
for _, vt := range v.Members {
m, _ := strconv.ParseInt(vt.Mid, 10, 64)
tmp := &model.Member{
Mid: m,
Uname: vt.Name,
}
tme = append(tme, tmp)
}
rhlt := &model.Record{
ID: v.ID,
Oid: v.Oid,
OidStr: strconv.FormatInt(v.Oid, 10),
Type: v.Type,
Floor: v.Floor,
Like: v.Like,
Rcount: v.Rcount,
Mid: v.Mid,
State: v.State,
Message: v.Message,
Ctime: v.Ctime,
Members: tme,
}
rhl.Records = append(rhl.Records, rhlt)
}
return
}
// ActivityPages activity pages api
func (d *Dao) ActivityPages(c context.Context, mid int64, aids []int64, accessKey, cookie, ip string) (at map[int64]*model.RecordAppend, err error) {
params := url.Values{}
params.Set("mid", strconv.FormatInt(mid, 10))
params.Set("pids", xstr.JoinInts(aids))
params.Set("all", "isOne")
params.Set("access_key", accessKey)
req, err := d.client.NewRequest(xhttp.MethodGet, d.activityPages, ip, params)
if err != nil {
return
}
var res struct {
Code int `json:"code"`
Data struct {
List []struct {
ID int64 `json:"id"`
Name string `json:"name"`
PcURL string `json:"pc_url"`
} `json:"list"`
} `json:"data"`
}
at = make(map[int64]*model.RecordAppend)
if err = d.client.Do(c, req, &res); err != nil {
log.Error("member interface reply request activity failed, err(%v)", err)
return
}
if res.Code != 0 {
log.Error("member interface reply request activity code != 0, err(%v)", err)
err = ecode.Int(res.Code)
return
}
for _, v := range res.Data.List {
at[v.ID] = &model.RecordAppend{
Title: v.Name,
URL: v.PcURL,
}
}
return
}

View File

@@ -0,0 +1,31 @@
package reply
import (
"context"
"flag"
"testing"
"go-common/app/interface/main/account/conf"
"github.com/smartystreets/goconvey/convey"
)
var d *Dao
func init() {
flag.Parse()
flag.Set("conf", "../../cmd/account-interface-example.toml")
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
}
func TestReplyHistoryList(t *testing.T) {
convey.Convey("ReplyHistoryList", t, func() {
res, err := d.ReplyHistoryList(context.TODO(), 1, "2017-3-21", "2017-3-21", "time", "desc", 1, 50, "access_key", "cookie", "0.0.0.0")
convey.So(err, convey.ShouldBeNil)
convey.So(res, convey.ShouldNotBeNil)
})
}

View File

@@ -0,0 +1,54 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
name = "go_default_library",
srcs = [
"api.go",
"dao.go",
],
importpath = "go-common/app/interface/main/account/dao/usersuit",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/account/conf:go_default_library",
"//app/service/main/usersuit/model:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
go_test(
name = "go_default_test",
srcs = [
"api_test.go",
"dao_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/account/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)

View File

@@ -0,0 +1,170 @@
package usersuit
import (
"context"
"net/url"
"strconv"
usmdl "go-common/app/service/main/usersuit/model"
"go-common/library/ecode"
"go-common/library/log"
)
const (
_groupInfo = "/x/internal/pendant/groupInfo"
_entryGroup = "/x/internal/pendant/entryGroup"
_vipGroup = "/x/internal/pendant/vipGroup"
_pendantInfo = "/x/internal/pendant/pendantByID"
_packageInfo = "/x/internal/pendant/package"
_orderInfo = "/x/internal/pendant/order"
_orderHistory = "/x/internal/pendant/orderHistory"
)
// Group get pendant group info.
func (d *Dao) Group(c context.Context, ip string) (groups []*usmdl.PendantGroupInfo, err error) {
var res struct {
Code int `json:"code"`
Data []*usmdl.PendantGroupInfo `json:"data"`
}
if err = d.http.Get(c, d.groupURL, ip, nil, &res); err != nil {
log.Error("d.http.Get(%s) error(%v)", d.groupURL, err)
return
}
if res.Code != ecode.OK.Code() {
err = ecode.Int(res.Code)
log.Error("d.http.Get(%s) error(%v)", d.groupURL, err)
return
}
groups = res.Data
return
}
// GroupEntry get entry group.
func (d *Dao) GroupEntry(c context.Context, ip string) (group *usmdl.PendantGroupInfo, err error) {
var res struct {
Code int `json:"code"`
Data *usmdl.PendantGroupInfo `json:"data"`
}
if err = d.http.Get(c, d.entryGroupURL, ip, nil, &res); err != nil {
log.Error("d.http.Get(%s) error(%v)", d.entryGroupURL, err)
return
}
if res.Code != ecode.OK.Code() {
err = ecode.Int(res.Code)
log.Error("d.http.Get(%s) error(%v)", d.entryGroupURL, err)
return
}
group = res.Data
return
}
// GroupVip get vip group.
func (d *Dao) GroupVip(c context.Context, ip string) (group *usmdl.PendantGroupInfo, err error) {
var res struct {
Code int `json:"code"`
Data *usmdl.PendantGroupInfo `json:"data"`
}
if err = d.http.Get(c, d.vipGroupURL, ip, nil, &res); err != nil {
log.Error("d.http.Get(%s) error(%v)", d.vipGroupURL, err)
return
}
if res.Code != 0 {
err = ecode.Int(res.Code)
log.Error("d.http.Get(%s) error(%v)", d.vipGroupURL, err)
return
}
group = res.Data
return
}
// Pendant get pendant info.
func (d *Dao) Pendant(c context.Context, pid int64, ip string) (pendant *usmdl.Pendant, err error) {
var res struct {
Code int `json:"code"`
Data *usmdl.Pendant `json:"data"`
}
params := url.Values{}
params.Set("pid", strconv.FormatInt(pid, 10))
if err = d.http.Get(c, d.pendantURL, ip, params, &res); err != nil {
log.Error("d.http.Get(%s) error(%v)", d.pendantURL, err)
return
}
if res.Code != ecode.OK.Code() {
err = ecode.Int(res.Code)
log.Error("d.http.Get(%s) error(%v)", d.pendantURL, err)
return
}
pendant = res.Data
return
}
// Packages get package info.
func (d *Dao) Packages(c context.Context, mid int64, ip string) (pkg []*usmdl.PendantPackage, err error) {
var res struct {
Code int `json:"code"`
Data []*usmdl.PendantPackage `json:"data"`
}
params := url.Values{}
params.Set("mid", strconv.FormatInt(mid, 10))
if err = d.http.Get(c, d.packageURL, ip, params, &res); err != nil {
log.Error("d.http.Get(%s) error(%v)", d.packageURL, err)
return
}
if res.Code != ecode.OK.Code() {
err = ecode.Int(res.Code)
log.Error("d.http.Get(%s) error(%v)", d.packageURL, err)
return
}
pkg = res.Data
return
}
// Order order pendant.
func (d *Dao) Order(c context.Context, mid, pid, expires int64, moneyType int8, ip string) (payInfo *usmdl.PayInfo, err error) {
params := url.Values{}
params.Set("moneytype", strconv.Itoa(int(expires)))
params.Set("expires", strconv.FormatInt(expires, 10))
params.Set("mid", strconv.FormatInt(mid, 10))
params.Set("pid", strconv.FormatInt(pid, 10))
var res struct {
Code int `json:"code"`
Data *usmdl.PayInfo `json:"data"`
}
if err = d.http.Post(c, d.orderURL, ip, params, &res); err != nil {
log.Error("d.http.Post(%d) url(%s) error(%v)", mid, d.orderURL, err)
return
}
if res.Code != ecode.OK.Code() {
err = ecode.Int(res.Code)
log.Error("d.http.Post(%d) url(%s) error(%v)", mid, d.orderURL, err)
return
}
payInfo = res.Data
return
}
// OrderHistory get order history by mid.
func (d *Dao) OrderHistory(c context.Context, mid, page int64, payType int8, orderID, ip string) (hs []*usmdl.PendantOrderInfo, count map[string]int64, err error) {
params := url.Values{}
params.Set("orderID", orderID)
params.Set("mid", strconv.FormatInt(mid, 10))
params.Set("page", strconv.FormatInt(page, 10))
params.Set("payType", strconv.Itoa(int(payType)))
var res struct {
Code int `json:"code"`
Orders []*usmdl.PendantOrderInfo `json:"data"`
Count map[string]int64 `json:"count"`
}
if err = d.http.Get(c, d.orderHistory, ip, params, &res); err != nil {
log.Error("d.http.Get(%d) url(%s) error(%v)", mid, d.orderHistory, err)
return
}
if res.Code != ecode.OK.Code() {
err = ecode.Int(res.Code)
log.Error("d.http.Get(%s) error(%v)", d.orderHistory, err)
return
}
hs = res.Orders
count = res.Count
return
}

View File

@@ -0,0 +1,16 @@
package usersuit
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDao_Group(t *testing.T) {
convey.Convey("Group", t, func() {
groups, err := d.Group(context.TODO(), "")
convey.So(err, convey.ShouldBeNil)
convey.So(groups, convey.ShouldNotBeEmpty)
})
}

View File

@@ -0,0 +1,35 @@
package usersuit
import (
"go-common/app/interface/main/account/conf"
bm "go-common/library/net/http/blademaster"
)
// Dao struct.
type Dao struct {
c *conf.Config
http *bm.Client
orderURL string
orderHistory string
groupURL string
entryGroupURL string
vipGroupURL string
pendantURL string
packageURL string
}
// New new a Dao
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
http: bm.NewClient(c.HTTPClient.Normal),
groupURL: c.Host.API + _groupInfo,
orderURL: c.Host.API + _orderInfo,
orderHistory: c.Host.API + _orderHistory,
entryGroupURL: c.Host.API + _entryGroup,
vipGroupURL: c.Host.API + _vipGroup,
pendantURL: c.Host.API + _pendantInfo,
packageURL: c.Host.API + _packageInfo,
}
return
}

View File

@@ -0,0 +1,19 @@
package usersuit
import (
"flag"
"go-common/app/interface/main/account/conf"
)
var d *Dao
func init() {
flag.Parse()
flag.Set("conf", "../../cmd/account-interface-example.toml")
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
}

View File

@@ -0,0 +1,66 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
go_test(
name = "go_default_test",
srcs = [
"api_test.go",
"dao_test.go",
"oauth2_api_test.go",
"oauth2_client_test.go",
"vip_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/account/conf:go_default_library",
"//app/interface/main/account/model:go_default_library",
"//app/service/main/vip/model:go_default_library",
"//library/ecode:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"api.go",
"dao.go",
"oauth2_api.go",
"oauth2_client.go",
],
importpath = "go-common/app/interface/main/account/dao/vip",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/account/conf:go_default_library",
"//app/interface/main/account/model:go_default_library",
"//app/service/main/vip/model:go_default_library",
"//library/conf/env:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/metadata:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
],
)

View File

@@ -0,0 +1,150 @@
package vip
import (
"context"
"fmt"
"net/url"
"strconv"
"go-common/app/interface/main/account/model"
vipmol "go-common/app/service/main/vip/model"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/net/metadata"
"github.com/pkg/errors"
)
const (
_vipCodeVerify = "/x/internal/vip/code/verify"
_vipCodeOpen = "/x/internal/vip/code/open"
_viptips = "/x/internal/vip/tips"
_couponCancel = "/x/internal/vip/coupon/cancel"
_vipCodeOpened = "/x/internal/vip/code/opened"
// vip with java
_vipInfo = "/internal/v1/user/"
)
//CodeVerify code verify
func (d *Dao) CodeVerify(c context.Context) (token *model.Token, err error) {
ip := metadata.String(c, metadata.RemoteIP)
var tokenResq *model.TokenResq
val := url.Values{}
if err = d.client.Get(c, d.codeVerifyURL, ip, val, &tokenResq); err != nil {
err = errors.WithStack(err)
return
}
if tokenResq.Code == int64(ecode.OK.Code()) {
token = tokenResq.Data
}
return
}
//CodeOpen http code open
func (d *Dao) CodeOpen(c context.Context, mid int64, code, token, verify string) (data *model.ResourceCodeResq, err error) {
ip := metadata.String(c, metadata.RemoteIP)
val := url.Values{}
val.Add("mid", fmt.Sprintf("%v", mid))
val.Add("token", token)
val.Add("verify", verify)
val.Add("code", code)
defer func() {
log.Info("qingqiu url(%+v) params(%+v) return(%+v)", d.codeOpenURL, val, data)
}()
if err = d.client.Post(c, d.codeOpenURL, ip, val, &data); err != nil {
err = errors.WithStack(err)
return
}
if data.Code > int64(ecode.OK.Code()) {
err = ecode.Int(int(data.Code))
return
}
return
}
// Info get vip info
func (d *Dao) Info(c context.Context, mid int64, ip string) (info *model.VIPInfo, err error) {
var res struct {
Code int `json:"code"`
Data *model.VIPInfo `json:"data"`
}
if err = d.client.Get(c, d.infoURL+strconv.FormatInt(mid, 10), ip, nil, &res); err != nil {
log.Error("d.client.Get(%d) error(%v)", mid, err)
return
}
if res.Code != ecode.OK.Code() {
err = ecode.Int(res.Code)
log.Error("d.client.Get(%d) error(%v)", mid, err)
return
}
info = res.Data
return
}
// Tips tips info.
func (d *Dao) Tips(c context.Context, version int64, platform string) (data *vipmol.TipsResp, err error) {
params := url.Values{}
params.Add("version", fmt.Sprintf("%v", version))
params.Add("platform", platform)
var resp struct {
Code int `json:"code"`
Data *vipmol.TipsResp `json:"data"`
}
if err = d.client.Get(c, d.tipsURL, "", params, &resp); err != nil {
err = errors.Errorf("vip tips d.httpClient.Do(%s) error(%+v)", d.tipsURL+"?"+params.Encode(), err)
return
}
if resp.Code != ecode.OK.Code() {
err = errors.Errorf("vip tips url(%s) res(%+v) err(%+v)", d.tipsURL+"?"+params.Encode(), resp, ecode.Int(resp.Code))
}
data = resp.Data
return
}
// CancelUseCoupon cancel use coupon.
func (d *Dao) CancelUseCoupon(c context.Context, arg *vipmol.ArgCancelUseCoupon) (err error) {
params := url.Values{}
params.Add("mid", fmt.Sprintf("%d", arg.Mid))
params.Add("coupon_token", arg.CouponToken)
var resp struct {
Code int `json:"code"`
}
if err = d.clientSlow.Post(c, d.cancelCouponURL, "", params, &resp); err != nil {
err = errors.Errorf("vip cancel coupon d.httpClient.Do(%s) error(%+v)", d.cancelCouponURL+"?"+params.Encode(), err)
return
}
if resp.Code != ecode.OK.Code() {
err = ecode.Int(resp.Code)
}
return
}
//CodeOpeneds sel code opened data
func (d *Dao) CodeOpeneds(c context.Context, arg *model.CodeInfoReq, ip string) (resp []*vipmol.CodeInfoResp, err error) {
val := url.Values{}
val.Add("bis_appkey", arg.Appkey)
val.Add("bis_sign", arg.Sign)
val.Add("bis_ts", strconv.FormatInt(arg.Ts.Time().Unix(), 10))
val.Add("start_time", strconv.FormatInt(arg.StartTime.Time().Unix(), 10))
val.Add("end_time", strconv.FormatInt(arg.EndTime.Time().Unix(), 10))
val.Add("cursor", strconv.FormatInt(arg.Cursor, 10))
rep := new(struct {
Code int `json:"code"`
Data []*vipmol.CodeInfoResp `json:"data"`
})
defer func() {
log.Info("vip code opened url:%+v params:%+v return:%+v", d.codeOpenedURL, val, rep)
}()
if err = d.client.Get(c, d.codeOpenedURL, ip, val, rep); err != nil {
err = errors.Errorf("vip code opened url:%+v params:%+v return:%+v,err:%+v", d.codeOpenedURL, val, rep, err)
return
}
if rep.Code != ecode.OK.Code() {
err = ecode.Int(rep.Code)
return
}
resp = rep.Data
return
}

View File

@@ -0,0 +1,42 @@
package vip
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestVipCodeVerify(t *testing.T) {
convey.Convey("CodeVerify", t, func(convCtx convey.C) {
var (
c = context.Background()
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
token, err := d.CodeVerify(c)
convCtx.Convey("Then err should be nil.token should not be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
convCtx.So(token, convey.ShouldNotBeNil)
})
})
})
}
func TestVipCodeOpen(t *testing.T) {
convey.Convey("CodeOpen", t, func(convCtx convey.C) {
var (
c = context.Background()
mid = int64(0)
code = ""
token = ""
verify = ""
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
data, err := d.CodeOpen(c, mid, code, token, verify)
convCtx.Convey("Then err should be nil.data should not be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
convCtx.So(data, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,38 @@
package vip
import (
"go-common/app/interface/main/account/conf"
bm "go-common/library/net/http/blademaster"
)
// Dao dao
type Dao struct {
c *conf.Config
client *bm.Client
clientSlow *bm.Client
infoURL string
codeOpenURL string
codeVerifyURL string
tipsURL string
cancelCouponURL string
codeOpenedURL string
cl *Clientl
}
// New new
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
client: bm.NewClient(c.HTTPClient.Normal),
clientSlow: bm.NewClient(c.HTTPClient.Slow),
infoURL: c.Host.Vip + _vipInfo,
codeOpenURL: c.Host.API + _vipCodeOpen,
codeVerifyURL: c.Host.API + _vipCodeVerify,
tipsURL: c.Host.API + _viptips,
cancelCouponURL: c.Host.API + _couponCancel,
codeOpenedURL: c.Host.API + _vipCodeOpened,
}
// http client for had url md5 sign.
d.cl = NewClientl(c.Vipproperty.OAuthClient, d.client)
return
}

View File

@@ -0,0 +1,35 @@
package vip
import (
"flag"
"os"
"testing"
"go-common/app/interface/main/account/conf"
)
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.account.account-interface")
flag.Set("conf_token", "967eef77ad40b478234f11b0d489d6d6")
flag.Set("tree_id", "3815")
flag.Set("conf_version", "docker-1")
flag.Set("deploy_env", "uat")
flag.Set("conf_host", "config.bilibili.co")
flag.Set("conf_path", "/tmp")
flag.Set("region", "sh")
flag.Set("zone", "sh001")
} else {
flag.Set("conf", "../../cmd/account-interface-example.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
os.Exit(m.Run())
}

View File

@@ -0,0 +1,36 @@
package vip
import (
"context"
"net/url"
"go-common/app/interface/main/account/model"
"go-common/library/ecode"
pkgerr "github.com/pkg/errors"
)
const (
_oauth2UserInfoPath = "/oauth2/user_info"
)
//OAuth2ByCode get user info by oauth2 code.
func (d *Dao) OAuth2ByCode(c context.Context, a *model.ArgAuthCode) (data *model.OAuth2InfoResp, err error) {
params := url.Values{}
params.Add("code", a.Code)
params.Add("grant_type", "authorization_code")
var res struct {
Code int `json:"code"`
Data *model.OAuth2InfoResp `json:"data"`
}
if err = d.cl.get(c, d.c.Host.PassportCom, _oauth2UserInfoPath, a.IP, params, &res); err != nil {
return
}
if res.Code != 0 {
err = ecode.Int(res.Code)
err = pkgerr.Wrap(err, "dao oauth2 userinfo")
return
}
data = res.Data
return
}

View File

@@ -0,0 +1,25 @@
package vip
import (
"context"
"fmt"
"testing"
"go-common/app/interface/main/account/model"
. "github.com/smartystreets/goconvey/convey"
)
// go test -test.v -test.run TestDaoOAuth2
func TestDaoOAuth2(t *testing.T) {
Convey("TestDaoOAuth2", t, func() {
data, err := d.OAuth2ByCode(context.Background(), &model.ArgAuthCode{
Code: "778b91c87a43e4fdab6c647010b77566",
})
if fmt.Sprintf("%v", err) != "dao oauth2 userinfo: -907" {
So(err, ShouldBeNil)
So(data, ShouldNotBeNil)
}
So(fmt.Sprintf("%v", err) == "dao oauth2 userinfo: -907", ShouldBeTrue)
})
}

View File

@@ -0,0 +1,95 @@
package vip
import (
"bytes"
"context"
"crypto/md5"
"encoding/hex"
xhttp "net/http"
"net/url"
"strings"
"go-common/library/conf/env"
bm "go-common/library/net/http/blademaster"
pkgerr "github.com/pkg/errors"
)
//Clientl Client is http client, for url sign.
type Clientl struct {
client *bm.Client
conf *bm.ClientConfig
}
// NewClientl new a http client.
func NewClientl(c *bm.ClientConfig, client *bm.Client) *Clientl {
// check appkey
if c.Key == "" || c.Secret == "" {
panic("http client must config appkey and appsecret")
}
cl := new(Clientl)
cl.client = client
cl.conf = c
return cl
}
const (
_httpHeaderRemoteIP = "x-backend-bili-real-ip"
_noKickUserAgent = "haoguanwei@bilibili.com "
)
func (cl *Clientl) get(c context.Context, host, path, realIP string, params url.Values, res interface{}) (err error) {
req, err := cl.newGetRequest(host, path, realIP, params)
if err != nil {
return
}
return cl.client.Do(c, req, res)
}
// newGetRequest new get http request with host, path, ip, values and headers, without sign.
func (cl *Clientl) newGetRequest(host, path, realIP string, params url.Values) (req *xhttp.Request, err error) {
if params == nil {
params = url.Values{}
}
params.Add("client_id", cl.conf.App.Key)
enc := sign(params, path, cl.conf.App.Secret)
ru := host + path
if enc != "" {
ru = ru + "?" + enc
}
req, err = xhttp.NewRequest(xhttp.MethodGet, ru, nil)
if err != nil {
err = pkgerr.Wrapf(err, "uri:%s", ru)
return
}
const (
_userAgent = "User-Agent"
)
if realIP != "" {
req.Header.Set(_httpHeaderRemoteIP, realIP)
}
req.Header.Set(_userAgent, _noKickUserAgent+" "+env.AppID)
return
}
func sign(params url.Values, path, secret string) string {
if params == nil {
params = url.Values{}
}
tmp := params.Encode()
if strings.IndexByte(tmp, '+') > -1 {
tmp = strings.Replace(tmp, "+", "%20", -1)
}
var b bytes.Buffer
b.WriteString(path)
b.WriteString("?")
b.WriteString(tmp)
b.WriteString(secret)
mh := md5.Sum(b.Bytes())
// query
var qb bytes.Buffer
qb.WriteString(tmp)
qb.WriteString("&sign=")
qb.WriteString(hex.EncodeToString(mh[:]))
return qb.String()
}

View File

@@ -0,0 +1,24 @@
package vip
import (
"net/url"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestVipsign(t *testing.T) {
convey.Convey("sign", t, func(convCtx convey.C) {
var (
params url.Values
path = ""
secret = ""
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
p1 := sign(params, path, secret)
convCtx.Convey("Then p1 should not be nil.", func(convCtx convey.C) {
convCtx.So(p1, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,29 @@
package vip
import (
"context"
"testing"
vipmol "go-common/app/service/main/vip/model"
"go-common/library/ecode"
. "github.com/smartystreets/goconvey/convey"
)
func TestDao_CodeVerify(t *testing.T) {
Convey("code verify", t, func() {
_, err := d.CodeVerify(context.TODO())
So(err, ShouldBeNil)
})
}
// go test -test.v -test.run TestDaoCancelUseCoupon
func TestDaoCancelUseCoupon(t *testing.T) {
Convey("TestDaoCancelUseCoupon", t, func() {
err := d.CancelUseCoupon(context.TODO(), &vipmol.ArgCancelUseCoupon{
CouponToken: "672889783020180721180426",
Mid: 1,
})
So(err == ecode.CouPonTokenNotFoundErr, ShouldBeTrue)
})
}