Compare commits
5 Commits
7ec78d1c35
...
38375ffdda
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
38375ffdda | ||
|
|
7200531c27 | ||
|
|
a248c6cbeb | ||
|
|
b43b5dbd59 | ||
|
|
a10e100364 |
135
fsm/fsm.go
Normal file
135
fsm/fsm.go
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
package fsm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/gob"
|
||||||
|
"fmt"
|
||||||
|
"fusenapi/model/gmodel"
|
||||||
|
"fusenapi/utils/auth"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/hashicorp/raft"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// StateCluster is a simple key-value store as an FSM.
|
||||||
|
type StateCluster struct {
|
||||||
|
mu sync.Mutex
|
||||||
|
|
||||||
|
store map[int64]*UserState
|
||||||
|
|
||||||
|
gdb *gorm.DB
|
||||||
|
waiter *WaitCallback
|
||||||
|
ra *raft.Raft // The consensus mechanism
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fsm *StateCluster) GetUserState(Userid int64) (*UserState, error) {
|
||||||
|
|
||||||
|
fsm.mu.Lock()
|
||||||
|
if us, ok := fsm.store[Userid]; ok {
|
||||||
|
// log.Println("exists")
|
||||||
|
fsm.mu.Unlock()
|
||||||
|
return us, nil
|
||||||
|
}
|
||||||
|
fsm.mu.Unlock()
|
||||||
|
|
||||||
|
// log.Println("apply")
|
||||||
|
cmd := &command{
|
||||||
|
Op: "update",
|
||||||
|
Key: Userid,
|
||||||
|
}
|
||||||
|
|
||||||
|
future := fsm.ra.Apply(cmd.Encode(), time.Minute)
|
||||||
|
// log.Println(future.Index())
|
||||||
|
|
||||||
|
if future.Response() != nil {
|
||||||
|
return nil, future.Response().(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
if us := fsm.waiter.Wait(Userid, time.Second*5); us != nil {
|
||||||
|
return us, nil
|
||||||
|
} else {
|
||||||
|
return nil, fmt.Errorf("timeout")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply applies a Raft log entry to the key-value store.
|
||||||
|
func (fsm *StateCluster) Apply(fsmlog *raft.Log) interface{} {
|
||||||
|
var cmd command
|
||||||
|
|
||||||
|
err := cmd.Decode(fsmlog.Data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch cmd.Op {
|
||||||
|
case "update":
|
||||||
|
fsm.mu.Lock()
|
||||||
|
defer fsm.mu.Unlock()
|
||||||
|
|
||||||
|
// log.Println("update")
|
||||||
|
models := gmodel.NewAllModels(fsm.gdb)
|
||||||
|
user, err := models.FsUser.FindUserById(context.TODO(), cmd.Key)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
userState := &UserState{
|
||||||
|
UserId: cmd.Key,
|
||||||
|
PwdHash: auth.StringToHash(*user.PasswordHash),
|
||||||
|
Expired: time.Now(),
|
||||||
|
}
|
||||||
|
fsm.store[cmd.Key] = userState
|
||||||
|
fsm.waiter.Done(userState)
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unrecognized command operation: %s", cmd.Op)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Snapshot returns a snapshot of the key-value store.
|
||||||
|
func (fsm *StateCluster) Snapshot() (raft.FSMSnapshot, error) {
|
||||||
|
fsm.mu.Lock()
|
||||||
|
defer fsm.mu.Unlock()
|
||||||
|
|
||||||
|
snapshot := kvStoreSnapshot{
|
||||||
|
store: make(map[int64]*UserState),
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range fsm.store {
|
||||||
|
snapshot.store[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
return &snapshot, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore stores the key-value store to a previous state.
|
||||||
|
func (fsm *StateCluster) Restore(rc io.ReadCloser) error {
|
||||||
|
var snapshot kvStoreSnapshot
|
||||||
|
dec := gob.NewDecoder(rc)
|
||||||
|
if err := dec.Decode(&snapshot); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fsm.store = snapshot.store
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// kvStoreSnapshot represents a snapshot of the key-value store.
|
||||||
|
type kvStoreSnapshot struct {
|
||||||
|
store map[int64]*UserState
|
||||||
|
}
|
||||||
|
|
||||||
|
// Persist writes the snapshot to the provided sink.
|
||||||
|
func (snapshot *kvStoreSnapshot) Persist(sink raft.SnapshotSink) error {
|
||||||
|
// The example has been simplified. In a production environment, you would
|
||||||
|
// need to handle this operation with more care.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Release is invoked when the Raft instance is finished with the snapshot.
|
||||||
|
func (snapshot *kvStoreSnapshot) Release() {
|
||||||
|
// Normally you would put any cleanup here.
|
||||||
|
}
|
||||||
182
fsm/main.go
Normal file
182
fsm/main.go
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
package fsm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/gob"
|
||||||
|
"fmt"
|
||||||
|
"fusenapi/initalize"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/hashicorp/raft"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func test1() {
|
||||||
|
log.SetFlags(log.Llongfile)
|
||||||
|
|
||||||
|
fsm := StartNode("fs1", "localhost:5500", initalize.InitMysql("fusentest:XErSYmLELKMnf3Dh@tcp(110.41.19.98:3306)/fusentest"))
|
||||||
|
|
||||||
|
time.Sleep(time.Second * 5)
|
||||||
|
|
||||||
|
for i := 0; i < 30; i++ {
|
||||||
|
go log.Println(fsm.GetUserState(39))
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println(fsm.GetUserState(39))
|
||||||
|
|
||||||
|
select {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// StartNode 启动节点
|
||||||
|
func StartNode(ServerID string, RaftBind string, gdb *gorm.DB) *StateCluster {
|
||||||
|
|
||||||
|
fsm := &StateCluster{
|
||||||
|
store: make(map[int64]*UserState),
|
||||||
|
waiter: NewWaitCallback(),
|
||||||
|
gdb: gdb,
|
||||||
|
}
|
||||||
|
|
||||||
|
var retainSnapshotCount = 2
|
||||||
|
// var ServerID string = "fs1"
|
||||||
|
// var RaftBind string = "localhost:5500"
|
||||||
|
var RaftDir string = fmt.Sprintf("/tmp/raftdir/%s", ServerID)
|
||||||
|
|
||||||
|
// Setup Raft configuration.
|
||||||
|
config := raft.DefaultConfig()
|
||||||
|
config.LocalID = raft.ServerID(ServerID)
|
||||||
|
|
||||||
|
// Setup Raft communication.
|
||||||
|
addr, err := net.ResolveTCPAddr("tcp", RaftBind)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
transport, err := raft.NewTCPTransport(RaftBind, addr, 3, 30*time.Second, os.Stderr)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the snapshot store. This allows the Raft to truncate the log.
|
||||||
|
snapshots, err := raft.NewFileSnapshotStore(RaftDir, retainSnapshotCount, os.Stderr)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Errorf("file snapshot store: %s", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the log store and stable store.
|
||||||
|
logStore := raft.NewInmemStore()
|
||||||
|
stableStore := raft.NewInmemStore()
|
||||||
|
|
||||||
|
// Create the Raft system.
|
||||||
|
fsm.ra, err = raft.NewRaft(config, fsm, logStore, stableStore, snapshots, transport)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
configuration := raft.Configuration{
|
||||||
|
Servers: []raft.Server{
|
||||||
|
{
|
||||||
|
Suffrage: raft.Voter,
|
||||||
|
ID: config.LocalID,
|
||||||
|
Address: transport.LocalAddr(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
fu := fsm.ra.BootstrapCluster(configuration)
|
||||||
|
if err := fu.Error(); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
waitForLeader(fsm.ra)
|
||||||
|
|
||||||
|
return fsm
|
||||||
|
}
|
||||||
|
|
||||||
|
func JoinCluster(ServerID string, LeaderAddress string, RaftBind string, gdb *gorm.DB) *StateCluster {
|
||||||
|
|
||||||
|
fsm := StartNode(ServerID, RaftBind, gdb)
|
||||||
|
|
||||||
|
configFuture := fsm.ra.GetConfiguration()
|
||||||
|
if err := configFuture.Error(); err != nil {
|
||||||
|
log.Fatalf("failed to get raft configuration: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, srv := range configFuture.Configuration().Servers {
|
||||||
|
if srv.ID == raft.ServerID(ServerID) && srv.Address == raft.ServerAddress(LeaderAddress) {
|
||||||
|
if future := fsm.ra.RemoveServer(srv.ID, 0, 0); future.Error() != nil {
|
||||||
|
log.Fatalf("Error removing existing server [%s]: %v", ServerID, future.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
f := fsm.ra.AddVoter(raft.ServerID(ServerID), raft.ServerAddress(RaftBind), 0, 0)
|
||||||
|
if f.Error() != nil {
|
||||||
|
log.Fatalf("Error adding voter: %v", f.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return fsm
|
||||||
|
}
|
||||||
|
|
||||||
|
func waitForLeader(ra *raft.Raft) {
|
||||||
|
leaderCh := ra.LeaderCh()
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case isLeader := <-leaderCh:
|
||||||
|
if isLeader {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
case <-time.After(10 * time.Second):
|
||||||
|
log.Println("Still waiting for the leader...")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// var gdb *gorm.DB = initalize.InitMysql("fusentest:XErSYmLELKMnf3Dh@tcp(110.41.19.98:3306)/fusentest")
|
||||||
|
|
||||||
|
type UserState struct {
|
||||||
|
Expired time.Time
|
||||||
|
UserId int64
|
||||||
|
PwdHash uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (us *UserState) Encode() []byte {
|
||||||
|
var buf = bytes.NewBuffer(nil)
|
||||||
|
err := gob.NewEncoder(buf).Encode(us)
|
||||||
|
if err != nil {
|
||||||
|
log.Panic(err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
// command is used for internal command representation.
|
||||||
|
type command struct {
|
||||||
|
Op string
|
||||||
|
Key int64
|
||||||
|
Value *UserState
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *command) Encode() []byte {
|
||||||
|
var buf = bytes.NewBuffer(nil)
|
||||||
|
err := gob.NewEncoder(buf).Encode(cmd)
|
||||||
|
if err != nil {
|
||||||
|
log.Panic(err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *command) Decode(sbuf []byte) error {
|
||||||
|
var buf = bytes.NewBuffer(sbuf)
|
||||||
|
err := gob.NewDecoder(buf).Decode(cmd)
|
||||||
|
if err != nil {
|
||||||
|
// log.Panic(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
7
fsm/main_test.go
Normal file
7
fsm/main_test.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package fsm
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestMain(t *testing.T) {
|
||||||
|
test1()
|
||||||
|
}
|
||||||
57
fsm/waitcallback.go
Normal file
57
fsm/waitcallback.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
package fsm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type condAndState struct {
|
||||||
|
cond *sync.Cond
|
||||||
|
state *UserState
|
||||||
|
}
|
||||||
|
|
||||||
|
type WaitCallback struct {
|
||||||
|
Waiter sync.Map
|
||||||
|
mu sync.Mutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWaitCallback() *WaitCallback {
|
||||||
|
return &WaitCallback{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WaitCallback) Done(us *UserState) {
|
||||||
|
if v, ok := w.Waiter.Load(us.UserId); ok {
|
||||||
|
w.mu.Lock()
|
||||||
|
defer w.mu.Unlock()
|
||||||
|
cas := v.(*condAndState)
|
||||||
|
cas.state = us
|
||||||
|
cas.cond.Broadcast()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WaitCallback) Wait(key int64, timeout time.Duration) *UserState {
|
||||||
|
cas := &condAndState{
|
||||||
|
cond: sync.NewCond(&w.mu),
|
||||||
|
state: nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
v, loaded := w.Waiter.LoadOrStore(key, cas)
|
||||||
|
if loaded {
|
||||||
|
cas = v.(*condAndState)
|
||||||
|
}
|
||||||
|
|
||||||
|
done := make(chan struct{})
|
||||||
|
go func() {
|
||||||
|
w.mu.Lock()
|
||||||
|
defer w.mu.Unlock()
|
||||||
|
cas.cond.Wait()
|
||||||
|
close(done)
|
||||||
|
}()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-done:
|
||||||
|
return cas.state
|
||||||
|
case <-time.After(timeout):
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
6
go.mod
6
go.mod
@ -8,6 +8,7 @@ require (
|
|||||||
github.com/bwmarrin/snowflake v0.3.0
|
github.com/bwmarrin/snowflake v0.3.0
|
||||||
github.com/golang-jwt/jwt v3.2.2+incompatible
|
github.com/golang-jwt/jwt v3.2.2+incompatible
|
||||||
github.com/google/uuid v1.3.0
|
github.com/google/uuid v1.3.0
|
||||||
|
github.com/hashicorp/raft v1.5.0
|
||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
||||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
||||||
github.com/stripe/stripe-go/v74 v74.26.0
|
github.com/stripe/stripe-go/v74 v74.26.0
|
||||||
@ -22,6 +23,11 @@ require (
|
|||||||
cloud.google.com/go/compute v1.20.1 // indirect
|
cloud.google.com/go/compute v1.20.1 // indirect
|
||||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||||
github.com/andybalholm/brotli v1.0.5 // indirect
|
github.com/andybalholm/brotli v1.0.5 // indirect
|
||||||
|
github.com/armon/go-metrics v0.4.1 // indirect
|
||||||
|
github.com/hashicorp/go-hclog v1.5.0 // indirect
|
||||||
|
github.com/hashicorp/go-immutable-radix v1.0.0 // indirect
|
||||||
|
github.com/hashicorp/go-msgpack v0.5.5 // indirect
|
||||||
|
github.com/hashicorp/golang-lru v0.5.1 // indirect
|
||||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||||
github.com/schollz/progressbar v1.0.0 // indirect
|
github.com/schollz/progressbar v1.0.0 // indirect
|
||||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0 // indirect
|
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0 // indirect
|
||||||
|
|||||||
85
go.sum
85
go.sum
@ -41,16 +41,25 @@ github.com/474420502/requests v1.40.0/go.mod h1:2SCVzim0ONFYG09g/GrM7RTeJIC6qTyZ
|
|||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
|
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
|
||||||
|
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
github.com/SebastiaanKlippert/go-wkhtmltopdf v1.9.0 h1:DNrExYwvyyI404SxdUCCANAj9TwnGjRfa3cYFMNY1AU=
|
github.com/SebastiaanKlippert/go-wkhtmltopdf v1.9.0 h1:DNrExYwvyyI404SxdUCCANAj9TwnGjRfa3cYFMNY1AU=
|
||||||
github.com/SebastiaanKlippert/go-wkhtmltopdf v1.9.0/go.mod h1:SQq4xfIdvf6WYKSDxAJc+xOJdolt+/bc1jnQKMtPMvQ=
|
github.com/SebastiaanKlippert/go-wkhtmltopdf v1.9.0/go.mod h1:SQq4xfIdvf6WYKSDxAJc+xOJdolt+/bc1jnQKMtPMvQ=
|
||||||
|
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
|
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
|
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk=
|
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk=
|
||||||
github.com/alicebob/miniredis/v2 v2.30.4 h1:8S4/o1/KoUArAGbGwPxcwf0krlzceva2XVOSchFS7Eo=
|
github.com/alicebob/miniredis/v2 v2.30.4 h1:8S4/o1/KoUArAGbGwPxcwf0krlzceva2XVOSchFS7Eo=
|
||||||
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
||||||
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||||
|
github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA=
|
||||||
|
github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4=
|
||||||
github.com/aws/aws-sdk-go v1.44.295 h1:SGjU1+MqttXfRiWHD6WU0DRhaanJgAFY+xIhEaugV8Y=
|
github.com/aws/aws-sdk-go v1.44.295 h1:SGjU1+MqttXfRiWHD6WU0DRhaanJgAFY+xIhEaugV8Y=
|
||||||
github.com/aws/aws-sdk-go v1.44.295/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
|
github.com/aws/aws-sdk-go v1.44.295/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
|
||||||
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||||
|
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0=
|
github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0=
|
||||||
@ -65,6 +74,8 @@ github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
|
|||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||||
|
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
|
||||||
|
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||||
@ -86,6 +97,7 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m
|
|||||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
|
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
|
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
|
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||||
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
|
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
|
||||||
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
|
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
|
||||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||||
@ -93,6 +105,10 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME
|
|||||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
|
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
|
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
|
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||||
|
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
|
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
|
||||||
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
@ -103,6 +119,8 @@ github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq
|
|||||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||||
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
|
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
|
||||||
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||||
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
|
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||||
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
||||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||||
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
|
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
|
||||||
@ -150,6 +168,7 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||||
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||||
@ -170,8 +189,21 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4Zs
|
|||||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.0 h1:1JYBfzqrWPcCclBwxFCPAou9n+q86mfnu7NAeHfte7A=
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.0 h1:1JYBfzqrWPcCclBwxFCPAou9n+q86mfnu7NAeHfte7A=
|
||||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.0/go.mod h1:YDZoGHuwE+ov0c8smSH49WLF3F2LaWnYYuDVd+EWrc0=
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.0/go.mod h1:YDZoGHuwE+ov0c8smSH49WLF3F2LaWnYYuDVd+EWrc0=
|
||||||
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
|
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
|
||||||
|
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||||
|
github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c=
|
||||||
|
github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
||||||
|
github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0=
|
||||||
|
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||||
|
github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI=
|
||||||
|
github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
||||||
|
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
|
||||||
|
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||||
|
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
|
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
||||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
|
github.com/hashicorp/raft v1.5.0 h1:uNs9EfJ4FwiArZRxxfd/dQ5d33nV31/CdCHArH89hT8=
|
||||||
|
github.com/hashicorp/raft v1.5.0/go.mod h1:pKHB2mf/Y25u3AHNSXVRv+yT+WAnmeTX0BwVppVQV+M=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||||
@ -181,22 +213,37 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y
|
|||||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
||||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||||
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
|
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||||
|
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw=
|
github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
|
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||||
|
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
|
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||||
|
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
|
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
|
||||||
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
|
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
|
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||||
@ -204,19 +251,34 @@ github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
|||||||
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
|
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
|
||||||
github.com/openzipkin/zipkin-go v0.4.1 h1:kNd/ST2yLLWhaWrkgchya40TJabe8Hioj9udfPcEO5A=
|
github.com/openzipkin/zipkin-go v0.4.1 h1:kNd/ST2yLLWhaWrkgchya40TJabe8Hioj9udfPcEO5A=
|
||||||
github.com/openzipkin/zipkin-go v0.4.1/go.mod h1:qY0VqDSN1pOBN94dBc6w2GJlWLiovAyg7Qt6/I9HecM=
|
github.com/openzipkin/zipkin-go v0.4.1/go.mod h1:qY0VqDSN1pOBN94dBc6w2GJlWLiovAyg7Qt6/I9HecM=
|
||||||
|
github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
|
||||||
|
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||||
github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0=
|
github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0=
|
||||||
github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
||||||
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
|
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
|
||||||
|
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
|
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||||
|
github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
|
||||||
github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8=
|
github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8=
|
||||||
github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc=
|
github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc=
|
||||||
|
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
|
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
|
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
|
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
|
||||||
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
|
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
|
||||||
|
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
|
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
|
||||||
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
|
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
|
||||||
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
|
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
|
||||||
|
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
|
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
|
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||||
github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg=
|
github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg=
|
||||||
github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
|
github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
|
||||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||||
@ -224,20 +286,27 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
|
|||||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||||
github.com/schollz/progressbar v1.0.0 h1:gbyFReLHDkZo8mxy/dLWMr+Mpb1MokGJ1FqCiqacjZM=
|
github.com/schollz/progressbar v1.0.0 h1:gbyFReLHDkZo8mxy/dLWMr+Mpb1MokGJ1FqCiqacjZM=
|
||||||
github.com/schollz/progressbar v1.0.0/go.mod h1:/l9I7PC3L3erOuz54ghIRKUEFcosiWfLvJv+Eq26UMs=
|
github.com/schollz/progressbar v1.0.0/go.mod h1:/l9I7PC3L3erOuz54ghIRKUEFcosiWfLvJv+Eq26UMs=
|
||||||
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
|
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
|
||||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
|
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
|
||||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
||||||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
|
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
|
||||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
|
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
github.com/stripe/stripe-go/v74 v74.26.0 h1:enbhLtjKGWvJKcGM0f2CazqFSXzpHXcQ42nG2PNsWK0=
|
github.com/stripe/stripe-go/v74 v74.26.0 h1:enbhLtjKGWvJKcGM0f2CazqFSXzpHXcQ42nG2PNsWK0=
|
||||||
@ -248,6 +317,7 @@ github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
|||||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||||
|
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
||||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
@ -286,6 +356,7 @@ go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI
|
|||||||
go.uber.org/automaxprocs v1.5.2 h1:2LxUOGiR3O6tw8ui5sZa2LAaHnsviZdVOUZw4fvbnME=
|
go.uber.org/automaxprocs v1.5.2 h1:2LxUOGiR3O6tw8ui5sZa2LAaHnsviZdVOUZw4fvbnME=
|
||||||
go.uber.org/automaxprocs v1.5.2/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
|
go.uber.org/automaxprocs v1.5.2/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
|
||||||
go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
|
go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
|
||||||
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
@ -326,6 +397,7 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
@ -333,6 +405,7 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
|
|||||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||||
|
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
@ -375,9 +448,12 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
|
|||||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@ -387,6 +463,7 @@ golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@ -404,6 +481,9 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
@ -566,14 +646,19 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ
|
|||||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY=
|
gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||||
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package svc
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"fusenapi/fsm"
|
||||||
"fusenapi/server/assistant/internal/config"
|
"fusenapi/server/assistant/internal/config"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
@ -15,16 +16,20 @@ import (
|
|||||||
|
|
||||||
type ServiceContext struct {
|
type ServiceContext struct {
|
||||||
Config config.Config
|
Config config.Config
|
||||||
|
SharedState *fsm.StateCluster
|
||||||
|
|
||||||
MysqlConn *gorm.DB
|
MysqlConn *gorm.DB
|
||||||
AllModels *gmodel.AllModelsGen
|
AllModels *gmodel.AllModelsGen
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServiceContext(c config.Config) *ServiceContext {
|
func NewServiceContext(c config.Config) *ServiceContext {
|
||||||
|
conn := initalize.InitMysql(c.SourceMysql)
|
||||||
|
StateServer := fsm.StartNode(c.Name, fmt.Sprintf("%s:%d", c.Host, c.Port-2000), conn)
|
||||||
|
|
||||||
return &ServiceContext{
|
return &ServiceContext{
|
||||||
Config: c,
|
Config: c,
|
||||||
MysqlConn: initalize.InitMysql(c.SourceMysql),
|
MysqlConn: conn,
|
||||||
|
SharedState: StateServer,
|
||||||
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
36
server/auth/auth.go
Normal file
36
server/auth/auth.go
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"fusenapi/utils/auth"
|
||||||
|
|
||||||
|
"fusenapi/server/auth/internal/config"
|
||||||
|
"fusenapi/server/auth/internal/handler"
|
||||||
|
"fusenapi/server/auth/internal/svc"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/conf"
|
||||||
|
"github.com/zeromicro/go-zero/rest"
|
||||||
|
)
|
||||||
|
|
||||||
|
var configFile = flag.String("f", "etc/auth.yaml", "the config file")
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
var c config.Config
|
||||||
|
conf.MustLoad(*configFile, &c)
|
||||||
|
c.Timeout = int64(time.Second * 15)
|
||||||
|
server := rest.MustNewServer(c.RestConf, rest.WithCustomCors(auth.FsCors, func(w http.ResponseWriter) {
|
||||||
|
}))
|
||||||
|
defer server.Stop()
|
||||||
|
|
||||||
|
ctx := svc.NewServiceContext(c)
|
||||||
|
handler.RegisterHandlers(server, ctx)
|
||||||
|
|
||||||
|
fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
|
||||||
|
server.Start()
|
||||||
|
}
|
||||||
7
server/auth/auth_test.go
Normal file
7
server/auth/auth_test.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestMain(t *testing.T) {
|
||||||
|
main()
|
||||||
|
}
|
||||||
18
server/auth/etc/auth.yaml
Normal file
18
server/auth/etc/auth.yaml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
Name: auth
|
||||||
|
Host: 0.0.0.0
|
||||||
|
Port: 9980
|
||||||
|
MainAddress: "http://localhost:9900"
|
||||||
|
SourceMysql: fusentest:XErSYmLELKMnf3Dh@tcp(110.41.19.98:3306)/fusentest
|
||||||
|
Auth:
|
||||||
|
AccessSecret: fusen2023
|
||||||
|
AccessExpire: 2592000
|
||||||
|
RefreshAfter: 1592000
|
||||||
|
|
||||||
|
OAuth:
|
||||||
|
google:
|
||||||
|
appid: "1064842923358-e94msq2glj6qr4lrva9ts3hqjjt53q8h.apps.googleusercontent.com"
|
||||||
|
secret: "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"
|
||||||
|
|
||||||
|
facebook:
|
||||||
|
appid: "1095953604597065"
|
||||||
|
secret: "b146872550a190d5275b1420c212002e"
|
||||||
27
server/auth/internal/config/config.go
Normal file
27
server/auth/internal/config/config.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fusenapi/server/auth/internal/types"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/rest"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
rest.RestConf
|
||||||
|
SourceMysql string
|
||||||
|
Auth types.Auth
|
||||||
|
|
||||||
|
MainAddress string
|
||||||
|
|
||||||
|
OAuth struct {
|
||||||
|
Google struct {
|
||||||
|
Appid string
|
||||||
|
Secret string
|
||||||
|
}
|
||||||
|
|
||||||
|
Facebook struct {
|
||||||
|
Appid string
|
||||||
|
Secret string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -6,9 +6,9 @@ import (
|
|||||||
|
|
||||||
"fusenapi/utils/basic"
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
"fusenapi/server/home-user-auth/internal/logic"
|
"fusenapi/server/auth/internal/logic"
|
||||||
"fusenapi/server/home-user-auth/internal/svc"
|
"fusenapi/server/auth/internal/svc"
|
||||||
"fusenapi/server/home-user-auth/internal/types"
|
"fusenapi/server/auth/internal/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func AcceptCookieHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
func AcceptCookieHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
37
server/auth/internal/handler/routes.go
Normal file
37
server/auth/internal/handler/routes.go
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// Code generated by goctl. DO NOT EDIT.
|
||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"fusenapi/server/auth/internal/svc"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/rest"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||||
|
server.AddRoutes(
|
||||||
|
[]rest.Route{
|
||||||
|
{
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Path: "/api/auth/login",
|
||||||
|
Handler: UserLoginHandler(serverCtx),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Path: "/api/auth/accept-cookie",
|
||||||
|
Handler: AcceptCookieHandler(serverCtx),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Path: "/api/auth/oauth2/login/google",
|
||||||
|
Handler: UserGoogleLoginHandler(serverCtx),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Path: "/api/auth/oauth2/register",
|
||||||
|
Handler: UserEmailRegisterHandler(serverCtx),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -6,9 +6,9 @@ import (
|
|||||||
|
|
||||||
"fusenapi/utils/basic"
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
"fusenapi/server/home-user-auth/internal/logic"
|
"fusenapi/server/auth/internal/logic"
|
||||||
"fusenapi/server/home-user-auth/internal/svc"
|
"fusenapi/server/auth/internal/svc"
|
||||||
"fusenapi/server/home-user-auth/internal/types"
|
"fusenapi/server/auth/internal/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func UserEmailRegisterHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
func UserEmailRegisterHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
@ -6,9 +6,9 @@ import (
|
|||||||
|
|
||||||
"fusenapi/utils/basic"
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
"fusenapi/server/home-user-auth/internal/logic"
|
"fusenapi/server/auth/internal/logic"
|
||||||
"fusenapi/server/home-user-auth/internal/svc"
|
"fusenapi/server/auth/internal/svc"
|
||||||
"fusenapi/server/home-user-auth/internal/types"
|
"fusenapi/server/auth/internal/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func UserGoogleLoginHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
func UserGoogleLoginHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
@ -6,9 +6,9 @@ import (
|
|||||||
|
|
||||||
"fusenapi/utils/basic"
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
"fusenapi/server/home-user-auth/internal/logic"
|
"fusenapi/server/auth/internal/logic"
|
||||||
"fusenapi/server/home-user-auth/internal/svc"
|
"fusenapi/server/auth/internal/svc"
|
||||||
"fusenapi/server/home-user-auth/internal/types"
|
"fusenapi/server/auth/internal/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func UserLoginHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
func UserLoginHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
@ -6,8 +6,8 @@ import (
|
|||||||
|
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"fusenapi/server/home-user-auth/internal/svc"
|
"fusenapi/server/auth/internal/svc"
|
||||||
"fusenapi/server/home-user-auth/internal/types"
|
"fusenapi/server/auth/internal/types"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
)
|
)
|
||||||
@ -26,6 +26,15 @@ func NewAcceptCookieLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Acce
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理进入前逻辑w,r
|
||||||
|
// func (l *AcceptCookieLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||||
|
// func (l *AcceptCookieLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
||||||
|
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
// }
|
||||||
|
|
||||||
func (l *AcceptCookieLogic) AcceptCookie(req *types.Request, userinfo *auth.UserInfo) (resp *basic.Response) {
|
func (l *AcceptCookieLogic) AcceptCookie(req *types.Request, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||||
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
||||||
// userinfo 传入值时, 一定不为null
|
// userinfo 传入值时, 一定不为null
|
||||||
168
server/auth/internal/logic/email_manager.go
Normal file
168
server/auth/internal/logic/email_manager.go
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
package logic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"log"
|
||||||
|
"net/smtp"
|
||||||
|
"sync"
|
||||||
|
"text/template"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var EmailManager *EmailSender
|
||||||
|
|
||||||
|
// EmailSender
|
||||||
|
type EmailSender struct {
|
||||||
|
lock sync.Mutex
|
||||||
|
EmailTasks chan string
|
||||||
|
Auth smtp.Auth
|
||||||
|
FromEmail string
|
||||||
|
emailSending map[string]*EmailTask
|
||||||
|
ResendTimeLimit time.Duration
|
||||||
|
semaphore chan struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// EmailTask
|
||||||
|
type EmailTask struct {
|
||||||
|
Email string // email
|
||||||
|
SendTime time.Time // 处理的任务时间
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *EmailSender) ProcessEmailTasks() {
|
||||||
|
for {
|
||||||
|
emailTarget, ok := <-m.EmailTasks
|
||||||
|
if !ok {
|
||||||
|
log.Println("Email task channel closed")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
m.lock.Lock()
|
||||||
|
_, isSending := m.emailSending[emailTarget]
|
||||||
|
if isSending {
|
||||||
|
m.lock.Unlock()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
m.emailSending[emailTarget] = &EmailTask{
|
||||||
|
Email: emailTarget,
|
||||||
|
SendTime: time.Now(),
|
||||||
|
}
|
||||||
|
m.lock.Unlock()
|
||||||
|
|
||||||
|
// Acquire a token
|
||||||
|
m.semaphore <- struct{}{}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
defer func() { <-m.semaphore }() // Release a token
|
||||||
|
|
||||||
|
content := RenderEmailTemplate("fusen", "http://www.baidu.com", "fusen@gmail.com", "mail-valid")
|
||||||
|
err := smtp.SendMail("smtp.gmail.com:587", m.Auth, m.FromEmail, []string{emailTarget}, content)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Failed to send email to %s: %v\n", emailTarget, err)
|
||||||
|
m.Resend(emailTarget, content)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resend 重发邮件
|
||||||
|
func (m *EmailSender) Resend(emailTarget string, content []byte) {
|
||||||
|
time.Sleep(m.ResendTimeLimit)
|
||||||
|
|
||||||
|
m.lock.Lock()
|
||||||
|
defer m.lock.Unlock()
|
||||||
|
|
||||||
|
// Check if the email task still exists and has not been sent successfully
|
||||||
|
if task, ok := m.emailSending[emailTarget]; ok && task.SendTime.Add(m.ResendTimeLimit).After(time.Now()) {
|
||||||
|
err := smtp.SendMail(emailTarget, m.Auth, m.FromEmail, []string{emailTarget}, content)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Failed to resend email to %s: %v\n", emailTarget, err)
|
||||||
|
} else {
|
||||||
|
delete(m.emailSending, emailTarget)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearExpiredTasks 清除过期的邮件任务
|
||||||
|
func (m *EmailSender) ClearExpiredTasks() {
|
||||||
|
ticker := time.NewTicker(time.Minute)
|
||||||
|
defer ticker.Stop()
|
||||||
|
|
||||||
|
for {
|
||||||
|
<-ticker.C
|
||||||
|
|
||||||
|
m.lock.Lock()
|
||||||
|
for email, task := range m.emailSending {
|
||||||
|
if task.SendTime.Add(m.ResendTimeLimit).Before(time.Now()) {
|
||||||
|
delete(m.emailSending, email)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m.lock.Unlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
|
||||||
|
// Initialize the email manager
|
||||||
|
EmailManager = &EmailSender{
|
||||||
|
EmailTasks: make(chan string, 10),
|
||||||
|
Auth: smtp.PlainAuth(
|
||||||
|
"",
|
||||||
|
"user@example.com",
|
||||||
|
"password",
|
||||||
|
"smtp.gmail.com",
|
||||||
|
),
|
||||||
|
FromEmail: "user@example.com",
|
||||||
|
emailSending: make(map[string]*EmailTask, 10),
|
||||||
|
ResendTimeLimit: time.Minute * 1,
|
||||||
|
semaphore: make(chan struct{}, 10), // Initialize semaphore with a capacity of 10
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start processing email tasks
|
||||||
|
go EmailManager.ProcessEmailTasks()
|
||||||
|
|
||||||
|
// Start clearing expired tasks
|
||||||
|
go EmailManager.ClearExpiredTasks()
|
||||||
|
}
|
||||||
|
|
||||||
|
const emailTemplate = `Subject: Your {{.CompanyName}} Account Confirmation
|
||||||
|
|
||||||
|
Dear
|
||||||
|
|
||||||
|
Thank you for creating an account with {{.CompanyName}}. We're excited to have you on board!
|
||||||
|
|
||||||
|
Before we get started, we just need to confirm that this is the right email address. Please confirm your email address by clicking on the link below:
|
||||||
|
|
||||||
|
{{.ConfirmationLink}}
|
||||||
|
|
||||||
|
Once you've confirmed, you can get started with {{.CompanyName}}. If you have any questions, feel free to reply to this email. We're here to help!
|
||||||
|
|
||||||
|
If you did not create an account with us, please ignore this email.
|
||||||
|
|
||||||
|
Thanks,
|
||||||
|
{{.SenderName}}
|
||||||
|
{{.SenderTitle}}
|
||||||
|
{{.CompanyName}}
|
||||||
|
`
|
||||||
|
|
||||||
|
func RenderEmailTemplate(companyName, confirmationLink, senderName, senderTitle string) []byte {
|
||||||
|
tmpl, err := template.New("email").Parse(emailTemplate)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
data := map[string]string{
|
||||||
|
"CompanyName": companyName,
|
||||||
|
"ConfirmationLink": confirmationLink,
|
||||||
|
"SenderName": senderName,
|
||||||
|
"SenderTitle": senderTitle,
|
||||||
|
}
|
||||||
|
|
||||||
|
var result bytes.Buffer
|
||||||
|
err = tmpl.Execute(&result, data)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.Bytes()
|
||||||
|
}
|
||||||
@ -6,8 +6,8 @@ import (
|
|||||||
|
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"fusenapi/server/home-user-auth/internal/svc"
|
"fusenapi/server/auth/internal/svc"
|
||||||
"fusenapi/server/home-user-auth/internal/types"
|
"fusenapi/server/auth/internal/types"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
)
|
)
|
||||||
@ -30,8 +30,9 @@ func NewUserEmailRegisterLogic(ctx context.Context, svcCtx *svc.ServiceContext)
|
|||||||
// func (l *UserEmailRegisterLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
// func (l *UserEmailRegisterLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// 处理逻辑后 w,r 如:重定向
|
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||||
// func (l *UserEmailRegisterLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
// func (l *UserEmailRegisterLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
||||||
|
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
func (l *UserEmailRegisterLogic) UserEmailRegister(req *types.RequestEmailRegister, userinfo *auth.UserInfo) (resp *basic.Response) {
|
func (l *UserEmailRegisterLogic) UserEmailRegister(req *types.RequestEmailRegister, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||||
@ -6,16 +6,16 @@ import (
|
|||||||
"fusenapi/utils/basic"
|
"fusenapi/utils/basic"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"fusenapi/server/home-user-auth/internal/svc"
|
"fusenapi/server/auth/internal/svc"
|
||||||
"fusenapi/server/home-user-auth/internal/types"
|
"fusenapi/server/auth/internal/types"
|
||||||
|
|
||||||
"github.com/474420502/requests"
|
"github.com/474420502/requests"
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
"golang.org/x/net/proxy"
|
"golang.org/x/net/proxy"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
"golang.org/x/oauth2/google"
|
"golang.org/x/oauth2/google"
|
||||||
@ -31,6 +31,7 @@ type UserGoogleLoginLogic struct {
|
|||||||
|
|
||||||
isRegistered bool // 是否注册
|
isRegistered bool // 是否注册
|
||||||
registerToken string // 注册邮箱的token
|
registerToken string // 注册邮箱的token
|
||||||
|
oauthinfo *auth.OAuthInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewUserGoogleLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserGoogleLoginLogic {
|
func NewUserGoogleLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserGoogleLoginLogic {
|
||||||
@ -41,12 +42,32 @@ func NewUserGoogleLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *U
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理进入前逻辑w,r
|
||||||
// func (l *UserGoogleLoginLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
// func (l *UserGoogleLoginLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
||||||
// log.Println(r, w)
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||||
func (l *UserGoogleLoginLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
func (l *UserGoogleLoginLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
||||||
|
|
||||||
|
if resp.Code == 200 {
|
||||||
|
|
||||||
|
if !l.isRegistered {
|
||||||
|
now := time.Now()
|
||||||
|
rtoken, err := auth.GenerateRegisterToken(
|
||||||
|
&l.svcCtx.Config.Auth.AccessSecret,
|
||||||
|
l.svcCtx.Config.Auth.AccessExpire,
|
||||||
|
now.Unix(),
|
||||||
|
l.oauthinfo.Id,
|
||||||
|
l.oauthinfo.Platform,
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
resp.SetStatus(basic.CodeOAuthRegisterTokenErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
l.registerToken = rtoken
|
||||||
|
}
|
||||||
|
|
||||||
rurl := fmt.Sprintf(
|
rurl := fmt.Sprintf(
|
||||||
l.svcCtx.Config.MainAddress+"/oauth?token=%s&is_registered=%t®ister_token=%s",
|
l.svcCtx.Config.MainAddress+"/oauth?token=%s&is_registered=%t®ister_token=%s",
|
||||||
l.token,
|
l.token,
|
||||||
@ -70,6 +91,10 @@ func (l *UserGoogleLoginLogic) AfterLogic(w http.ResponseWriter, r *http.Request
|
|||||||
</html>
|
</html>
|
||||||
`, rurl)
|
`, rurl)
|
||||||
fmt.Fprintln(w, html)
|
fmt.Fprintln(w, html)
|
||||||
|
} else {
|
||||||
|
httpx.OkJson(w, resp)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *UserGoogleLoginLogic) UserGoogleLogin(req *types.RequestGoogleLogin, userinfo *auth.UserInfo) (resp *basic.Response) {
|
func (l *UserGoogleLoginLogic) UserGoogleLogin(req *types.RequestGoogleLogin, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||||
@ -114,24 +139,33 @@ func (l *UserGoogleLoginLogic) UserGoogleLogin(req *types.RequestGoogleLogin, us
|
|||||||
log.Println(r.Json())
|
log.Println(r.Json())
|
||||||
|
|
||||||
googleId := r.Json().Get("id").Int()
|
googleId := r.Json().Get("id").Int()
|
||||||
|
|
||||||
// l.redirectUrl = "http://localhost:9900/oauth?token=21321123&is_registered"
|
|
||||||
// return resp.Set(304, "21321321")
|
|
||||||
user, err := l.svcCtx.AllModels.FsUser.FindUserByGoogleId(context.TODO(), googleId)
|
user, err := l.svcCtx.AllModels.FsUser.FindUserByGoogleId(context.TODO(), googleId)
|
||||||
log.Println(user)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err != gorm.ErrRecordNotFound {
|
if err != gorm.ErrRecordNotFound {
|
||||||
logx.Error(err)
|
logx.Error(err)
|
||||||
return resp.SetStatus(basic.CodeDbSqlErr)
|
return resp.SetStatus(basic.CodeDbSqlErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 进入邮件注册流程
|
||||||
if req.Email == "" {
|
if req.Email == "" {
|
||||||
return resp.SetStatus(basic.CodeOK)
|
return resp.SetStatus(basic.CodeOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 这里是注册模块, 发邮件, 通过邮件注册确认邮箱存在
|
||||||
|
|
||||||
|
// 邮箱验证格式错误
|
||||||
|
if !auth.ValidateEmail(req.Email) {
|
||||||
|
return resp.SetStatus(basic.CodeOAuthEmailErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
EmailManager.EmailTasks <- req.Email // email进入队
|
||||||
|
|
||||||
|
return resp.SetStatus(basic.CodeOK)
|
||||||
|
}
|
||||||
|
|
||||||
// 如果密码匹配,则生成 JWT Token。
|
// 如果密码匹配,则生成 JWT Token。
|
||||||
nowSec := time.Now().Unix()
|
nowSec := time.Now().Unix()
|
||||||
jwtToken, err := auth.GenerateJwtToken(&l.svcCtx.Config.Auth.AccessSecret, l.svcCtx.Config.Auth.AccessExpire, nowSec, 0, 0)
|
jwtToken, err := auth.GenerateJwtToken(&l.svcCtx.Config.Auth.AccessSecret, l.svcCtx.Config.Auth.AccessExpire, nowSec, user.Id, 0)
|
||||||
|
|
||||||
// 如果生成 JWT Token 失败,则抛出错误并返回未认证的状态码。
|
// 如果生成 JWT Token 失败,则抛出错误并返回未认证的状态码。
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -139,11 +173,7 @@ func (l *UserGoogleLoginLogic) UserGoogleLogin(req *types.RequestGoogleLogin, us
|
|||||||
return resp.SetStatus(basic.CodeServiceErr)
|
return resp.SetStatus(basic.CodeServiceErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp.SetRewriteHandler(func(w http.ResponseWriter, r *http.Request) {
|
l.token = jwtToken
|
||||||
http.Redirect(w, r, "http://localhost:9900?token="+url.QueryEscape(jwtToken), http.StatusFound)
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp.SetStatus(basic.CodeOK)
|
return resp.SetStatus(basic.CodeOK)
|
||||||
}
|
}
|
||||||
@ -1,16 +1,17 @@
|
|||||||
package logic
|
package logic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"fusenapi/utils/auth"
|
||||||
|
"fusenapi/utils/basic"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"fusenapi/server/home-user-auth/internal/svc"
|
"context"
|
||||||
"fusenapi/server/home-user-auth/internal/types"
|
|
||||||
"fusenapi/utils/auth"
|
"fusenapi/server/auth/internal/svc"
|
||||||
"fusenapi/utils/basic"
|
"fusenapi/server/auth/internal/types"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
"github.com/zeromicro/go-zero/rest/httpx"
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
@ -33,6 +34,11 @@ func NewUserLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserLog
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理进入前逻辑w,r
|
||||||
|
// func (l *UserLoginLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||||
func (l *UserLoginLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
func (l *UserLoginLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
||||||
if l.token != "" {
|
if l.token != "" {
|
||||||
w.Header().Add("Authorization", fmt.Sprintf("Bearer %s", l.token))
|
w.Header().Add("Authorization", fmt.Sprintf("Bearer %s", l.token))
|
||||||
@ -42,6 +48,9 @@ func (l *UserLoginLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *UserLoginLogic) UserLogin(req *types.RequestUserLogin, userinfo *auth.UserInfo) (resp *basic.Response) {
|
func (l *UserLoginLogic) UserLogin(req *types.RequestUserLogin, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||||
|
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
||||||
|
// userinfo 传入值时, 一定不为null
|
||||||
|
|
||||||
// 创建一个 FsUserModel 对象 m 并实例化之,该对象用于操作 MySQL 数据库中的用户数据表。
|
// 创建一个 FsUserModel 对象 m 并实例化之,该对象用于操作 MySQL 数据库中的用户数据表。
|
||||||
m := l.svcCtx.AllModels.FsUser
|
m := l.svcCtx.AllModels.FsUser
|
||||||
|
|
||||||
@ -59,6 +68,7 @@ func (l *UserLoginLogic) UserLogin(req *types.RequestUserLogin, userinfo *auth.U
|
|||||||
|
|
||||||
// 如果密码匹配,则生成 JWT Token。
|
// 如果密码匹配,则生成 JWT Token。
|
||||||
nowSec := time.Now().Unix()
|
nowSec := time.Now().Unix()
|
||||||
|
|
||||||
jwtToken, err := auth.GenerateJwtToken(&l.svcCtx.Config.Auth.AccessSecret, l.svcCtx.Config.Auth.AccessExpire, nowSec, user.Id, 0)
|
jwtToken, err := auth.GenerateJwtToken(&l.svcCtx.Config.Auth.AccessSecret, l.svcCtx.Config.Auth.AccessExpire, nowSec, user.Id, 0)
|
||||||
|
|
||||||
// 如果生成 JWT Token 失败,则抛出错误并返回未认证的状态码。
|
// 如果生成 JWT Token 失败,则抛出错误并返回未认证的状态码。
|
||||||
@ -78,7 +88,6 @@ func (l *UserLoginLogic) UserLogin(req *types.RequestUserLogin, userinfo *auth.U
|
|||||||
}
|
}
|
||||||
|
|
||||||
l.token = jwtToken
|
l.token = jwtToken
|
||||||
|
|
||||||
// 返回认证成功的状态码以及数据对象 data 和 JWT Token。
|
// 返回认证成功的状态码以及数据对象 data 和 JWT Token。
|
||||||
return resp.SetStatus(basic.CodeOK, data)
|
return resp.SetStatus(basic.CodeOK, data)
|
||||||
}
|
}
|
||||||
66
server/auth/internal/svc/servicecontext.go
Normal file
66
server/auth/internal/svc/servicecontext.go
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
package svc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"fusenapi/fsm"
|
||||||
|
"fusenapi/server/auth/internal/config"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"fusenapi/initalize"
|
||||||
|
"fusenapi/model/gmodel"
|
||||||
|
|
||||||
|
"github.com/golang-jwt/jwt"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ServiceContext struct {
|
||||||
|
Config config.Config
|
||||||
|
SharedState *fsm.StateCluster
|
||||||
|
|
||||||
|
MysqlConn *gorm.DB
|
||||||
|
AllModels *gmodel.AllModelsGen
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewServiceContext(c config.Config) *ServiceContext {
|
||||||
|
conn := initalize.InitMysql(c.SourceMysql)
|
||||||
|
StateServer := fsm.StartNode(c.Name, fmt.Sprintf("localhost:%d", c.Port-2001), conn)
|
||||||
|
|
||||||
|
return &ServiceContext{
|
||||||
|
Config: c,
|
||||||
|
MysqlConn: conn,
|
||||||
|
SharedState: StateServer,
|
||||||
|
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (svcCtx *ServiceContext) ParseJwtToken(r *http.Request) (jwt.MapClaims, error) {
|
||||||
|
AuthKey := r.Header.Get("Authorization")
|
||||||
|
if AuthKey == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
AuthKey = AuthKey[7:]
|
||||||
|
|
||||||
|
if len(AuthKey) <= 50 {
|
||||||
|
return nil, errors.New(fmt.Sprint("Error parsing token, len:", len(AuthKey)))
|
||||||
|
}
|
||||||
|
|
||||||
|
token, err := jwt.Parse(AuthKey, func(token *jwt.Token) (interface{}, error) {
|
||||||
|
// 检查签名方法是否为 HS256
|
||||||
|
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||||
|
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
|
||||||
|
}
|
||||||
|
// 返回用于验证签名的密钥
|
||||||
|
return []byte(svcCtx.Config.Auth.AccessSecret), nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New(fmt.Sprint("Error parsing token:", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证成功返回
|
||||||
|
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
|
||||||
|
return claims, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, errors.New(fmt.Sprint("Invalid token", err))
|
||||||
|
}
|
||||||
101
server/auth/internal/types/types.go
Normal file
101
server/auth/internal/types/types.go
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
// Code generated by goctl. DO NOT EDIT.
|
||||||
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fusenapi/utils/basic"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RequestUserLogin struct {
|
||||||
|
Email string `json:"email"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RequestGoogleLogin struct {
|
||||||
|
Code string `form:"code"`
|
||||||
|
Scope string `form:"scope"`
|
||||||
|
AuthUser string `form:"authuser"`
|
||||||
|
Prompt string `form:"prompt"`
|
||||||
|
Email string `form:"email,optional"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RequestEmailRegister struct {
|
||||||
|
Email string `json:"email"`
|
||||||
|
RegisterToken string `json:"register_token"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DataUserLogin struct {
|
||||||
|
Token string `json:"token"` // 登录jwt token
|
||||||
|
}
|
||||||
|
|
||||||
|
type DataGuest struct {
|
||||||
|
Token string `json:"token"` // 登录jwt token
|
||||||
|
}
|
||||||
|
|
||||||
|
type Request struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
type Response struct {
|
||||||
|
Code int `json:"code"`
|
||||||
|
Message string `json:"msg"`
|
||||||
|
Data interface{} `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Auth struct {
|
||||||
|
AccessSecret string `json:"accessSecret"`
|
||||||
|
AccessExpire int64 `json:"accessExpire"`
|
||||||
|
RefreshAfter int64 `json:"refreshAfter"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type File struct {
|
||||||
|
Filename string `fsfile:"filename"`
|
||||||
|
Header map[string][]string `fsfile:"header"`
|
||||||
|
Size int64 `fsfile:"size"`
|
||||||
|
Data []byte `fsfile:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Meta struct {
|
||||||
|
TotalCount int64 `json:"totalCount"`
|
||||||
|
PageCount int64 `json:"pageCount"`
|
||||||
|
CurrentPage int `json:"currentPage"`
|
||||||
|
PerPage int `json:"perPage"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set 设置Response的Code和Message值
|
||||||
|
func (resp *Response) Set(Code int, Message string) *Response {
|
||||||
|
return &Response{
|
||||||
|
Code: Code,
|
||||||
|
Message: Message,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set 设置整个Response
|
||||||
|
func (resp *Response) SetWithData(Code int, Message string, Data interface{}) *Response {
|
||||||
|
return &Response{
|
||||||
|
Code: Code,
|
||||||
|
Message: Message,
|
||||||
|
Data: Data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetStatus 设置默认StatusResponse(内部自定义) 默认msg, 可以带data, data只使用一个参数
|
||||||
|
func (resp *Response) SetStatus(sr *basic.StatusResponse, data ...interface{}) *Response {
|
||||||
|
newResp := &Response{
|
||||||
|
Code: sr.Code,
|
||||||
|
}
|
||||||
|
if len(data) == 1 {
|
||||||
|
newResp.Data = data[0]
|
||||||
|
}
|
||||||
|
return newResp
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetStatusWithMessage 设置默认StatusResponse(内部自定义) 非默认msg, 可以带data, data只使用一个参数
|
||||||
|
func (resp *Response) SetStatusWithMessage(sr *basic.StatusResponse, msg string, data ...interface{}) *Response {
|
||||||
|
newResp := &Response{
|
||||||
|
Code: sr.Code,
|
||||||
|
Message: msg,
|
||||||
|
}
|
||||||
|
if len(data) == 1 {
|
||||||
|
newResp.Data = data[0]
|
||||||
|
}
|
||||||
|
return newResp
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package homeuserauthtest
|
package authtest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -19,7 +19,7 @@ func TestAcceptCookieLogic(t *testing.T) {
|
|||||||
ses := fstests.GetSesssion()
|
ses := fstests.GetSesssion()
|
||||||
|
|
||||||
// 向服务器发送 GET 请求,获取 cookie 信息
|
// 向服务器发送 GET 请求,获取 cookie 信息
|
||||||
resp, err = ses.Post(fmt.Sprintf("http://%s:%d/user/accept-cookie", cnf.Host, cnf.Port)).TestExecute(gserver)
|
resp, err = ses.Post(fmt.Sprintf("http://%s:%d/api/auth/accept-cookie", cnf.Host, cnf.Port)).TestExecute(gserver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
40
server/auth/test/basic.go
Normal file
40
server/auth/test/basic.go
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package authtest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"fusenapi/server/auth/internal/config"
|
||||||
|
"fusenapi/server/auth/internal/handler"
|
||||||
|
"fusenapi/server/auth/internal/svc"
|
||||||
|
"fusenapi/utils/fstests"
|
||||||
|
"log"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/conf"
|
||||||
|
"github.com/zeromicro/go-zero/rest"
|
||||||
|
)
|
||||||
|
|
||||||
|
var cnf config.Config
|
||||||
|
var gserver *rest.Server
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
log.SetFlags(log.Llongfile)
|
||||||
|
gserver = GetTestServer()
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetTestServer() *rest.Server {
|
||||||
|
|
||||||
|
conf.MustLoad(fstests.GetEtcYamlPathAuto(), &cnf)
|
||||||
|
|
||||||
|
server := rest.MustNewServer(cnf.RestConf)
|
||||||
|
runtime.SetFinalizer(server, func(server *rest.Server) {
|
||||||
|
if server != nil {
|
||||||
|
server.Stop()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
ctx := svc.NewServiceContext(cnf)
|
||||||
|
handler.RegisterHandlers(server, ctx)
|
||||||
|
|
||||||
|
fmt.Printf("Starting server at %s:%d...\n", cnf.Host, cnf.Port)
|
||||||
|
return server
|
||||||
|
}
|
||||||
@ -3,6 +3,7 @@ package svc
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"fusenapi/fsm"
|
||||||
"fusenapi/server/backend/internal/config"
|
"fusenapi/server/backend/internal/config"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
@ -16,6 +17,7 @@ import (
|
|||||||
|
|
||||||
type ServiceContext struct {
|
type ServiceContext struct {
|
||||||
Config config.Config
|
Config config.Config
|
||||||
|
SharedState *fsm.StateCluster
|
||||||
|
|
||||||
MysqlConn *gorm.DB
|
MysqlConn *gorm.DB
|
||||||
AllModels *gmodel.AllModelsGen
|
AllModels *gmodel.AllModelsGen
|
||||||
|
|||||||
@ -2,10 +2,11 @@ package backendtest
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
authtest "fusenapi/server/auth/test"
|
||||||
"fusenapi/server/backend/internal/config"
|
"fusenapi/server/backend/internal/config"
|
||||||
"fusenapi/server/backend/internal/handler"
|
"fusenapi/server/backend/internal/handler"
|
||||||
"fusenapi/server/backend/internal/svc"
|
"fusenapi/server/backend/internal/svc"
|
||||||
homeuserauthtest "fusenapi/server/home-user-auth/test"
|
|
||||||
"fusenapi/utils/fstests"
|
"fusenapi/utils/fstests"
|
||||||
"log"
|
"log"
|
||||||
"runtime"
|
"runtime"
|
||||||
@ -19,7 +20,7 @@ var userver, gserver *rest.Server
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
log.SetFlags(log.Llongfile)
|
log.SetFlags(log.Llongfile)
|
||||||
userver = homeuserauthtest.GetTestServer()
|
userver = authtest.GetTestServer()
|
||||||
gserver = GetTestServer()
|
gserver = GetTestServer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,7 @@ func TestCaseQuotationDetail(t *testing.T) {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// 向服务器发送 POST 请求,新增用户地址
|
// 向服务器发送 POST 请求,新增用户地址
|
||||||
tp := ses.Get(fmt.Sprintf("http://%s:%d//quotation/detail", cnf.Host, cnf.Port))
|
tp := ses.Get(fmt.Sprintf("http://%s:%d/api//quotation/detail", cnf.Host, cnf.Port))
|
||||||
tp.QueryParam("id").Set(1003)
|
tp.QueryParam("id").Set(1003)
|
||||||
resp, err := tp.TestExecute(gserver)
|
resp, err := tp.TestExecute(gserver)
|
||||||
log.Println(resp.Json())
|
log.Println(resp.Json())
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package svc
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"fusenapi/fsm"
|
||||||
"fusenapi/server/canteen/internal/config"
|
"fusenapi/server/canteen/internal/config"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
@ -15,16 +16,20 @@ import (
|
|||||||
|
|
||||||
type ServiceContext struct {
|
type ServiceContext struct {
|
||||||
Config config.Config
|
Config config.Config
|
||||||
|
SharedState *fsm.StateCluster
|
||||||
|
|
||||||
MysqlConn *gorm.DB
|
MysqlConn *gorm.DB
|
||||||
AllModels *gmodel.AllModelsGen
|
AllModels *gmodel.AllModelsGen
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServiceContext(c config.Config) *ServiceContext {
|
func NewServiceContext(c config.Config) *ServiceContext {
|
||||||
|
conn := initalize.InitMysql(c.SourceMysql)
|
||||||
|
StateServer := fsm.StartNode(c.Name, fmt.Sprintf("%s:%d", c.Host, c.Port-2000), conn)
|
||||||
|
|
||||||
return &ServiceContext{
|
return &ServiceContext{
|
||||||
Config: c,
|
Config: c,
|
||||||
MysqlConn: initalize.InitMysql(c.SourceMysql),
|
MysqlConn: conn,
|
||||||
|
SharedState: StateServer,
|
||||||
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package svc
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"fusenapi/fsm"
|
||||||
"fusenapi/server/data-transfer/internal/config"
|
"fusenapi/server/data-transfer/internal/config"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
@ -15,16 +16,20 @@ import (
|
|||||||
|
|
||||||
type ServiceContext struct {
|
type ServiceContext struct {
|
||||||
Config config.Config
|
Config config.Config
|
||||||
|
SharedState *fsm.StateCluster
|
||||||
|
|
||||||
MysqlConn *gorm.DB
|
MysqlConn *gorm.DB
|
||||||
AllModels *gmodel.AllModelsGen
|
AllModels *gmodel.AllModelsGen
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServiceContext(c config.Config) *ServiceContext {
|
func NewServiceContext(c config.Config) *ServiceContext {
|
||||||
|
conn := initalize.InitMysql(c.SourceMysql)
|
||||||
|
StateServer := fsm.StartNode(c.Name, fmt.Sprintf("%s:%d", c.Host, c.Port-2000), conn)
|
||||||
|
|
||||||
return &ServiceContext{
|
return &ServiceContext{
|
||||||
Config: c,
|
Config: c,
|
||||||
MysqlConn: initalize.InitMysql(c.SourceMysql),
|
MysqlConn: conn,
|
||||||
|
SharedState: StateServer,
|
||||||
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,14 +9,5 @@ Auth:
|
|||||||
AccessExpire: 2592000
|
AccessExpire: 2592000
|
||||||
RefreshAfter: 1592000
|
RefreshAfter: 1592000
|
||||||
|
|
||||||
OAuth:
|
|
||||||
google:
|
|
||||||
appid: "1064842923358-e94msq2glj6qr4lrva9ts3hqjjt53q8h.apps.googleusercontent.com"
|
|
||||||
secret: "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"
|
|
||||||
|
|
||||||
facebook:
|
|
||||||
appid: "1095953604597065"
|
|
||||||
secret: "b146872550a190d5275b1420c212002e"
|
|
||||||
|
|
||||||
Stripe:
|
Stripe:
|
||||||
SK: "sk_test_51IisojHygnIJZeghPVSBhkwySfcyDV4SoAduIxu3J7bvSJ9cZMD96LY1LO6SpdbYquLJX5oKvgEBB67KT9pecfCy00iEC4pp9y"
|
SK: "sk_test_51IisojHygnIJZeghPVSBhkwySfcyDV4SoAduIxu3J7bvSJ9cZMD96LY1LO6SpdbYquLJX5oKvgEBB67KT9pecfCy00iEC4pp9y"
|
||||||
|
|||||||
@ -7,6 +7,5 @@ import (
|
|||||||
// var configFile = flag.String("f", "etc/home-user-auth.yaml", "the config file")
|
// var configFile = flag.String("f", "etc/home-user-auth.yaml", "the config file")
|
||||||
|
|
||||||
func TestMain(t *testing.T) {
|
func TestMain(t *testing.T) {
|
||||||
// log.Println(model.RawFieldNames[FsCanteenType]())
|
|
||||||
main()
|
main()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,18 +13,6 @@ type Config struct {
|
|||||||
|
|
||||||
MainAddress string
|
MainAddress string
|
||||||
|
|
||||||
OAuth struct {
|
|
||||||
Google struct {
|
|
||||||
Appid string
|
|
||||||
Secret string
|
|
||||||
}
|
|
||||||
|
|
||||||
Facebook struct {
|
|
||||||
Appid string
|
|
||||||
Secret string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Stripe struct {
|
Stripe struct {
|
||||||
SK string
|
SK string
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,16 +12,6 @@ import (
|
|||||||
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||||
server.AddRoutes(
|
server.AddRoutes(
|
||||||
[]rest.Route{
|
[]rest.Route{
|
||||||
{
|
|
||||||
Method: http.MethodPost,
|
|
||||||
Path: "/api/user/login",
|
|
||||||
Handler: UserLoginHandler(serverCtx),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Method: http.MethodPost,
|
|
||||||
Path: "/api/user/accept-cookie",
|
|
||||||
Handler: AcceptCookieHandler(serverCtx),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
Method: http.MethodGet,
|
Method: http.MethodGet,
|
||||||
Path: "/api/user/fonts",
|
Path: "/api/user/fonts",
|
||||||
@ -67,16 +57,6 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||||||
Path: "/api/user/order-delete",
|
Path: "/api/user/order-delete",
|
||||||
Handler: UserOderDeleteHandler(serverCtx),
|
Handler: UserOderDeleteHandler(serverCtx),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
Method: http.MethodGet,
|
|
||||||
Path: "/api/user/oauth2/login/google",
|
|
||||||
Handler: UserGoogleLoginHandler(serverCtx),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Method: http.MethodGet,
|
|
||||||
Path: "/api/user/oauth2/login/register",
|
|
||||||
Handler: UserEmailRegisterHandler(serverCtx),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
Method: http.MethodGet,
|
Method: http.MethodGet,
|
||||||
Path: "/api/user/order-list",
|
Path: "/api/user/order-list",
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package svc
|
package svc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fusenapi/fsm"
|
||||||
"fusenapi/initalize"
|
"fusenapi/initalize"
|
||||||
"fusenapi/model/gmodel"
|
"fusenapi/model/gmodel"
|
||||||
|
|
||||||
@ -15,16 +16,20 @@ import (
|
|||||||
|
|
||||||
type ServiceContext struct {
|
type ServiceContext struct {
|
||||||
Config config.Config
|
Config config.Config
|
||||||
|
SharedState *fsm.StateCluster
|
||||||
|
|
||||||
MysqlConn *gorm.DB
|
MysqlConn *gorm.DB
|
||||||
AllModels *gmodel.AllModelsGen
|
AllModels *gmodel.AllModelsGen
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServiceContext(c config.Config) *ServiceContext {
|
func NewServiceContext(c config.Config) *ServiceContext {
|
||||||
|
conn := initalize.InitMysql(c.SourceMysql)
|
||||||
|
StateServer := fsm.StartNode(c.Name, fmt.Sprintf("%s:%d", c.Host, c.Port-2000), conn)
|
||||||
|
|
||||||
return &ServiceContext{
|
return &ServiceContext{
|
||||||
Config: c,
|
Config: c,
|
||||||
MysqlConn: initalize.InitMysql(c.SourceMysql),
|
MysqlConn: conn,
|
||||||
|
SharedState: StateServer,
|
||||||
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -70,19 +70,6 @@ type Product struct {
|
|||||||
IsStop int64 `json:"is_stop"`
|
IsStop int64 `json:"is_stop"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RequestGoogleLogin struct {
|
|
||||||
Code string `form:"code"`
|
|
||||||
Scope string `form:"scope"`
|
|
||||||
AuthUser string `form:"authuser"`
|
|
||||||
Prompt string `form:"prompt"`
|
|
||||||
Email string `form:"email,optional"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type RequestEmailRegister struct {
|
|
||||||
Email string `json:"email"`
|
|
||||||
RegisterToken string `json:"register_token"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type RequestContactService struct {
|
type RequestContactService struct {
|
||||||
Type string `json:"type"` // 类型
|
Type string `json:"type"` // 类型
|
||||||
RelationID int64 `json:"relation_id"` // 关系id
|
RelationID int64 `json:"relation_id"` // 关系id
|
||||||
@ -108,11 +95,6 @@ type RequestBasicInfoForm struct {
|
|||||||
IsRemoveBg int64 `json:"is_remove_bg"` // 用户上传logo是否去除背景
|
IsRemoveBg int64 `json:"is_remove_bg"` // 用户上传logo是否去除背景
|
||||||
}
|
}
|
||||||
|
|
||||||
type RequestUserLogin struct {
|
|
||||||
Email string `json:"email"`
|
|
||||||
Password string `json:"password"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type RequestAddAddress struct {
|
type RequestAddAddress struct {
|
||||||
Id int64 `json:"id"` // address_id 地址id
|
Id int64 `json:"id"` // address_id 地址id
|
||||||
IsDefault int64 `json:"is_default"` //是否默认
|
IsDefault int64 `json:"is_default"` //是否默认
|
||||||
@ -133,14 +115,6 @@ type RequestOrderId struct {
|
|||||||
RefundReason string `json:"refund_reason"` //取消原因
|
RefundReason string `json:"refund_reason"` //取消原因
|
||||||
}
|
}
|
||||||
|
|
||||||
type DataUserLogin struct {
|
|
||||||
Token string `json:"token"` // 登录jwt token
|
|
||||||
}
|
|
||||||
|
|
||||||
type DataGuest struct {
|
|
||||||
Token string `json:"token"` // 登录jwt token
|
|
||||||
}
|
|
||||||
|
|
||||||
type DataUserBasicInfo struct {
|
type DataUserBasicInfo struct {
|
||||||
Type int64 `json:"type"` // 1普通餐厅 2连锁餐厅
|
Type int64 `json:"type"` // 1普通餐厅 2连锁餐厅
|
||||||
IsOrderStatusEmail int64 `json:"is_order_status_email"` // 订单状态改变时是否接收邮件
|
IsOrderStatusEmail int64 `json:"is_order_status_email"` // 订单状态改变时是否接收邮件
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package homeuserauthtest
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
authtest "fusenapi/server/auth/test"
|
||||||
"fusenapi/server/home-user-auth/internal/config"
|
"fusenapi/server/home-user-auth/internal/config"
|
||||||
"fusenapi/server/home-user-auth/internal/handler"
|
"fusenapi/server/home-user-auth/internal/handler"
|
||||||
"fusenapi/server/home-user-auth/internal/svc"
|
"fusenapi/server/home-user-auth/internal/svc"
|
||||||
@ -15,10 +16,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var cnf config.Config
|
var cnf config.Config
|
||||||
|
var userserver *rest.Server
|
||||||
var gserver *rest.Server
|
var gserver *rest.Server
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
log.SetFlags(log.Llongfile)
|
log.SetFlags(log.Llongfile)
|
||||||
|
userserver = authtest.GetTestServer()
|
||||||
gserver = GetTestServer()
|
gserver = GetTestServer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,7 @@ func TestCaseUserAddAddress(t *testing.T) {
|
|||||||
var result gjson.Result
|
var result gjson.Result
|
||||||
|
|
||||||
// 获取 session,并携带 JWT token
|
// 获取 session,并携带 JWT token
|
||||||
ses := fstests.GetSessionWithUserToken(t, gserver, cnf.Host, cnf.Port)
|
ses := fstests.GetSessionWithUserToken(t, userserver, cnf.Host, cnf.Port)
|
||||||
|
|
||||||
// 构建新增地址请求体
|
// 构建新增地址请求体
|
||||||
addrReq := types.RequestAddAddress{
|
addrReq := types.RequestAddAddress{
|
||||||
@ -32,7 +32,7 @@ func TestCaseUserAddAddress(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 向服务器发送 POST 请求,新增用户地址
|
// 向服务器发送 POST 请求,新增用户地址
|
||||||
tp := ses.Post(fmt.Sprintf("http://%s:%d/user/add-address", cnf.Host, cnf.Port))
|
tp := ses.Post(fmt.Sprintf("http://%s:%d/api/user/add-address", cnf.Host, cnf.Port))
|
||||||
tp.SetBodyJson(addrReq)
|
tp.SetBodyJson(addrReq)
|
||||||
resp, err = tp.TestExecute(gserver)
|
resp, err = tp.TestExecute(gserver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -85,7 +85,7 @@ func TestCaseUserAddAddress(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 向服务器发送 POST 请求,新增用户地址
|
// 向服务器发送 POST 请求,新增用户地址
|
||||||
tp = ses.Post(fmt.Sprintf("http://%s:%d/user/add-address", cnf.Host, cnf.Port))
|
tp = ses.Post(fmt.Sprintf("http://%s:%d/api/user/add-address", cnf.Host, cnf.Port))
|
||||||
tp.SetBodyJson(addrReq)
|
tp.SetBodyJson(addrReq)
|
||||||
resp, err = tp.TestExecute(gserver)
|
resp, err = tp.TestExecute(gserver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -15,10 +15,10 @@ func TestCaseAddressList(t *testing.T) {
|
|||||||
var result gjson.Result
|
var result gjson.Result
|
||||||
|
|
||||||
// 获取 session,并携带 JWT token
|
// 获取 session,并携带 JWT token
|
||||||
ses := fstests.GetSessionWithUserToken(t, gserver, cnf.Host, cnf.Port)
|
ses := fstests.GetSessionWithUserToken(t, userserver, cnf.Host, cnf.Port)
|
||||||
|
|
||||||
// 向服务器发送 GET 请求,获取用户地址列表
|
// 向服务器发送 GET 请求,获取用户地址列表
|
||||||
resp, err = ses.Get(fmt.Sprintf("http://%s:%d/user/address-list", cnf.Host, cnf.Port)).TestExecute(gserver)
|
resp, err = ses.Get(fmt.Sprintf("http://%s:%d/api/user/address-list", cnf.Host, cnf.Port)).TestExecute(gserver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,10 +15,10 @@ func TestCaseBasicInfoLogic(t *testing.T) {
|
|||||||
var result gjson.Result
|
var result gjson.Result
|
||||||
|
|
||||||
// 获取 session,并携带 JWT token
|
// 获取 session,并携带 JWT token
|
||||||
ses := fstests.GetSessionWithUserToken(t, gserver, cnf.Host, cnf.Port)
|
ses := fstests.GetSessionWithUserToken(t, userserver, cnf.Host, cnf.Port)
|
||||||
|
|
||||||
// 向服务器发送 GET 请求,获取用户基本信息
|
// 向服务器发送 GET 请求,获取用户基本信息
|
||||||
resp, err = ses.Get(fmt.Sprintf("http://%s:%d/user/basic-info", cnf.Host, cnf.Port)).TestExecute(gserver)
|
resp, err = ses.Get(fmt.Sprintf("http://%s:%d/api/user/basic-info", cnf.Host, cnf.Port)).TestExecute(gserver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,8 +16,8 @@ func TestUserContactService(t *testing.T) {
|
|||||||
var result gjson.Result
|
var result gjson.Result
|
||||||
|
|
||||||
// 获取 session,并携带 JWT token
|
// 获取 session,并携带 JWT token
|
||||||
ses := fstests.GetSessionWithUserToken(t, gserver, cnf.Host, cnf.Port)
|
ses := fstests.GetSessionWithUserToken(t, userserver, cnf.Host, cnf.Port)
|
||||||
tp := ses.Post(fmt.Sprintf("http://%s:%d/user/contact-service", cnf.Host, cnf.Port))
|
tp := ses.Post(fmt.Sprintf("http://%s:%d/api/user/contact-service", cnf.Host, cnf.Port))
|
||||||
req := types.RequestContactService{Type: "order", RelationID: 481, Email: "9107058@qq.com", Name: "zhang"}
|
req := types.RequestContactService{Type: "order", RelationID: 481, Email: "9107058@qq.com", Name: "zhang"}
|
||||||
tp.SetBodyJson(req)
|
tp.SetBodyJson(req)
|
||||||
// 向服务器发送 GET 请求,获取用户基本信息
|
// 向服务器发送 GET 请求,获取用户基本信息
|
||||||
|
|||||||
@ -16,10 +16,10 @@ func TestCaseUserFontsLogic(t *testing.T) {
|
|||||||
var result gjson.Result
|
var result gjson.Result
|
||||||
|
|
||||||
// 获取 session,并携带 JWT token
|
// 获取 session,并携带 JWT token
|
||||||
ses := fstests.GetSessionWithUserToken(t, gserver, cnf.Host, cnf.Port)
|
ses := fstests.GetSessionWithUserToken(t, userserver, cnf.Host, cnf.Port)
|
||||||
|
|
||||||
// 向服务器发送 GET 请求,获取字体列表
|
// 向服务器发送 GET 请求,获取字体列表
|
||||||
resp, err = ses.Get(fmt.Sprintf("http://%s:%d/user/fonts", cnf.Host, cnf.Port)).TestExecute(gserver)
|
resp, err = ses.Get(fmt.Sprintf("http://%s:%d/api/user/fonts", cnf.Host, cnf.Port)).TestExecute(gserver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,10 +15,10 @@ func TestCaseGetTypeLogic(t *testing.T) {
|
|||||||
var result gjson.Result
|
var result gjson.Result
|
||||||
|
|
||||||
// 获取 session,并携带 JWT token
|
// 获取 session,并携带 JWT token
|
||||||
ses := fstests.GetSessionWithUserToken(t, gserver, cnf.Host, cnf.Port)
|
ses := fstests.GetSessionWithUserToken(t, userserver, cnf.Host, cnf.Port)
|
||||||
|
|
||||||
// 向服务器发送 GET 请求,获取用户类型信息
|
// 向服务器发送 GET 请求,获取用户类型信息
|
||||||
resp, err = ses.Get(fmt.Sprintf("http://%s:%d/user/get-type", cnf.Host, cnf.Port)).TestExecute(gserver)
|
resp, err = ses.Get(fmt.Sprintf("http://%s:%d/api/user/get-type", cnf.Host, cnf.Port)).TestExecute(gserver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,10 +16,10 @@ func TestCaseLogic(t *testing.T) {
|
|||||||
var result gjson.Result
|
var result gjson.Result
|
||||||
|
|
||||||
// 获取 session,并携带 JWT token
|
// 获取 session,并携带 JWT token
|
||||||
ses := fstests.GetSessionWithUserToken(t, gserver, cnf.Host, cnf.Port)
|
ses := fstests.GetSessionWithUserToken(t, userserver, cnf.Host, cnf.Port)
|
||||||
|
|
||||||
// 向服务器发送 GET 请求,获取用户类型信息
|
// 向服务器发送 GET 请求,获取用户类型信息
|
||||||
tp := ses.Post(fmt.Sprintf("http://%s:%d/user/order-delete", cnf.Host, cnf.Port))
|
tp := ses.Post(fmt.Sprintf("http://%s:%d/api/user/order-delete", cnf.Host, cnf.Port))
|
||||||
reqO := types.RequestOrderId{
|
reqO := types.RequestOrderId{
|
||||||
OrderId: 12,
|
OrderId: 12,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,10 +17,10 @@ func TestCaseUserSaveBasicinfoLogic(t *testing.T) {
|
|||||||
var result gjson.Result
|
var result gjson.Result
|
||||||
|
|
||||||
// 获取 session,并携带 JWT token
|
// 获取 session,并携带 JWT token
|
||||||
ses := fstests.GetSessionWithUserToken(t, gserver, cnf.Host, cnf.Port)
|
ses := fstests.GetSessionWithUserToken(t, userserver, cnf.Host, cnf.Port)
|
||||||
var tp *requests.Temporary
|
var tp *requests.Temporary
|
||||||
|
|
||||||
tp = ses.Get(fmt.Sprintf("http://%s:%d/user/basic-info", cnf.Host, cnf.Port))
|
tp = ses.Get(fmt.Sprintf("http://%s:%d/api/user/basic-info", cnf.Host, cnf.Port))
|
||||||
resp, err = tp.TestExecute(gserver)
|
resp, err = tp.TestExecute(gserver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
@ -52,7 +52,7 @@ func TestCaseUserSaveBasicinfoLogic(t *testing.T) {
|
|||||||
req.IsRemoveBg = ^req.IsRemoveBg + 2
|
req.IsRemoveBg = ^req.IsRemoveBg + 2
|
||||||
|
|
||||||
// 向服务器发送 GET 请求,获取用户类型信息
|
// 向服务器发送 GET 请求,获取用户类型信息
|
||||||
tp = ses.Post(fmt.Sprintf("http://%s:%d/user/basic-info", cnf.Host, cnf.Port)).SetBodyJson(req)
|
tp = ses.Post(fmt.Sprintf("http://%s:%d/api/user/basic-info", cnf.Host, cnf.Port)).SetBodyJson(req)
|
||||||
resp, err = tp.TestExecute(gserver)
|
resp, err = tp.TestExecute(gserver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
@ -69,7 +69,7 @@ func TestCaseUserSaveBasicinfoLogic(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tp = ses.Get(fmt.Sprintf("http://%s:%d/user/basic-info", cnf.Host, cnf.Port))
|
tp = ses.Get(fmt.Sprintf("http://%s:%d/api/user/basic-info", cnf.Host, cnf.Port))
|
||||||
resp, err = tp.TestExecute(gserver)
|
resp, err = tp.TestExecute(gserver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
|
|||||||
@ -15,10 +15,10 @@ func TestCaseUserStatusConfigLogic(t *testing.T) {
|
|||||||
var result gjson.Result
|
var result gjson.Result
|
||||||
|
|
||||||
// 获取 session,并携带 JWT token
|
// 获取 session,并携带 JWT token
|
||||||
ses := fstests.GetSessionWithUserToken(t, gserver, cnf.Host, cnf.Port)
|
ses := fstests.GetSessionWithUserToken(t, userserver, cnf.Host, cnf.Port)
|
||||||
|
|
||||||
// 向服务器发送 GET 请求,获取用户类型信息
|
// 向服务器发送 GET 请求,获取用户类型信息
|
||||||
resp, err = ses.Post(fmt.Sprintf("http://%s:%d/user/status-config", cnf.Host, cnf.Port)).TestExecute(gserver)
|
resp, err = ses.Post(fmt.Sprintf("http://%s:%d/api/user/status-config", cnf.Host, cnf.Port)).TestExecute(gserver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package svc
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"fusenapi/fsm"
|
||||||
"fusenapi/server/inventory/internal/config"
|
"fusenapi/server/inventory/internal/config"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
@ -15,16 +16,20 @@ import (
|
|||||||
|
|
||||||
type ServiceContext struct {
|
type ServiceContext struct {
|
||||||
Config config.Config
|
Config config.Config
|
||||||
|
SharedState *fsm.StateCluster
|
||||||
|
|
||||||
MysqlConn *gorm.DB
|
MysqlConn *gorm.DB
|
||||||
AllModels *gmodel.AllModelsGen
|
AllModels *gmodel.AllModelsGen
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServiceContext(c config.Config) *ServiceContext {
|
func NewServiceContext(c config.Config) *ServiceContext {
|
||||||
|
conn := initalize.InitMysql(c.SourceMysql)
|
||||||
|
StateServer := fsm.StartNode(c.Name, fmt.Sprintf("%s:%d", c.Host, c.Port-2000), conn)
|
||||||
|
|
||||||
return &ServiceContext{
|
return &ServiceContext{
|
||||||
Config: c,
|
Config: c,
|
||||||
MysqlConn: initalize.InitMysql(c.SourceMysql),
|
MysqlConn: conn,
|
||||||
|
SharedState: StateServer,
|
||||||
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package svc
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"fusenapi/fsm"
|
||||||
"fusenapi/server/map-library/internal/config"
|
"fusenapi/server/map-library/internal/config"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
@ -15,16 +16,20 @@ import (
|
|||||||
|
|
||||||
type ServiceContext struct {
|
type ServiceContext struct {
|
||||||
Config config.Config
|
Config config.Config
|
||||||
|
SharedState *fsm.StateCluster
|
||||||
|
|
||||||
MysqlConn *gorm.DB
|
MysqlConn *gorm.DB
|
||||||
AllModels *gmodel.AllModelsGen
|
AllModels *gmodel.AllModelsGen
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServiceContext(c config.Config) *ServiceContext {
|
func NewServiceContext(c config.Config) *ServiceContext {
|
||||||
|
conn := initalize.InitMysql(c.SourceMysql)
|
||||||
|
StateServer := fsm.StartNode(c.Name, fmt.Sprintf("%s:%d", c.Host, c.Port-2000), conn)
|
||||||
|
|
||||||
return &ServiceContext{
|
return &ServiceContext{
|
||||||
Config: c,
|
Config: c,
|
||||||
MysqlConn: initalize.InitMysql(c.SourceMysql),
|
MysqlConn: conn,
|
||||||
|
SharedState: StateServer,
|
||||||
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package svc
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"fusenapi/fsm"
|
||||||
"fusenapi/server/orders/internal/config"
|
"fusenapi/server/orders/internal/config"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
@ -15,16 +16,20 @@ import (
|
|||||||
|
|
||||||
type ServiceContext struct {
|
type ServiceContext struct {
|
||||||
Config config.Config
|
Config config.Config
|
||||||
|
SharedState *fsm.StateCluster
|
||||||
|
|
||||||
MysqlConn *gorm.DB
|
MysqlConn *gorm.DB
|
||||||
AllModels *gmodel.AllModelsGen
|
AllModels *gmodel.AllModelsGen
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServiceContext(c config.Config) *ServiceContext {
|
func NewServiceContext(c config.Config) *ServiceContext {
|
||||||
|
conn := initalize.InitMysql(c.SourceMysql)
|
||||||
|
StateServer := fsm.StartNode(c.Name, fmt.Sprintf("%s:%d", c.Host, c.Port-2000), conn)
|
||||||
|
|
||||||
return &ServiceContext{
|
return &ServiceContext{
|
||||||
Config: c,
|
Config: c,
|
||||||
MysqlConn: initalize.InitMysql(c.SourceMysql),
|
MysqlConn: conn,
|
||||||
|
SharedState: StateServer,
|
||||||
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package svc
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"fusenapi/fsm"
|
||||||
"fusenapi/server/product-model/internal/config"
|
"fusenapi/server/product-model/internal/config"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
@ -15,16 +16,20 @@ import (
|
|||||||
|
|
||||||
type ServiceContext struct {
|
type ServiceContext struct {
|
||||||
Config config.Config
|
Config config.Config
|
||||||
|
SharedState *fsm.StateCluster
|
||||||
|
|
||||||
MysqlConn *gorm.DB
|
MysqlConn *gorm.DB
|
||||||
AllModels *gmodel.AllModelsGen
|
AllModels *gmodel.AllModelsGen
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServiceContext(c config.Config) *ServiceContext {
|
func NewServiceContext(c config.Config) *ServiceContext {
|
||||||
|
conn := initalize.InitMysql(c.SourceMysql)
|
||||||
|
StateServer := fsm.StartNode(c.Name, fmt.Sprintf("%s:%d", c.Host, c.Port-2000), conn)
|
||||||
|
|
||||||
return &ServiceContext{
|
return &ServiceContext{
|
||||||
Config: c,
|
Config: c,
|
||||||
MysqlConn: initalize.InitMysql(c.SourceMysql),
|
MysqlConn: conn,
|
||||||
|
SharedState: StateServer,
|
||||||
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package svc
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"fusenapi/fsm"
|
||||||
"fusenapi/server/product-template/internal/config"
|
"fusenapi/server/product-template/internal/config"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
@ -15,16 +16,20 @@ import (
|
|||||||
|
|
||||||
type ServiceContext struct {
|
type ServiceContext struct {
|
||||||
Config config.Config
|
Config config.Config
|
||||||
|
SharedState *fsm.StateCluster
|
||||||
|
|
||||||
MysqlConn *gorm.DB
|
MysqlConn *gorm.DB
|
||||||
AllModels *gmodel.AllModelsGen
|
AllModels *gmodel.AllModelsGen
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServiceContext(c config.Config) *ServiceContext {
|
func NewServiceContext(c config.Config) *ServiceContext {
|
||||||
|
conn := initalize.InitMysql(c.SourceMysql)
|
||||||
|
StateServer := fsm.StartNode(c.Name, fmt.Sprintf("%s:%d", c.Host, c.Port-2000), conn)
|
||||||
|
|
||||||
return &ServiceContext{
|
return &ServiceContext{
|
||||||
Config: c,
|
Config: c,
|
||||||
MysqlConn: initalize.InitMysql(c.SourceMysql),
|
MysqlConn: conn,
|
||||||
|
SharedState: StateServer,
|
||||||
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package svc
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"fusenapi/fsm"
|
||||||
"fusenapi/server/product/internal/config"
|
"fusenapi/server/product/internal/config"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
@ -15,13 +16,13 @@ import (
|
|||||||
|
|
||||||
type ServiceContext struct {
|
type ServiceContext struct {
|
||||||
Config config.Config
|
Config config.Config
|
||||||
|
SharedState *fsm.StateCluster
|
||||||
|
|
||||||
MysqlConn *gorm.DB
|
MysqlConn *gorm.DB
|
||||||
AllModels *gmodel.AllModelsGen
|
AllModels *gmodel.AllModelsGen
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServiceContext(c config.Config) *ServiceContext {
|
func NewServiceContext(c config.Config) *ServiceContext {
|
||||||
|
|
||||||
return &ServiceContext{
|
return &ServiceContext{
|
||||||
Config: c,
|
Config: c,
|
||||||
MysqlConn: initalize.InitMysql(c.SourceMysql),
|
MysqlConn: initalize.InitMysql(c.SourceMysql),
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package svc
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"fusenapi/fsm"
|
||||||
"fusenapi/server/render/internal/config"
|
"fusenapi/server/render/internal/config"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
@ -15,16 +16,20 @@ import (
|
|||||||
|
|
||||||
type ServiceContext struct {
|
type ServiceContext struct {
|
||||||
Config config.Config
|
Config config.Config
|
||||||
|
SharedState *fsm.StateCluster
|
||||||
|
|
||||||
MysqlConn *gorm.DB
|
MysqlConn *gorm.DB
|
||||||
AllModels *gmodel.AllModelsGen
|
AllModels *gmodel.AllModelsGen
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServiceContext(c config.Config) *ServiceContext {
|
func NewServiceContext(c config.Config) *ServiceContext {
|
||||||
|
conn := initalize.InitMysql(c.SourceMysql)
|
||||||
|
StateServer := fsm.StartNode(c.Name, fmt.Sprintf("%s:%d", c.Host, c.Port-2000), conn)
|
||||||
|
|
||||||
return &ServiceContext{
|
return &ServiceContext{
|
||||||
Config: c,
|
Config: c,
|
||||||
MysqlConn: initalize.InitMysql(c.SourceMysql),
|
MysqlConn: conn,
|
||||||
|
SharedState: StateServer,
|
||||||
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package svc
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"fusenapi/fsm"
|
||||||
"fusenapi/server/shopping-cart-confirmation/internal/config"
|
"fusenapi/server/shopping-cart-confirmation/internal/config"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
@ -15,16 +16,20 @@ import (
|
|||||||
|
|
||||||
type ServiceContext struct {
|
type ServiceContext struct {
|
||||||
Config config.Config
|
Config config.Config
|
||||||
|
SharedState *fsm.StateCluster
|
||||||
|
|
||||||
MysqlConn *gorm.DB
|
MysqlConn *gorm.DB
|
||||||
AllModels *gmodel.AllModelsGen
|
AllModels *gmodel.AllModelsGen
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServiceContext(c config.Config) *ServiceContext {
|
func NewServiceContext(c config.Config) *ServiceContext {
|
||||||
|
conn := initalize.InitMysql(c.SourceMysql)
|
||||||
|
StateServer := fsm.StartNode(c.Name, fmt.Sprintf("%s:%d", c.Host, c.Port-2000), conn)
|
||||||
|
|
||||||
return &ServiceContext{
|
return &ServiceContext{
|
||||||
Config: c,
|
Config: c,
|
||||||
MysqlConn: initalize.InitMysql(c.SourceMysql),
|
MysqlConn: conn,
|
||||||
|
SharedState: StateServer,
|
||||||
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package svc
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"fusenapi/fsm"
|
||||||
"fusenapi/server/upload/internal/config"
|
"fusenapi/server/upload/internal/config"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
@ -18,6 +19,7 @@ import (
|
|||||||
|
|
||||||
type ServiceContext struct {
|
type ServiceContext struct {
|
||||||
Config config.Config
|
Config config.Config
|
||||||
|
SharedState *fsm.StateCluster
|
||||||
|
|
||||||
MysqlConn *gorm.DB
|
MysqlConn *gorm.DB
|
||||||
AllModels *gmodel.AllModelsGen
|
AllModels *gmodel.AllModelsGen
|
||||||
|
|||||||
@ -2,7 +2,8 @@ package test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
homeuserauthtest "fusenapi/server/home-user-auth/test"
|
|
||||||
|
authtest "fusenapi/server/auth/test"
|
||||||
"fusenapi/server/upload/internal/config"
|
"fusenapi/server/upload/internal/config"
|
||||||
"fusenapi/server/upload/internal/handler"
|
"fusenapi/server/upload/internal/handler"
|
||||||
"fusenapi/server/upload/internal/svc"
|
"fusenapi/server/upload/internal/svc"
|
||||||
@ -20,7 +21,7 @@ var userver, gserver *rest.Server
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
log.SetFlags(log.Llongfile)
|
log.SetFlags(log.Llongfile)
|
||||||
userver = homeuserauthtest.GetTestServer()
|
userver = authtest.GetTestServer()
|
||||||
gserver = GetTestServer()
|
gserver = GetTestServer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,7 +19,7 @@ func TestCaseRenderMegre(t *testing.T) {
|
|||||||
|
|
||||||
// 获取 session,并携带 JWT token
|
// 获取 session,并携带 JWT token
|
||||||
ses := fstests.GetSessionWithUserToken(t, userver, cnf.Host, cnf.Port)
|
ses := fstests.GetSessionWithUserToken(t, userver, cnf.Host, cnf.Port)
|
||||||
tp := ses.Post(fmt.Sprintf("http://%s:%d/upload/upload-file-backend", cnf.Host, cnf.Port))
|
tp := ses.Post(fmt.Sprintf("http://%s:%d/api/upload/upload-file-backend", cnf.Host, cnf.Port))
|
||||||
|
|
||||||
mp := tp.CreateBodyMultipart()
|
mp := tp.CreateBodyMultipart()
|
||||||
f, err := os.Open("./fusen.webp")
|
f, err := os.Open("./fusen.webp")
|
||||||
|
|||||||
@ -20,7 +20,7 @@ func TestCasePersonalization(t *testing.T) {
|
|||||||
|
|
||||||
// 获取 session,并携带 JWT token
|
// 获取 session,并携带 JWT token
|
||||||
ses := fstests.GetSessionWithUserToken(t, userver, cnf.Host, cnf.Port)
|
ses := fstests.GetSessionWithUserToken(t, userver, cnf.Host, cnf.Port)
|
||||||
tp := ses.Post(fmt.Sprintf("http://%s:%d/upload/upload-file-frontend", cnf.Host, cnf.Port))
|
tp := ses.Post(fmt.Sprintf("http://%s:%d/api/upload/upload-file-frontend", cnf.Host, cnf.Port))
|
||||||
|
|
||||||
data, err := ioutil.ReadFile("./fusen.webp")
|
data, err := ioutil.ReadFile("./fusen.webp")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -75,7 +75,7 @@ func TestCaseRenderMegreF(t *testing.T) {
|
|||||||
|
|
||||||
// 获取 session,并携带 JWT token
|
// 获取 session,并携带 JWT token
|
||||||
ses := fstests.GetSessionWithUserToken(t, userver, cnf.Host, cnf.Port)
|
ses := fstests.GetSessionWithUserToken(t, userver, cnf.Host, cnf.Port)
|
||||||
tp := ses.Post(fmt.Sprintf("http://%s:%d/upload/upload-file-frontend", cnf.Host, cnf.Port))
|
tp := ses.Post(fmt.Sprintf("http://%s:%d/api/upload/upload-file-frontend", cnf.Host, cnf.Port))
|
||||||
|
|
||||||
data, err := ioutil.ReadFile("./fusen.webp")
|
data, err := ioutil.ReadFile("./fusen.webp")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package svc
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"fusenapi/fsm"
|
||||||
"fusenapi/server/webset/internal/config"
|
"fusenapi/server/webset/internal/config"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
@ -15,16 +16,20 @@ import (
|
|||||||
|
|
||||||
type ServiceContext struct {
|
type ServiceContext struct {
|
||||||
Config config.Config
|
Config config.Config
|
||||||
|
SharedState *fsm.StateCluster
|
||||||
|
|
||||||
MysqlConn *gorm.DB
|
MysqlConn *gorm.DB
|
||||||
AllModels *gmodel.AllModelsGen
|
AllModels *gmodel.AllModelsGen
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServiceContext(c config.Config) *ServiceContext {
|
func NewServiceContext(c config.Config) *ServiceContext {
|
||||||
|
conn := initalize.InitMysql(c.SourceMysql)
|
||||||
|
StateServer := fsm.StartNode(c.Name, fmt.Sprintf("%s:%d", c.Host, c.Port-2000), conn)
|
||||||
|
|
||||||
return &ServiceContext{
|
return &ServiceContext{
|
||||||
Config: c,
|
Config: c,
|
||||||
MysqlConn: initalize.InitMysql(c.SourceMysql),
|
MysqlConn: conn,
|
||||||
|
SharedState: StateServer,
|
||||||
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,8 @@ package webset_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
homeuserauthtest "fusenapi/server/home-user-auth/test"
|
|
||||||
|
authtest "fusenapi/server/auth/test"
|
||||||
"fusenapi/server/webset/internal/config"
|
"fusenapi/server/webset/internal/config"
|
||||||
"fusenapi/server/webset/internal/handler"
|
"fusenapi/server/webset/internal/handler"
|
||||||
"fusenapi/server/webset/internal/svc"
|
"fusenapi/server/webset/internal/svc"
|
||||||
@ -19,7 +20,7 @@ var userver, gserver *rest.Server
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
log.SetFlags(log.Llongfile)
|
log.SetFlags(log.Llongfile)
|
||||||
userver = homeuserauthtest.GetTestServer()
|
userver = authtest.GetTestServer()
|
||||||
gserver = GetTestServer()
|
gserver = GetTestServer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -20,7 +20,7 @@ func TestWebSetLogic(t *testing.T) {
|
|||||||
|
|
||||||
// 获取 session,并携带 JWT token
|
// 获取 session,并携带 JWT token
|
||||||
ses := fstests.GetSesssion()
|
ses := fstests.GetSesssion()
|
||||||
tp := ses.Get(fmt.Sprintf("http://%s:%d/web-set/setting", cnf.Host, cnf.Port))
|
tp := ses.Get(fmt.Sprintf("http://%s:%d/api/web-set/setting", cnf.Host, cnf.Port))
|
||||||
|
|
||||||
for _, tType := range testTypes {
|
for _, tType := range testTypes {
|
||||||
tp.QueryParam("type").Set(tType)
|
tp.QueryParam("type").Set(tType)
|
||||||
|
|||||||
53
server_api/auth.api
Normal file
53
server_api/auth.api
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
syntax = "v1"
|
||||||
|
|
||||||
|
info (
|
||||||
|
title: // TODO: add title
|
||||||
|
desc: // TODO: add description
|
||||||
|
author: ""
|
||||||
|
email: ""
|
||||||
|
)
|
||||||
|
|
||||||
|
import "basic.api"
|
||||||
|
|
||||||
|
service auth {
|
||||||
|
@handler UserLoginHandler
|
||||||
|
post /api/auth/login(RequestUserLogin) returns (response);
|
||||||
|
|
||||||
|
@handler AcceptCookieHandler
|
||||||
|
post /api/auth/accept-cookie(request) returns (response);
|
||||||
|
|
||||||
|
@handler UserGoogleLoginHandler
|
||||||
|
get /api/auth/oauth2/login/google(RequestGoogleLogin) returns (response);
|
||||||
|
|
||||||
|
@handler UserEmailRegisterHandler
|
||||||
|
get /api/auth/oauth2/register(RequestEmailRegister) returns (response);
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserAddAddressHandler 用户登录请求结构
|
||||||
|
type RequestUserLogin {
|
||||||
|
Email string `json:"email"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RequestGoogleLogin {
|
||||||
|
Code string `form:"code"`
|
||||||
|
Scope string `form:"scope"`
|
||||||
|
AuthUser string `form:"authuser"`
|
||||||
|
Prompt string `form:"prompt"`
|
||||||
|
Email string `form:"email,optional"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RequestEmailRegister {
|
||||||
|
Email string `json:"email"`
|
||||||
|
RegisterToken string `json:"register_token"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserLoginHandler 用户登录请求结构
|
||||||
|
type DataUserLogin {
|
||||||
|
Token string `json:"token"` // 登录jwt token
|
||||||
|
}
|
||||||
|
|
||||||
|
// DataGuest 游客获取toekn请求结构
|
||||||
|
type DataGuest {
|
||||||
|
Token string `json:"token"` // 登录jwt token
|
||||||
|
}
|
||||||
@ -14,12 +14,6 @@ service home-user-auth {
|
|||||||
// @handler UserRegisterHandler
|
// @handler UserRegisterHandler
|
||||||
// post /api/user/register(RequestUserRegister) returns (response);
|
// post /api/user/register(RequestUserRegister) returns (response);
|
||||||
|
|
||||||
@handler UserLoginHandler
|
|
||||||
post /api/user/login(RequestUserLogin) returns (response);
|
|
||||||
|
|
||||||
@handler AcceptCookieHandler
|
|
||||||
post /api/user/accept-cookie(request) returns (response);
|
|
||||||
|
|
||||||
@handler UserFontsHandler
|
@handler UserFontsHandler
|
||||||
get /api/user/fonts(request) returns (response);
|
get /api/user/fonts(request) returns (response);
|
||||||
|
|
||||||
@ -50,12 +44,6 @@ service home-user-auth {
|
|||||||
@handler UserOderDeleteHandler
|
@handler UserOderDeleteHandler
|
||||||
post /api/user/order-delete(RequestOrderId) returns (response);
|
post /api/user/order-delete(RequestOrderId) returns (response);
|
||||||
|
|
||||||
@handler UserGoogleLoginHandler
|
|
||||||
get /api/user/oauth2/login/google(RequestGoogleLogin) returns (response);
|
|
||||||
|
|
||||||
@handler UserEmailRegisterHandler
|
|
||||||
get /api/user/oauth2/login/register(RequestEmailRegister) returns (response);
|
|
||||||
|
|
||||||
//订单列表
|
//订单列表
|
||||||
@handler UserOrderListHandler
|
@handler UserOrderListHandler
|
||||||
get /api/user/order-list (UserOrderListReq) returns (response);
|
get /api/user/order-list (UserOrderListReq) returns (response);
|
||||||
@ -136,19 +124,6 @@ type Product {
|
|||||||
IsStop int64 `json:"is_stop"`
|
IsStop int64 `json:"is_stop"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RequestGoogleLogin {
|
|
||||||
Code string `form:"code"`
|
|
||||||
Scope string `form:"scope"`
|
|
||||||
AuthUser string `form:"authuser"`
|
|
||||||
Prompt string `form:"prompt"`
|
|
||||||
Email string `form:"email,optional"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type RequestEmailRegister {
|
|
||||||
Email string `json:"email"`
|
|
||||||
RegisterToken string `json:"register_token"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type RequestContactService {
|
type RequestContactService {
|
||||||
Type string `json:"type"` // 类型
|
Type string `json:"type"` // 类型
|
||||||
RelationID int64 `json:"relation_id"` // 关系id
|
RelationID int64 `json:"relation_id"` // 关系id
|
||||||
@ -176,12 +151,6 @@ type RequestBasicInfoForm {
|
|||||||
// NewPassword string `form:"new_password,optional" db:"new_password"` // new_password 如果存在新密码
|
// NewPassword string `form:"new_password,optional" db:"new_password"` // new_password 如果存在新密码
|
||||||
}
|
}
|
||||||
|
|
||||||
// UserAddAddressHandler 用户登录请求结构
|
|
||||||
type RequestUserLogin {
|
|
||||||
Email string `json:"email"`
|
|
||||||
Password string `json:"password"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// RequestAddAddress 增加地址结构
|
// RequestAddAddress 增加地址结构
|
||||||
type RequestAddAddress {
|
type RequestAddAddress {
|
||||||
Id int64 `json:"id"` // address_id 地址id
|
Id int64 `json:"id"` // address_id 地址id
|
||||||
@ -204,16 +173,6 @@ type RequestOrderId {
|
|||||||
RefundReason string `json:"refund_reason"` //取消原因
|
RefundReason string `json:"refund_reason"` //取消原因
|
||||||
}
|
}
|
||||||
|
|
||||||
// UserLoginHandler 用户登录请求结构
|
|
||||||
type DataUserLogin {
|
|
||||||
Token string `json:"token"` // 登录jwt token
|
|
||||||
}
|
|
||||||
|
|
||||||
// DataGuest 游客获取toekn请求结构
|
|
||||||
type DataGuest {
|
|
||||||
Token string `json:"token"` // 登录jwt token
|
|
||||||
}
|
|
||||||
|
|
||||||
// UserBasicInfoHandler 返回data结构
|
// UserBasicInfoHandler 返回data结构
|
||||||
type DataUserBasicInfo {
|
type DataUserBasicInfo {
|
||||||
Type int64 `json:"type"` // 1普通餐厅 2连锁餐厅
|
Type int64 `json:"type"` // 1普通餐厅 2连锁餐厅
|
||||||
|
|||||||
@ -1,9 +1,51 @@
|
|||||||
package auth
|
package auth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/binary"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
"net/mail"
|
"net/mail"
|
||||||
|
|
||||||
|
"github.com/golang-jwt/jwt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func ParseJwtTokenUint64Secret(r *http.Request, AccessSecret uint64) (jwt.MapClaims, error) {
|
||||||
|
AuthKey := r.Header.Get("Authorization")
|
||||||
|
if AuthKey == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
AuthKey = AuthKey[7:]
|
||||||
|
|
||||||
|
if len(AuthKey) <= 50 {
|
||||||
|
return nil, errors.New(fmt.Sprint("Error parsing token, len:", len(AuthKey)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert uint64 to []byte
|
||||||
|
key := make([]byte, 8)
|
||||||
|
binary.BigEndian.PutUint64(key, AccessSecret)
|
||||||
|
|
||||||
|
token, err := jwt.Parse(AuthKey, func(token *jwt.Token) (interface{}, error) {
|
||||||
|
// 检查签名方法是否为 HS256
|
||||||
|
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||||
|
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
|
||||||
|
}
|
||||||
|
// 返回用于验证签名的密钥
|
||||||
|
return key, nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New(fmt.Sprint("Error parsing token:", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证成功返回
|
||||||
|
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
|
||||||
|
return claims, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, errors.New(fmt.Sprint("Invalid token", err))
|
||||||
|
}
|
||||||
|
|
||||||
// ValidateEmail checks if the provided string is a valid email address.
|
// ValidateEmail checks if the provided string is a valid email address.
|
||||||
func ValidateEmail(email string) bool {
|
func ValidateEmail(email string) bool {
|
||||||
_, err := mail.ParseAddress(email)
|
_, err := mail.ParseAddress(email)
|
||||||
@ -17,6 +59,14 @@ func ValidatePassword(password string) bool {
|
|||||||
return len(password) >= minPasswordLength
|
return len(password) >= minPasswordLength
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func StringToHash(s string) uint64 {
|
||||||
|
hash := sha256.New()
|
||||||
|
hash.Write([]byte(s))
|
||||||
|
hashed := hash.Sum(nil)
|
||||||
|
intHash := binary.BigEndian.Uint64(hashed)
|
||||||
|
return intHash
|
||||||
|
}
|
||||||
|
|
||||||
var secret = []byte("your-secret")
|
var secret = []byte("your-secret")
|
||||||
|
|
||||||
// func generateConfirmationLink(id, email, password, name string, platform string) (string, error) {
|
// func generateConfirmationLink(id, email, password, name string, platform string) (string, error) {
|
||||||
|
|||||||
@ -68,6 +68,11 @@ type BackendUserInfo struct {
|
|||||||
DepartmentId int64 `json:"department_id"`
|
DepartmentId int64 `json:"department_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type OAuthInfo struct {
|
||||||
|
Id int64 `json:"id"`
|
||||||
|
Platform string `json:"platform"`
|
||||||
|
}
|
||||||
|
|
||||||
// 获取登录信息
|
// 获取登录信息
|
||||||
func GetUserInfoFormMapClaims(claims jwt.MapClaims) (*UserInfo, error) {
|
func GetUserInfoFormMapClaims(claims jwt.MapClaims) (*UserInfo, error) {
|
||||||
userinfo := &UserInfo{}
|
userinfo := &UserInfo{}
|
||||||
@ -195,3 +200,79 @@ func CheckValueRange[T comparable](v T, rangevalues ...T) bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GenerateRegisterToken 网站注册 token生成
|
||||||
|
func GenerateRegisterToken(accessSecret *string, accessExpire, nowSec int64, id int64, platform string) (string, error) {
|
||||||
|
claims := make(jwt.MapClaims)
|
||||||
|
claims["exp"] = nowSec + accessExpire
|
||||||
|
claims["iat"] = nowSec
|
||||||
|
|
||||||
|
if id == 0 {
|
||||||
|
err := errors.New("userid and guestid cannot be 0 at the same time")
|
||||||
|
logx.Error(err)
|
||||||
|
return "", err
|
||||||
|
|
||||||
|
}
|
||||||
|
claims["id"] = id
|
||||||
|
claims["platform"] = platform
|
||||||
|
|
||||||
|
token := jwt.New(jwt.SigningMethodHS256)
|
||||||
|
token.Claims = claims
|
||||||
|
return token.SignedString([]byte(*accessSecret))
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRegisterFormMapClaims 获取注册唯一token标识登录信息
|
||||||
|
func GetRegisterFormMapClaims(claims jwt.MapClaims) (*OAuthInfo, error) {
|
||||||
|
oauthinfo := &OAuthInfo{}
|
||||||
|
if userid, ok := claims["id"]; ok {
|
||||||
|
uid, ok := userid.(float64)
|
||||||
|
if !ok {
|
||||||
|
err := errors.New(fmt.Sprint("parse uid form context err:", userid))
|
||||||
|
logx.Error("parse uid form context err:", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
oauthinfo.Id = int64(uid)
|
||||||
|
} else {
|
||||||
|
err := errors.New(`id not in claims`)
|
||||||
|
logx.Error(`id not in claims`)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if splatform, ok := claims["id"]; ok {
|
||||||
|
platform, ok := splatform.(string)
|
||||||
|
if !ok {
|
||||||
|
err := errors.New(fmt.Sprint("parse uid form context err:", platform))
|
||||||
|
logx.Error("parse uid form context err:", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
oauthinfo.Platform = platform
|
||||||
|
} else {
|
||||||
|
err := errors.New(`id not in claims`)
|
||||||
|
logx.Error(`id not in claims`)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return oauthinfo, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getRegisterJwtClaims(Token string, AccessSecret *string) (jwt.MapClaims, error) {
|
||||||
|
|
||||||
|
token, err := jwt.Parse(Token, func(token *jwt.Token) (interface{}, error) {
|
||||||
|
// 检查签名方法是否为 HS256
|
||||||
|
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||||
|
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
|
||||||
|
}
|
||||||
|
// 返回用于验证签名的密钥
|
||||||
|
return []byte(*AccessSecret), nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New(fmt.Sprint("Error parsing token:", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证成功返回
|
||||||
|
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
|
||||||
|
return claims, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, errors.New(fmt.Sprint("Invalid token", err))
|
||||||
|
}
|
||||||
|
|||||||
@ -40,6 +40,8 @@ var (
|
|||||||
CodeUnAuth = &StatusResponse{401, "unauthorized"} // 未授权
|
CodeUnAuth = &StatusResponse{401, "unauthorized"} // 未授权
|
||||||
|
|
||||||
CodeOAuthGoogleApiErr = &StatusResponse{5070, "oauth2 google api error"}
|
CodeOAuthGoogleApiErr = &StatusResponse{5070, "oauth2 google api error"}
|
||||||
|
CodeOAuthRegisterTokenErr = &StatusResponse{5071, "oauth2 jwt token error"}
|
||||||
|
CodeOAuthEmailErr = &StatusResponse{5071, "Invalid email format"}
|
||||||
|
|
||||||
CodeS3PutObjectRequestErr = &StatusResponse{5060, "s3 PutObjectRequest error"} // s3 PutObjectRequest 错误
|
CodeS3PutObjectRequestErr = &StatusResponse{5060, "s3 PutObjectRequest error"} // s3 PutObjectRequest 错误
|
||||||
CodeS3PutSizeLimitErr = &StatusResponse{5061, "s3 over limit size error"} // s3 超过文件大小限制 错误
|
CodeS3PutSizeLimitErr = &StatusResponse{5061, "s3 over limit size error"} // s3 超过文件大小限制 错误
|
||||||
|
|||||||
@ -52,6 +52,8 @@ func RequestParse(w http.ResponseWriter, r *http.Request, svcCtx IJWTParse, Logi
|
|||||||
|
|
||||||
// 解析JWT token,并对空用户进行判断
|
// 解析JWT token,并对空用户进行判断
|
||||||
claims, err := svcCtx.ParseJwtToken(r)
|
claims, err := svcCtx.ParseJwtToken(r)
|
||||||
|
// auth.ParseJwtTokenUint64Secret()
|
||||||
|
|
||||||
// 如果解析JWT token出错,则返回未授权的JSON响应并记录错误消息
|
// 如果解析JWT token出错,则返回未授权的JSON响应并记录错误消息
|
||||||
if err != nil {
|
if err != nil {
|
||||||
httpx.OkJsonCtx(r.Context(), w, &Response{
|
httpx.OkJsonCtx(r.Context(), w, &Response{
|
||||||
|
|||||||
@ -85,10 +85,10 @@ func GetSesssion() *requests.Session {
|
|||||||
|
|
||||||
func GetSessionWithUserToken(t *testing.T, server requests.ITestServer, Host string, Port int) *requests.Session {
|
func GetSessionWithUserToken(t *testing.T, server requests.ITestServer, Host string, Port int) *requests.Session {
|
||||||
ses := requests.NewSession()
|
ses := requests.NewSession()
|
||||||
tp := ses.Post(fmt.Sprintf("http://%s:%d/user/login", Host, Port))
|
tp := ses.Post(fmt.Sprintf("http://%s:%d/api/auth/login", Host, Port))
|
||||||
tp.SetBodyJson(map[string]interface{}{
|
tp.SetBodyJson(map[string]interface{}{
|
||||||
"name": "9107058@qq.com",
|
"email": "9107058@qq.com",
|
||||||
"pwd": "$2y$13$2y4O4OIz/zcK5C0vlSc9LuSpjWySjInLBSe49yDkE.iURb.R1hDsy",
|
"password": "t1I0hOs0/AmhZfNk9ZiNnd3YZJpI+LL6COnHAmYEJk4=",
|
||||||
})
|
})
|
||||||
resp, err := tp.TestExecute(server)
|
resp, err := tp.TestExecute(server)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -104,16 +104,16 @@ func GetSessionWithUserToken(t *testing.T, server requests.ITestServer, Host str
|
|||||||
if !token.Exists() {
|
if !token.Exists() {
|
||||||
t.Error("data.token is not exists")
|
t.Error("data.token is not exists")
|
||||||
}
|
}
|
||||||
ses.Header.Add("Authorization", token.String())
|
ses.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token.String()))
|
||||||
|
|
||||||
return ses
|
return ses
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetBackendSessionWithUserToken(t *testing.T, server requests.ITestServer, Host string, Port int) *requests.Session {
|
func GetBackendSessionWithUserToken(t *testing.T, server requests.ITestServer, Host string, Port int) *requests.Session {
|
||||||
ses := requests.NewSession()
|
ses := requests.NewSession()
|
||||||
tp := ses.Post(fmt.Sprintf("http://%s:%d/backend-user/login", Host, Port))
|
tp := ses.Post(fmt.Sprintf("http://%s:%d/api/backend-user/login", Host, Port))
|
||||||
tp.SetBodyJson(map[string]interface{}{
|
tp.SetBodyJson(map[string]interface{}{
|
||||||
"name": "admin@admin.com",
|
"email": "admin@admin.com",
|
||||||
"pwd": "ZnVzZW5fYmFja2VuZF8yMDIz47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU=",
|
"pwd": "ZnVzZW5fYmFja2VuZF8yMDIz47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU=",
|
||||||
})
|
})
|
||||||
resp, err := tp.TestExecute(server)
|
resp, err := tp.TestExecute(server)
|
||||||
@ -130,14 +130,14 @@ func GetBackendSessionWithUserToken(t *testing.T, server requests.ITestServer, H
|
|||||||
if !token.Exists() {
|
if !token.Exists() {
|
||||||
t.Error("data.token is not exists")
|
t.Error("data.token is not exists")
|
||||||
}
|
}
|
||||||
ses.Header.Add("Authorization", token.String())
|
ses.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token.String()))
|
||||||
|
|
||||||
return ses
|
return ses
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetSesssionWithGuestToken(t *testing.T, server requests.ITestServer, Host string, Port int) *requests.Session {
|
func GetSesssionWithGuestToken(t *testing.T, server requests.ITestServer, Host string, Port int) *requests.Session {
|
||||||
ses := requests.NewSession()
|
ses := requests.NewSession()
|
||||||
tp := ses.Post(fmt.Sprintf("http://%s:%d/accept/cookie", Host, Port))
|
tp := ses.Post(fmt.Sprintf("http://%s:%d/api/auth/accept/cookie", Host, Port))
|
||||||
|
|
||||||
resp, err := tp.TestExecute(server)
|
resp, err := tp.TestExecute(server)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -148,7 +148,7 @@ func GetSesssionWithGuestToken(t *testing.T, server requests.ITestServer, Host s
|
|||||||
if !token.Exists() {
|
if !token.Exists() {
|
||||||
t.Error("data.token is not exists")
|
t.Error("data.token is not exists")
|
||||||
}
|
}
|
||||||
ses.Header.Add("Authorization", token.String())
|
ses.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token.String()))
|
||||||
|
|
||||||
return ses
|
return ses
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user