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,23 @@
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/service/main/open/api/grpc/v1:all-srcs",
"//app/service/main/open/cmd:all-srcs",
"//app/service/main/open/conf:all-srcs",
"//app/service/main/open/dao:all-srcs",
"//app/service/main/open/model:all-srcs",
"//app/service/main/open/server/grpc:all-srcs",
"//app/service/main/open/server/http:all-srcs",
"//app/service/main/open/service:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,24 @@
#1.2.0
1.增加rpc服务通过appkey查询appid
#1.1.1
1.增加memcache备份
2.修改memcache数据存储结构
3.使用常量表示mc的key
#1.0.4
1. 去掉db回源
#1.0.3
1.修改自定义验证方式
2.去除ts强校验
#1.0.2
1.移除conf不需要的配置
#1.0.1
1.增加记录不存在的404错误码
#1.0.0
1.修复缓存dm_apps不存在情况

View File

@@ -0,0 +1,10 @@
# Owner
zhapuyu
zhoushuguang
# Author
tuliang
# Reviewer
zhapuyu
zhoushuguang

View File

@@ -0,0 +1,16 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- tuliang
- zhapuyu
- zhoushuguang
labels:
- main
- service
- service/main/open
options:
no_parent_owners: true
reviewers:
- tuliang
- zhapuyu
- zhoushuguang

View File

View File

@@ -0,0 +1,54 @@
load(
"@io_bazel_rules_go//proto:def.bzl",
"go_proto_library",
)
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
proto_library(
name = "v1_proto",
srcs = ["api.proto"],
tags = ["automanaged"],
)
go_proto_library(
name = "v1_go_proto",
compilers = ["@io_bazel_rules_go//proto:go_grpc"],
importpath = "go-common/app/service/main/open/api/grpc/v1",
proto = ":v1_proto",
tags = ["automanaged"],
)
go_library(
name = "go_default_library",
srcs = ["client.go"],
embed = [":v1_go_proto"],
importpath = "go-common/app/service/main/open/api/grpc/v1",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//library/net/rpc/warden:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",
"@org_golang_google_grpc//:go_default_library",
"@org_golang_x_net//context: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"],
)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,45 @@
syntax = "proto3";
package manager.service.open;
option go_package = "v1";
message AppIDReply {
int64 app_id = 1;
}
message AppIDReq {
string app_key = 2;
}
message CloseReply {
}
message CloseReq {
}
message PingReply {
}
message PingReq {
}
message SecretReply {
string res = 1;
}
message SecretReq {
string sapp_key = 2;
}
service Open {
// Ping check dao health.
rpc Ping(PingReq) returns(PingReply);
// Close close all dao.
rpc Close(CloseReq) returns(CloseReply);
// Secret .
rpc Secret(SecretReq) returns(SecretReply);
// AppID .
rpc AppID(AppIDReq) returns(AppIDReply);
}

View File

@@ -0,0 +1,22 @@
package v1
import (
"context"
"go-common/library/net/rpc/warden"
"google.golang.org/grpc"
)
// AppID unique app id for service discovery
const AppID = "manager.service.open"
// NewClient new member grpc client
func NewClient(cfg *warden.ClientConfig, opts ...grpc.DialOption) (OpenClient, error) {
client := warden.NewClient(cfg, opts...)
conn, err := client.Dial(context.Background(), "discovery://default/"+AppID)
if err != nil {
return nil, err
}
return NewOpenClient(conn), nil
}

View File

@@ -0,0 +1,44 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
)
go_binary(
name = "cmd",
embed = [":go_default_library"],
tags = ["automanaged"],
)
go_library(
name = "go_default_library",
srcs = ["main.go"],
data = ["open-service-test.toml"],
importpath = "go-common/app/service/main/open/cmd",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/main/open/conf:go_default_library",
"//app/service/main/open/server/grpc:go_default_library",
"//app/service/main/open/server/http:go_default_library",
"//app/service/main/open/service:go_default_library",
"//library/log:go_default_library",
"//library/net/trace: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,56 @@
package main
import (
"context"
"flag"
"os"
"os/signal"
"syscall"
"time"
"go-common/app/service/main/open/conf"
"go-common/app/service/main/open/server/grpc"
"go-common/app/service/main/open/server/http"
"go-common/app/service/main/open/service"
"go-common/library/log"
"go-common/library/net/trace"
)
func main() {
flag.Parse()
if err := conf.Init(); err != nil {
log.Error("conf.Init() error(%v)", err)
panic(err)
}
// init log
log.Init(conf.Conf.Log)
trace.Init(conf.Conf.Tracer)
defer trace.Close()
defer func() {
log.Close()
// wait for a while to guarantee that all log messages are written
time.Sleep(10 * time.Millisecond)
}()
//service init
svc := service.New(conf.Conf)
ws := grpc.New(conf.Conf.WardenServer, svc)
http.Init(conf.Conf, svc)
// init signal
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
for {
s := <-c
log.Info("open-service get a signal %s", s.String())
switch s {
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGSTOP, syscall.SIGINT:
ws.Shutdown(context.Background())
svc.Close()
return
case syscall.SIGHUP:
// TODO reload
default:
return
}
}
}

View File

@@ -0,0 +1,25 @@
version = "1.0.0"
user = "nobody"
pid = "/tmp/open-service.pid"
dir = "./"
appTicker = "1m"
[orm]
dsn = "open:w965K973LuLfj82xB2DJSr01atpN2Sec@tcp(172.22.34.101:3309)/open?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
active = 5
idle = 5
idleTimeout = "4h"
[memcache]
proto = "tcp"
addr = "172.18.33.60:11236"
idle = 10
active = 10
dialTimeout = "2s"
readTimeout = "2s"
writeTimeout = "2s"
idleTimeout = "7h"
[wardenServer]
addr = "0.0.0.0:9000"
timeout = "1s"

View File

@@ -0,0 +1,39 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["conf.go"],
importpath = "go-common/app/service/main/open/conf",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//library/cache/memcache:go_default_library",
"//library/conf:go_default_library",
"//library/database/orm:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/rpc/warden:go_default_library",
"//library/net/trace:go_default_library",
"//library/time:go_default_library",
"//vendor/github.com/BurntSushi/toml: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,89 @@
package conf
import (
"errors"
"flag"
"go-common/library/cache/memcache"
"go-common/library/conf"
"go-common/library/database/orm"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/rpc/warden"
"go-common/library/net/trace"
xtime "go-common/library/time"
"github.com/BurntSushi/toml"
)
// Config .
type Config struct {
App *bm.App
Log *log.Config
Tracer *trace.Config
ORM *orm.Config
// Uname load ticker
AppTicker xtime.Duration
// mc
Memcache *memcache.Config
WardenServer *warden.ServerConfig
}
var (
confPath string
client *conf.Client
// Conf config
Conf = &Config{}
)
// init() .
func init() {
flag.StringVar(&confPath, "conf", "", "config path")
}
// Init .
func Init() (err error) {
if confPath != "" {
return local()
}
return remote()
}
// local .
func local() (err error) {
_, err = toml.DecodeFile(confPath, &Conf)
return
}
// remote .
func remote() (err error) {
if client, err = conf.New(); err != nil {
return
}
if err = load(); err != nil {
return
}
go func() {
for range client.Event() {
log.Info("config reload")
}
}()
return
}
// load .
func load() (err error) {
var (
s string
ok bool
tmpConf *Config
)
if s, ok = client.Toml2(); !ok {
return errors.New("load config center error")
}
if _, err = toml.Decode(s, &tmpConf); err != nil {
return errors.New("could not decode config")
}
*Conf = *tmpConf
return
}

View File

@@ -0,0 +1,57 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
name = "go_default_library",
srcs = [
"app.go",
"dao.go",
"memcache.go",
],
importpath = "go-common/app/service/main/open/dao",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/main/open/conf:go_default_library",
"//library/cache/memcache:go_default_library",
"//library/database/orm:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//vendor/github.com/jinzhu/gorm: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 = [
"app_test.go",
"dao_test.go",
"memcache_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/service/main/open/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)

View File

@@ -0,0 +1,17 @@
package dao
import (
"context"
"database/sql"
"go-common/library/ecode"
)
// Secret .
func (d *Dao) Secret(c context.Context, sappKey string) (res string, err error) {
err = d.DB.Table("dm_apps").Where("appkey = ?", sappKey).Select("app_secret").Row().Scan(&res)
if err == sql.ErrNoRows {
err = ecode.NothingFound
}
return
}

View File

@@ -0,0 +1,16 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoSecret(t *testing.T) {
convey.Convey("Secret", t, func() {
res, err := d.Secret(context.TODO(), "19e7f5b7d8ad531b")
convey.So(err, convey.ShouldBeNil)
convey.So(res, convey.ShouldNotBeNil)
})
}

View File

@@ -0,0 +1,56 @@
package dao
import (
"context"
"go-common/app/service/main/open/conf"
"go-common/library/cache/memcache"
"go-common/library/database/orm"
"go-common/library/log"
"github.com/jinzhu/gorm"
)
// Dao .
type Dao struct {
// db
DB *gorm.DB
//memcache
mc *memcache.Pool
}
// New new a instance.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
// db
DB: orm.NewMySQL(c.ORM),
//memcache
mc: memcache.NewPool(c.Memcache),
}
d.initORM()
return
}
func (d *Dao) initORM() {
d.DB.LogMode(true)
}
// Ping check connection of db , mc .
func (d *Dao) Ping(c context.Context) (err error) {
if d.DB != nil {
if err = d.DB.DB().PingContext(c); err != nil {
log.Error("d.PingContext error (%v)", err)
}
}
if err = d.pingMC(c); err != nil {
return
}
return
}
// Close close connection of db.
func (d *Dao) Close() {
if d.DB != nil {
d.DB.Close()
}
}

View File

@@ -0,0 +1,36 @@
package dao
import (
"flag"
"os"
"testing"
"go-common/app/service/main/open/conf"
)
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.manager.open-service")
flag.Set("conf_token", "3642c9070eda37909090a12271b40920")
flag.Set("tree_id", "55252")
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/open-service-test.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
m.Run()
os.Exit(1)
}

View File

@@ -0,0 +1,64 @@
package dao
import (
"context"
"encoding/json"
"go-common/library/cache/memcache"
"go-common/library/ecode"
"go-common/library/log"
)
const (
//appkeys represents key name
_asspkeys = "sappkeys"
)
// pingMC ping memcache .
func (d *Dao) pingMC(c context.Context) (err error) {
conn := d.mc.Get(c)
defer conn.Close()
if err = conn.Set(&memcache.Item{Key: "ping", Value: []byte{1}, Expiration: 0}); err != nil {
log.Error("conn.Store(set, ping, 1) error (%v)", err)
}
return
}
// AppkeyCache .
func (d *Dao) AppkeyCache(c context.Context) (res map[string]string, err error) {
var (
conn memcache.Conn
item *memcache.Item
)
conn = d.mc.Get(c)
defer conn.Close()
if item, err = conn.Get(_asspkeys); err != nil {
if err == memcache.ErrNotFound {
err = ecode.NothingFound
}
return
}
res = make(map[string]string)
err = json.Unmarshal([]byte(item.Value), &res)
return
}
// SetAppkeyCache .
func (d *Dao) SetAppkeyCache(c context.Context, newData map[string]string) (err error) {
var (
conn memcache.Conn
item *memcache.Item
jsonAppCache []byte
)
if jsonAppCache, err = json.Marshal(newData); err != nil {
return
}
conn = d.mc.Get(c)
defer conn.Close()
item = &memcache.Item{
Key: _asspkeys,
Value: jsonAppCache,
}
err = conn.Set(item)
return
}

View File

@@ -0,0 +1,51 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaopingMC(t *testing.T) {
convey.Convey("pingMC", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.pingMC(c)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoAppkeyCache(t *testing.T) {
convey.Convey("AppkeyCache", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, err := d.AppkeyCache(c)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoSetAppkeyCache(t *testing.T) {
convey.Convey("SetAppkeyCache", t, func(ctx convey.C) {
var (
c = context.Background()
newData map[string]string
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.SetAppkeyCache(c, newData)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}

View File

@@ -0,0 +1,28 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"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_library(
name = "go_default_library",
srcs = ["app.go"],
importpath = "go-common/app/service/main/open/model",
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,9 @@
package model
// App represents App info.
type App struct {
AppID int64 `json:"appid" gorm:"primary_key"`
AppName string `json:"app_name" gorm:"column:app_name"`
AppKey string `json:"appkey" gorm:"column:appkey"`
AppSecret string `json:"app_secret" gorm:"column:app_secret"`
}

View File

@@ -0,0 +1,34 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["server.go"],
importpath = "go-common/app/service/main/open/server/grpc",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/main/open/api/grpc/v1:go_default_library",
"//app/service/main/open/service:go_default_library",
"//library/ecode:go_default_library",
"//library/net/rpc/warden: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,56 @@
// Package grpc generate by warden_gen
package grpc
import (
"context"
"go-common/app/service/main/open/api/grpc/v1"
"go-common/app/service/main/open/service"
"go-common/library/ecode"
"go-common/library/net/rpc/warden"
)
// New Open warden rpc server
func New(c *warden.ServerConfig, svr *service.Service) *warden.Server {
w := warden.NewServer(c)
v1.RegisterOpenServer(w.Server(), &openService{svr})
ws, err := w.Start()
if err != nil {
panic(err)
}
return ws
}
type openService struct {
svr *service.Service
}
var _ v1.OpenServer = &openService{}
// Ping check dao health.
func (s *openService) Ping(ctx context.Context, req *v1.PingReq) (*v1.PingReply, error) {
return nil, ecode.MethodNotAllowed
}
// Close close all dao.
func (s *openService) Close(ctx context.Context, req *v1.CloseReq) (*v1.CloseReply, error) {
return nil, ecode.MethodNotAllowed
}
// Secret .
func (s *openService) Secret(ctx context.Context, req *v1.SecretReq) (*v1.SecretReply, error) {
return nil, ecode.MethodNotAllowed
}
// AppID .
func (s *openService) AppID(ctx context.Context, req *v1.AppIDReq) (*v1.AppIDReply, error) {
appID, err := s.svr.AppID(ctx, req.AppKey)
if err != nil {
return nil, err
}
appIDReply := &v1.AppIDReply{
AppId: appID,
}
return appIDReply, nil
}

View File

@@ -0,0 +1,38 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"app.go",
"http.go",
],
importpath = "go-common/app/service/main/open/server/http",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/main/open/conf:go_default_library",
"//app/service/main/open/service: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,25 @@
package http
import (
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
// Secret .
func secret(c *bm.Context) {
sappKey := c.Request.Form.Get("sappkey")
if sappKey == "" {
c.JSON(nil, ecode.RequestErr)
log.Error("sappkey is empty")
return
}
appSecret, err := openSvc.Secret(c, sappKey)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(map[string]interface{}{
"app_secret": appSecret,
}, err)
}

View File

@@ -0,0 +1,41 @@
package http
import (
"net/http"
"go-common/app/service/main/open/conf"
"go-common/app/service/main/open/service"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
var (
openSvc *service.Service
)
// Init init http sever instance.
func Init(c *conf.Config, s *service.Service) {
openSvc = s
// init inner router
engineIn := bm.DefaultServer(nil)
innerRouter(engineIn)
// init inner server
if err := engineIn.Start(); err != nil {
log.Error("engineInner.Start error (%v)", err)
panic(err)
}
}
// innerRouter .
func innerRouter(e *bm.Engine) {
e.Ping(ping)
e.GET("/api/getsecret", openSvc.Verify, secret)
}
// ping check server ok.
func ping(c *bm.Context) {
if err := openSvc.Ping(c); err != nil {
log.Error("service ping error(%v)", err)
c.AbortWithStatus(http.StatusServiceUnavailable)
}
}

View File

@@ -0,0 +1,40 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"app.go",
"service.go",
"verify.go",
],
importpath = "go-common/app/service/main/open/service",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/open/model:go_default_library",
"//app/service/main/open/conf:go_default_library",
"//app/service/main/open/dao: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,78 @@
package service
import (
"context"
"time"
"go-common/app/admin/main/open/model"
"go-common/library/ecode"
"go-common/library/log"
)
// Secret .
func (s *Service) Secret(c context.Context, sappKey string) (res string, err error) {
ok := false
if res, ok = s.appsecrets[sappKey]; !ok {
log.Error("appkey(%s) not found in cache", sappKey)
err = ecode.NothingFound
}
return
}
// AppID .
func (s *Service) AppID(c context.Context, appKey string) (appID int64, err error) {
if appKey == "" {
log.Error("appkey is null")
err = ecode.RequestErr
return
}
var ok bool
if appID, ok = s.appIDs[appKey]; !ok {
log.Error("failed to get appid of appkey(%v) in local cache")
err = ecode.NothingFound
}
return
}
// loadApp .
func (s *Service) loadAppSecrets() {
var (
apps []*model.App
appsecrets = map[string]string{}
)
if err := s.dao.DB.Table("dm_apps").Find(&apps).Error; err != nil {
log.Error("s.dao.DB error (%v)", err)
if len(s.appsecrets) == 0 {
if s.appsecrets, err = s.dao.AppkeyCache(context.Background()); err != nil {
log.Error("s.dao.AppkeyCache error (%v)", err)
}
}
return
}
for _, v := range apps {
appsecrets[v.AppKey] = v.AppSecret
s.appIDs[v.AppKey] = v.AppID
}
if length := len(appsecrets); length != 0 {
s.appsecrets = appsecrets
log.Info("loadAppSecrets refresh success! lines:%d", length)
//update memcache
if err := s.dao.SetAppkeyCache(context.Background(), appsecrets); err != nil {
log.Error("Refresh data failed in memcache! error(%v)", err)
}
}
}
// loadAppSecretsproc .
func (s *Service) loadAppSecretsproc() {
var duration time.Duration
if duration = time.Duration(s.c.AppTicker); duration == 0 {
//default value
duration = time.Duration(5 * time.Minute)
}
ticker := time.NewTicker(duration)
for range ticker.C {
s.loadAppSecrets()
}
ticker.Stop()
}

View File

@@ -0,0 +1,38 @@
package service
import (
"context"
"go-common/app/service/main/open/conf"
"go-common/app/service/main/open/dao"
)
// Service biz service def.
type Service struct {
c *conf.Config
dao *dao.Dao
appsecrets map[string]string
appIDs map[string]int64 //map[appkey]appid
}
// New new a Service and return.
func New(c *conf.Config) (s *Service) {
s = &Service{
c: c,
dao: dao.New(c),
}
s.appIDs = map[string]int64{}
s.loadAppSecrets()
go s.loadAppSecretsproc()
return
}
// Ping check dao health.
func (s *Service) Ping(c context.Context) (err error) {
return s.dao.Ping(c)
}
// Close close all dao.
func (s *Service) Close() {
s.dao.Close()
}

View File

@@ -0,0 +1,64 @@
package service
import (
"crypto/md5"
"encoding/hex"
"net/url"
"strings"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
// Verify .
func (s *Service) Verify(c *bm.Context) {
if err := s.verify(c); err != nil {
c.JSON(nil, err)
c.Abort()
return
}
}
// Verify .
func (s *Service) verify(c *bm.Context) error {
req := c.Request
params := req.Form
if req.Method == "POST" {
// Give priority to sign in url query, otherwise check sign in post form.
q := req.URL.Query()
if q.Get("sign") != "" {
params = q
}
}
sign := params.Get("sign")
params.Del("sign")
defer params.Set("sign", sign)
sappkey := params.Get("appkey")
secret, ok := s.appsecrets[sappkey]
if !ok {
log.Error("appkey(%s) not found in cache", sappkey)
return ecode.NothingFound
}
if hsign := s.sign(params, sappkey, secret, true); hsign != sign {
if hsign1 := s.sign(params, sappkey, secret, false); hsign1 != sign {
log.Error("Get sign: %s, expect %s", sign, hsign)
return ecode.SignCheckErr
}
}
return nil
}
// Sign is used to sign form params by given condition.
func (s *Service) sign(params url.Values, appkey, secret string, lower bool) string {
data := params.Encode()
if strings.IndexByte(data, '+') > -1 {
data = strings.Replace(data, "+", "%20", -1)
}
if lower {
data = strings.ToLower(data)
}
digest := md5.Sum([]byte(data + secret))
return hex.EncodeToString(digest[:])
}