@@ -17,15 +17,17 @@ limitations under the License.
1717package active24
1818
1919import (
20+ "crypto/hmac"
21+ "crypto/sha1"
22+ "encoding/hex"
2023 "fmt"
2124 "io"
22- "k8s.io/klog/v2"
2325 "net/http"
26+ "net/url"
27+ "path"
2428 "time"
25- )
2629
27- const (
28- SandboxToken = "123456qwerty-ok"
30+ "k8s.io/klog/v2"
2931)
3032
3133type Option func (c * client )
@@ -50,19 +52,19 @@ type ApiError interface {
5052type Client interface {
5153 // Dns provides interface to interact with DNS records
5254 Dns () Dns
53- // Domains provides interface to interact with domains
54- Domains () Domains
5555}
5656
57- func New (apiKey string , opts ... Option ) Client {
57+ func New (apiKey string , apiSecret string , opts ... Option ) Client {
5858 c := & client {
5959 h : helper {
60- apiEndpoint : "https://api.active24.com" ,
61- auth : apiKey ,
60+ apiEndpoint : "https://rest.active24.cz" ,
61+ authKey : apiKey ,
62+ authSecret : apiSecret ,
6263 c : http.Client {
6364 Timeout : time .Second * 10 ,
6465 },
65- l : klog .NewKlogr (),
66+ l : klog .NewKlogr (),
67+ maxPages : 100 , // default max pages to prevent infinite loops
6668 },
6769 }
6870 for _ , opt := range opts {
@@ -81,12 +83,6 @@ func (c *client) Dns() Dns {
8183 }
8284}
8385
84- func (c * client ) Domains () Domains {
85- return & domains {
86- h : c .h ,
87- }
88- }
89-
9086type apiError struct {
9187 err error
9288 resp * http.Response
@@ -102,21 +98,57 @@ func (a *apiError) Response() *http.Response {
10298
10399type helper struct {
104100 apiEndpoint string
105- auth string
101+ authKey string
102+ authSecret string
106103 c http.Client
107104 l klog.Logger
105+ maxPages int
106+ }
107+
108+ func (ch * helper ) getSignature (message , key string ) string {
109+ h := hmac .New (sha1 .New , []byte (key ))
110+ h .Write ([]byte (message ))
111+ return hex .EncodeToString (h .Sum (nil ))
108112}
109113
110- func (ch * helper ) do (method string , suffix string , body io.Reader ) (* http.Response , error ) {
111- r , err := http .NewRequest (method , fmt .Sprintf ("%s/%s" , ch .apiEndpoint , suffix ), body )
114+ func (ch * helper ) do (reqMethod string , reqPath string , reqBody io.Reader ) (* http.Response , error ) {
115+ return ch .doWithParams (reqMethod , reqPath , nil , reqBody )
116+ }
117+
118+ func (ch * helper ) doWithParams (reqMethod string , reqPath string , reqParams url.Values , reqBody io.Reader ) (* http.Response , error ) {
119+ reqPath = path .Join ("/" , reqPath )
120+ reqTimestamp := time .Now ()
121+ canonicalRequest := fmt .Sprintf ("%s %s %d" , reqMethod , reqPath , reqTimestamp .Unix ())
122+ authSignature := ch .getSignature (canonicalRequest , ch .authSecret )
123+
124+ r , err := http .NewRequest (reqMethod , fmt .Sprintf ("%s%s" , ch .apiEndpoint , reqPath ), reqBody )
112125 if err != nil {
113126 return nil , err
114127 }
115- r .Header . Set ( "Authorization" , fmt . Sprintf ( "Bearer %s" , ch . auth ) )
128+ r .URL . RawQuery = reqParams . Encode ( )
116129 r .Header .Set ("Content-Type" , "application/json" )
117130 r .Header .Set ("Accept" , "application/json" )
118- ch .l .V (4 ).Info ("Calling API" , "method" , method , "url" , r .URL .String ())
119- return ch .c .Do (r )
131+ r .Header .Set ("Date" , reqTimestamp .UTC ().Format (time .RFC3339 ))
132+ r .SetBasicAuth (ch .authKey , authSignature )
133+ ch .l .V (4 ).Info ("Calling API" , "method" , reqMethod , "URL" , r .URL .String ())
134+
135+ // Log the request
136+ /* dumpReq, dumpErr := httputil.DumpRequestOut(r, true)
137+ if dumpErr != nil {
138+ return nil, dumpErr
139+ }
140+ ch.l.V(4).Info("doWithParams", "REQUEST", string(dumpReq)) */
141+
142+ resp , err := ch .c .Do (r )
143+
144+ // Log the response
145+ /* dumpResp, dumpErr := httputil.DumpResponse(resp, true)
146+ if dumpErr != nil {
147+ return nil, dumpErr
148+ }
149+ ch.l.V(4).Info("doWithParams", "RESPONSE", string(dumpResp)) */
150+
151+ return resp , err
120152}
121153
122154func apiErr (resp * http.Response , err error ) ApiError {
0 commit comments