/
client.go
99 lines (82 loc) · 2.47 KB
/
client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package cato
import (
"context"
"fmt"
"net/http"
"sync/atomic"
"gitlab.com/pjrpc/pjrpc/v2/client"
"go.uber.org/zap"
"github.com/tranHieuDev23/cato/internal/handlers/http/middlewares"
"github.com/tranHieuDev23/cato/internal/handlers/http/rpc"
"github.com/tranHieuDev23/cato/internal/handlers/http/rpc/rpcclient"
"github.com/tranHieuDev23/cato/internal/utils"
)
func getHostEndpoint(address string) string {
return fmt.Sprintf("%s/api/", address)
}
func InitializeBaseClient(appArguments utils.Arguments) (rpcclient.APIClient, error) {
hostEndpoint := getHostEndpoint(appArguments.HostAddress)
pjrpcClient, err := client.New(hostEndpoint)
if err != nil {
return nil, err
}
return rpcclient.NewAPIClient(pjrpcClient), nil
}
type HTTPClientWithAuthToken client.HTTPDoer
type httpClientWithAuthToken struct {
appArguments utils.Arguments
logger *zap.Logger
authCookie *atomic.Pointer[string]
baseAPIClient rpcclient.APIClient
httpClient *http.Client
}
func NewHTTPClientWithAuthToken(
appArguments utils.Arguments,
logger *zap.Logger,
) (HTTPClientWithAuthToken, error) {
baseAPIClient, err := InitializeBaseClient(appArguments)
if err != nil {
return nil, err
}
return &httpClientWithAuthToken{
appArguments: appArguments,
logger: logger,
authCookie: new(atomic.Pointer[string]),
baseAPIClient: baseAPIClient,
httpClient: http.DefaultClient,
}, nil
}
func (h httpClientWithAuthToken) getAuthToken(ctx context.Context) (string, error) {
response, err := h.baseAPIClient.CreateSession(ctx, &rpc.CreateSessionRequest{
AccountName: h.appArguments.WorkerAccountName,
Password: h.appArguments.WorkerAccountPassword,
})
if err != nil {
h.logger.With(zap.Error(err)).Error("failed to get auth token")
return "", err
}
return response.Token, nil
}
func (h httpClientWithAuthToken) Do(req *http.Request) (*http.Response, error) {
ctx := req.Context()
token := h.authCookie.Load()
if token == nil {
newToken, err := h.getAuthToken(ctx)
if err != nil {
return nil, err
}
token = &newToken
h.authCookie.Store(token)
}
req.AddCookie(&http.Cookie{Name: middlewares.AuthorizationCookie, Value: *token})
return h.httpClient.Do(req)
}
func InitializeAuthenticatedClient(
appArguments utils.Arguments,
httpClientWithAuthCookie HTTPClientWithAuthToken,
) rpcclient.APIClient {
return rpcclient.NewAPIClient(&client.Client{
URL: getHostEndpoint(appArguments.HostAddress),
HTTPClient: httpClientWithAuthCookie,
})
}